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 23 import junit.framework.TestCase; 24 25 import java.util.ArrayList; 26 import java.util.EnumSet; 27 import java.util.List; 28 import java.util.Set; 29 import java.util.logging.Level; 30 import java.util.logging.Logger; 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 PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance(); 41 private ShortNumberInfo shortNumberInfo = ShortNumberInfo.getInstance(); 42 private List<PhoneNumber> invalidCases = new ArrayList<PhoneNumber>(); 43 private List<PhoneNumber> wrongTypeCases = new ArrayList<PhoneNumber>(); 44 45 /** 46 * @param exampleNumberRequestedType type we are requesting an example number for 47 * @param possibleExpectedTypes acceptable types that this number should match, such as 48 * FIXED_LINE and FIXED_LINE_OR_MOBILE for a fixed line example number. 49 */ checkNumbersValidAndCorrectType(PhoneNumberType exampleNumberRequestedType, Set<PhoneNumberType> possibleExpectedTypes)50 private void checkNumbersValidAndCorrectType(PhoneNumberType exampleNumberRequestedType, 51 Set<PhoneNumberType> possibleExpectedTypes) { 52 for (String regionCode : phoneNumberUtil.getSupportedRegions()) { 53 PhoneNumber exampleNumber = 54 phoneNumberUtil.getExampleNumberForType(regionCode, exampleNumberRequestedType); 55 if (exampleNumber != null) { 56 if (!phoneNumberUtil.isValidNumber(exampleNumber)) { 57 invalidCases.add(exampleNumber); 58 logger.log(Level.SEVERE, "Failed validation for " + exampleNumber.toString()); 59 } else { 60 // We know the number is valid, now we check the type. 61 PhoneNumberType exampleNumberType = phoneNumberUtil.getNumberType(exampleNumber); 62 if (!possibleExpectedTypes.contains(exampleNumberType)) { 63 wrongTypeCases.add(exampleNumber); 64 logger.log(Level.SEVERE, "Wrong type for " 65 + exampleNumber.toString() 66 + ": got " + exampleNumberType); 67 logger.log(Level.WARNING, "Expected types: "); 68 for (PhoneNumberType type : possibleExpectedTypes) { 69 logger.log(Level.WARNING, type.toString()); 70 } 71 } 72 } 73 } 74 } 75 } 76 testFixedLine()77 public void testFixedLine() throws Exception { 78 Set<PhoneNumberType> fixedLineTypes = EnumSet.of(PhoneNumberType.FIXED_LINE, 79 PhoneNumberType.FIXED_LINE_OR_MOBILE); 80 checkNumbersValidAndCorrectType(PhoneNumberType.FIXED_LINE, fixedLineTypes); 81 assertEquals(0, invalidCases.size()); 82 assertEquals(0, wrongTypeCases.size()); 83 } 84 testMobile()85 public void testMobile() throws Exception { 86 Set<PhoneNumberType> mobileTypes = EnumSet.of(PhoneNumberType.MOBILE, 87 PhoneNumberType.FIXED_LINE_OR_MOBILE); 88 checkNumbersValidAndCorrectType(PhoneNumberType.MOBILE, mobileTypes); 89 assertEquals(0, invalidCases.size()); 90 assertEquals(0, wrongTypeCases.size()); 91 } 92 testTollFree()93 public void testTollFree() throws Exception { 94 Set<PhoneNumberType> tollFreeTypes = EnumSet.of(PhoneNumberType.TOLL_FREE); 95 checkNumbersValidAndCorrectType(PhoneNumberType.TOLL_FREE, tollFreeTypes); 96 assertEquals(0, invalidCases.size()); 97 assertEquals(0, wrongTypeCases.size()); 98 } 99 testPremiumRate()100 public void testPremiumRate() throws Exception { 101 Set<PhoneNumberType> premiumRateTypes = EnumSet.of(PhoneNumberType.PREMIUM_RATE); 102 checkNumbersValidAndCorrectType(PhoneNumberType.PREMIUM_RATE, premiumRateTypes); 103 assertEquals(0, invalidCases.size()); 104 assertEquals(0, wrongTypeCases.size()); 105 } 106 testVoip()107 public void testVoip() throws Exception { 108 Set<PhoneNumberType> voipTypes = EnumSet.of(PhoneNumberType.VOIP); 109 checkNumbersValidAndCorrectType(PhoneNumberType.VOIP, voipTypes); 110 assertEquals(0, invalidCases.size()); 111 assertEquals(0, wrongTypeCases.size()); 112 } 113 testPager()114 public void testPager() throws Exception { 115 Set<PhoneNumberType> pagerTypes = EnumSet.of(PhoneNumberType.PAGER); 116 checkNumbersValidAndCorrectType(PhoneNumberType.PAGER, pagerTypes); 117 assertEquals(0, invalidCases.size()); 118 assertEquals(0, wrongTypeCases.size()); 119 } 120 testUan()121 public void testUan() throws Exception { 122 Set<PhoneNumberType> uanTypes = EnumSet.of(PhoneNumberType.UAN); 123 checkNumbersValidAndCorrectType(PhoneNumberType.UAN, uanTypes); 124 assertEquals(0, invalidCases.size()); 125 assertEquals(0, wrongTypeCases.size()); 126 } 127 testVoicemail()128 public void testVoicemail() throws Exception { 129 Set<PhoneNumberType> voicemailTypes = EnumSet.of(PhoneNumberType.VOICEMAIL); 130 checkNumbersValidAndCorrectType(PhoneNumberType.VOICEMAIL, voicemailTypes); 131 assertEquals(0, invalidCases.size()); 132 assertEquals(0, wrongTypeCases.size()); 133 } 134 testSharedCost()135 public void testSharedCost() throws Exception { 136 Set<PhoneNumberType> sharedCostTypes = EnumSet.of(PhoneNumberType.SHARED_COST); 137 checkNumbersValidAndCorrectType(PhoneNumberType.SHARED_COST, sharedCostTypes); 138 assertEquals(0, invalidCases.size()); 139 assertEquals(0, wrongTypeCases.size()); 140 } 141 testCanBeInternationallyDialled()142 public void testCanBeInternationallyDialled() throws Exception { 143 for (String regionCode : phoneNumberUtil.getSupportedRegions()) { 144 PhoneNumber exampleNumber = null; 145 PhoneNumberDesc desc = 146 phoneNumberUtil.getMetadataForRegion(regionCode).getNoInternationalDialling(); 147 try { 148 if (desc.hasExampleNumber()) { 149 exampleNumber = phoneNumberUtil.parse(desc.getExampleNumber(), regionCode); 150 } 151 } catch (NumberParseException e) { 152 logger.log(Level.SEVERE, e.toString()); 153 } 154 if (exampleNumber != null && phoneNumberUtil.canBeInternationallyDialled(exampleNumber)) { 155 wrongTypeCases.add(exampleNumber); 156 logger.log(Level.SEVERE, "Number " + exampleNumber.toString() 157 + " should not be internationally diallable"); 158 } 159 } 160 assertEquals(0, wrongTypeCases.size()); 161 } 162 testGlobalNetworkNumbers()163 public void testGlobalNetworkNumbers() throws Exception { 164 for (Integer callingCode : phoneNumberUtil.getSupportedGlobalNetworkCallingCodes()) { 165 PhoneNumber exampleNumber = 166 phoneNumberUtil.getExampleNumberForNonGeoEntity(callingCode); 167 assertNotNull("No example phone number for calling code " + callingCode, exampleNumber); 168 if (!phoneNumberUtil.isValidNumber(exampleNumber)) { 169 invalidCases.add(exampleNumber); 170 logger.log(Level.SEVERE, "Failed validation for " + exampleNumber.toString()); 171 } 172 } 173 assertEquals(0, invalidCases.size()); 174 } 175 testEveryRegionHasAnExampleNumber()176 public void testEveryRegionHasAnExampleNumber() throws Exception { 177 for (String regionCode : phoneNumberUtil.getSupportedRegions()) { 178 PhoneNumber exampleNumber = phoneNumberUtil.getExampleNumber(regionCode); 179 assertNotNull("No example number found for region " + regionCode, exampleNumber); 180 } 181 } 182 testEveryRegionHasAnInvalidExampleNumber()183 public void testEveryRegionHasAnInvalidExampleNumber() throws Exception { 184 for (String regionCode : phoneNumberUtil.getSupportedRegions()) { 185 PhoneNumber exampleNumber = phoneNumberUtil.getInvalidExampleNumber(regionCode); 186 assertNotNull("No invalid example number found for region " + regionCode, exampleNumber); 187 } 188 } 189 testEveryTypeHasAnExampleNumber()190 public void testEveryTypeHasAnExampleNumber() throws Exception { 191 for (PhoneNumberUtil.PhoneNumberType type : PhoneNumberUtil.PhoneNumberType.values()) { 192 if (type == PhoneNumberType.UNKNOWN) { 193 continue; 194 } 195 PhoneNumber exampleNumber = phoneNumberUtil.getExampleNumberForType(type); 196 assertNotNull("No example number found for type " + type, exampleNumber); 197 } 198 } 199 testShortNumbersValidAndCorrectCost()200 public void testShortNumbersValidAndCorrectCost() throws Exception { 201 List<String> invalidStringCases = new ArrayList<String>(); 202 for (String regionCode : shortNumberInfo.getSupportedRegions()) { 203 String exampleShortNumber = shortNumberInfo.getExampleShortNumber(regionCode); 204 if (!shortNumberInfo.isValidShortNumberForRegion( 205 phoneNumberUtil.parse(exampleShortNumber, regionCode), regionCode)) { 206 String invalidStringCase = "region_code: " + regionCode + ", national_number: " 207 + exampleShortNumber; 208 invalidStringCases.add(invalidStringCase); 209 logger.log(Level.SEVERE, "Failed validation for string " + invalidStringCase); 210 } 211 PhoneNumber phoneNumber = phoneNumberUtil.parse(exampleShortNumber, regionCode); 212 if (!shortNumberInfo.isValidShortNumber(phoneNumber)) { 213 invalidCases.add(phoneNumber); 214 logger.log(Level.SEVERE, "Failed validation for " + phoneNumber.toString()); 215 } 216 217 for (ShortNumberInfo.ShortNumberCost cost : ShortNumberInfo.ShortNumberCost.values()) { 218 exampleShortNumber = shortNumberInfo.getExampleShortNumberForCost(regionCode, cost); 219 if (!exampleShortNumber.equals("")) { 220 phoneNumber = phoneNumberUtil.parse(exampleShortNumber, regionCode); 221 ShortNumberInfo.ShortNumberCost exampleShortNumberCost = 222 shortNumberInfo.getExpectedCostForRegion(phoneNumber, regionCode); 223 if (cost != exampleShortNumberCost) { 224 wrongTypeCases.add(phoneNumber); 225 logger.log(Level.SEVERE, "Wrong cost for " + phoneNumber.toString() 226 + ": got " + exampleShortNumberCost 227 + ", expected: " + cost); 228 } 229 } 230 } 231 } 232 assertEquals(0, invalidStringCases.size()); 233 assertEquals(0, invalidCases.size()); 234 assertEquals(0, wrongTypeCases.size()); 235 } 236 testEmergency()237 public void testEmergency() throws Exception { 238 int wrongTypeCounter = 0; 239 for (String regionCode : shortNumberInfo.getSupportedRegions()) { 240 PhoneNumberDesc desc = 241 MetadataManager.getShortNumberMetadataForRegion(regionCode).getEmergency(); 242 if (desc.hasExampleNumber()) { 243 String exampleNumber = desc.getExampleNumber(); 244 PhoneNumber phoneNumber = phoneNumberUtil.parse(exampleNumber, regionCode); 245 if (!shortNumberInfo.isPossibleShortNumberForRegion(phoneNumber, regionCode) 246 || !shortNumberInfo.isEmergencyNumber(exampleNumber, regionCode)) { 247 wrongTypeCounter++; 248 logger.log(Level.SEVERE, "Emergency example number test failed for " + regionCode); 249 } else if (shortNumberInfo.getExpectedCostForRegion(phoneNumber, regionCode) 250 != ShortNumberInfo.ShortNumberCost.TOLL_FREE) { 251 wrongTypeCounter++; 252 logger.log(Level.WARNING, "Emergency example number not toll free for " + regionCode); 253 } 254 } 255 } 256 assertEquals(0, wrongTypeCounter); 257 } 258 testCarrierSpecificShortNumbers()259 public void testCarrierSpecificShortNumbers() throws Exception { 260 int wrongTagCounter = 0; 261 for (String regionCode : shortNumberInfo.getSupportedRegions()) { 262 PhoneNumberDesc desc = 263 MetadataManager.getShortNumberMetadataForRegion(regionCode).getCarrierSpecific(); 264 if (desc.hasExampleNumber()) { 265 String exampleNumber = desc.getExampleNumber(); 266 PhoneNumber carrierSpecificNumber = phoneNumberUtil.parse(exampleNumber, regionCode); 267 if (!shortNumberInfo.isPossibleShortNumberForRegion(carrierSpecificNumber, regionCode) 268 || !shortNumberInfo.isCarrierSpecificForRegion(carrierSpecificNumber, regionCode)) { 269 wrongTagCounter++; 270 logger.log(Level.SEVERE, "Carrier-specific test failed for " + regionCode); 271 } 272 } 273 } 274 assertEquals(0, wrongTagCounter); 275 } 276 testSmsServiceShortNumbers()277 public void testSmsServiceShortNumbers() throws Exception { 278 int wrongTagCounter = 0; 279 for (String regionCode : shortNumberInfo.getSupportedRegions()) { 280 PhoneNumberDesc desc = 281 MetadataManager.getShortNumberMetadataForRegion(regionCode).getSmsServices(); 282 if (desc.hasExampleNumber()) { 283 String exampleNumber = desc.getExampleNumber(); 284 PhoneNumber smsServiceNumber = phoneNumberUtil.parse(exampleNumber, regionCode); 285 if (!shortNumberInfo.isPossibleShortNumberForRegion(smsServiceNumber, regionCode) 286 || !shortNumberInfo.isSmsServiceForRegion(smsServiceNumber, regionCode)) { 287 wrongTagCounter++; 288 logger.log(Level.SEVERE, "SMS service test failed for " + regionCode); 289 } 290 } 291 } 292 assertEquals(0, wrongTagCounter); 293 } 294 } 295