| /* |
| * Copyright (C) 2009 The Guava Authors |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.google.common.net; |
| |
| import com.google.common.annotations.GwtCompatible; |
| import com.google.common.annotations.GwtIncompatible; |
| import com.google.common.base.Ascii; |
| import com.google.common.base.Strings; |
| import com.google.common.collect.ImmutableSet; |
| import com.google.common.collect.Iterables; |
| import com.google.common.testing.EqualsTester; |
| import com.google.common.testing.NullPointerTester; |
| import junit.framework.TestCase; |
| |
| /** |
| * {@link TestCase} for {@link InternetDomainName}. |
| * |
| * @author Craig Berry |
| */ |
| @GwtCompatible(emulated = true) |
| public final class InternetDomainNameTest extends TestCase { |
| private static final InternetDomainName UNICODE_EXAMPLE = |
| InternetDomainName.from("j\u00f8rpeland.no"); |
| private static final InternetDomainName PUNYCODE_EXAMPLE = |
| InternetDomainName.from("xn--jrpeland-54a.no"); |
| |
| /** The Greek letter delta, used in unicode testing. */ |
| private static final String DELTA = "\u0394"; |
| |
| /** A domain part which is valid under lenient validation, but invalid under strict validation. */ |
| static final String LOTS_OF_DELTAS = Strings.repeat(DELTA, 62); |
| |
| private static final String ALMOST_TOO_MANY_LEVELS = Strings.repeat("a.", 127); |
| |
| private static final String ALMOST_TOO_LONG = Strings.repeat("aaaaa.", 40) + "1234567890.c"; |
| |
| private static final ImmutableSet<String> VALID_NAME = |
| ImmutableSet.of( |
| "foo.com", |
| "f-_-o.cOM", |
| "f--1.com", |
| "f11-1.com", |
| "www", |
| "abc.a23", |
| "biz.com.ua", |
| "x", |
| "fOo", |
| "f--o", |
| "f_a", |
| "foo.net.us\uFF61ocm", |
| "woo.com.", |
| "a" + DELTA + "b.com", |
| ALMOST_TOO_MANY_LEVELS, |
| ALMOST_TOO_LONG); |
| |
| private static final ImmutableSet<String> INVALID_NAME = |
| ImmutableSet.of( |
| "", |
| " ", |
| "127.0.0.1", |
| "::1", |
| "13", |
| "abc.12c", |
| "foo-.com", |
| "_bar.quux", |
| "foo+bar.com", |
| "foo!bar.com", |
| ".foo.com", |
| "..bar.com", |
| "baz..com", |
| "..quiffle.com", |
| "fleeb.com..", |
| ".", |
| "..", |
| "...", |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com", |
| "a" + DELTA + " .com", |
| ALMOST_TOO_MANY_LEVELS + "com", |
| ALMOST_TOO_LONG + ".c"); |
| |
| private static final ImmutableSet<String> RS = |
| ImmutableSet.of( |
| "com", |
| "co.uk", |
| "foo.bd", |
| "xxxxxx.bd", |
| "org.mK", |
| "us", |
| "co.uk.", // Trailing dot |
| "co\uFF61uk", // Alternate dot character |
| "\u7f51\u7edc.Cn", // "网络.Cn" |
| "j\u00f8rpeland.no", // "jorpeland.no" (first o slashed) |
| "xn--jrpeland-54a.no"); // IDNA (punycode) encoding of above |
| |
| private static final ImmutableSet<String> PS_NOT_RS = |
| ImmutableSet.of("blogspot.com", "blogspot.co.uk", "uk.com"); |
| |
| private static final ImmutableSet<String> PS = |
| ImmutableSet.<String>builder().addAll(RS).addAll(PS_NOT_RS).build(); |
| |
| private static final ImmutableSet<String> NO_PS = |
| ImmutableSet.of("www", "foo.ihopethiswillneverbeapublicsuffix", "x.y.z"); |
| |
| /** |
| * Having a public suffix is equivalent to having a registry suffix, because all registry suffixes |
| * are public suffixes, and all public suffixes have registry suffixes. |
| */ |
| private static final ImmutableSet<String> NO_RS = NO_PS; |
| |
| private static final ImmutableSet<String> NON_PS = |
| ImmutableSet.of( |
| "foo.bar.com", |
| "foo.ca", |
| "foo.bar.ca", |
| "foo.blogspot.com", |
| "foo.blogspot.co.uk", |
| "foo.uk.com", |
| "foo.bar.co.il", |
| "state.CA.us", |
| "www.state.pa.us", |
| "pvt.k12.ca.us", |
| "www.google.com", |
| "www4.yahoo.co.uk", |
| "home.netscape.com", |
| "web.MIT.edu", |
| "foo.eDu.au", |
| "utenti.blah.IT", |
| "dominio.com.co"); |
| |
| private static final ImmutableSet<String> NON_RS = |
| ImmutableSet.<String>builder().addAll(NON_PS).addAll(PS_NOT_RS).build(); |
| |
| private static final ImmutableSet<String> TOP_UNDER_REGISTRY_SUFFIX = |
| ImmutableSet.of("google.com", "foo.Co.uk", "foo.ca.us."); |
| |
| private static final ImmutableSet<String> TOP_PRIVATE_DOMAIN = |
| ImmutableSet.of("google.com", "foo.Co.uk", "foo.ca.us.", "foo.blogspot.com"); |
| |
| private static final ImmutableSet<String> UNDER_TOP_UNDER_REGISTRY_SUFFIX = |
| ImmutableSet.of("foo.bar.google.com", "a.b.co.uk", "x.y.ca.us"); |
| |
| private static final ImmutableSet<String> UNDER_PRIVATE_DOMAIN = |
| ImmutableSet.of("foo.bar.google.com", "a.b.co.uk", "x.y.ca.us", "a.b.blogspot.com"); |
| |
| private static final ImmutableSet<String> VALID_IP_ADDRS = |
| ImmutableSet.of("1.2.3.4", "127.0.0.1", "::1", "2001:db8::1"); |
| |
| private static final ImmutableSet<String> INVALID_IP_ADDRS = |
| ImmutableSet.of( |
| "", "1", "1.2.3", "...", "1.2.3.4.5", "400.500.600.700", ":", ":::1", "2001:db8:"); |
| |
| private static final ImmutableSet<String> SOMEWHERE_UNDER_PS = |
| ImmutableSet.of( |
| "foo.bar.google.com", |
| "a.b.c.1.2.3.ca.us", |
| "site.jp", |
| "uomi-online.kir.jp", |
| "jprs.co.jp", |
| "site.quick.jp", |
| "site.tenki.jp", |
| "site.or.jp", |
| "site.gr.jp", |
| "site.ne.jp", |
| "site.ac.jp", |
| "site.ad.jp", |
| "site.ed.jp", |
| "site.geo.jp", |
| "site.go.jp", |
| "site.lg.jp", |
| "1.fm", |
| "site.cc", |
| "site.ee", |
| "site.fi", |
| "site.fm", |
| "site.gr", |
| "www.leguide.ma", |
| "site.ma", |
| "some.org.mk", |
| "site.mk", |
| "site.tv", |
| "site.us", |
| "www.odev.us", |
| "www.GOOGLE.com", |
| "www.com", |
| "google.com", |
| "www7.google.co.uk", |
| "google.Co.uK", |
| "jobs.kt.com.", |
| "home.netscape.com", |
| "web.stanford.edu", |
| "stanford.edu", |
| "state.ca.us", |
| "www.state.ca.us", |
| "state.ca.us", |
| "pvt.k12.ca.us", |
| "www.rave.ca.", |
| "cnn.ca", |
| "ledger-enquirer.com", |
| "it-trace.ch", |
| "cool.dk", |
| "cool.co.uk", |
| "cool.de", |
| "cool.es", |
| "cool\uFF61fr", // Alternate dot character |
| "cool.nl", |
| "members.blah.nl.", |
| "cool.se", |
| "utenti.blah.it", |
| "kt.co", |
| "a\u7f51\u7edcA.\u7f51\u7edc.Cn" // "a网络A.网络.Cn" |
| ); |
| |
| private static final ImmutableSet<String> SOMEWHERE_UNDER_RS = |
| ImmutableSet.<String>builder().addAll(SOMEWHERE_UNDER_PS).addAll(PS_NOT_RS).build(); |
| |
| public void testValid() { |
| for (String name : VALID_NAME) { |
| InternetDomainName.from(name); |
| } |
| } |
| |
| public void testInvalid() { |
| for (String name : INVALID_NAME) { |
| try { |
| InternetDomainName.from(name); |
| fail("Should have been invalid: '" + name + "'"); |
| } catch (IllegalArgumentException expected) { |
| } |
| } |
| } |
| |
| public void testPublicSuffix() { |
| for (String name : PS) { |
| final InternetDomainName domain = InternetDomainName.from(name); |
| assertTrue(name, domain.isPublicSuffix()); |
| assertTrue(name, domain.hasPublicSuffix()); |
| assertFalse(name, domain.isUnderPublicSuffix()); |
| assertFalse(name, domain.isTopPrivateDomain()); |
| assertEquals(domain, domain.publicSuffix()); |
| } |
| |
| for (String name : NO_PS) { |
| final InternetDomainName domain = InternetDomainName.from(name); |
| assertFalse(name, domain.isPublicSuffix()); |
| assertFalse(name, domain.hasPublicSuffix()); |
| assertFalse(name, domain.isUnderPublicSuffix()); |
| assertFalse(name, domain.isTopPrivateDomain()); |
| assertNull(domain.publicSuffix()); |
| } |
| |
| for (String name : NON_PS) { |
| final InternetDomainName domain = InternetDomainName.from(name); |
| assertFalse(name, domain.isPublicSuffix()); |
| assertTrue(name, domain.hasPublicSuffix()); |
| assertTrue(name, domain.isUnderPublicSuffix()); |
| } |
| } |
| |
| public void testUnderPublicSuffix() { |
| for (String name : SOMEWHERE_UNDER_PS) { |
| final InternetDomainName domain = InternetDomainName.from(name); |
| assertFalse(name, domain.isPublicSuffix()); |
| assertTrue(name, domain.hasPublicSuffix()); |
| assertTrue(name, domain.isUnderPublicSuffix()); |
| } |
| } |
| |
| public void testTopPrivateDomain() { |
| for (String name : TOP_PRIVATE_DOMAIN) { |
| final InternetDomainName domain = InternetDomainName.from(name); |
| assertFalse(name, domain.isPublicSuffix()); |
| assertTrue(name, domain.hasPublicSuffix()); |
| assertTrue(name, domain.isUnderPublicSuffix()); |
| assertTrue(name, domain.isTopPrivateDomain()); |
| assertEquals(domain.parent(), domain.publicSuffix()); |
| } |
| } |
| |
| public void testUnderPrivateDomain() { |
| for (String name : UNDER_PRIVATE_DOMAIN) { |
| final InternetDomainName domain = InternetDomainName.from(name); |
| assertFalse(name, domain.isPublicSuffix()); |
| assertTrue(name, domain.hasPublicSuffix()); |
| assertTrue(name, domain.isUnderPublicSuffix()); |
| assertFalse(name, domain.isTopPrivateDomain()); |
| } |
| } |
| |
| public void testRegistrySuffix() { |
| for (String name : RS) { |
| final InternetDomainName domain = InternetDomainName.from(name); |
| assertTrue(name, domain.isRegistrySuffix()); |
| assertTrue(name, domain.hasRegistrySuffix()); |
| assertFalse(name, domain.isUnderRegistrySuffix()); |
| assertFalse(name, domain.isTopDomainUnderRegistrySuffix()); |
| assertEquals(domain, domain.registrySuffix()); |
| } |
| |
| for (String name : NO_RS) { |
| final InternetDomainName domain = InternetDomainName.from(name); |
| assertFalse(name, domain.isRegistrySuffix()); |
| assertFalse(name, domain.hasRegistrySuffix()); |
| assertFalse(name, domain.isUnderRegistrySuffix()); |
| assertFalse(name, domain.isTopDomainUnderRegistrySuffix()); |
| assertNull(domain.registrySuffix()); |
| } |
| |
| for (String name : NON_RS) { |
| final InternetDomainName domain = InternetDomainName.from(name); |
| assertFalse(name, domain.isRegistrySuffix()); |
| assertTrue(name, domain.hasRegistrySuffix()); |
| assertTrue(name, domain.isUnderRegistrySuffix()); |
| } |
| } |
| |
| public void testUnderRegistrySuffix() { |
| for (String name : SOMEWHERE_UNDER_RS) { |
| final InternetDomainName domain = InternetDomainName.from(name); |
| assertFalse(name, domain.isRegistrySuffix()); |
| assertTrue(name, domain.hasRegistrySuffix()); |
| assertTrue(name, domain.isUnderRegistrySuffix()); |
| } |
| } |
| |
| public void testTopDomainUnderRegistrySuffix() { |
| for (String name : TOP_UNDER_REGISTRY_SUFFIX) { |
| final InternetDomainName domain = InternetDomainName.from(name); |
| assertFalse(name, domain.isRegistrySuffix()); |
| assertTrue(name, domain.hasRegistrySuffix()); |
| assertTrue(name, domain.isUnderRegistrySuffix()); |
| assertTrue(name, domain.isTopDomainUnderRegistrySuffix()); |
| assertEquals(domain.parent(), domain.registrySuffix()); |
| } |
| } |
| |
| public void testUnderTopDomainUnderRegistrySuffix() { |
| for (String name : UNDER_TOP_UNDER_REGISTRY_SUFFIX) { |
| final InternetDomainName domain = InternetDomainName.from(name); |
| assertFalse(name, domain.isRegistrySuffix()); |
| assertTrue(name, domain.hasRegistrySuffix()); |
| assertTrue(name, domain.isUnderRegistrySuffix()); |
| assertFalse(name, domain.isTopDomainUnderRegistrySuffix()); |
| } |
| } |
| |
| public void testParent() { |
| assertEquals("com", InternetDomainName.from("google.com").parent().toString()); |
| assertEquals("uk", InternetDomainName.from("co.uk").parent().toString()); |
| assertEquals("google.com", InternetDomainName.from("www.google.com").parent().toString()); |
| |
| try { |
| InternetDomainName.from("com").parent(); |
| fail("'com' should throw ISE on .parent() call"); |
| } catch (IllegalStateException expected) { |
| } |
| } |
| |
| public void testChild() { |
| InternetDomainName domain = InternetDomainName.from("foo.com"); |
| |
| assertEquals("www.foo.com", domain.child("www").toString()); |
| |
| try { |
| domain.child("www."); |
| fail("www..google.com should have been invalid"); |
| } catch (IllegalArgumentException expected) { |
| } |
| } |
| |
| public void testParentChild() { |
| InternetDomainName origin = InternetDomainName.from("foo.com"); |
| InternetDomainName parent = origin.parent(); |
| assertEquals("com", parent.toString()); |
| |
| // These would throw an exception if leniency were not preserved during parent() and child() |
| // calls. |
| InternetDomainName child = parent.child(LOTS_OF_DELTAS); |
| child.child(LOTS_OF_DELTAS); |
| } |
| |
| public void testValidTopPrivateDomain() { |
| InternetDomainName googleDomain = InternetDomainName.from("google.com"); |
| |
| assertEquals(googleDomain, googleDomain.topPrivateDomain()); |
| assertEquals(googleDomain, googleDomain.child("mail").topPrivateDomain()); |
| assertEquals(googleDomain, googleDomain.child("foo.bar").topPrivateDomain()); |
| } |
| |
| public void testInvalidTopPrivateDomain() { |
| ImmutableSet<String> badCookieDomains = ImmutableSet.of("co.uk", "foo", "com"); |
| |
| for (String domain : badCookieDomains) { |
| try { |
| InternetDomainName.from(domain).topPrivateDomain(); |
| fail(domain); |
| } catch (IllegalStateException expected) { |
| } |
| } |
| } |
| |
| public void testIsValid() { |
| final Iterable<String> validCases = Iterables.concat(VALID_NAME, PS, NO_PS, NON_PS); |
| final Iterable<String> invalidCases = |
| Iterables.concat(INVALID_NAME, VALID_IP_ADDRS, INVALID_IP_ADDRS); |
| |
| for (String valid : validCases) { |
| assertTrue(valid, InternetDomainName.isValid(valid)); |
| } |
| |
| for (String invalid : invalidCases) { |
| assertFalse(invalid, InternetDomainName.isValid(invalid)); |
| } |
| } |
| |
| public void testToString() { |
| for (String inputName : SOMEWHERE_UNDER_PS) { |
| InternetDomainName domain = InternetDomainName.from(inputName); |
| |
| /* |
| * We would ordinarily use constants for the expected results, but |
| * doing it by derivation allows us to reuse the test case definitions |
| * used in other tests. |
| */ |
| |
| String expectedName = Ascii.toLowerCase(inputName); |
| expectedName = expectedName.replaceAll("[\u3002\uFF0E\uFF61]", "."); |
| |
| if (expectedName.endsWith(".")) { |
| expectedName = expectedName.substring(0, expectedName.length() - 1); |
| } |
| |
| assertEquals(expectedName, domain.toString()); |
| } |
| } |
| |
| public void testPublicSuffixExclusion() { |
| InternetDomainName domain = InternetDomainName.from("foo.city.yokohama.jp"); |
| assertTrue(domain.hasPublicSuffix()); |
| assertEquals("yokohama.jp", domain.publicSuffix().toString()); |
| |
| // Behold the weirdness! |
| assertFalse(domain.publicSuffix().isPublicSuffix()); |
| } |
| |
| public void testPublicSuffixMultipleUnders() { |
| // PSL has both *.uk and *.sch.uk; the latter should win. |
| // See http://code.google.com/p/guava-libraries/issues/detail?id=1176 |
| |
| InternetDomainName domain = InternetDomainName.from("www.essex.sch.uk"); |
| assertTrue(domain.hasPublicSuffix()); |
| assertEquals("essex.sch.uk", domain.publicSuffix().toString()); |
| assertEquals("www.essex.sch.uk", domain.topPrivateDomain().toString()); |
| } |
| |
| public void testRegistrySuffixExclusion() { |
| InternetDomainName domain = InternetDomainName.from("foo.city.yokohama.jp"); |
| assertTrue(domain.hasRegistrySuffix()); |
| assertEquals("yokohama.jp", domain.registrySuffix().toString()); |
| |
| // Behold the weirdness! |
| assertFalse(domain.registrySuffix().isRegistrySuffix()); |
| } |
| |
| public void testRegistrySuffixMultipleUnders() { |
| // PSL has both *.uk and *.sch.uk; the latter should win. |
| // See http://code.google.com/p/guava-libraries/issues/detail?id=1176 |
| |
| InternetDomainName domain = InternetDomainName.from("www.essex.sch.uk"); |
| assertTrue(domain.hasRegistrySuffix()); |
| assertEquals("essex.sch.uk", domain.registrySuffix().toString()); |
| assertEquals("www.essex.sch.uk", domain.topDomainUnderRegistrySuffix().toString()); |
| } |
| |
| public void testEquality() { |
| new EqualsTester() |
| .addEqualityGroup(idn("google.com"), idn("google.com"), idn("GOOGLE.COM")) |
| .addEqualityGroup(idn("www.google.com")) |
| .addEqualityGroup(UNICODE_EXAMPLE) |
| .addEqualityGroup(PUNYCODE_EXAMPLE) |
| .testEquals(); |
| } |
| |
| private static InternetDomainName idn(String domain) { |
| return InternetDomainName.from(domain); |
| } |
| |
| @GwtIncompatible // NullPointerTester |
| public void testNulls() { |
| final NullPointerTester tester = new NullPointerTester(); |
| |
| tester.testAllPublicStaticMethods(InternetDomainName.class); |
| tester.testAllPublicInstanceMethods(InternetDomainName.from("google.com")); |
| } |
| } |