def testPrepending(self):
        # prepends scheme for abbreviated domains
        self.assertEqual(self.x('google.ca'), ('http://google.ca', None))

        # prepends scheme for abbreviated domains
        self.assertEqual(self.x('google.ca:8080'),
                         ('http://google.ca:8080', None))

        # does not prepend when scheme already exists
        self.assertEqual(self.x('https://google.ca'),
                         ('https://google.ca', None))

        y = IS_HTTP_URL(prepend_scheme='https',
                        allowed_schemes=[None, 'https'])
        self.assertEqual(
            y('google.ca'),
            ('https://google.ca', None))  # prepends https if asked

        z = IS_HTTP_URL(prepend_scheme=None)
        self.assertEqual(z('google.ca:8080'),
                         ('google.ca:8080', None))  # prepending disabled

        try:
            IS_HTTP_URL(prepend_scheme='mailto')
        except Exception as e:
            if str(e)\
                    != "prepend_scheme='mailto' is not in allowed_schemes=[None, 'http', 'https']":
                self.fail('Wrong exception: ' + str(e))
        else:
            self.fail("Got invalid prepend_scheme: 'mailto'")

        # Does not prepend if None type is not specified in allowed_scheme, because a scheme is required

        a = IS_HTTP_URL(allowed_schemes=['http'])
        self.assertEqual(a('google.ca'), ('google.ca', 'Enter a valid URL'))
        self.assertEqual(a('google.ca:80'),
                         ('google.ca:80', 'Enter a valid URL'))
class TestIsHttpUrl(unittest.TestCase):

    x = IS_HTTP_URL()

    def testInvalidUrls(self):
        urlsToCheck = [
            None,
            '',
            'http://invalid' + chr(2) + '.com',
            'htp://invalid_scheme.com',
            'blargg://invalid_scheme.com',
            'http://-123.com',
            'http://abcd-.ca',
            'http://-abc123-.me',
            'http://www.dom&ain.com/',
            'http://www.dom=ain.com/',
            'http://www.benn.ca&',
            'http://%62%65%6E%6E%2E%63%61/path',
            'http://.domain.com',
            'http://.domain.com./path',
            'http://domain..com',
            'http://domain...at..com',
            'http://domain.com..',
            'http://domain.com../path',
            'http://domain.3m',
            'http://domain.-3m',
            'http://domain.3m-',
            'http://domain.-3m-',
            'http://domain.co&m',
            'http://domain.m3456',
            'http://domain.m-3/path#fragment',
            'http://domain.m---k/path?query=value',
            'http://23.32..',
            'http://23..32.56.0',
            'http://38997.222.999',
            'http://23.32.56.99.',
            'http://.23.32.56.99',
            'http://.23.32.56.99.',
            'http://w127.123.0.256:8080',
            'http://23.32.56.99:abcd',
            'http://23.32.56.99:23cd',
            'http://google.com:cd22',
            'http://23.32:1300.56.99',
            'http://www.yahoo:1600.com',
            'path/segment/without/starting/slash',
            'http://www.math.uio.no;param=3',
            '://ABC.com:/%7esmith/home.html',
        ]

        failures = []

        for url in urlsToCheck:
            if self.x(url)[1] is None:
                failures.append('Incorrectly accepted: ' + str(url))

        if len(failures) > 0:
            self.fail(failures)

    def testValidUrls(self):

        urlsToCheck = [
            'http://abc.com:80/~smith/home.html',
            'http://ABC.com/%7Esmith/home.html',
            'http://ABC.com:/%7esmith/home.html',
            'http://www.math.uio.no/faq/compression-faq/part1.html',
            '//google.ca/faq/compression-faq/part1.html',
            '//google.ca/faq;param=3',
            '//google.ca/faq/index.html?query=5',
            '//google.ca/faq/index.html;param=value?query=5',
            '/faq/compression-faq/part1.html',
            '/faq;param=3',
            '/faq/index.html?query=5',
            '/faq/index.html;param=value?query=5',
            'google.com',
            'benn.ca/init/default',
            'benn.ca/init;param=value/default?query=value',
            'http://host-name---with-dashes.me',
            'http://www.host-name---with-dashes.me',
            'http://a.com',
            'http://a.3.com',
            'http://a.bl-ck.com',
            'http://bl-e.b.com',
            'http://host123with456numbers.ca',
            'http://1234567890.com.',
            'http://1234567890.com./path',
            'http://google.com./path',
            'http://domain.xn--d1acj3b',
            'http://127.123.0.256',
            'http://127.123.0.256/document/drawer',
            '127.123.0.256/document/',
            '156.212.123.100',
            'http://www.google.com:180200',
            'http://www.google.com:8080/path',
            'http://www.google.com:8080',
            '//www.google.com:8080',
            'www.google.com:8080',
            'http://127.123.0.256:8080/path',
            '//127.123.0.256:8080',
            '127.123.0.256:8080',
            'http://example.me??query=value?',
            'http://a.com',
            'http://3.com',
            'http://www.benn.ca',
            'http://benn.ca',
            'http://amazon.com/books/',
            'https://amazon.com/movies',
            'hTTp://allcaps.com',
            'http://localhost',
            'HTTPS://localhost.',
            'http://localhost#fragment',
            'http://localhost/hello;param=value',
            'http://localhost/hello;param=value/hi;param2=value2;param3=value3',
            'http://localhost/hello?query=True',
            'http://www.benn.ca/hello;param=value/hi;param2=value2;param3=value3/index.html?query=3',
            'http://localhost/hello/?query=1500&five=6',
            'http://localhost:8080',
            'http://localhost:8080/',
            'http://localhost:8080/hello',
            'http://localhost:8080/hello%20world/',
            'http://www.a.3.be-nn.5.ca',
            'http://www.amazon.COM',
        ]

        failures = []

        for url in urlsToCheck:
            if self.x(url)[1] is not None:
                failures.append('Incorrectly rejected: ' + str(url))

        if len(failures) > 0:
            self.fail(failures)

    def testPrepending(self):
        # prepends scheme for abbreviated domains
        self.assertEqual(self.x('google.ca'), ('http://google.ca', None))

        # prepends scheme for abbreviated domains
        self.assertEqual(self.x('google.ca:8080'),
                         ('http://google.ca:8080', None))

        # does not prepend when scheme already exists
        self.assertEqual(self.x('https://google.ca'),
                         ('https://google.ca', None))

        y = IS_HTTP_URL(prepend_scheme='https',
                        allowed_schemes=[None, 'https'])
        self.assertEqual(
            y('google.ca'),
            ('https://google.ca', None))  # prepends https if asked

        z = IS_HTTP_URL(prepend_scheme=None)
        self.assertEqual(z('google.ca:8080'),
                         ('google.ca:8080', None))  # prepending disabled

        try:
            IS_HTTP_URL(prepend_scheme='mailto')
        except Exception as e:
            if str(e)\
                    != "prepend_scheme='mailto' is not in allowed_schemes=[None, 'http', 'https']":
                self.fail('Wrong exception: ' + str(e))
        else:
            self.fail("Got invalid prepend_scheme: 'mailto'")

        # Does not prepend if None type is not specified in allowed_scheme, because a scheme is required

        a = IS_HTTP_URL(allowed_schemes=['http'])
        self.assertEqual(a('google.ca'), ('google.ca', 'Enter a valid URL'))
        self.assertEqual(a('google.ca:80'),
                         ('google.ca:80', 'Enter a valid URL'))