diff options
Diffstat (limited to 'tests/forms_tests/field_tests/test_urlfield.py')
| -rw-r--r-- | tests/forms_tests/field_tests/test_urlfield.py | 85 |
1 files changed, 83 insertions, 2 deletions
diff --git a/tests/forms_tests/field_tests/test_urlfield.py b/tests/forms_tests/field_tests/test_urlfield.py index f7d318fdc9..87d3489687 100644 --- a/tests/forms_tests/field_tests/test_urlfield.py +++ b/tests/forms_tests/field_tests/test_urlfield.py @@ -1,4 +1,5 @@ from django.core.exceptions import ValidationError +from django.core.validators import URLValidator from django.forms import URLField from django.test import SimpleTestCase @@ -72,6 +73,16 @@ class URLFieldTest(FormFieldAssertionsMixin, SimpleTestCase): # IPv6. ("http://[12:34::3a53]/", "http://[12:34::3a53]/"), ("http://[a34:9238::]:8080/", "http://[a34:9238::]:8080/"), + # IPv6 without scheme. + ("[12:34::3a53]/", "https://[12:34::3a53]/"), + # IDN domain without scheme but with port. + ("ñandú.es:8080/", "https://ñandú.es:8080/"), + # Scheme-relative. + ("//example.com", "https://example.com"), + ("//example.com/path", "https://example.com/path"), + # Whitespace stripped. + ("\t\n//example.com \n\t\n", "https://example.com"), + ("\t\nhttp://example.com \n\t\n", "http://example.com"), ] for url, expected in tests: with self.subTest(url=url): @@ -102,10 +113,19 @@ class URLFieldTest(FormFieldAssertionsMixin, SimpleTestCase): # even on domains that don't fail the domain label length check in # the regex. "http://%s" % ("X" * 200,), - # urlsplit() raises ValueError. + # Scheme prepend yields a structurally invalid URL. "////]@N.AN", - # Empty hostname. + # Scheme prepend yields an empty hostname. "#@A.bO", + # Known problematic unicode chars. + "http://" + "¾" * 200, + # Non-ASCII character before the first colon. + "¾:example.com", + # ASCII digit before the first colon. + "1http://example.com", + # Empty scheme. + "://example.com", + ":example.com", ] msg = "'Enter a valid URL.'" for value in tests: @@ -143,3 +163,64 @@ class URLFieldTest(FormFieldAssertionsMixin, SimpleTestCase): self.assertEqual(f.clean("example.com"), "http://example.com") f = URLField(assume_scheme="https") self.assertEqual(f.clean("example.com"), "https://example.com") + + def test_urlfield_assume_scheme_when_colons(self): + f = URLField() + tests = [ + # Port number. + ("http://example.com:8080/", "http://example.com:8080/"), + ("https://example.com:443/path", "https://example.com:443/path"), + # Userinfo with password. + ("http://user:pass@example.com", "http://user:pass@example.com"), + ( + "http://user:pass@example.com:8080/", + "http://user:pass@example.com:8080/", + ), + # Colon in path segment. + ("http://example.com/path:segment", "http://example.com/path:segment"), + ("http://example.com/a:b/c:d", "http://example.com/a:b/c:d"), + # Colon in query string. + ("http://example.com/?key=val:ue", "http://example.com/?key=val:ue"), + # Colon in fragment. + ("http://example.com/#section:1", "http://example.com/#section:1"), + # IPv6 -- multiple colons in host. + ("http://[::1]/", "http://[::1]/"), + ("http://[2001:db8::1]/", "http://[2001:db8::1]/"), + ("http://[2001:db8::1]:8080/", "http://[2001:db8::1]:8080/"), + # Colons across multiple components. + ( + "http://user:pass@example.com:8080/path:x?q=a:b#id:1", + "http://user:pass@example.com:8080/path:x?q=a:b#id:1", + ), + # FTP with port and userinfo. + ( + "ftp://user:pass@ftp.example.com:21/file", + "ftp://user:pass@ftp.example.com:21/file", + ), + ( + "ftps://user:pass@ftp.example.com:990/", + "ftps://user:pass@ftp.example.com:990/", + ), + # Scheme-relative URLs, starts with "//". + ("//example.com:8080/path", "https://example.com:8080/path"), + ("//user:pass@example.com/", "https://user:pass@example.com/"), + ] + for value, expected in tests: + with self.subTest(value=value): + self.assertEqual(f.clean(value), expected) + + def test_custom_validator_longer_max_length(self): + + class CustomLongURLValidator(URLValidator): + max_length = 4096 + + class CustomURLField(URLField): + default_validators = [CustomLongURLValidator()] + + field = CustomURLField() + # A URL with 4096 chars is valid given the custom validator. + prefix = "https://example.com/" + url = prefix + "a" * (4096 - len(prefix)) + self.assertEqual(len(url), 4096) + # No ValidationError is raised. + field.clean(url) |
