diff options
| author | Adrian Holovaty <adrian@holovaty.com> | 2007-09-15 21:42:51 +0000 |
|---|---|---|
| committer | Adrian Holovaty <adrian@holovaty.com> | 2007-09-15 21:42:51 +0000 |
| commit | 5ce2e6c2c827cf877f73bf0e42e6afb7e6a71ccf (patch) | |
| tree | 8c8c2fb8329e2db7dbfcf2c47026a11ff079e5c5 /tests | |
| parent | ea9cd5421382c047e2cc140bd6736b54ba660793 (diff) | |
queryset-refactor: Merged to [6220]
git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@6337 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/modeltests/custom_pk/models.py | 5 | ||||
| -rw-r--r-- | tests/modeltests/test_client/models.py | 16 | ||||
| -rw-r--r-- | tests/modeltests/test_client/urls.py | 1 | ||||
| -rw-r--r-- | tests/modeltests/test_client/views.py | 8 | ||||
| -rw-r--r-- | tests/regressiontests/backends/__init__.py | 0 | ||||
| -rw-r--r-- | tests/regressiontests/backends/models.py | 29 | ||||
| -rw-r--r-- | tests/regressiontests/forms/localflavor.py | 376 |
7 files changed, 435 insertions, 0 deletions
diff --git a/tests/modeltests/custom_pk/models.py b/tests/modeltests/custom_pk/models.py index 53bbadbfd4..375859c897 100644 --- a/tests/modeltests/custom_pk/models.py +++ b/tests/modeltests/custom_pk/models.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ 14. Using a custom primary key @@ -92,4 +93,8 @@ DoesNotExist: Employee matching query does not exist. >>> Business.objects.filter(employees__first_name__startswith='Fran') [<Business: Sears>] +# Primary key may be unicode string +>>> emp = Employee(employee_code='jaźń') +>>> emp.save() + """} diff --git a/tests/modeltests/test_client/models.py b/tests/modeltests/test_client/models.py index 32647552eb..2df5d3cf77 100644 --- a/tests/modeltests/test_client/models.py +++ b/tests/modeltests/test_client/models.py @@ -250,6 +250,22 @@ class ClientTest(TestCase): self.assertEqual(response.status_code, 200) self.assertEqual(response.context['user'].username, 'testclient') + def test_view_with_login_and_custom_redirect(self): + "Request a page that is protected with @login_required(redirect_field_name='redirect_to')" + + # Get the page without logging in. Should result in 302. + response = self.client.get('/test_client/login_protected_view_custom_redirect/') + self.assertRedirects(response, 'http://testserver/accounts/login/?redirect_to=/test_client/login_protected_view_custom_redirect/') + + # Log in + login = self.client.login(username='testclient', password='password') + self.failUnless(login, 'Could not log in') + + # Request a page that requires a login + response = self.client.get('/test_client/login_protected_view_custom_redirect/') + self.assertEqual(response.status_code, 200) + self.assertEqual(response.context['user'].username, 'testclient') + def test_view_with_bad_login(self): "Request a page that is protected with @login, but use bad credentials" diff --git a/tests/modeltests/test_client/urls.py b/tests/modeltests/test_client/urls.py index 538c0e4b43..3779a0ecd1 100644 --- a/tests/modeltests/test_client/urls.py +++ b/tests/modeltests/test_client/urls.py @@ -13,6 +13,7 @@ urlpatterns = patterns('', (r'^form_view/$', views.form_view), (r'^form_view_with_template/$', views.form_view_with_template), (r'^login_protected_view/$', views.login_protected_view), + (r'^login_protected_view_custom_redirect/$', views.login_protected_view_changed_redirect), (r'^session_view/$', views.session_view), (r'^broken_view/$', views.broken_view), (r'^mail_sending_view/$', views.mail_sending_view), diff --git a/tests/modeltests/test_client/views.py b/tests/modeltests/test_client/views.py index e2a9081fb2..c406e17d30 100644 --- a/tests/modeltests/test_client/views.py +++ b/tests/modeltests/test_client/views.py @@ -122,6 +122,14 @@ def login_protected_view(request): return HttpResponse(t.render(c)) login_protected_view = login_required(login_protected_view) +def login_protected_view_changed_redirect(request): + "A simple view that is login protected with a custom redirect field set" + t = Template('This is a login protected test. Username is {{ user.username }}.', name='Login Template') + c = Context({'user': request.user}) + + return HttpResponse(t.render(c)) +login_protected_view_changed_redirect = login_required(redirect_field_name="redirect_to")(login_protected_view_changed_redirect) + def session_view(request): "A view that modifies the session" request.session['tobacconist'] = 'hovercraft' diff --git a/tests/regressiontests/backends/__init__.py b/tests/regressiontests/backends/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/regressiontests/backends/__init__.py diff --git a/tests/regressiontests/backends/models.py b/tests/regressiontests/backends/models.py new file mode 100644 index 0000000000..50a628a22e --- /dev/null +++ b/tests/regressiontests/backends/models.py @@ -0,0 +1,29 @@ +from django.db import models + +class Square(models.Model): + root = models.IntegerField() + square = models.PositiveIntegerField() + + def __unicode__(self): + return "%s ** 2 == %s" % (self.root, self.square) + +__test__ = {'API_TESTS': """ + +#4896: Test cursor.executemany +>>> from django.db import connection +>>> cursor = connection.cursor() +>>> cursor.executemany('INSERT INTO BACKENDS_SQUARE (ROOT, SQUARE) VALUES (%s, %s)', +... [(i, i**2) for i in range(-5, 6)]) and None or None +>>> Square.objects.order_by('root') +[<Square: -5 ** 2 == 25>, <Square: -4 ** 2 == 16>, <Square: -3 ** 2 == 9>, <Square: -2 ** 2 == 4>, <Square: -1 ** 2 == 1>, <Square: 0 ** 2 == 0>, <Square: 1 ** 2 == 1>, <Square: 2 ** 2 == 4>, <Square: 3 ** 2 == 9>, <Square: 4 ** 2 == 16>, <Square: 5 ** 2 == 25>] + +#4765: executemany with params=None or params=[] does nothing +>>> cursor.executemany('INSERT INTO BACKENDS_SQUARE (ROOT, SQUARE) VALUES (%s, %s)', None) and None or None +>>> Square.objects.count() +11 + +>>> cursor.executemany('INSERT INTO BACKENDS_SQUARE (ROOT, SQUARE) VALUES (%s, %s)', []) and None or None +>>> Square.objects.count() +11 + +"""} diff --git a/tests/regressiontests/forms/localflavor.py b/tests/regressiontests/forms/localflavor.py index 1d46adfc0b..2fe15847c7 100644 --- a/tests/regressiontests/forms/localflavor.py +++ b/tests/regressiontests/forms/localflavor.py @@ -1818,4 +1818,380 @@ u'' u'' >>> f.clean(u'') u'' + +# CAPostalCodeField ############################################################## + +CAPostalCodeField validates that the data is a six-character Canadian postal code. +>>> from django.contrib.localflavor.ca.forms import CAPostalCodeField +>>> f = CAPostalCodeField() +>>> f.clean('T2S 2H7') +u'T2S 2H7' +>>> f.clean('T2S 2H') +Traceback (most recent call last): +... +ValidationError: [u'Enter a postal code in the format XXX XXX.'] +>>> f.clean('2T6 H8I') +Traceback (most recent call last): +... +ValidationError: [u'Enter a postal code in the format XXX XXX.'] +>>> f.clean('T2S2H') +Traceback (most recent call last): +... +ValidationError: [u'Enter a postal code in the format XXX XXX.'] +>>> f.clean(90210) +Traceback (most recent call last): +... +ValidationError: [u'Enter a postal code in the format XXX XXX.'] +>>> f.clean(None) +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] +>>> f.clean('') +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] +>>> f = CAPostalCodeField(required=False) +>>> f.clean('T2S 2H7') +u'T2S 2H7' +>>> f.clean('T2S2H7') +Traceback (most recent call last): +... +ValidationError: [u'Enter a postal code in the format XXX XXX.'] +>>> f.clean('T2S 2H') +Traceback (most recent call last): +... +ValidationError: [u'Enter a postal code in the format XXX XXX.'] +>>> f.clean('2T6 H8I') +Traceback (most recent call last): +... +ValidationError: [u'Enter a postal code in the format XXX XXX.'] +>>> f.clean('T2S2H') +Traceback (most recent call last): +... +ValidationError: [u'Enter a postal code in the format XXX XXX.'] +>>> f.clean(90210) +Traceback (most recent call last): +... +ValidationError: [u'Enter a postal code in the format XXX XXX.'] +>>> f.clean(None) +u'' +>>> f.clean('') +u'' + +# CAPhoneNumberField ########################################################## + +CAPhoneNumberField validates that the data is a valid Canadian phone number, +including the area code. It's normalized to XXX-XXX-XXXX format. +Note: This test is exactly the same as the USPhoneNumberField except using a real +Candian area code + +>>> from django.contrib.localflavor.ca.forms import CAPhoneNumberField +>>> f = CAPhoneNumberField() +>>> f.clean('403-555-1212') +u'403-555-1212' +>>> f.clean('4035551212') +u'403-555-1212' +>>> f.clean('403 555-1212') +u'403-555-1212' +>>> f.clean('(403) 555-1212') +u'403-555-1212' +>>> f.clean('403 555 1212') +u'403-555-1212' +>>> f.clean('403.555.1212') +u'403-555-1212' +>>> f.clean('403.555-1212') +u'403-555-1212' +>>> f.clean(' (403) 555.1212 ') +u'403-555-1212' +>>> f.clean('555-1212') +Traceback (most recent call last): +... +ValidationError: [u'Phone numbers must be in XXX-XXX-XXXX format.'] +>>> f.clean('403-55-1212') +Traceback (most recent call last): +... +ValidationError: [u'Phone numbers must be in XXX-XXX-XXXX format.'] +>>> f.clean(None) +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] +>>> f.clean('') +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] + +>>> f = CAPhoneNumberField(required=False) +>>> f.clean('403-555-1212') +u'403-555-1212' +>>> f.clean('4035551212') +u'403-555-1212' +>>> f.clean('403 555-1212') +u'403-555-1212' +>>> f.clean('(403) 555-1212') +u'403-555-1212' +>>> f.clean('403 555 1212') +u'403-555-1212' +>>> f.clean('403.555.1212') +u'403-555-1212' +>>> f.clean('403.555-1212') +u'403-555-1212' +>>> f.clean(' (403) 555.1212 ') +u'403-555-1212' +>>> f.clean('555-1212') +Traceback (most recent call last): +... +ValidationError: [u'Phone numbers must be in XXX-XXX-XXXX format.'] +>>> f.clean('403-55-1212') +Traceback (most recent call last): +... +ValidationError: [u'Phone numbers must be in XXX-XXX-XXXX format.'] +>>> f.clean(None) +u'' +>>> f.clean('') +u'' + +# CAProvinceField ################################################################ + +CAProvinceField validates that the data is either an abbreviation or name of a +Canadian province. +>>> from django.contrib.localflavor.ca.forms import CAProvinceField +>>> f = CAProvinceField() +>>> f.clean('ab') +u'AB' +>>> f.clean('BC') +u'BC' +>>> f.clean('nova scotia') +u'NS' +>>> f.clean(' manitoba ') +u'MB' +>>> f.clean('T2S 2H7') +Traceback (most recent call last): +... +ValidationError: [u'Enter a Canadian province or territory.'] +>>> f.clean(None) +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] +>>> f.clean('') +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] + +>>> f = CAProvinceField(required=False) +>>> f.clean('ab') +u'AB' +>>> f.clean('BC') +u'BC' +>>> f.clean('nova scotia') +u'NS' +>>> f.clean(' manitoba ') +u'MB' +>>> f.clean('T2S 2H7') +Traceback (most recent call last): +... +ValidationError: [u'Enter a Canadian province or territory.'] +>>> f.clean(None) +u'' +>>> f.clean('') +u'' + +# CAProvinceSelect ############################################################### + +CAProvinceSelect is a Select widget that uses a list of Canadian provinces/territories +as its choices. +>>> from django.contrib.localflavor.ca.forms import CAProvinceSelect +>>> w = CAProvinceSelect() +>>> print w.render('province', 'AB') +<select name="province"> +<option value="AB" selected="selected">Alberta</option> +<option value="BC">British Columbia</option> +<option value="MB">Manitoba</option> +<option value="NB">New Brunswick</option> +<option value="NF">Newfoundland and Labrador</option> +<option value="NT">Northwest Territories</option> +<option value="NS">Nova Scotia</option> +<option value="NU">Nunavut</option> +<option value="ON">Ontario</option> +<option value="PE">Prince Edward Island</option> +<option value="QC">Quebec</option> +<option value="SK">Saskatchewan</option> +<option value="YK">Yukon</option> +</select> + +# CASocialInsuranceNumberField ################################################# +>>> from django.contrib.localflavor.ca.forms import CASocialInsuranceNumberField +>>> f = CASocialInsuranceNumberField() +>>> f.clean('046-454-286') +u'046-454-286' +>>> f.clean('046-454-287') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid Canadian Social Insurance number in XXX-XXX-XXXX format.'] +>>> f.clean('046 454 286') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid Canadian Social Insurance number in XXX-XXX-XXXX format.'] +>>> f.clean('046-44-286') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid Canadian Social Insurance number in XXX-XXX-XXXX format.'] + +## Generic DateField ########################################################## + +>>> from django.contrib.localflavor.generic.forms import * + +A DateField that uses generic dd/mm/yy dates instead of mm/dd/yy where +appropriate. + +>>> import datetime +>>> f = DateField() +>>> f.clean(datetime.date(2006, 10, 25)) +datetime.date(2006, 10, 25) +>>> f.clean(datetime.datetime(2006, 10, 25, 14, 30)) +datetime.date(2006, 10, 25) +>>> f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59)) +datetime.date(2006, 10, 25) +>>> f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59, 200)) +datetime.date(2006, 10, 25) +>>> f.clean('2006-10-25') +datetime.date(2006, 10, 25) +>>> f.clean('25/10/2006') +datetime.date(2006, 10, 25) +>>> f.clean('25/10/06') +datetime.date(2006, 10, 25) +>>> f.clean('Oct 25 2006') +datetime.date(2006, 10, 25) +>>> f.clean('October 25 2006') +datetime.date(2006, 10, 25) +>>> f.clean('October 25, 2006') +datetime.date(2006, 10, 25) +>>> f.clean('25 October 2006') +datetime.date(2006, 10, 25) +>>> f.clean('25 October, 2006') +datetime.date(2006, 10, 25) +>>> f.clean('2006-4-31') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid date.'] +>>> f.clean('200a-10-25') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid date.'] +>>> f.clean('10/25/06') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid date.'] +>>> f.clean(None) +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] + +>>> f = DateField(required=False) +>>> f.clean(None) +>>> repr(f.clean(None)) +'None' +>>> f.clean('') +>>> repr(f.clean('')) +'None' + +DateField accepts an optional input_formats parameter: +>>> f = DateField(input_formats=['%Y %m %d']) +>>> f.clean(datetime.date(2006, 10, 25)) +datetime.date(2006, 10, 25) +>>> f.clean(datetime.datetime(2006, 10, 25, 14, 30)) +datetime.date(2006, 10, 25) +>>> f.clean('2006 10 25') +datetime.date(2006, 10, 25) + +The input_formats parameter overrides all default input formats, +so the default formats won't work unless you specify them: +>>> f.clean('2006-10-25') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid date.'] +>>> f.clean('25/10/2006') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid date.'] +>>> f.clean('25/10/06') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid date.'] + +## Generic DateTimeField ###################################################### + +A DateField that uses generic dd/mm/yy dates instead of mm/dd/yy where +appropriate. + +>>> import datetime +>>> f = DateTimeField() +>>> f.clean(datetime.date(2006, 10, 25)) +datetime.datetime(2006, 10, 25, 0, 0) +>>> f.clean(datetime.datetime(2006, 10, 25, 14, 30)) +datetime.datetime(2006, 10, 25, 14, 30) +>>> f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59)) +datetime.datetime(2006, 10, 25, 14, 30, 59) +>>> f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59, 200)) +datetime.datetime(2006, 10, 25, 14, 30, 59, 200) +>>> f.clean('2006-10-25 14:30:45') +datetime.datetime(2006, 10, 25, 14, 30, 45) +>>> f.clean('2006-10-25 14:30:00') +datetime.datetime(2006, 10, 25, 14, 30) +>>> f.clean('2006-10-25 14:30') +datetime.datetime(2006, 10, 25, 14, 30) +>>> f.clean('2006-10-25') +datetime.datetime(2006, 10, 25, 0, 0) +>>> f.clean('25/10/2006 14:30:45') +datetime.datetime(2006, 10, 25, 14, 30, 45) +>>> f.clean('25/10/2006 14:30:00') +datetime.datetime(2006, 10, 25, 14, 30) +>>> f.clean('25/10/2006 14:30') +datetime.datetime(2006, 10, 25, 14, 30) +>>> f.clean('25/10/2006') +datetime.datetime(2006, 10, 25, 0, 0) +>>> f.clean('25/10/06 14:30:45') +datetime.datetime(2006, 10, 25, 14, 30, 45) +>>> f.clean('25/10/06 14:30:00') +datetime.datetime(2006, 10, 25, 14, 30) +>>> f.clean('25/10/06 14:30') +datetime.datetime(2006, 10, 25, 14, 30) +>>> f.clean('25/10/06') +datetime.datetime(2006, 10, 25, 0, 0) +>>> f.clean('hello') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid date/time.'] +>>> f.clean('2006-10-25 4:30 p.m.') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid date/time.'] + +DateField accepts an optional input_formats parameter: +>>> f = DateTimeField(input_formats=['%Y %m %d %I:%M %p']) +>>> f.clean(datetime.date(2006, 10, 25)) +datetime.datetime(2006, 10, 25, 0, 0) +>>> f.clean(datetime.datetime(2006, 10, 25, 14, 30)) +datetime.datetime(2006, 10, 25, 14, 30) +>>> f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59)) +datetime.datetime(2006, 10, 25, 14, 30, 59) +>>> f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59, 200)) +datetime.datetime(2006, 10, 25, 14, 30, 59, 200) +>>> f.clean('2006 10 25 2:30 PM') +datetime.datetime(2006, 10, 25, 14, 30) + +The input_formats parameter overrides all default input formats, +so the default formats won't work unless you specify them: +>>> f.clean('2006-10-25 14:30:45') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid date/time.'] + +>>> f = DateTimeField(required=False) +>>> f.clean(None) +>>> repr(f.clean(None)) +'None' +>>> f.clean('') +>>> repr(f.clean('')) +'None' + """ |
