from django.core.exceptions import ValidationError from django.forms import URLField from django.test import SimpleTestCase from . import FormFieldAssertionsMixin class URLFieldTest(FormFieldAssertionsMixin, SimpleTestCase): def test_urlfield_1(self): f = URLField() self.assertWidgetRendersTo(f, '') with self.assertRaisesMessage(ValidationError, "'This field is required.'"): f.clean("") with self.assertRaisesMessage(ValidationError, "'This field is required.'"): f.clean(None) self.assertEqual("http://localhost", f.clean("http://localhost")) self.assertEqual("http://example.com", f.clean("http://example.com")) self.assertEqual("http://example.com.", f.clean("http://example.com.")) self.assertEqual("http://www.example.com", f.clean("http://www.example.com")) self.assertEqual( "http://www.example.com:8000/test", f.clean("http://www.example.com:8000/test"), ) self.assertEqual( "http://valid-with-hyphens.com", f.clean("valid-with-hyphens.com") ) self.assertEqual("http://subdomain.domain.com", f.clean("subdomain.domain.com")) self.assertEqual("http://200.8.9.10", f.clean("http://200.8.9.10")) self.assertEqual( "http://200.8.9.10:8000/test", f.clean("http://200.8.9.10:8000/test") ) with self.assertRaisesMessage(ValidationError, "'Enter a valid URL.'"): f.clean("foo") with self.assertRaisesMessage(ValidationError, "'Enter a valid URL.'"): f.clean("http://") with self.assertRaisesMessage(ValidationError, "'Enter a valid URL.'"): f.clean("http://example") with self.assertRaisesMessage(ValidationError, "'Enter a valid URL.'"): f.clean("http://example.") with self.assertRaisesMessage(ValidationError, "'Enter a valid URL.'"): f.clean("com.") with self.assertRaisesMessage(ValidationError, "'Enter a valid URL.'"): f.clean(".") with self.assertRaisesMessage(ValidationError, "'Enter a valid URL.'"): f.clean("http://.com") with self.assertRaisesMessage(ValidationError, "'Enter a valid URL.'"): f.clean("http://invalid-.com") with self.assertRaisesMessage(ValidationError, "'Enter a valid URL.'"): f.clean("http://-invalid.com") with self.assertRaisesMessage(ValidationError, "'Enter a valid URL.'"): f.clean("http://inv-.alid-.com") with self.assertRaisesMessage(ValidationError, "'Enter a valid URL.'"): f.clean("http://inv-.-alid.com") self.assertEqual( "http://valid-----hyphens.com", f.clean("http://valid-----hyphens.com") ) self.assertEqual( "http://some.idn.xyz\xe4\xf6\xfc\xdfabc.domain.com:123/blah", f.clean("http://some.idn.xyzäöüßabc.domain.com:123/blah"), ) self.assertEqual( "http://www.example.com/s/http://code.djangoproject.com/ticket/13804", f.clean("www.example.com/s/http://code.djangoproject.com/ticket/13804"), ) with self.assertRaisesMessage(ValidationError, "'Enter a valid URL.'"): f.clean("[a") with self.assertRaisesMessage(ValidationError, "'Enter a valid URL.'"): f.clean("http://[a") def test_url_regex_ticket11198(self): f = URLField() # hangs "forever" if catastrophic backtracking in ticket:#11198 not fixed with self.assertRaisesMessage(ValidationError, "'Enter a valid URL.'"): f.clean("http://%s" % ("X" * 200,)) # a second test, to make sure the problem is really addressed, even on # domains that don't fail the domain label length check in the regex with self.assertRaisesMessage(ValidationError, "'Enter a valid URL.'"): f.clean("http://%s" % ("X" * 60,)) def test_urlfield_2(self): f = URLField(required=False) self.assertEqual("", f.clean("")) self.assertEqual("", f.clean(None)) self.assertEqual("http://example.com", f.clean("http://example.com")) self.assertEqual("http://www.example.com", f.clean("http://www.example.com")) with self.assertRaisesMessage(ValidationError, "'Enter a valid URL.'"): f.clean("foo") with self.assertRaisesMessage(ValidationError, "'Enter a valid URL.'"): f.clean("http://") with self.assertRaisesMessage(ValidationError, "'Enter a valid URL.'"): f.clean("http://example") with self.assertRaisesMessage(ValidationError, "'Enter a valid URL.'"): f.clean("http://example.") with self.assertRaisesMessage(ValidationError, "'Enter a valid URL.'"): f.clean("http://.com") def test_urlfield_5(self): f = URLField(min_length=15, max_length=20) self.assertWidgetRendersTo( f, '", ) with self.assertRaisesMessage( ValidationError, "'Ensure this value has at least 15 characters (it has 12).'", ): f.clean("http://f.com") self.assertEqual("http://example.com", f.clean("http://example.com")) with self.assertRaisesMessage( ValidationError, "'Ensure this value has at most 20 characters (it has 37).'", ): f.clean("http://abcdefghijklmnopqrstuvwxyz.com") def test_urlfield_6(self): f = URLField(required=False) self.assertEqual("http://example.com", f.clean("example.com")) self.assertEqual("", f.clean("")) self.assertEqual("https://example.com", f.clean("https://example.com")) def test_urlfield_7(self): f = URLField() self.assertEqual("http://example.com", f.clean("http://example.com")) self.assertEqual("http://example.com/test", f.clean("http://example.com/test")) self.assertEqual( "http://example.com?some_param=some_value", f.clean("http://example.com?some_param=some_value"), ) def test_urlfield_9(self): f = URLField() urls = ( "http://עברית.idn.icann.org/", "http://sãopaulo.com/", "http://sãopaulo.com.br/", "http://пример.испытание/", "http://مثال.إختبار/", "http://例子.测试/", "http://例子.測試/", "http://उदाहरण.परीक्षा/", "http://例え.テスト/", "http://مثال.آزمایشی/", "http://실례.테스트/", "http://العربية.idn.icann.org/", ) for url in urls: with self.subTest(url=url): # Valid IDN self.assertEqual(url, f.clean(url)) def test_urlfield_10(self): """URLField correctly validates IPv6 (#18779).""" f = URLField() urls = ( "http://[12:34::3a53]/", "http://[a34:9238::]:8080/", ) for url in urls: with self.subTest(url=url): self.assertEqual(url, f.clean(url)) def test_urlfield_not_string(self): f = URLField(required=False) with self.assertRaisesMessage(ValidationError, "'Enter a valid URL.'"): f.clean(23) def test_urlfield_normalization(self): f = URLField() self.assertEqual(f.clean("http://example.com/ "), "http://example.com/") def test_urlfield_strip_on_none_value(self): f = URLField(required=False, empty_value=None) self.assertIsNone(f.clean("")) self.assertIsNone(f.clean(None)) def test_urlfield_unable_to_set_strip_kwarg(self): msg = "__init__() got multiple values for keyword argument 'strip'" with self.assertRaisesMessage(TypeError, msg): URLField(strip=False)