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