diff options
| author | Brian Rosner <brosner@gmail.com> | 2008-06-07 17:10:16 +0000 |
|---|---|---|
| committer | Brian Rosner <brosner@gmail.com> | 2008-06-07 17:10:16 +0000 |
| commit | 453d560a945d207013b163228de5ed9a7316a772 (patch) | |
| tree | 380a7c3782cfc9efe46ec8301d21aceff6e0f015 /tests/regressiontests | |
| parent | 0836745c8e850b0bec2df743ff7648ff4cea588e (diff) | |
newforms-admin: Merged from trunk up to [7583].
git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@7584 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests/regressiontests')
| -rw-r--r-- | tests/regressiontests/defaultfilters/tests.py | 18 | ||||
| -rw-r--r-- | tests/regressiontests/many_to_one_regress/models.py | 46 | ||||
| -rw-r--r-- | tests/regressiontests/one_to_one_regress/models.py | 54 | ||||
| -rw-r--r-- | tests/regressiontests/queries/models.py | 5 | ||||
| -rw-r--r-- | tests/regressiontests/templates/loaders.py | 92 | ||||
| -rw-r--r-- | tests/regressiontests/templates/tests.py | 7 | ||||
| -rw-r--r-- | tests/regressiontests/test_client_regress/fixtures/testdata.json | 36 | ||||
| -rw-r--r-- | tests/regressiontests/test_client_regress/models.py | 29 | ||||
| -rw-r--r-- | tests/regressiontests/test_client_regress/urls.py | 1 | ||||
| -rw-r--r-- | tests/regressiontests/test_client_regress/views.py | 14 |
10 files changed, 288 insertions, 14 deletions
diff --git a/tests/regressiontests/defaultfilters/tests.py b/tests/regressiontests/defaultfilters/tests.py index 668ecb9d5a..4a8b68a897 100644 --- a/tests/regressiontests/defaultfilters/tests.py +++ b/tests/regressiontests/defaultfilters/tests.py @@ -226,15 +226,17 @@ u'some <b>html</b> with alert("You smell") disallowed tags' >>> striptags(u'some <b>html</b> with <script>alert("You smell")</script> disallowed <img /> tags') u'some html with alert("You smell") disallowed tags' ->>> dictsort([{'age': 23, 'name': 'Barbara-Ann'}, -... {'age': 63, 'name': 'Ra Ra Rasputin'}, -... {'name': 'Jonny B Goode', 'age': 18}], 'age') -[{'age': 18, 'name': 'Jonny B Goode'}, {'age': 23, 'name': 'Barbara-Ann'}, {'age': 63, 'name': 'Ra Ra Rasputin'}] +>>> sorted_dicts = dictsort([{'age': 23, 'name': 'Barbara-Ann'}, +... {'age': 63, 'name': 'Ra Ra Rasputin'}, +... {'name': 'Jonny B Goode', 'age': 18}], 'age') +>>> [sorted(dict.items()) for dict in sorted_dicts] +[[('age', 18), ('name', 'Jonny B Goode')], [('age', 23), ('name', 'Barbara-Ann')], [('age', 63), ('name', 'Ra Ra Rasputin')]] ->>> dictsortreversed([{'age': 23, 'name': 'Barbara-Ann'}, -... {'age': 63, 'name': 'Ra Ra Rasputin'}, -... {'name': 'Jonny B Goode', 'age': 18}], 'age') -[{'age': 63, 'name': 'Ra Ra Rasputin'}, {'age': 23, 'name': 'Barbara-Ann'}, {'age': 18, 'name': 'Jonny B Goode'}] +>>> sorted_dicts = dictsortreversed([{'age': 23, 'name': 'Barbara-Ann'}, +... {'age': 63, 'name': 'Ra Ra Rasputin'}, +... {'name': 'Jonny B Goode', 'age': 18}], 'age') +>>> [sorted(dict.items()) for dict in sorted_dicts] +[[('age', 63), ('name', 'Ra Ra Rasputin')], [('age', 23), ('name', 'Barbara-Ann')], [('age', 18), ('name', 'Jonny B Goode')]] >>> first([0,1,2]) 0 diff --git a/tests/regressiontests/many_to_one_regress/models.py b/tests/regressiontests/many_to_one_regress/models.py index 57bbcd8489..4e49df1555 100644 --- a/tests/regressiontests/many_to_one_regress/models.py +++ b/tests/regressiontests/many_to_one_regress/models.py @@ -1,3 +1,7 @@ +""" +Regression tests for a few FK bugs: #1578, #6886 +""" + from django.db import models # If ticket #1578 ever slips back in, these models will not be able to be @@ -25,10 +29,48 @@ class Child(models.Model): __test__ = {'API_TESTS':""" ->>> Third.AddManipulator().save(dict(id='3', name='An example', another=None)) +>>> Third.objects.create(id='3', name='An example') <Third: Third object> >>> parent = Parent(name = 'fred') >>> parent.save() ->>> Child.AddManipulator().save(dict(name='bam-bam', parent=parent.id)) +>>> Child.objects.create(name='bam-bam', parent=parent) <Child: Child object> + +# +# Tests of ForeignKey assignment and the related-object cache (see #6886) +# +>>> p = Parent.objects.create(name="Parent") +>>> c = Child.objects.create(name="Child", parent=p) + +# Look up the object again so that we get a "fresh" object +>>> c = Child.objects.get(name="Child") +>>> p = c.parent + +# Accessing the related object again returns the exactly same object +>>> c.parent is p +True + +# But if we kill the cache, we get a new object +>>> del c._parent_cache +>>> c.parent is p +False + +# Assigning a new object results in that object getting cached immediately +>>> p2 = Parent.objects.create(name="Parent 2") +>>> c.parent = p2 +>>> c.parent is p2 +True + +# Assigning None fails: Child.parent is null=False +>>> c.parent = None +Traceback (most recent call last): + ... +ValueError: Cannot assign None: "Child.parent" does not allow null values. + +# You also can't assign an object of the wrong type here +>>> c.parent = First(id=1, second=1) +Traceback (most recent call last): + ... +ValueError: Cannot assign "<First: First object>": "Child.parent" must be a "Parent" instance. + """} diff --git a/tests/regressiontests/one_to_one_regress/models.py b/tests/regressiontests/one_to_one_regress/models.py index c5ffd3fb3c..99022882f2 100644 --- a/tests/regressiontests/one_to_one_regress/models.py +++ b/tests/regressiontests/one_to_one_regress/models.py @@ -15,6 +15,13 @@ class Restaurant(models.Model): def __unicode__(self): return u"%s the restaurant" % self.place.name +class Bar(models.Model): + place = models.OneToOneField(Place) + serves_cocktails = models.BooleanField() + + def __unicode__(self): + return u"%s the bar" % self.place.name + class Favorites(models.Model): name = models.CharField(max_length = 50) restaurants = models.ManyToManyField(Restaurant) @@ -34,4 +41,51 @@ __test__ = {'API_TESTS':""" >>> f.restaurants = [r] >>> f.restaurants.all() [<Restaurant: Demon Dogs the restaurant>] + +# Regression test for #7173: Check that the name of the cache for the +# reverse object is correct. +>>> b = Bar(place=p1, serves_cocktails=False) +>>> b.save() +>>> p1.restaurant +<Restaurant: Demon Dogs the restaurant> +>>> p1.bar +<Bar: Demon Dogs the bar> + +# +# Regression test for #6886 (the related-object cache) +# + +# Look up the objects again so that we get "fresh" objects +>>> p = Place.objects.get(name="Demon Dogs") +>>> r = p.restaurant + +# Accessing the related object again returns the exactly same object +>>> p.restaurant is r +True + +# But if we kill the cache, we get a new object +>>> del p._restaurant_cache +>>> p.restaurant is r +False + +# Reassigning the Restaurant object results in an immediate cache update +# We can't use a new Restaurant because that'll violate one-to-one, but +# with a new *instance* the is test below will fail if #6886 regresses. +>>> r2 = Restaurant.objects.get(pk=r.pk) +>>> p.restaurant = r2 +>>> p.restaurant is r2 +True + +# Assigning None fails: Place.restaurant is null=False +>>> p.restaurant = None +Traceback (most recent call last): + ... +ValueError: Cannot assign None: "Place.restaurant" does not allow null values. + +# You also can't assign an object of the wrong type here +>>> p.restaurant = p +Traceback (most recent call last): + ... +ValueError: Cannot assign "<Place: Demon Dogs the place>": "Place.restaurant" must be a "Restaurant" instance. + """} diff --git a/tests/regressiontests/queries/models.py b/tests/regressiontests/queries/models.py index 5beaf5fb09..8c9334c849 100644 --- a/tests/regressiontests/queries/models.py +++ b/tests/regressiontests/queries/models.py @@ -503,8 +503,9 @@ True # Despite having some extra aliases in the query, we can still omit them in a # values() query. ->>> qs.values('id', 'rank').order_by('id') -[{'id': 1, 'rank': 2}, {'id': 2, 'rank': 1}, {'id': 3, 'rank': 3}] +>>> dicts = qs.values('id', 'rank').order_by('id') +>>> [sorted(d.items()) for d in dicts] +[[('id', 1), ('rank', 2)], [('id', 2), ('rank', 1)], [('id', 3), ('rank', 3)]] Bugs #2874, #3002 >>> qs = Item.objects.select_related().order_by('note__note', 'name') diff --git a/tests/regressiontests/templates/loaders.py b/tests/regressiontests/templates/loaders.py new file mode 100644 index 0000000000..82e3c622d1 --- /dev/null +++ b/tests/regressiontests/templates/loaders.py @@ -0,0 +1,92 @@ +# -*- coding: utf-8 -*- +""" +Test cases for the template loaders +""" + +from django.conf import settings + +if __name__ == '__main__': + settings.configure() + +import unittest +import sys +import pkg_resources +import imp +import StringIO + +from django.template import TemplateDoesNotExist +from django.template.loaders.eggs import load_template_source as lts_egg + +#Mock classes and objects for pkg_resources functions +class MockProvider(pkg_resources.NullProvider): + def __init__(self, module): + pkg_resources.NullProvider.__init__(self, module) + self.module = module + + def _has(self, path): + return path in self.module._resources + + def _isdir(self,path): + return False + + def get_resource_stream(self, manager, resource_name): + return self.module._resources[resource_name] + + def _get(self, path): + return self.module._resources[path].read() + +class MockLoader(object): pass + +def create_egg(name, resources): + """ + Creates a mock egg with a list of resources + + name: The name of the module + resources: A dictionary of resources. Keys are the names and values the the data. + """ + egg = imp.new_module(name) + egg.__loader__ = MockLoader() + egg._resources = resources + sys.modules[name] = egg + + +class EggLoader(unittest.TestCase): + def setUp(self): + pkg_resources._provider_factories[MockLoader] = MockProvider + + self.empty_egg = create_egg("egg_empty", {}) + self.egg_1 = create_egg("egg_1", { + 'templates/y.html' : StringIO.StringIO("y"), + 'templates/x.txt' : StringIO.StringIO("x"), + }) + self._old_installed_apps = settings.INSTALLED_APPS + settings.INSTALLED_APPS = [] + + def tearDown(self): + settings.INSTALLED_APPS = self._old_installed_apps + + def test_empty(self): + "Loading any template on an empty egg should fail" + settings.INSTALLED_APPS = ['egg_empty'] + self.assertRaises(TemplateDoesNotExist, lts_egg, "not-existing.html") + + def test_non_existing(self): + "Template loading fails if the template is not in the egg" + settings.INSTALLED_APPS = ['egg_1'] + self.assertRaises(TemplateDoesNotExist, lts_egg, "not-existing.html") + + def test_existing(self): + "A template can be loaded from an egg" + settings.INSTALLED_APPS = ['egg_1'] + contents, template_name = lts_egg("y.html") + self.assertEqual(contents, "y") + self.assertEqual(template_name, "egg:egg_1:templates/y.html") + + def test_not_installed(self): + "Loading an existent template from an egg not included in INSTALLED_APPS should fail" + settings.INSTALLED_APPS = [] + self.assertRaises(TemplateDoesNotExist, lts_egg, "y.html") + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py index aef6f504b1..4effea55de 100644 --- a/tests/regressiontests/templates/tests.py +++ b/tests/regressiontests/templates/tests.py @@ -19,12 +19,15 @@ from django.utils.tzinfo import LocalTimezone from unicode import unicode_tests from context import context_tests + +from loaders import * + import filters # Some other tests we would like to run __test__ = { - 'unicode': unicode_tests, - 'context': context_tests, + 'unicode': unicode_tests, + 'context': context_tests } ################################# diff --git a/tests/regressiontests/test_client_regress/fixtures/testdata.json b/tests/regressiontests/test_client_regress/fixtures/testdata.json index 5c9e415240..0dcf625939 100644 --- a/tests/regressiontests/test_client_regress/fixtures/testdata.json +++ b/tests/regressiontests/test_client_regress/fixtures/testdata.json @@ -16,5 +16,41 @@ "email": "testclient@example.com", "date_joined": "2006-12-17 07:03:31" } + }, + { + "pk": "2", + "model": "auth.user", + "fields": { + "username": "inactive", + "first_name": "Inactive", + "last_name": "User", + "is_active": false, + "is_superuser": false, + "is_staff": false, + "last_login": "2006-12-17 07:03:31", + "groups": [], + "user_permissions": [], + "password": "sha1$6efc0$f93efe9fd7542f25a7be94871ea45aa95de57161", + "email": "testclient@example.com", + "date_joined": "2006-12-17 07:03:31" + } + }, + { + "pk": "3", + "model": "auth.user", + "fields": { + "username": "staff", + "first_name": "Staff", + "last_name": "Member", + "is_active": true, + "is_superuser": false, + "is_staff": true, + "last_login": "2006-12-17 07:03:31", + "groups": [], + "user_permissions": [], + "password": "sha1$6efc0$f93efe9fd7542f25a7be94871ea45aa95de57161", + "email": "testclient@example.com", + "date_joined": "2006-12-17 07:03:31" + } } ]
\ No newline at end of file diff --git a/tests/regressiontests/test_client_regress/models.py b/tests/regressiontests/test_client_regress/models.py index 305ccc9aa3..a204ec3e72 100644 --- a/tests/regressiontests/test_client_regress/models.py +++ b/tests/regressiontests/test_client_regress/models.py @@ -4,6 +4,7 @@ Regression tests for the Test Client, especially the customized assertions. """ from django.test import Client, TestCase from django.core.urlresolvers import reverse +from django.core.exceptions import SuspiciousOperation import os class AssertContainsTests(TestCase): @@ -11,6 +12,7 @@ class AssertContainsTests(TestCase): "Responses can be inspected for content, including counting repeated substrings" response = self.client.get('/test_client_regress/no_template_view/') + self.assertNotContains(response, 'never') self.assertContains(response, 'never', 0) self.assertContains(response, 'once') self.assertContains(response, 'once', 1) @@ -18,6 +20,11 @@ class AssertContainsTests(TestCase): self.assertContains(response, 'twice', 2) try: + self.assertNotContains(response, 'once') + except AssertionError, e: + self.assertEquals(str(e), "Response should not contain 'once'") + + try: self.assertContains(response, 'never', 1) except AssertionError, e: self.assertEquals(str(e), "Found 0 instances of 'never' in response (expected 1)") @@ -288,4 +295,26 @@ class URLEscapingTests(TestCase): self.assertEqual(response.status_code, 200) self.assertEqual(response.content, 'Hi, Arthur') +class ExceptionTests(TestCase): + fixtures = ['testdata.json'] + + def test_exception_cleared(self): + "#5836 - A stale user exception isn't re-raised by the test client." + + login = self.client.login(username='testclient',password='password') + self.failUnless(login, 'Could not log in') + try: + response = self.client.get("/test_client_regress/staff_only/") + self.fail("General users should not be able to visit this page") + except SuspiciousOperation: + pass + # At this point, an exception has been raised, and should be cleared. + + # This next operation should be successful; if it isn't we have a problem. + login = self.client.login(username='staff', password='password') + self.failUnless(login, 'Could not log in') + try: + self.client.get("/test_client_regress/staff_only/") + except SuspiciousOperation: + self.fail("Staff should be able to visit this page") diff --git a/tests/regressiontests/test_client_regress/urls.py b/tests/regressiontests/test_client_regress/urls.py index d3304caef0..dc26d1260a 100644 --- a/tests/regressiontests/test_client_regress/urls.py +++ b/tests/regressiontests/test_client_regress/urls.py @@ -4,6 +4,7 @@ import views urlpatterns = patterns('', (r'^no_template_view/$', views.no_template_view), (r'^file_upload/$', views.file_upload_view), + (r'^staff_only/$', views.staff_only_view), (r'^get_view/$', views.get_view), url(r'^arg_view/(?P<name>.+)/$', views.view_with_argument, name='arg_view'), (r'^login_protected_redirect_view/$', views.login_protected_redirect_view) diff --git a/tests/regressiontests/test_client_regress/views.py b/tests/regressiontests/test_client_regress/views.py index f44757dc10..9632c17284 100644 --- a/tests/regressiontests/test_client_regress/views.py +++ b/tests/regressiontests/test_client_regress/views.py @@ -1,5 +1,8 @@ +import os + from django.contrib.auth.decorators import login_required from django.http import HttpResponse, HttpResponseRedirect, HttpResponseServerError +from django.core.exceptions import SuspiciousOperation def no_template_view(request): "A simple view that expects a GET request, and returns a rendered template" @@ -13,10 +16,21 @@ def file_upload_view(request): form_data = request.POST.copy() form_data.update(request.FILES) if isinstance(form_data['file_field'], dict) and isinstance(form_data['name'], unicode): + # If a file is posted, the dummy client should only post the file name, + # not the full path. + if os.path.dirname(form_data['file_field']['filename']) != '': + return HttpResponseServerError() return HttpResponse('') else: return HttpResponseServerError() +def staff_only_view(request): + "A view that can only be visited by staff. Non staff members get an exception" + if request.user.is_staff: + return HttpResponse('') + else: + raise SuspiciousOperation() + def get_view(request): "A simple login protected view" return HttpResponse("Hello world") |
