package com.atlassian.bitbucket.validation;

import com.google.common.collect.ImmutableMap;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import javax.validation.ConstraintValidatorContext;
import java.util.Map;

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

@RunWith(MockitoJUnitRunner.class)
public class HttpURLValidatorTest {

    public final Map<String, Boolean> testUrls = ImmutableMap.<String, Boolean>builder()
            .put("", true)
            .put(" ", false)
            .put("/", false)
            .put("invalid", false)
            .put("#test", false)
            .put("ftp://example.com", false)
            .put("http:///", false)
            .put("http://example.com", true)
            .put("http://example.com/", true)
            .put("https://example.com", true)
            .put("https://example.com/", true)
            .put("http://www.example.com", true)
            .put("http://www.example.com/", true)
            .put("https://www.example.com", true)
            .put("https://www.example.com/", true)
            .put("http://example.com:", false)
            .put("http://example.com:foo", false)
            .put("http://example.com:8080", true)
            .put("http://example.com:8080/foo", true)
            .put("http://example.com:8080/foo?abc", false)
            .put("http://example.com:8080/foo#abc", false)
            .put("http://example.com:8080/foo/", true)
            .put("http://example.com:8080/foo%", false)
            .put("http://example.com:8080/foo{}[]", false)
            .put("http://example.com:8080/foo>?{}[]", false)
            .put("https://example.com:8080", true)
            .put("https://example.com:8080/foo", true)
            .put("https://example.com:8080/foo/", true)
            .put("ftp://example.com:8080/foo", false)
            .put("urn:issn:1111-2222", false)
            .put("http://国際交流.com:8080/foo", false)
            .build();

    @Mock
    private ConstraintValidatorContext context;

    @Test
    public void testUrls() throws Exception {
        HttpURLValidator validator = new HttpURLValidator();
        for (Map.Entry<String, Boolean> test : testUrls.entrySet()) {
            final String toValidate = test.getKey();
            assertEquals("invalid result for " + toValidate, (boolean) test.getValue(), validator.isValid(toValidate, context));
        }
    }

    @Test
    public void testNullUrl() throws Exception {
        assertTrue("Null URLs should be valid", new HttpURLValidator().isValid(null, context));
    }
}
