diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/modeltests/expressions/models.py | 10 | ||||
| -rw-r--r-- | tests/regressiontests/admin_views/fixtures/admin-views-person.xml | 2 | ||||
| -rw-r--r-- | tests/regressiontests/admin_views/tests.py | 3 | ||||
| -rw-r--r-- | tests/regressiontests/decorators/tests.py | 70 | ||||
| -rw-r--r-- | tests/regressiontests/forms/fields.py | 23 |
5 files changed, 103 insertions, 5 deletions
diff --git a/tests/modeltests/expressions/models.py b/tests/modeltests/expressions/models.py index 27daabad71..b515682a9c 100644 --- a/tests/modeltests/expressions/models.py +++ b/tests/modeltests/expressions/models.py @@ -56,6 +56,16 @@ __test__ = {'API_TESTS': """ >>> company_query [{'num_chairs': 2302, 'name': u'Example Inc.', 'num_employees': 2300}, {'num_chairs': 5, 'name': u'Foobar Ltd.', 'num_employees': 3}, {'num_chairs': 34, 'name': u'Test GmbH', 'num_employees': 32}] +# Law of order of operations is followed +>>> _ =company_query.update(num_chairs=F('num_employees') + 2 * F('num_employees')) +>>> company_query +[{'num_chairs': 6900, 'name': u'Example Inc.', 'num_employees': 2300}, {'num_chairs': 9, 'name': u'Foobar Ltd.', 'num_employees': 3}, {'num_chairs': 96, 'name': u'Test GmbH', 'num_employees': 32}] + +# Law of order of operations can be overridden by parentheses +>>> _ =company_query.update(num_chairs=((F('num_employees') + 2) * F('num_employees'))) +>>> company_query +[{'num_chairs': 5294600, 'name': u'Example Inc.', 'num_employees': 2300}, {'num_chairs': 15, 'name': u'Foobar Ltd.', 'num_employees': 3}, {'num_chairs': 1088, 'name': u'Test GmbH', 'num_employees': 32}] + # The relation of a foreign key can become copied over to an other foreign key. >>> Company.objects.update(point_of_contact=F('ceo')) 3 diff --git a/tests/regressiontests/admin_views/fixtures/admin-views-person.xml b/tests/regressiontests/admin_views/fixtures/admin-views-person.xml index 77928a834b..ff00fd2169 100644 --- a/tests/regressiontests/admin_views/fixtures/admin-views-person.xml +++ b/tests/regressiontests/admin_views/fixtures/admin-views-person.xml @@ -6,7 +6,7 @@ <field type="BooleanField" name="alive">True</field> </object> <object pk="2" model="admin_views.person"> - <field type="CharField" name="name">Grace Hooper</field> + <field type="CharField" name="name">Grace Hopper</field> <field type="IntegerField" name="gender">1</field> <field type="BooleanField" name="alive">False</field> </object> diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py index 669755051e..7273d3f320 100644 --- a/tests/regressiontests/admin_views/tests.py +++ b/tests/regressiontests/admin_views/tests.py @@ -908,7 +908,7 @@ class AdminViewListEditable(TestCase): self.client.post('/test_admin/admin/admin_views/person/', data) self.failUnlessEqual(Person.objects.get(name="John Mauchly").alive, False) - self.failUnlessEqual(Person.objects.get(name="Grace Hooper").gender, 2) + self.failUnlessEqual(Person.objects.get(name="Grace Hopper").gender, 2) # test a filtered page data = { @@ -1616,4 +1616,3 @@ class NeverCacheTests(TestCase): "Check the never-cache status of the Javascript i18n view" response = self.client.get('/test_admin/jsi18n/') self.failUnlessEqual(get_max_age(response), None) - diff --git a/tests/regressiontests/decorators/tests.py b/tests/regressiontests/decorators/tests.py index 3c58637f1a..b81a5d665a 100644 --- a/tests/regressiontests/decorators/tests.py +++ b/tests/regressiontests/decorators/tests.py @@ -1,11 +1,16 @@ from unittest import TestCase from sys import version_info +try: + from functools import wraps +except ImportError: + from django.utils.functional import wraps # Python 2.3, 2.4 fallback. -from django.http import HttpResponse +from django.http import HttpResponse, HttpRequest from django.utils.functional import allow_lazy, lazy, memoize from django.views.decorators.http import require_http_methods, require_GET, require_POST from django.views.decorators.vary import vary_on_headers, vary_on_cookie from django.views.decorators.cache import cache_page, never_cache, cache_control +from django.utils.decorators import auto_adapt_to_methods from django.contrib.auth.decorators import login_required, permission_required, user_passes_test from django.contrib.admin.views.decorators import staff_member_required @@ -84,4 +89,65 @@ class DecoratorsTest(TestCase): response = callback(request) self.assertEqual(response, ['test2', 'test1']) - + + def test_cache_page_new_style(self): + """ + Test that we can call cache_page the new way + """ + def my_view(request): + return "response" + my_view_cached = cache_page(123)(my_view) + self.assertEqual(my_view_cached(HttpRequest()), "response") + my_view_cached2 = cache_page(123, key_prefix="test")(my_view) + self.assertEqual(my_view_cached2(HttpRequest()), "response") + + def test_cache_page_old_style(self): + """ + Test that we can call cache_page the old way + """ + def my_view(request): + return "response" + my_view_cached = cache_page(my_view, 123) + self.assertEqual(my_view_cached(HttpRequest()), "response") + my_view_cached2 = cache_page(my_view, 123, key_prefix="test") + self.assertEqual(my_view_cached2(HttpRequest()), "response") + +class MethodDecoratorAdapterTests(TestCase): + def test_auto_adapt_to_methods(self): + """ + Test that auto_adapt_to_methods actually works. + """ + # Need 2 decorators with auto_adapt_to_methods, + # to check it plays nicely with composing itself. + + def my_decorator(func): + def wrapped(*args, **kwargs): + # need to ensure that the first arg isn't 'self' + self.assertEqual(args[0], "test") + return "my_decorator:" + func(*args, **kwargs) + wrapped.my_decorator_custom_attribute = True + return wraps(func)(wrapped) + my_decorator = auto_adapt_to_methods(my_decorator) + + def my_decorator2(func): + def wrapped(*args, **kwargs): + # need to ensure that the first arg isn't 'self' + self.assertEqual(args[0], "test") + return "my_decorator2:" + func(*args, **kwargs) + wrapped.my_decorator2_custom_attribute = True + return wraps(func)(wrapped) + my_decorator2 = auto_adapt_to_methods(my_decorator2) + + class MyClass(object): + def my_method(self, *args, **kwargs): + return "my_method:%r %r" % (args, kwargs) + my_method = my_decorator2(my_decorator(my_method)) + + obj = MyClass() + self.assertEqual(obj.my_method("test", 123, name='foo'), + "my_decorator2:my_decorator:my_method:('test', 123) {'name': 'foo'}") + self.assertEqual(obj.my_method.__name__, 'my_method') + self.assertEqual(getattr(obj.my_method, 'my_decorator_custom_attribute', False), + True) + self.assertEqual(getattr(obj.my_method, 'my_decorator2_custom_attribute', False), + True) diff --git a/tests/regressiontests/forms/fields.py b/tests/regressiontests/forms/fields.py index 2efe72d02c..b02b4612a2 100644 --- a/tests/regressiontests/forms/fields.py +++ b/tests/regressiontests/forms/fields.py @@ -381,6 +381,17 @@ class TestFields(TestCase): self.assertEqual(u'example@valid-----hyphens.com', f.clean('example@valid-----hyphens.com')) self.assertEqual(u'example@valid-with-hyphens.com', f.clean('example@valid-with-hyphens.com')) + def test_email_regexp_for_performance(self): + f = EmailField() + # Check for runaway regex security problem. This will take for-freeking-ever + # if the security fix isn't in place. + self.assertRaisesErrorWithMessage( + ValidationError, + "[u'Enter a valid e-mail address.']", + f.clean, + 'viewx3dtextx26qx3d@yahoo.comx26latlngx3d15854521645943074058' + ) + def test_emailfield_33(self): f = EmailField(required=False) self.assertEqual(u'', f.clean('')) @@ -431,6 +442,7 @@ class TestFields(TestCase): self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, None) self.assertEqual(u'http://localhost/', f.clean('http://localhost')) self.assertEqual(u'http://example.com/', f.clean('http://example.com')) + self.assertEqual(u'http://example.com./', f.clean('http://example.com.')) self.assertEqual(u'http://www.example.com/', f.clean('http://www.example.com')) self.assertEqual(u'http://www.example.com:8000/test', f.clean('http://www.example.com:8000/test')) self.assertEqual(u'http://valid-with-hyphens.com/', f.clean('valid-with-hyphens.com')) @@ -441,6 +453,8 @@ class TestFields(TestCase): self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://') self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://example') self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://example.') + self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'com.') + self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, '.') self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://.com') self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://invalid-.com') self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://-invalid.com') @@ -448,6 +462,15 @@ class TestFields(TestCase): self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://inv-.-alid.com') self.assertEqual(u'http://valid-----hyphens.com/', f.clean('http://valid-----hyphens.com')) + def test_url_regexp_for_performance(self): + f = URLField() + # hangs "forever" if catastrophic backtracking in ticket:#11198 not fixed + self.assertRaisesErrorWithMessage(ValidationError, "[u'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 + self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://%s' % ("X"*60,)) + def test_urlfield_38(self): f = URLField(required=False) self.assertEqual(u'', f.clean('')) |
