1 /* 2 * Copyright (C) 2009 The Libphonenumber Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.i18n.phonenumbers; 18 19 import com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberType; 20 import com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc; 21 import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber; 22 import com.google.i18n.phonenumbers.metadata.DefaultMetadataDependenciesProvider; 23 import com.google.i18n.phonenumbers.metadata.source.RegionMetadataSource; 24 import java.util.ArrayList; 25 import java.util.EnumSet; 26 import java.util.List; 27 import java.util.Set; 28 import java.util.logging.Level; 29 import java.util.logging.Logger; 30 import junit.framework.TestCase; 31 32 /** 33 * Verifies all of the example numbers in the metadata are valid and of the correct type. If no 34 * example number exists for a particular type, the test still passes since not all types are 35 * relevant for all regions. Tests that check the XML schema will ensure that an exampleNumber 36 * node is present for every phone number description. 37 */ 38 public class ExampleNumbersTest extends TestCase { 39 private static final Logger logger = Logger.getLogger(ExampleNumbersTest.class.getName()); 40 private final PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance(); 41 private final ShortNumberInfo shortNumberInfo = ShortNumberInfo.getInstance(); 42 private final RegionMetadataSource shortNumberMetadataSource = 43 DefaultMetadataDependenciesProvider.getInstance().getShortNumberMetadataSource(); 44 45 private final List<PhoneNumber> invalidCases = new ArrayList<>(); 46 private final List<PhoneNumber> wrongTypeCases = new ArrayList<>(); 47 private final Set<String> shortNumberSupportedRegions = ShortNumbersRegionCodeSet.getRegionCodeSet(); 48 49 /** 50 * @param exampleNumberRequestedType type we are requesting an example number for 51 * @param possibleExpectedTypes acceptable types that this number should match, such as 52 * FIXED_LINE and FIXED_LINE_OR_MOBILE for a fixed line example number. 53 */ checkNumbersValidAndCorrectType(PhoneNumberType exampleNumberRequestedType, Set<PhoneNumberType> possibleExpectedTypes)54 private void checkNumbersValidAndCorrectType(PhoneNumberType exampleNumberRequestedType, 55 Set<PhoneNumberType> possibleExpectedTypes) { 56 for (String regionCode : phoneNumberUtil.getSupportedRegions()) { 57 PhoneNumber exampleNumber = 58 phoneNumberUtil.getExampleNumberForType(regionCode, exampleNumberRequestedType); 59 if (exampleNumber != null) { 60 if (!phoneNumberUtil.isValidNumber(exampleNumber)) { 61 invalidCases.add(exampleNumber); 62 logger.log(Level.SEVERE, "Failed validation for " + exampleNumber); 63 } else { 64 // We know the number is valid, now we check the type. 65 PhoneNumberType exampleNumberType = phoneNumberUtil.getNumberType(exampleNumber); 66 if (!possibleExpectedTypes.contains(exampleNumberType)) { 67 wrongTypeCases.add(exampleNumber); 68 logger.log(Level.SEVERE, "Wrong type for " 69 + exampleNumber 70 + ": got " + exampleNumberType); 71 logger.log(Level.WARNING, "Expected types: "); 72 for (PhoneNumberType type : possibleExpectedTypes) { 73 logger.log(Level.WARNING, type.toString()); 74 } 75 } 76 } 77 } 78 } 79 } 80 testFixedLine()81 public void testFixedLine() { 82 Set<PhoneNumberType> fixedLineTypes = EnumSet.of(PhoneNumberType.FIXED_LINE, 83 PhoneNumberType.FIXED_LINE_OR_MOBILE); 84 checkNumbersValidAndCorrectType(PhoneNumberType.FIXED_LINE, fixedLineTypes); 85 assertEquals(0, invalidCases.size()); 86 assertEquals(0, wrongTypeCases.size()); 87 } 88 testMobile()89 public void testMobile() { 90 Set<PhoneNumberType> mobileTypes = EnumSet.of(PhoneNumberType.MOBILE, 91 PhoneNumberType.FIXED_LINE_OR_MOBILE); 92 checkNumbersValidAndCorrectType(PhoneNumberType.MOBILE, mobileTypes); 93 assertEquals(0, invalidCases.size()); 94 assertEquals(0, wrongTypeCases.size()); 95 } 96 testTollFree()97 public void testTollFree() { 98 Set<PhoneNumberType> tollFreeTypes = EnumSet.of(PhoneNumberType.TOLL_FREE); 99 checkNumbersValidAndCorrectType(PhoneNumberType.TOLL_FREE, tollFreeTypes); 100 assertEquals(0, invalidCases.size()); 101 assertEquals(0, wrongTypeCases.size()); 102 } 103 testPremiumRate()104 public void testPremiumRate() { 105 Set<PhoneNumberType> premiumRateTypes = EnumSet.of(PhoneNumberType.PREMIUM_RATE); 106 checkNumbersValidAndCorrectType(PhoneNumberType.PREMIUM_RATE, premiumRateTypes); 107 assertEquals(0, invalidCases.size()); 108 assertEquals(0, wrongTypeCases.size()); 109 } 110 testVoip()111 public void testVoip() { 112 Set<PhoneNumberType> voipTypes = EnumSet.of(PhoneNumberType.VOIP); 113 checkNumbersValidAndCorrectType(PhoneNumberType.VOIP, voipTypes); 114 assertEquals(0, invalidCases.size()); 115 assertEquals(0, wrongTypeCases.size()); 116 } 117 testPager()118 public void testPager() { 119 Set<PhoneNumberType> pagerTypes = EnumSet.of(PhoneNumberType.PAGER); 120 checkNumbersValidAndCorrectType(PhoneNumberType.PAGER, pagerTypes); 121 assertEquals(0, invalidCases.size()); 122 assertEquals(0, wrongTypeCases.size()); 123 } 124 testUan()125 public void testUan() { 126 Set<PhoneNumberType> uanTypes = EnumSet.of(PhoneNumberType.UAN); 127 checkNumbersValidAndCorrectType(PhoneNumberType.UAN, uanTypes); 128 assertEquals(0, invalidCases.size()); 129 assertEquals(0, wrongTypeCases.size()); 130 } 131 testVoicemail()132 public void testVoicemail() { 133 Set<PhoneNumberType> voicemailTypes = EnumSet.of(PhoneNumberType.VOICEMAIL); 134 checkNumbersValidAndCorrectType(PhoneNumberType.VOICEMAIL, voicemailTypes); 135 assertEquals(0, invalidCases.size()); 136 assertEquals(0, wrongTypeCases.size()); 137 } 138 testSharedCost()139 public void testSharedCost() { 140 Set<PhoneNumberType> sharedCostTypes = EnumSet.of(PhoneNumberType.SHARED_COST); 141 checkNumbersValidAndCorrectType(PhoneNumberType.SHARED_COST, sharedCostTypes); 142 assertEquals(0, invalidCases.size()); 143 assertEquals(0, wrongTypeCases.size()); 144 } 145 testCanBeInternationallyDialled()146 public void testCanBeInternationallyDialled() { 147 for (String regionCode : phoneNumberUtil.getSupportedRegions()) { 148 PhoneNumber exampleNumber = null; 149 PhoneNumberDesc desc = 150 phoneNumberUtil.getMetadataForRegion(regionCode).getNoInternationalDialling(); 151 try { 152 if (desc.hasExampleNumber()) { 153 exampleNumber = phoneNumberUtil.parse(desc.getExampleNumber(), regionCode); 154 } 155 } catch (NumberParseException e) { 156 logger.log(Level.SEVERE, e.toString()); 157 } 158 if (exampleNumber != null && phoneNumberUtil.canBeInternationallyDialled(exampleNumber)) { 159 wrongTypeCases.add(exampleNumber); 160 logger.log(Level.SEVERE, "Number " + exampleNumber 161 + " should not be internationally diallable"); 162 } 163 } 164 assertEquals(0, wrongTypeCases.size()); 165 } 166 testGlobalNetworkNumbers()167 public void testGlobalNetworkNumbers() { 168 for (Integer callingCode : phoneNumberUtil.getSupportedGlobalNetworkCallingCodes()) { 169 PhoneNumber exampleNumber = 170 phoneNumberUtil.getExampleNumberForNonGeoEntity(callingCode); 171 assertNotNull("No example phone number for calling code " + callingCode, exampleNumber); 172 if (!phoneNumberUtil.isValidNumber(exampleNumber)) { 173 invalidCases.add(exampleNumber); 174 logger.log(Level.SEVERE, "Failed validation for " + exampleNumber); 175 } 176 } 177 assertEquals(0, invalidCases.size()); 178 } 179 testEveryRegionHasAnExampleNumber()180 public void testEveryRegionHasAnExampleNumber() { 181 for (String regionCode : phoneNumberUtil.getSupportedRegions()) { 182 PhoneNumber exampleNumber = phoneNumberUtil.getExampleNumber(regionCode); 183 assertNotNull("No example number found for region " + regionCode, exampleNumber); 184 } 185 } 186 testEveryRegionHasAnInvalidExampleNumber()187 public void testEveryRegionHasAnInvalidExampleNumber() { 188 for (String regionCode : phoneNumberUtil.getSupportedRegions()) { 189 PhoneNumber exampleNumber = phoneNumberUtil.getInvalidExampleNumber(regionCode); 190 assertNotNull("No invalid example number found for region " + regionCode, exampleNumber); 191 } 192 } 193 testEveryTypeHasAnExampleNumber()194 public void testEveryTypeHasAnExampleNumber() { 195 for (PhoneNumberUtil.PhoneNumberType type : PhoneNumberUtil.PhoneNumberType.values()) { 196 if (type == PhoneNumberType.UNKNOWN) { 197 continue; 198 } 199 PhoneNumber exampleNumber = phoneNumberUtil.getExampleNumberForType(type); 200 assertNotNull("No example number found for type " + type, exampleNumber); 201 } 202 } 203 testShortNumbersValidAndCorrectCost()204 public void testShortNumbersValidAndCorrectCost() throws Exception { 205 List<String> invalidStringCases = new ArrayList<>(); 206 for (String regionCode : shortNumberSupportedRegions) { 207 String exampleShortNumber = shortNumberInfo.getExampleShortNumber(regionCode); 208 if (!shortNumberInfo.isValidShortNumberForRegion( 209 phoneNumberUtil.parse(exampleShortNumber, regionCode), regionCode)) { 210 String invalidStringCase = "region_code: " + regionCode + ", national_number: " 211 + exampleShortNumber; 212 invalidStringCases.add(invalidStringCase); 213 logger.log(Level.SEVERE, "Failed validation for string " + invalidStringCase); 214 } 215 PhoneNumber phoneNumber = phoneNumberUtil.parse(exampleShortNumber, regionCode); 216 if (!shortNumberInfo.isValidShortNumber(phoneNumber)) { 217 invalidCases.add(phoneNumber); 218 logger.log(Level.SEVERE, "Failed validation for " + phoneNumber); 219 } 220 221 for (ShortNumberInfo.ShortNumberCost cost : ShortNumberInfo.ShortNumberCost.values()) { 222 exampleShortNumber = shortNumberInfo.getExampleShortNumberForCost(regionCode, cost); 223 if (!exampleShortNumber.equals("")) { 224 phoneNumber = phoneNumberUtil.parse(exampleShortNumber, regionCode); 225 ShortNumberInfo.ShortNumberCost exampleShortNumberCost = 226 shortNumberInfo.getExpectedCostForRegion(phoneNumber, regionCode); 227 if (cost != exampleShortNumberCost) { 228 wrongTypeCases.add(phoneNumber); 229 logger.log(Level.SEVERE, "Wrong cost for " + phoneNumber.toString() 230 + ": got " + exampleShortNumberCost 231 + ", expected: " + cost); 232 } 233 } 234 } 235 } 236 assertEquals(0, invalidStringCases.size()); 237 assertEquals(0, invalidCases.size()); 238 assertEquals(0, wrongTypeCases.size()); 239 } 240 testEmergency()241 public void testEmergency() throws Exception { 242 int wrongTypeCounter = 0; 243 for (String regionCode : shortNumberSupportedRegions) { 244 PhoneNumberDesc desc = shortNumberMetadataSource.getMetadataForRegion(regionCode).getEmergency(); 245 if (desc.hasExampleNumber()) { 246 String exampleNumber = desc.getExampleNumber(); 247 PhoneNumber phoneNumber = phoneNumberUtil.parse(exampleNumber, regionCode); 248 if (!shortNumberInfo.isPossibleShortNumberForRegion(phoneNumber, regionCode) 249 || !shortNumberInfo.isEmergencyNumber(exampleNumber, regionCode)) { 250 wrongTypeCounter++; 251 logger.log(Level.SEVERE, "Emergency example number test failed for " + regionCode); 252 } else if (shortNumberInfo.getExpectedCostForRegion(phoneNumber, regionCode) 253 != ShortNumberInfo.ShortNumberCost.TOLL_FREE) { 254 wrongTypeCounter++; 255 logger.log(Level.WARNING, "Emergency example number not toll free for " + regionCode); 256 } 257 } 258 } 259 assertEquals(0, wrongTypeCounter); 260 } 261 testCarrierSpecificShortNumbers()262 public void testCarrierSpecificShortNumbers() throws Exception { 263 int wrongTagCounter = 0; 264 for (String regionCode : shortNumberSupportedRegions) { 265 PhoneNumberDesc desc = shortNumberMetadataSource.getMetadataForRegion(regionCode).getCarrierSpecific(); 266 if (desc.hasExampleNumber()) { 267 String exampleNumber = desc.getExampleNumber(); 268 PhoneNumber carrierSpecificNumber = phoneNumberUtil.parse(exampleNumber, regionCode); 269 if (!shortNumberInfo.isPossibleShortNumberForRegion(carrierSpecificNumber, regionCode) 270 || !shortNumberInfo.isCarrierSpecificForRegion(carrierSpecificNumber, regionCode)) { 271 wrongTagCounter++; 272 logger.log(Level.SEVERE, "Carrier-specific test failed for " + regionCode); 273 } 274 } 275 } 276 assertEquals(0, wrongTagCounter); 277 } 278 testSmsServiceShortNumbers()279 public void testSmsServiceShortNumbers() throws Exception { 280 int wrongTagCounter = 0; 281 for (String regionCode : shortNumberSupportedRegions) { 282 PhoneNumberDesc desc = shortNumberMetadataSource.getMetadataForRegion(regionCode).getSmsServices(); 283 if (desc.hasExampleNumber()) { 284 String exampleNumber = desc.getExampleNumber(); 285 PhoneNumber smsServiceNumber = phoneNumberUtil.parse(exampleNumber, regionCode); 286 if (!shortNumberInfo.isPossibleShortNumberForRegion(smsServiceNumber, regionCode) 287 || !shortNumberInfo.isSmsServiceForRegion(smsServiceNumber, regionCode)) { 288 wrongTagCounter++; 289 logger.log(Level.SEVERE, "SMS service test failed for " + regionCode); 290 } 291 } 292 } 293 assertEquals(0, wrongTagCounter); 294 } 295 } 296