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