• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Guava 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.common.net;
18 
19 import com.google.common.annotations.GwtCompatible;
20 import com.google.common.annotations.GwtIncompatible;
21 import com.google.common.base.Strings;
22 import com.google.common.collect.ImmutableList;
23 import com.google.common.collect.Iterables;
24 import com.google.common.testing.EqualsTester;
25 import com.google.common.testing.NullPointerTester;
26 
27 import junit.framework.TestCase;
28 
29 import java.util.List;
30 import java.util.Locale;
31 
32 /**
33  * {@link TestCase} for {@link InternetDomainName}.
34  *
35  * @author Craig Berry
36  */
37 @GwtCompatible(emulated = true)
38 public final class InternetDomainNameTest extends TestCase {
39   private static final InternetDomainName UNICODE_EXAMPLE =
40       InternetDomainName.from("j\u00f8rpeland.no");
41   private static final InternetDomainName PUNYCODE_EXAMPLE =
42       InternetDomainName.from("xn--jrpeland-54a.no");
43 
44   /**
45    * The Greek letter delta, used in unicode testing.
46    */
47   private static final String DELTA = "\u0394";
48 
49   /**
50    * A domain part which is valid under lenient validation, but invalid under
51    * strict validation.
52    */
53   static final String LOTS_OF_DELTAS = Strings.repeat(DELTA, 62);
54 
55   private static final String ALMOST_TOO_MANY_LEVELS =
56       Strings.repeat("a.", 127);
57 
58   private static final String ALMOST_TOO_LONG =
59       Strings.repeat("aaaaa.", 40) + "1234567890.c";
60 
61   private static final List<String> VALID_NAME = ImmutableList.of(
62       "foo.com",
63       "f-_-o.cOM",
64       "f--1.com",
65       "f11-1.com",
66       "www",
67       "abc.a23",
68       "biz.com.ua",
69       "x",
70       "fOo",
71       "f--o",
72       "f_a",
73       "foo.net.us\uFF61ocm",
74       "woo.com.",
75       "a" + DELTA + "b.com",
76       ALMOST_TOO_MANY_LEVELS,
77       ALMOST_TOO_LONG);
78 
79   private static final List<String> INVALID_NAME = ImmutableList.of(
80       "",
81       " ",
82       "127.0.0.1",
83       "::1", "13",
84       "abc.12c",
85       "foo-.com",
86       "_bar.quux",
87       "foo+bar.com",
88       "foo!bar.com",
89       ".foo.com",
90       "..bar.com",
91       "baz..com",
92       "..quiffle.com",
93       "fleeb.com..",
94       ".",
95       "..",
96       "...",
97       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com",
98       "a" + DELTA + " .com",
99       ALMOST_TOO_MANY_LEVELS + "com",
100       ALMOST_TOO_LONG + ".c");
101 
102   private static final List<String> PS = ImmutableList.of(
103       "com",
104       "co.uk",
105       "foo.ar",
106       "xxxxxx.ar",
107       "org.mK",
108       "us",
109       "uk\uFF61com.",  // Alternate dot character
110       "\u7f51\u7edc.Cn",  // "网络.Cn"
111       "j\u00f8rpeland.no",  // "jorpeland.no" (first o slashed)
112       "xn--jrpeland-54a.no"  // IDNA (punycode) encoding of above
113   );
114 
115   private static final List<String> NO_PS = ImmutableList.of(
116       "www", "foo.google", "x.y.z");
117 
118   private static final List<String> NON_PS = ImmutableList.of(
119       "foo.bar.com", "foo.ca", "foo.bar.ca",
120       "foo.bar.co.il", "state.CA.us", "www.state.pa.us", "pvt.k12.ca.us",
121       "www.google.com", "www4.yahoo.co.uk", "home.netscape.com",
122       "web.MIT.edu", "foo.eDu.au", "utenti.blah.IT", "dominio.com.co");
123 
124   private static final List<String> TOP_PRIVATE_DOMAIN = ImmutableList.of(
125       "google.com", "foo.Co.uk", "foo.ca.us.");
126 
127   private static final List<String> UNDER_PRIVATE_DOMAIN = ImmutableList.of(
128       "foo.bar.google.com", "a.b.co.uk", "x.y.ca.us");
129 
130   private static final List<String> VALID_IP_ADDRS = ImmutableList.of(
131       "1.2.3.4", "127.0.0.1", "::1", "2001:db8::1");
132 
133   private static final List<String> INVALID_IP_ADDRS = ImmutableList.of(
134       "", "1", "1.2.3", "...", "1.2.3.4.5", "400.500.600.700",
135       ":", ":::1", "2001:db8:");
136 
137   private static final List<String> SOMEWHERE_UNDER_PS = ImmutableList.of(
138       "foo.bar.google.com",
139       "a.b.c.1.2.3.ca.us",
140       "site.jp",
141       "uomi-online.kir.jp",
142       "jprs.co.jp",
143       "site.quick.jp",
144       "site.tenki.jp",
145       "site.or.jp",
146       "site.gr.jp",
147       "site.ne.jp",
148       "site.ac.jp",
149       "site.ad.jp",
150       "site.ed.jp",
151       "site.geo.jp",
152       "site.go.jp",
153       "site.lg.jp",
154       "1.fm",
155       "site.cc",
156       "site.ee",
157       "site.fi",
158       "site.fm",
159       "site.gr",
160       "www.leguide.ma",
161       "site.ma",
162       "some.org.mk",
163       "site.mk",
164       "site.tv",
165       "site.us",
166       "www.odev.us",
167       "www.GOOGLE.com",
168       "www.com",
169       "google.com",
170       "www7.google.co.uk",
171       "google.Co.uK",
172       "jobs.kt.com.",
173       "home.netscape.com",
174       "web.stanford.edu",
175       "stanford.edu",
176       "state.ca.us",
177       "www.state.ca.us",
178       "state.ca.us",
179       "pvt.k12.ca.us",
180       "www.rave.ca.",
181       "cnn.ca",
182       "ledger-enquirer.com",
183       "it-trace.ch",
184       "cool.dk",
185       "cool.co.uk",
186       "cool.de",
187       "cool.es",
188       "cool\uFF61fr", // Alternate dot character
189       "cool.nl",
190       "members.blah.nl.",
191       "cool.se",
192       "utenti.blah.it",
193       "kt.co",
194       "a\u7f51\u7edcA.\u7f51\u7edc.Cn"  // "a网络A.网络.Cn"
195   );
196 
testValid()197   public void testValid() {
198     for (String name : VALID_NAME) {
199       InternetDomainName.from(name);
200     }
201   }
202 
testInvalid()203   public void testInvalid() {
204     for (String name : INVALID_NAME) {
205       try {
206         InternetDomainName.from(name);
207         fail("Should have been invalid: '" + name + "'");
208       } catch (IllegalArgumentException expected) {
209         // Expected case
210       }
211     }
212   }
213 
testPublicSuffix()214   public void testPublicSuffix() {
215     for (String name : PS) {
216       final InternetDomainName domain = InternetDomainName.from(name);
217       assertTrue(name, domain.isPublicSuffix());
218       assertTrue(name, domain.hasPublicSuffix());
219       assertFalse(name, domain.isUnderPublicSuffix());
220       assertFalse(name, domain.isTopPrivateDomain());
221       assertEquals(domain, domain.publicSuffix());
222     }
223 
224     for (String name : NO_PS) {
225       final InternetDomainName domain = InternetDomainName.from(name);
226       assertFalse(name, domain.isPublicSuffix());
227       assertFalse(name, domain.hasPublicSuffix());
228       assertFalse(name, domain.isUnderPublicSuffix());
229       assertFalse(name, domain.isTopPrivateDomain());
230       assertNull(domain.publicSuffix());
231     }
232 
233     for (String name : NON_PS) {
234       final InternetDomainName domain = InternetDomainName.from(name);
235       assertFalse(name, domain.isPublicSuffix());
236       assertTrue(name, domain.hasPublicSuffix());
237       assertTrue(name, domain.isUnderPublicSuffix());
238     }
239   }
240 
testUnderPublicSuffix()241   public void testUnderPublicSuffix() {
242     for (String name : SOMEWHERE_UNDER_PS) {
243       final InternetDomainName domain = InternetDomainName.from(name);
244       assertFalse(name, domain.isPublicSuffix());
245       assertTrue(name, domain.hasPublicSuffix());
246       assertTrue(name, domain.isUnderPublicSuffix());
247     }
248   }
249 
testTopPrivateDomain()250   public void testTopPrivateDomain() {
251     for (String name : TOP_PRIVATE_DOMAIN) {
252       final InternetDomainName domain = InternetDomainName.from(name);
253       assertFalse(name, domain.isPublicSuffix());
254       assertTrue(name, domain.hasPublicSuffix());
255       assertTrue(name, domain.isUnderPublicSuffix());
256       assertTrue(name, domain.isTopPrivateDomain());
257       assertEquals(domain.parent(), domain.publicSuffix());
258     }
259   }
260 
testUnderPrivateDomain()261   public void testUnderPrivateDomain() {
262     for (String name : UNDER_PRIVATE_DOMAIN) {
263       final InternetDomainName domain = InternetDomainName.from(name);
264       assertFalse(name, domain.isPublicSuffix());
265       assertTrue(name, domain.hasPublicSuffix());
266       assertTrue(name, domain.isUnderPublicSuffix());
267       assertFalse(name, domain.isTopPrivateDomain());
268     }
269   }
270 
testParent()271   public void testParent() {
272     assertEquals(
273         "com",
274         InternetDomainName.from("google.com").parent().name());
275     assertEquals(
276         "uk",
277         InternetDomainName.from("co.uk").parent().name());
278     assertEquals(
279         "google.com",
280         InternetDomainName.from("www.google.com").parent().name());
281 
282     try {
283       InternetDomainName.from("com").parent();
284       fail("'com' should throw ISE on .parent() call");
285     } catch (IllegalStateException expected) {
286     }
287   }
288 
testChild()289   public void testChild() {
290     InternetDomainName domain = InternetDomainName.from("foo.com");
291 
292     assertEquals("www.foo.com", domain.child("www").name());
293 
294     try {
295       domain.child("www.");
296       fail("www..google.com should have been invalid");
297     } catch (IllegalArgumentException expected) {
298       // Expected outcome
299     }
300   }
301 
testParentChild()302   public void testParentChild() {
303     InternetDomainName origin = InternetDomainName.from("foo.com");
304     InternetDomainName parent = origin.parent();
305     assertEquals("com", parent.name());
306 
307     // These would throw an exception if leniency were not preserved during parent() and child()
308     // calls.
309     InternetDomainName child = parent.child(LOTS_OF_DELTAS);
310     child.child(LOTS_OF_DELTAS);
311   }
312 
testValidTopPrivateDomain()313   public void testValidTopPrivateDomain() {
314     InternetDomainName googleDomain = InternetDomainName.from("google.com");
315 
316     assertEquals(googleDomain, googleDomain.topPrivateDomain());
317     assertEquals(googleDomain, googleDomain.child("mail").topPrivateDomain());
318     assertEquals(googleDomain, googleDomain.child("foo.bar").topPrivateDomain());
319   }
320 
testInvalidTopPrivateDomain()321   public void testInvalidTopPrivateDomain() {
322     List<String> badCookieDomains = ImmutableList.of("co.uk", "foo", "com");
323 
324     for (String domain : badCookieDomains) {
325       try {
326         InternetDomainName.from(domain).topPrivateDomain();
327         fail(domain);
328       } catch (IllegalStateException expected) {
329       }
330     }
331   }
332 
testIsValid()333   public void testIsValid() {
334     final Iterable<String> validCases = Iterables.concat(
335         VALID_NAME, PS, NO_PS, NON_PS);
336     final Iterable<String> invalidCases = Iterables.concat(
337         INVALID_NAME, VALID_IP_ADDRS, INVALID_IP_ADDRS);
338 
339     for (String valid : validCases) {
340       assertTrue(valid, InternetDomainName.isValid(valid));
341     }
342 
343     for (String invalid : invalidCases) {
344       assertFalse(invalid, InternetDomainName.isValid(invalid));
345     }
346   }
347 
348   // TODO(hhchan): Resurrect this test after removing the reference to
349   // String.toLowerCase(Locale)
350   @GwtIncompatible("String.toLowerCase(Locale)")
testName()351   public void testName() {
352     for (String inputName : SOMEWHERE_UNDER_PS) {
353       InternetDomainName domain = InternetDomainName.from(inputName);
354 
355       /*
356        * We would ordinarily use constants for the expected results, but
357        * doing it by derivation allows us to reuse the test case definitions
358        * used in other tests.
359        */
360 
361       String expectedName = inputName.toLowerCase(Locale.ENGLISH);
362       expectedName = expectedName.replaceAll("[\u3002\uFF0E\uFF61]", ".");
363 
364       if (expectedName.endsWith(".")) {
365         expectedName = expectedName.substring(0, expectedName.length() - 1);
366       }
367 
368       assertEquals(expectedName, domain.name());
369     }
370   }
371 
testExclusion()372   public void testExclusion() {
373     InternetDomainName domain = InternetDomainName.from("foo.nhs.uk");
374     assertTrue(domain.hasPublicSuffix());
375     assertEquals("uk", domain.publicSuffix().name());
376 
377     // Behold the weirdness!
378     assertFalse(domain.publicSuffix().isPublicSuffix());
379   }
380 
testEquality()381   public void testEquality() {
382     new EqualsTester()
383         .addEqualityGroup(
384             idn("google.com"), idn("google.com"), idn("GOOGLE.COM"))
385         .addEqualityGroup(idn("www.google.com"))
386         .addEqualityGroup(UNICODE_EXAMPLE)
387         .addEqualityGroup(PUNYCODE_EXAMPLE)
388         .testEquals();
389   }
390 
idn(String domain)391   private static InternetDomainName idn(String domain) {
392     return InternetDomainName.from(domain);
393   }
394 
395   @GwtIncompatible("NullPointerTester")
testNulls()396   public void testNulls() throws Exception {
397     final NullPointerTester tester = new NullPointerTester();
398 
399     tester.testAllPublicStaticMethods(InternetDomainName.class);
400     tester.testAllPublicInstanceMethods(InternetDomainName.from("google.com"));
401   }
402 
403 }
404