package com.datatheorem.android.trustkit.config;


import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;

import android.support.test.runner.AndroidJUnit4;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import org.junit.Test;
import org.junit.runner.RunWith;


@RunWith(AndroidJUnit4.class)
public class DomainPinningPolicyTest {

    private final static Set<String> pins = new HashSet<>();
    static {
        pins.add("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=");
        pins.add("rFjc3wG7lTZe43zeYTvPq8k4xdDEutCmIhI5dn4oCeE=");
    }

    private final static Set<String> reportUris = new HashSet<>();
    static {
        reportUris.add("https://www.test.com");
        reportUris.add("https://www.test2.com");
    }

    private final static Date date = new Date();

    @Test
    public void testValidPolicy() throws MalformedURLException {
        DomainPinningPolicy policy = new DomainPinningPolicy("www.test.com", true, pins, true,
                date, reportUris, false);

        assertEquals("www.test.com", policy.getHostname());
        assertEquals(date, policy.getExpirationDate());

        Set<PublicKeyPin> expectedPins = new HashSet<>();
        for (String pinStr : pins) {
            expectedPins.add(new PublicKeyPin(pinStr));

        }
        assertEquals(expectedPins, policy.getPublicKeyPins());

        // Ensure the default report URI was added as shouldDisableDefaultReportUri is false
        Set<URL> expectedReportUris = new HashSet<>();
        for (String uriStr : reportUris) {
            expectedReportUris.add(new URL(uriStr));
        }
        expectedReportUris.add(new URL("https://overmind.datatheorem.com/trustkit/report"));
        assertEquals(expectedReportUris, policy.getReportUris());

        assertTrue(policy.shouldEnforcePinning());
        assertTrue(policy.shouldIncludeSubdomains());
    }

    @Test
    public void testValidPolicyInternationalizeHostname() throws MalformedURLException {
        DomainPinningPolicy policy = new DomainPinningPolicy("českárepublika.icom.museum", true,
                pins, true, date, reportUris, false);

        assertEquals(policy.getHostname(), "českárepublika.icom.museum");
    }

    @Test
    public void testBadPolicyOnlyOnePin() throws MalformedURLException {
        Set<String> badPins = new HashSet<>();
        badPins.add("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=");

        boolean didReceiveConfigError = false;
        try {
            new DomainPinningPolicy("www.test.com", true, badPins, true, date, reportUris, false);
        } catch (ConfigurationException e) {
            if (e.getMessage().startsWith("Less than two pins")) {
                didReceiveConfigError = true;
            } else {
                throw e;
            }
        }
        assertTrue(didReceiveConfigError);
    }

    
    @Test
    public void testNoPinsButPinningEnforceDisabledShouldBeValid() throws MalformedURLException {
        Set<String> emptyPins = new HashSet<>();
        boolean didReceivedConfigError = false;

        try {
            new DomainPinningPolicy("www.test.com", true, emptyPins, true, date, reportUris, false);
        } catch (ConfigurationException e) {
            if (e.getMessage().startsWith("An empty pin-set")) {
                didReceivedConfigError = true;
            } else {
                throw e;
            }
        }
        
        assertTrue(didReceivedConfigError);
    }

    @Test
    public void testBadPolicyPinTld() throws MalformedURLException {
        boolean didReceiveConfigError = false;
        try {
            new DomainPinningPolicy(".", true, pins, true, date, reportUris, false);
        }
        catch (ConfigurationException e) {
            if (e.getMessage().startsWith("Tried to pin an invalid domain")) {
                didReceiveConfigError = true;
            } else {
                throw e;
            }
        }
        assertTrue(didReceiveConfigError);
    }
}

@@ -968,32 +968,117 @@
 dURLException %7B%0A
+        // Given a valid policy for a domain%0A        // When parsing it, it succeeds%0A
         DomainPi
@@ -1114,32 +1114,49 @@
 inPinningPolicy(
+%0A                
 %22www.test.com%22, 
@@ -1168,24 +1168,48 @@
  pins, true,
+ date, reportUris, false
 %0A           
@@ -1205,24 +1205,27 @@
         
+);%0A
         
 date, re
@@ -1220,34 +1220,48 @@
     
-date, reportUris, false);%0A
+// And the right configuration was saved
 %0A   
@@ -1369,24 +1369,166 @@
 ionDate());%0A
+        assertTrue(policy.shouldEnforcePinning());%0A        assertTrue(policy.shouldIncludeSubdomains());%0A%0A        // And right pins were saved
 %0A        Set
@@ -1757,14 +1757,11 @@
  // 
-Ensure
+And
  the
@@ -2155,114 +2155,8 @@
 ());
-%0A%0A        assertTrue(policy.shouldEnforcePinning());%0A        assertTrue(policy.shouldIncludeSubdomains());
 %0A   
@@ -2250,32 +2250,152 @@
 dURLException %7B%0A
+        // Given a valid policy for a domain name with international characters%0A        // When parsing it, it succeeds%0A
         DomainPi
@@ -2439,16 +2439,33 @@
 gPolicy(
+%0A                
 %22%C4%8Desk%C3%A1re
@@ -2491,32 +2491,16 @@
 %22, true,
-%0A               
  pins, t
@@ -2527,20 +2527,28 @@
 s, false
+%0A        
 );%0A
-%0A
         
@@ -2695,32 +2695,97 @@
 dURLException %7B%0A
+        // Given a bad policy for a domain that only has one pin%0A
         Set%3CStri
@@ -2881,24 +2881,61 @@
 AAAAAA=%22);%0A%0A
+        // When parsing it, it fails%0A
         bool
@@ -3465,32 +3465,100 @@
 dURLException %7B%0A
+        // Given a bad policy for a domain that has one pins at all%0A
         Set%3CStri
@@ -3639,16 +3639,53 @@
 false;%0A%0A
+        // When parsing it, it fails%0A
         
@@ -4022,17 +4022,8 @@
   %7D%0A
-        %0A
     
@@ -4140,32 +4140,153 @@
 dURLException %7B%0A
+        // Given a policy for an invalid domain%0A        String badDomain = %22.com%22;%0A%0A        // When parsing it, it fails%0A
         boolean 
@@ -4370,11 +4370,17 @@
 icy(
-%22.%22
+badDomain
 , tr

Add comments to the tests