diff options
Diffstat (limited to 'tests')
35 files changed, 626 insertions, 476 deletions
diff --git a/tests/admin_validation/tests.py b/tests/admin_validation/tests.py index 16f73c6390..5eee3e7105 100644 --- a/tests/admin_validation/tests.py +++ b/tests/admin_validation/tests.py @@ -2,7 +2,6 @@ from __future__ import absolute_import from django import forms from django.contrib import admin -from django.contrib.admin.validation import validate, validate_inline from django.core.exceptions import ImproperlyConfigured from django.test import TestCase @@ -38,13 +37,13 @@ class ValidationTestCase(TestCase): "fields": ["title", "original_release"], }), ] - validate(SongAdmin, Song) + SongAdmin.validate(Song) def test_custom_modelforms_with_fields_fieldsets(self): """ # Regression test for #8027: custom ModelForms with fields/fieldsets """ - validate(ValidFields, Song) + ValidFields.validate(Song) def test_custom_get_form_with_fieldsets(self): """ @@ -52,7 +51,7 @@ class ValidationTestCase(TestCase): is overridden. Refs #19445. """ - validate(ValidFormFieldsets, Song) + ValidFormFieldsets.validate(Song) def test_exclude_values(self): """ @@ -62,16 +61,16 @@ class ValidationTestCase(TestCase): exclude = ('foo') self.assertRaisesMessage(ImproperlyConfigured, "'ExcludedFields1.exclude' must be a list or tuple.", - validate, - ExcludedFields1, Book) + ExcludedFields1.validate, + Book) def test_exclude_duplicate_values(self): class ExcludedFields2(admin.ModelAdmin): exclude = ('name', 'name') self.assertRaisesMessage(ImproperlyConfigured, "There are duplicate field(s) in ExcludedFields2.exclude", - validate, - ExcludedFields2, Book) + ExcludedFields2.validate, + Book) def test_exclude_in_inline(self): class ExcludedFieldsInline(admin.TabularInline): @@ -84,8 +83,8 @@ class ValidationTestCase(TestCase): self.assertRaisesMessage(ImproperlyConfigured, "'ExcludedFieldsInline.exclude' must be a list or tuple.", - validate, - ExcludedFieldsAlbumAdmin, Album) + ExcludedFieldsAlbumAdmin.validate, + Album) def test_exclude_inline_model_admin(self): """ @@ -102,8 +101,8 @@ class ValidationTestCase(TestCase): self.assertRaisesMessage(ImproperlyConfigured, "SongInline cannot exclude the field 'album' - this is the foreign key to the parent model admin_validation.Album.", - validate, - AlbumAdmin, Album) + AlbumAdmin.validate, + Album) def test_app_label_in_admin_validation(self): """ @@ -114,8 +113,8 @@ class ValidationTestCase(TestCase): self.assertRaisesMessage(ImproperlyConfigured, "'RawIdNonexistingAdmin.raw_id_fields' refers to field 'nonexisting' that is missing from model 'admin_validation.Album'.", - validate, - RawIdNonexistingAdmin, Album) + RawIdNonexistingAdmin.validate, + Album) def test_fk_exclusion(self): """ @@ -127,28 +126,35 @@ class ValidationTestCase(TestCase): model = TwoAlbumFKAndAnE exclude = ("e",) fk_name = "album1" - validate_inline(TwoAlbumFKAndAnEInline, None, Album) + class MyAdmin(admin.ModelAdmin): + inlines = [TwoAlbumFKAndAnEInline] + MyAdmin.validate(Album) + def test_inline_self_validation(self): class TwoAlbumFKAndAnEInline(admin.TabularInline): model = TwoAlbumFKAndAnE + class MyAdmin(admin.ModelAdmin): + inlines = [TwoAlbumFKAndAnEInline] self.assertRaisesMessage(Exception, "<class 'admin_validation.models.TwoAlbumFKAndAnE'> has more than 1 ForeignKey to <class 'admin_validation.models.Album'>", - validate_inline, - TwoAlbumFKAndAnEInline, None, Album) + MyAdmin.validate, Album) def test_inline_with_specified(self): class TwoAlbumFKAndAnEInline(admin.TabularInline): model = TwoAlbumFKAndAnE fk_name = "album1" - validate_inline(TwoAlbumFKAndAnEInline, None, Album) + + class MyAdmin(admin.ModelAdmin): + inlines = [TwoAlbumFKAndAnEInline] + MyAdmin.validate(Album) def test_readonly(self): class SongAdmin(admin.ModelAdmin): readonly_fields = ("title",) - validate(SongAdmin, Song) + SongAdmin.validate(Song) def test_readonly_on_method(self): def my_function(obj): @@ -157,7 +163,7 @@ class ValidationTestCase(TestCase): class SongAdmin(admin.ModelAdmin): readonly_fields = (my_function,) - validate(SongAdmin, Song) + SongAdmin.validate(Song) def test_readonly_on_modeladmin(self): class SongAdmin(admin.ModelAdmin): @@ -166,13 +172,13 @@ class ValidationTestCase(TestCase): def readonly_method_on_modeladmin(self, obj): pass - validate(SongAdmin, Song) + SongAdmin.validate(Song) def test_readonly_method_on_model(self): class SongAdmin(admin.ModelAdmin): readonly_fields = ("readonly_method_on_model",) - validate(SongAdmin, Song) + SongAdmin.validate(Song) def test_nonexistant_field(self): class SongAdmin(admin.ModelAdmin): @@ -180,8 +186,8 @@ class ValidationTestCase(TestCase): self.assertRaisesMessage(ImproperlyConfigured, "SongAdmin.readonly_fields[1], 'nonexistant' is not a callable or an attribute of 'SongAdmin' or found in the model 'Song'.", - validate, - SongAdmin, Song) + SongAdmin.validate, + Song) def test_nonexistant_field_on_inline(self): class CityInline(admin.TabularInline): @@ -190,8 +196,8 @@ class ValidationTestCase(TestCase): self.assertRaisesMessage(ImproperlyConfigured, "CityInline.readonly_fields[0], 'i_dont_exist' is not a callable or an attribute of 'CityInline' or found in the model 'City'.", - validate_inline, - CityInline, None, State) + CityInline.validate, + City) def test_extra(self): class SongAdmin(admin.ModelAdmin): @@ -199,13 +205,13 @@ class ValidationTestCase(TestCase): if instance.title == "Born to Run": return "Best Ever!" return "Status unknown." - validate(SongAdmin, Song) + SongAdmin.validate(Song) def test_readonly_lambda(self): class SongAdmin(admin.ModelAdmin): readonly_fields = (lambda obj: "test",) - validate(SongAdmin, Song) + SongAdmin.validate(Song) def test_graceful_m2m_fail(self): """ @@ -219,8 +225,8 @@ class ValidationTestCase(TestCase): self.assertRaisesMessage(ImproperlyConfigured, "'BookAdmin.fields' can't include the ManyToManyField field 'authors' because 'authors' manually specifies a 'through' model.", - validate, - BookAdmin, Book) + BookAdmin.validate, + Book) def test_cannot_include_through(self): class FieldsetBookAdmin(admin.ModelAdmin): @@ -230,20 +236,20 @@ class ValidationTestCase(TestCase): ) self.assertRaisesMessage(ImproperlyConfigured, "'FieldsetBookAdmin.fieldsets[1][1]['fields']' can't include the ManyToManyField field 'authors' because 'authors' manually specifies a 'through' model.", - validate, - FieldsetBookAdmin, Book) + FieldsetBookAdmin.validate, + Book) def test_nested_fields(self): class NestedFieldsAdmin(admin.ModelAdmin): fields = ('price', ('name', 'subtitle')) - validate(NestedFieldsAdmin, Book) + NestedFieldsAdmin.validate(Book) def test_nested_fieldsets(self): class NestedFieldsetAdmin(admin.ModelAdmin): fieldsets = ( ('Main', {'fields': ('price', ('name', 'subtitle'))}), ) - validate(NestedFieldsetAdmin, Book) + NestedFieldsetAdmin.validate(Book) def test_explicit_through_override(self): """ @@ -260,7 +266,7 @@ class ValidationTestCase(TestCase): # If the through model is still a string (and hasn't been resolved to a model) # the validation will fail. - validate(BookAdmin, Book) + BookAdmin.validate(Book) def test_non_model_fields(self): """ @@ -274,7 +280,7 @@ class ValidationTestCase(TestCase): form = SongForm fields = ['title', 'extra_data'] - validate(FieldsOnFormOnlyAdmin, Song) + FieldsOnFormOnlyAdmin.validate(Song) def test_non_model_first_field(self): """ @@ -292,4 +298,4 @@ class ValidationTestCase(TestCase): form = SongForm fields = ['extra_data', 'title'] - validate(FieldsOnFormOnlyAdmin, Song) + FieldsOnFormOnlyAdmin.validate(Song) diff --git a/tests/base/models.py b/tests/base/models.py index bddb406820..d47ddcfd66 100644 --- a/tests/base/models.py +++ b/tests/base/models.py @@ -14,8 +14,10 @@ class CustomBaseModel(models.base.ModelBase): class MyModel(six.with_metaclass(CustomBaseModel, models.Model)): - """Model subclass with a custom base using six.with_metaclass.""" + """Model subclass with a custom base using six.with_metaclass.""" +# This is done to ensure that for Python2 only, defining metaclasses +# still does not fail to create the model. if not six.PY3: class MyModel(models.Model): diff --git a/tests/cache/tests.py b/tests/cache/tests.py index 00c51638b7..231a3bfb50 100644 --- a/tests/cache/tests.py +++ b/tests/cache/tests.py @@ -28,8 +28,8 @@ from django.middleware.cache import (FetchFromCacheMiddleware, from django.template import Template from django.template.response import TemplateResponse from django.test import TestCase, TransactionTestCase, RequestFactory -from django.test.utils import override_settings, six -from django.utils import timezone, translation, unittest +from django.test.utils import override_settings, IgnorePendingDeprecationWarningsMixin +from django.utils import six, timezone, translation, unittest from django.utils.cache import (patch_vary_headers, get_cache_key, learn_cache_key, patch_cache_control, patch_response_headers) from django.utils.encoding import force_text @@ -441,6 +441,34 @@ class BaseCacheTests(object): self.assertEqual(self.cache.get('key3'), 'sausage') self.assertEqual(self.cache.get('key4'), 'lobster bisque') + def test_forever_timeout(self): + ''' + Passing in None into timeout results in a value that is cached forever + ''' + self.cache.set('key1', 'eggs', None) + self.assertEqual(self.cache.get('key1'), 'eggs') + + self.cache.add('key2', 'ham', None) + self.assertEqual(self.cache.get('key2'), 'ham') + + self.cache.set_many({'key3': 'sausage', 'key4': 'lobster bisque'}, None) + self.assertEqual(self.cache.get('key3'), 'sausage') + self.assertEqual(self.cache.get('key4'), 'lobster bisque') + + def test_zero_timeout(self): + ''' + Passing in None into timeout results in a value that is cached forever + ''' + self.cache.set('key1', 'eggs', 0) + self.assertEqual(self.cache.get('key1'), None) + + self.cache.add('key2', 'ham', 0) + self.assertEqual(self.cache.get('key2'), None) + + self.cache.set_many({'key3': 'sausage', 'key4': 'lobster bisque'}, 0) + self.assertEqual(self.cache.get('key3'), None) + self.assertEqual(self.cache.get('key4'), None) + def test_float_timeout(self): # Make sure a timeout given as a float doesn't crash anything. self.cache.set("key1", "spam", 100.2) @@ -1564,9 +1592,10 @@ def hello_world_view(request, value): }, }, ) -class CacheMiddlewareTest(TestCase): +class CacheMiddlewareTest(IgnorePendingDeprecationWarningsMixin, TestCase): def setUp(self): + super(CacheMiddlewareTest, self).setUp() self.factory = RequestFactory() self.default_cache = get_cache('default') self.other_cache = get_cache('other') @@ -1574,6 +1603,7 @@ class CacheMiddlewareTest(TestCase): def tearDown(self): self.default_cache.clear() self.other_cache.clear() + super(CacheMiddlewareTest, self).tearDown() def test_constructor(self): """ diff --git a/tests/csrf_tests/tests.py b/tests/csrf_tests/tests.py index b9e8cb5f75..841b24bb42 100644 --- a/tests/csrf_tests/tests.py +++ b/tests/csrf_tests/tests.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals +import logging from django.conf import settings from django.core.context_processors import csrf @@ -78,18 +79,18 @@ class CsrfViewMiddlewareTest(TestCase): def _check_token_present(self, response, csrf_id=None): self.assertContains(response, "name='csrfmiddlewaretoken' value='%s'" % (csrf_id or self._csrf_id)) - def test_process_view_token_too_long(self): - """ - Check that if the token is longer than expected, it is ignored and - a new token is created. - """ - req = self._get_GET_no_csrf_cookie_request() - req.COOKIES[settings.CSRF_COOKIE_NAME] = 'x' * 10000000 - CsrfViewMiddleware().process_view(req, token_view, (), {}) - resp = token_view(req) - resp2 = CsrfViewMiddleware().process_response(req, resp) - csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False) - self.assertEqual(len(csrf_cookie.value), CSRF_KEY_LENGTH) + def test_process_view_token_too_long(self): + """ + Check that if the token is longer than expected, it is ignored and + a new token is created. + """ + req = self._get_GET_no_csrf_cookie_request() + req.COOKIES[settings.CSRF_COOKIE_NAME] = 'x' * 10000000 + CsrfViewMiddleware().process_view(req, token_view, (), {}) + resp = token_view(req) + resp2 = CsrfViewMiddleware().process_response(req, resp) + csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False) + self.assertEqual(len(csrf_cookie.value), CSRF_KEY_LENGTH) def test_process_response_get_token_used(self): """ @@ -353,3 +354,29 @@ class CsrfViewMiddlewareTest(TestCase): resp2 = CsrfViewMiddleware().process_response(req, resp) self.assertTrue(resp2.cookies.get(settings.CSRF_COOKIE_NAME, False)) self.assertTrue('Cookie' in resp2.get('Vary','')) + + def test_ensures_csrf_cookie_no_logging(self): + """ + Tests that ensure_csrf_cookie doesn't log warnings. See #19436. + """ + @ensure_csrf_cookie + def view(request): + # Doesn't insert a token or anything + return HttpResponse(content="") + + class TestHandler(logging.Handler): + def emit(self, record): + raise Exception("This shouldn't have happened!") + + logger = logging.getLogger('django.request') + test_handler = TestHandler() + old_log_level = logger.level + try: + logger.addHandler(test_handler) + logger.setLevel(logging.WARNING) + + req = self._get_GET_no_csrf_cookie_request() + resp = view(req) + finally: + logger.removeHandler(test_handler) + logger.setLevel(old_log_level) diff --git a/tests/defaultfilters/tests.py b/tests/defaultfilters/tests.py index 21734faf95..be16719c8e 100644 --- a/tests/defaultfilters/tests.py +++ b/tests/defaultfilters/tests.py @@ -527,24 +527,26 @@ class DefaultFiltersTests(TestCase): def test_timesince(self): # real testing is done in timesince.py, where we can provide our own 'now' + # NOTE: \xa0 avoids wrapping between value and unit self.assertEqual( timesince_filter(datetime.datetime.now() - datetime.timedelta(1)), - '1 day') + '1\xa0day') self.assertEqual( timesince_filter(datetime.datetime(2005, 12, 29), datetime.datetime(2005, 12, 30)), - '1 day') + '1\xa0day') def test_timeuntil(self): + # NOTE: \xa0 avoids wrapping between value and unit self.assertEqual( timeuntil_filter(datetime.datetime.now() + datetime.timedelta(1, 1)), - '1 day') + '1\xa0day') self.assertEqual( timeuntil_filter(datetime.datetime(2005, 12, 30), datetime.datetime(2005, 12, 29)), - '1 day') + '1\xa0day') def test_default(self): self.assertEqual(default("val", "default"), 'val') @@ -574,43 +576,45 @@ class DefaultFiltersTests(TestCase): 'get out of town') def test_filesizeformat(self): - self.assertEqual(filesizeformat(1023), '1023 bytes') - self.assertEqual(filesizeformat(1024), '1.0 KB') - self.assertEqual(filesizeformat(10*1024), '10.0 KB') - self.assertEqual(filesizeformat(1024*1024-1), '1024.0 KB') - self.assertEqual(filesizeformat(1024*1024), '1.0 MB') - self.assertEqual(filesizeformat(1024*1024*50), '50.0 MB') - self.assertEqual(filesizeformat(1024*1024*1024-1), '1024.0 MB') - self.assertEqual(filesizeformat(1024*1024*1024), '1.0 GB') - self.assertEqual(filesizeformat(1024*1024*1024*1024), '1.0 TB') - self.assertEqual(filesizeformat(1024*1024*1024*1024*1024), '1.0 PB') + # NOTE: \xa0 avoids wrapping between value and unit + self.assertEqual(filesizeformat(1023), '1023\xa0bytes') + self.assertEqual(filesizeformat(1024), '1.0\xa0KB') + self.assertEqual(filesizeformat(10*1024), '10.0\xa0KB') + self.assertEqual(filesizeformat(1024*1024-1), '1024.0\xa0KB') + self.assertEqual(filesizeformat(1024*1024), '1.0\xa0MB') + self.assertEqual(filesizeformat(1024*1024*50), '50.0\xa0MB') + self.assertEqual(filesizeformat(1024*1024*1024-1), '1024.0\xa0MB') + self.assertEqual(filesizeformat(1024*1024*1024), '1.0\xa0GB') + self.assertEqual(filesizeformat(1024*1024*1024*1024), '1.0\xa0TB') + self.assertEqual(filesizeformat(1024*1024*1024*1024*1024), '1.0\xa0PB') self.assertEqual(filesizeformat(1024*1024*1024*1024*1024*2000), - '2000.0 PB') - self.assertEqual(filesizeformat(complex(1,-1)), '0 bytes') - self.assertEqual(filesizeformat(""), '0 bytes') + '2000.0\xa0PB') + self.assertEqual(filesizeformat(complex(1,-1)), '0\xa0bytes') + self.assertEqual(filesizeformat(""), '0\xa0bytes') self.assertEqual(filesizeformat("\N{GREEK SMALL LETTER ALPHA}"), - '0 bytes') + '0\xa0bytes') def test_localized_filesizeformat(self): + # NOTE: \xa0 avoids wrapping between value and unit with self.settings(USE_L10N=True): with translation.override('de', deactivate=True): - self.assertEqual(filesizeformat(1023), '1023 Bytes') - self.assertEqual(filesizeformat(1024), '1,0 KB') - self.assertEqual(filesizeformat(10*1024), '10,0 KB') - self.assertEqual(filesizeformat(1024*1024-1), '1024,0 KB') - self.assertEqual(filesizeformat(1024*1024), '1,0 MB') - self.assertEqual(filesizeformat(1024*1024*50), '50,0 MB') - self.assertEqual(filesizeformat(1024*1024*1024-1), '1024,0 MB') - self.assertEqual(filesizeformat(1024*1024*1024), '1,0 GB') - self.assertEqual(filesizeformat(1024*1024*1024*1024), '1,0 TB') + self.assertEqual(filesizeformat(1023), '1023\xa0Bytes') + self.assertEqual(filesizeformat(1024), '1,0\xa0KB') + self.assertEqual(filesizeformat(10*1024), '10,0\xa0KB') + self.assertEqual(filesizeformat(1024*1024-1), '1024,0\xa0KB') + self.assertEqual(filesizeformat(1024*1024), '1,0\xa0MB') + self.assertEqual(filesizeformat(1024*1024*50), '50,0\xa0MB') + self.assertEqual(filesizeformat(1024*1024*1024-1), '1024,0\xa0MB') + self.assertEqual(filesizeformat(1024*1024*1024), '1,0\xa0GB') + self.assertEqual(filesizeformat(1024*1024*1024*1024), '1,0\xa0TB') self.assertEqual(filesizeformat(1024*1024*1024*1024*1024), - '1,0 PB') + '1,0\xa0PB') self.assertEqual(filesizeformat(1024*1024*1024*1024*1024*2000), - '2000,0 PB') - self.assertEqual(filesizeformat(complex(1,-1)), '0 Bytes') - self.assertEqual(filesizeformat(""), '0 Bytes') + '2000,0\xa0PB') + self.assertEqual(filesizeformat(complex(1,-1)), '0\xa0Bytes') + self.assertEqual(filesizeformat(""), '0\xa0Bytes') self.assertEqual(filesizeformat("\N{GREEK SMALL LETTER ALPHA}"), - '0 Bytes') + '0\xa0Bytes') def test_pluralize(self): self.assertEqual(pluralize(1), '') diff --git a/tests/fixtures/tests.py b/tests/fixtures/tests.py index 103612198e..f954933046 100644 --- a/tests/fixtures/tests.py +++ b/tests/fixtures/tests.py @@ -1,5 +1,7 @@ from __future__ import absolute_import +import warnings + from django.contrib.sites.models import Site from django.core import management from django.db import connection, IntegrityError @@ -137,8 +139,18 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase): '<Book: Music for all ages by Artist formerly known as "Prince" and Django Reinhardt>' ]) - # Load a fixture that doesn't exist - management.call_command('loaddata', 'unknown.json', verbosity=0, commit=False) + # Loading a fixture that doesn't exist emits a warning + with warnings.catch_warnings(record=True) as w: + management.call_command('loaddata', 'unknown.json', verbosity=0, + commit=False) + self.assertEqual(len(w), 1) + self.assertTrue(w[0].message, "No fixture named 'unknown' found.") + + # An attempt to load a nonexistent 'initial_data' fixture isn't an error + with warnings.catch_warnings(record=True) as w: + management.call_command('loaddata', 'initial_data.json', verbosity=0, + commit=False) + self.assertEqual(len(w), 0) # object list is unaffected self.assertQuerysetEqual(Article.objects.all(), [ @@ -273,10 +285,11 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase): def test_unmatched_identifier_loading(self): # Try to load db fixture 3. This won't load because the database identifier doesn't match - management.call_command('loaddata', 'db_fixture_3', verbosity=0, commit=False) - self.assertQuerysetEqual(Article.objects.all(), []) + with warnings.catch_warnings(record=True): + management.call_command('loaddata', 'db_fixture_3', verbosity=0, commit=False) - management.call_command('loaddata', 'db_fixture_3', verbosity=0, using='default', commit=False) + with warnings.catch_warnings(record=True): + management.call_command('loaddata', 'db_fixture_3', verbosity=0, using='default', commit=False) self.assertQuerysetEqual(Article.objects.all(), []) def test_output_formats(self): diff --git a/tests/fixtures_model_package/tests.py b/tests/fixtures_model_package/tests.py index c250f647ce..fbd0271336 100644 --- a/tests/fixtures_model_package/tests.py +++ b/tests/fixtures_model_package/tests.py @@ -1,5 +1,7 @@ from __future__ import unicode_literals +import warnings + from django.core import management from django.db import transaction from django.test import TestCase, TransactionTestCase @@ -100,7 +102,9 @@ class FixtureTestCase(TestCase): ) # Load a fixture that doesn't exist - management.call_command("loaddata", "unknown.json", verbosity=0, commit=False) + with warnings.catch_warnings(record=True): + management.call_command("loaddata", "unknown.json", verbosity=0, commit=False) + self.assertQuerysetEqual( Article.objects.all(), [ "Django conquers world!", diff --git a/tests/fixtures_regress/tests.py b/tests/fixtures_regress/tests.py index 02e923e386..5114302267 100644 --- a/tests/fixtures_regress/tests.py +++ b/tests/fixtures_regress/tests.py @@ -4,6 +4,7 @@ from __future__ import absolute_import, unicode_literals import os import re +import warnings from django.core.serializers.base import DeserializationError from django.core import management @@ -441,13 +442,14 @@ class TestFixtures(TestCase): def test_loaddata_not_existant_fixture_file(self): stdout_output = StringIO() - management.call_command( - 'loaddata', - 'this_fixture_doesnt_exist', - verbosity=2, - commit=False, - stdout=stdout_output, - ) + with warnings.catch_warnings(record=True): + management.call_command( + 'loaddata', + 'this_fixture_doesnt_exist', + verbosity=2, + commit=False, + stdout=stdout_output, + ) self.assertTrue("No xml fixture 'this_fixture_doesnt_exist' in" in force_text(stdout_output.getvalue())) diff --git a/tests/forms_tests/tests/test_extra.py b/tests/forms_tests/tests/test_extra.py index a83cdfc05f..ea0f063c30 100644 --- a/tests/forms_tests/tests/test_extra.py +++ b/tests/forms_tests/tests/test_extra.py @@ -569,6 +569,14 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin): f = GenericIPAddressField(unpack_ipv4=True) self.assertEqual(f.clean(' ::ffff:0a0a:0a0a'), '10.10.10.10') + def test_slugfield_normalization(self): + f = SlugField() + self.assertEqual(f.clean(' aa-bb-cc '), 'aa-bb-cc') + + def test_urlfield_normalization(self): + f = URLField() + self.assertEqual(f.clean('http://example.com/ '), 'http://example.com/') + def test_smart_text(self): class Test: if six.PY3: diff --git a/tests/forms_tests/tests/test_fields.py b/tests/forms_tests/tests/test_fields.py index 7516de29b4..47c637befa 100644 --- a/tests/forms_tests/tests/test_fields.py +++ b/tests/forms_tests/tests/test_fields.py @@ -125,6 +125,15 @@ class FieldsTests(SimpleTestCase): self.assertEqual(f.max_length, None) self.assertEqual(f.min_length, 10) + def test_charfield_length_not_int(self): + """ + Ensure that setting min_length or max_length to something that is not a + number returns an exception. + """ + self.assertRaises(ValueError, CharField, min_length='a') + self.assertRaises(ValueError, CharField, max_length='a') + self.assertRaises(ValueError, CharField, 'a') + def test_charfield_widget_attrs(self): """ Ensure that CharField.widget_attrs() always returns a dictionary. diff --git a/tests/generic_views/test_base.py b/tests/generic_views/test_base.py index 0e84e17132..ffdad4b69f 100644 --- a/tests/generic_views/test_base.py +++ b/tests/generic_views/test_base.py @@ -411,3 +411,36 @@ class GetContextDataTest(unittest.TestCase): # test that kwarg overrides values assigned higher up context = test_view.get_context_data(test_name='test_value') self.assertEqual(context['test_name'], 'test_value') + + def test_object_at_custom_name_in_context_data(self): + # Checks 'pony' key presence in dict returned by get_context_date + test_view = views.CustomSingleObjectView() + test_view.context_object_name = 'pony' + context = test_view.get_context_data() + self.assertEqual(context['pony'], test_view.object) + + def test_object_in_get_context_data(self): + # Checks 'object' key presence in dict returned by get_context_date #20234 + test_view = views.CustomSingleObjectView() + context = test_view.get_context_data() + self.assertEqual(context['object'], test_view.object) + + +class UseMultipleObjectMixinTest(unittest.TestCase): + rf = RequestFactory() + + def test_use_queryset_from_view(self): + test_view = views.CustomMultipleObjectMixinView() + test_view.get(self.rf.get('/')) + # Don't pass queryset as argument + context = test_view.get_context_data() + self.assertEqual(context['object_list'], test_view.queryset) + + def test_overwrite_queryset(self): + test_view = views.CustomMultipleObjectMixinView() + test_view.get(self.rf.get('/')) + queryset = [{'name': 'Lennon'}, {'name': 'Ono'}] + self.assertNotEqual(test_view.queryset, queryset) + # Overwrite the view's queryset with queryset from kwarg + context = test_view.get_context_data(object_list=queryset) + self.assertEqual(context['object_list'], queryset) diff --git a/tests/generic_views/views.py b/tests/generic_views/views.py index aa8777e8c6..fd331f14b7 100644 --- a/tests/generic_views/views.py +++ b/tests/generic_views/views.py @@ -1,7 +1,6 @@ from __future__ import absolute_import from django.contrib.auth.decorators import login_required -from django.contrib.messages.views import SuccessMessageMixin from django.core.paginator import Paginator from django.core.urlresolvers import reverse, reverse_lazy from django.utils.decorators import method_decorator @@ -201,6 +200,17 @@ class BookDetailGetObjectCustomQueryset(BookDetail): return super(BookDetailGetObjectCustomQueryset,self).get_object( queryset=Book.objects.filter(pk=2)) + +class CustomMultipleObjectMixinView(generic.list.MultipleObjectMixin, generic.View): + queryset = [ + {'name': 'John'}, + {'name': 'Yoko'}, + ] + + def get(self, request): + self.object_list = self.get_queryset() + + class CustomContextView(generic.detail.SingleObjectMixin, generic.View): model = Book object = Book(name='dummy') @@ -216,6 +226,10 @@ class CustomContextView(generic.detail.SingleObjectMixin, generic.View): def get_context_object_name(self, obj): return "test_name" +class CustomSingleObjectView(generic.detail.SingleObjectMixin, generic.View): + model = Book + object = Book(name="dummy") + class BookSigningConfig(object): model = BookSigning date_field = 'event_date' diff --git a/tests/i18n/__init__.py b/tests/i18n/__init__.py index e69de29bb2..a3e9ce7053 100644 --- a/tests/i18n/__init__.py +++ b/tests/i18n/__init__.py @@ -0,0 +1,17 @@ +from threading import local + + +class TransRealMixin(object): + """This is the only way to reset the translation machinery. Otherwise + the test suite occasionally fails because of global state pollution + between tests.""" + def flush_caches(self): + from django.utils.translation import trans_real + trans_real._translations = {} + trans_real._active = local() + trans_real._default = None + trans_real._accepted = {} + + def tearDown(self): + self.flush_caches() + super(TransRealMixin, self).tearDown() diff --git a/tests/i18n/contenttypes/tests.py b/tests/i18n/contenttypes/tests.py index 5e8a9823e1..cbac9ec5da 100644 --- a/tests/i18n/contenttypes/tests.py +++ b/tests/i18n/contenttypes/tests.py @@ -10,6 +10,8 @@ from django.utils._os import upath from django.utils import six from django.utils import translation +from i18n import TransRealMixin + @override_settings( USE_I18N=True, @@ -22,7 +24,7 @@ from django.utils import translation ('fr', 'French'), ), ) -class ContentTypeTests(TestCase): +class ContentTypeTests(TransRealMixin, TestCase): def test_verbose_name(self): company_type = ContentType.objects.get(app_label='i18n', model='company') with translation.override('en'): diff --git a/tests/i18n/tests.py b/tests/i18n/tests.py index 1022c8d2f1..137270f830 100644 --- a/tests/i18n/tests.py +++ b/tests/i18n/tests.py @@ -30,7 +30,8 @@ from django.utils.translation import (activate, deactivate, ngettext, ngettext_lazy, ungettext, ungettext_lazy, pgettext, pgettext_lazy, - npgettext, npgettext_lazy) + npgettext, npgettext_lazy, + check_for_language) from .commands.tests import can_run_extraction_tests, can_run_compilation_tests if can_run_extraction_tests: @@ -43,6 +44,7 @@ if can_run_compilation_tests: from .commands.compilation import (PoFileTests, PoFileContentsTests, PercentRenderingTests, MultipleLocaleCompilationTests, CompilationErrorHandling) +from . import TransRealMixin from .forms import I18nForm, SelectDateForm, SelectDateWidget, CompanyForm from .models import Company, TestModel @@ -52,7 +54,8 @@ extended_locale_paths = settings.LOCALE_PATHS + ( os.path.join(here, 'other', 'locale'), ) -class TranslationTests(TestCase): + +class TranslationTests(TransRealMixin, TestCase): def test_override(self): activate('de') @@ -333,10 +336,43 @@ class TranslationTests(TestCase): self.assertEqual(rendered, 'My other name is James.') +class TranslationThreadSafetyTests(TestCase): + """Specifically not using TransRealMixin here to test threading.""" + + def setUp(self): + self._old_language = get_language() + self._translations = trans_real._translations + + # here we rely on .split() being called inside the _fetch() + # in trans_real.translation() + class sideeffect_str(str): + def split(self, *args, **kwargs): + res = str.split(self, *args, **kwargs) + trans_real._translations['en-YY'] = None + return res + + trans_real._translations = {sideeffect_str('en-XX'): None} + + def tearDown(self): + trans_real._translations = self._translations + activate(self._old_language) + + def test_bug14894_translation_activate_thread_safety(self): + translation_count = len(trans_real._translations) + try: + translation.activate('pl') + except RuntimeError: + self.fail('translation.activate() is not thread-safe') + + # make sure sideeffect_str actually added a new translation + self.assertLess(translation_count, len(trans_real._translations)) + + @override_settings(USE_L10N=True) -class FormattingTests(TestCase): +class FormattingTests(TransRealMixin, TestCase): def setUp(self): + super(FormattingTests, self).setUp() self.n = decimal.Decimal('66666.666') self.f = 99999.999 self.d = datetime.date(2009, 12, 31) @@ -738,9 +774,10 @@ class FormattingTests(TestCase): self.assertEqual(template2.render(context), output2) self.assertEqual(template3.render(context), output3) -class MiscTests(TestCase): +class MiscTests(TransRealMixin, TestCase): def setUp(self): + super(MiscTests, self).setUp() self.rf = RequestFactory() def test_parse_spec_http_header(self): @@ -884,17 +921,15 @@ class MiscTests(TestCase): self.assertEqual(t_plur.render(Context({'percent': 42, 'num': 4})), '%(percent)s% represents 4 objects') -class ResolutionOrderI18NTests(TestCase): +class ResolutionOrderI18NTests(TransRealMixin, TestCase): def setUp(self): - # Okay, this is brutal, but we have no other choice to fully reset - # the translation framework - trans_real._active = local() - trans_real._translations = {} + super(ResolutionOrderI18NTests, self).setUp() activate('de') def tearDown(self): deactivate() + super(ResolutionOrderI18NTests, self).tearDown() def assertUgettext(self, msgid, msgstr): result = ugettext(msgid) @@ -967,15 +1002,17 @@ class TestLanguageInfo(TestCase): six.assertRaisesRegex(self, KeyError, r"Unknown language code xx-xx and xx\.", get_language_info, 'xx-xx') -class MultipleLocaleActivationTests(TestCase): +class MultipleLocaleActivationTests(TransRealMixin, TestCase): """ Tests for template rendering behavior when multiple locales are activated during the lifetime of the same process. """ def setUp(self): + super(MultipleLocaleActivationTests, self).setUp() self._old_language = get_language() def tearDown(self): + super(MultipleLocaleActivationTests, self).tearDown() activate(self._old_language) def test_single_locale_activation(self): @@ -1104,7 +1141,7 @@ class MultipleLocaleActivationTests(TestCase): 'django.middleware.common.CommonMiddleware', ), ) -class LocaleMiddlewareTests(TestCase): +class LocaleMiddlewareTests(TransRealMixin, TestCase): urls = 'i18n.urls' @@ -1114,3 +1151,41 @@ class LocaleMiddlewareTests(TestCase): self.assertContains(response, "Oui/Non") response = self.client.get('/en/streaming/') self.assertContains(response, "Yes/No") + +@override_settings( + USE_I18N=True, + LANGUAGES=( + ('bg', 'Bulgarian'), + ('en-us', 'English'), + ), + MIDDLEWARE_CLASSES=( + 'django.middleware.locale.LocaleMiddleware', + 'django.middleware.common.CommonMiddleware', + ), +) +class CountrySpecificLanguageTests(TransRealMixin, TestCase): + + urls = 'i18n.urls' + + def setUp(self): + super(CountrySpecificLanguageTests, self).setUp() + self.rf = RequestFactory() + + def test_check_for_language(self): + self.assertTrue(check_for_language('en')) + self.assertTrue(check_for_language('en-us')) + self.assertTrue(check_for_language('en-US')) + + + def test_get_language_from_request(self): + # issue 19919 + r = self.rf.get('/') + r.COOKIES = {} + r.META = {'HTTP_ACCEPT_LANGUAGE': 'en-US,en;q=0.8,bg;q=0.6,ru;q=0.4'} + lang = get_language_from_request(r) + self.assertEqual('en-us', lang) + r = self.rf.get('/') + r.COOKIES = {} + r.META = {'HTTP_ACCEPT_LANGUAGE': 'bg-bg,en-US;q=0.8,en;q=0.6,ru;q=0.4'} + lang = get_language_from_request(r) + self.assertEqual('bg', lang) diff --git a/tests/invalid_models/invalid_models/models.py b/tests/invalid_models/invalid_models/models.py index 3c21e1ddb8..6ba3f04e5e 100644 --- a/tests/invalid_models/invalid_models/models.py +++ b/tests/invalid_models/invalid_models/models.py @@ -375,8 +375,8 @@ invalid_models.fielderrors: "decimalfield3": DecimalFields require a "max_digits invalid_models.fielderrors: "decimalfield4": DecimalFields require a "max_digits" attribute value that is greater than or equal to the value of the "decimal_places" attribute. invalid_models.fielderrors: "filefield": FileFields require an "upload_to" attribute. invalid_models.fielderrors: "choices": "choices" should be iterable (e.g., a tuple or list). -invalid_models.fielderrors: "choices2": "choices" should be a sequence of two-tuples. -invalid_models.fielderrors: "choices2": "choices" should be a sequence of two-tuples. +invalid_models.fielderrors: "choices2": "choices" should be a sequence of two-item iterables (e.g. list of 2 item tuples). +invalid_models.fielderrors: "choices2": "choices" should be a sequence of two-item iterables (e.g. list of 2 item tuples). invalid_models.fielderrors: "index": "db_index" should be either None, True or False. invalid_models.fielderrors: "field_": Field names cannot end with underscores, because this would lead to ambiguous queryset filters. invalid_models.fielderrors: "nullbool": BooleanFields do not accept null values. Use a NullBooleanField instead. diff --git a/tests/middleware/tests.py b/tests/middleware/tests.py index e526da4772..1ff8390f31 100644 --- a/tests/middleware/tests.py +++ b/tests/middleware/tests.py @@ -18,14 +18,12 @@ from django.middleware.http import ConditionalGetMiddleware from django.middleware.gzip import GZipMiddleware from django.middleware.transaction import TransactionMiddleware from django.test import TransactionTestCase, TestCase, RequestFactory -from django.test.utils import override_settings +from django.test.utils import override_settings, IgnorePendingDeprecationWarningsMixin from django.utils import six from django.utils.encoding import force_str from django.utils.six.moves import xrange from django.utils.unittest import expectedFailure, skipIf -from transactions.tests import IgnorePendingDeprecationWarningsMixin - from .models import Band diff --git a/tests/model_forms_regress/tests.py b/tests/model_forms_regress/tests.py index 0e033e033f..80900a59e0 100644 --- a/tests/model_forms_regress/tests.py +++ b/tests/model_forms_regress/tests.py @@ -92,6 +92,41 @@ class OverrideCleanTests(TestCase): self.assertEqual(form.instance.left, 1) + +class PartiallyLocalizedTripleForm(forms.ModelForm): + class Meta: + model = Triple + localized_fields = ('left', 'right',) + + +class FullyLocalizedTripleForm(forms.ModelForm): + class Meta: + model = Triple + localized_fields = "__all__" + +class LocalizedModelFormTest(TestCase): + def test_model_form_applies_localize_to_some_fields(self): + f = PartiallyLocalizedTripleForm({'left': 10, 'middle': 10, 'right': 10}) + self.assertTrue(f.is_valid()) + self.assertTrue(f.fields['left'].localize) + self.assertFalse(f.fields['middle'].localize) + self.assertTrue(f.fields['right'].localize) + + def test_model_form_applies_localize_to_all_fields(self): + f = FullyLocalizedTripleForm({'left': 10, 'middle': 10, 'right': 10}) + self.assertTrue(f.is_valid()) + self.assertTrue(f.fields['left'].localize) + self.assertTrue(f.fields['middle'].localize) + self.assertTrue(f.fields['right'].localize) + + def test_model_form_refuses_arbitrary_string(self): + with self.assertRaises(TypeError): + class BrokenLocalizedTripleForm(forms.ModelForm): + class Meta: + model = Triple + localized_fields = "foo" + + # Regression test for #12960. # Make sure the cleaned_data returned from ModelForm.clean() is applied to the # model instance. diff --git a/tests/model_formsets_regress/tests.py b/tests/model_formsets_regress/tests.py index 38ebd9d24b..c8fb1e76c1 100644 --- a/tests/model_formsets_regress/tests.py +++ b/tests/model_formsets_regress/tests.py @@ -273,6 +273,7 @@ class UserSiteForm(forms.ModelForm): 'id': CustomWidget, 'data': CustomWidget, } + localized_fields = ('data',) class Callback(object): @@ -297,19 +298,23 @@ class FormfieldCallbackTests(TestCase): form = Formset().forms[0] self.assertTrue(isinstance(form['id'].field.widget, CustomWidget)) self.assertTrue(isinstance(form['data'].field.widget, CustomWidget)) + self.assertFalse(form.fields['id'].localize) + self.assertTrue(form.fields['data'].localize) def test_modelformset_factory_default(self): Formset = modelformset_factory(UserSite, form=UserSiteForm) form = Formset().forms[0] self.assertTrue(isinstance(form['id'].field.widget, CustomWidget)) self.assertTrue(isinstance(form['data'].field.widget, CustomWidget)) + self.assertFalse(form.fields['id'].localize) + self.assertTrue(form.fields['data'].localize) def assertCallbackCalled(self, callback): id_field, user_field, data_field = UserSite._meta.fields expected_log = [ (id_field, {'widget': CustomWidget}), (user_field, {}), - (data_field, {'widget': CustomWidget}), + (data_field, {'widget': CustomWidget, 'localize': True}), ] self.assertEqual(callback.log, expected_log) diff --git a/tests/special_headers/__init__.py b/tests/model_validation/__init__.py index e69de29bb2..e69de29bb2 100644 --- a/tests/special_headers/__init__.py +++ b/tests/model_validation/__init__.py diff --git a/tests/model_validation/models.py b/tests/model_validation/models.py new file mode 100644 index 0000000000..9a2a5f7cd0 --- /dev/null +++ b/tests/model_validation/models.py @@ -0,0 +1,27 @@ +from django.db import models + + +class ThingItem(object): + + def __init__(self, value, display): + self.value = value + self.display = display + + def __iter__(self): + return (x for x in [self.value, self.display]) + + def __len__(self): + return 2 + + +class Things(object): + + def __iter__(self): + return (x for x in [ThingItem(1, 2), ThingItem(3, 4)]) + + +class ThingWithIterableChoices(models.Model): + + # Testing choices= Iterable of Iterables + # See: https://code.djangoproject.com/ticket/20430 + thing = models.CharField(max_length=100, blank=True, choices=Things()) diff --git a/tests/model_validation/tests.py b/tests/model_validation/tests.py new file mode 100644 index 0000000000..ffd0d89412 --- /dev/null +++ b/tests/model_validation/tests.py @@ -0,0 +1,13 @@ +from django.core import management +from django.test import TestCase +from django.utils import six + + +class ModelValidationTest(TestCase): + + def test_models_validate(self): + # All our models should validate properly + # Validation Tests: + # * choices= Iterable of Iterables + # See: https://code.djangoproject.com/ticket/20430 + management.call_command("validate", stdout=six.StringIO()) diff --git a/tests/modeladmin/tests.py b/tests/modeladmin/tests.py index 0d933bc1f9..f89f1c20ec 100644 --- a/tests/modeladmin/tests.py +++ b/tests/modeladmin/tests.py @@ -7,7 +7,6 @@ from django.conf import settings from django.contrib.admin.options import (ModelAdmin, TabularInline, HORIZONTAL, VERTICAL) from django.contrib.admin.sites import AdminSite -from django.contrib.admin.validation import validate from django.contrib.admin.widgets import AdminDateWidget, AdminRadioSelect from django.contrib.admin import (SimpleListFilter, BooleanFieldListFilter) @@ -523,8 +522,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.raw_id_fields' must be a list or tuple.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -534,8 +532,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.raw_id_fields' refers to field 'non_existent_field' that is missing from model 'modeladmin.ValidationTestModel'.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -545,15 +542,14 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.raw_id_fields\[0\]', 'name' must be either a ForeignKey or ManyToManyField.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) class ValidationTestModelAdmin(ModelAdmin): raw_id_fields = ('users',) - validate(ValidationTestModelAdmin, ValidationTestModel) + ValidationTestModelAdmin.validate(ValidationTestModel) def test_fieldsets_validation(self): @@ -563,8 +559,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.fieldsets' must be a list or tuple.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -574,8 +569,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.fieldsets\[0\]' must be a list or tuple.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -585,8 +579,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.fieldsets\[0\]' does not have exactly two elements.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -596,8 +589,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.fieldsets\[0\]\[1\]' must be a dictionary.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -607,15 +599,14 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'fields' key is required in ValidationTestModelAdmin.fieldsets\[0\]\[1\] field options dict.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) class ValidationTestModelAdmin(ModelAdmin): fieldsets = (("General", {"fields": ("name",)}),) - validate(ValidationTestModelAdmin, ValidationTestModel) + ValidationTestModelAdmin.validate(ValidationTestModel) class ValidationTestModelAdmin(ModelAdmin): fieldsets = (("General", {"fields": ("name",)}),) @@ -624,8 +615,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "Both fieldsets and fields are specified in ValidationTestModelAdmin.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -635,8 +625,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "There are duplicate field\(s\) in ValidationTestModelAdmin.fieldsets", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -646,8 +635,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "There are duplicate field\(s\) in ValidationTestModelAdmin.fields", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -662,8 +650,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "ValidationTestModelAdmin.form does not inherit from BaseModelForm.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -676,7 +663,7 @@ class ValidationTests(unittest.TestCase): }), ) - validate(BandAdmin, Band) + BandAdmin.validate(Band) class AdminBandForm(forms.ModelForm): delete = forms.BooleanField() @@ -690,7 +677,7 @@ class ValidationTests(unittest.TestCase): }), ) - validate(BandAdmin, Band) + BandAdmin.validate(Band) def test_filter_vertical_validation(self): @@ -700,8 +687,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.filter_vertical' must be a list or tuple.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -711,8 +697,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.filter_vertical' refers to field 'non_existent_field' that is missing from model 'modeladmin.ValidationTestModel'.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -722,15 +707,14 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.filter_vertical\[0\]' must be a ManyToManyField.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) class ValidationTestModelAdmin(ModelAdmin): filter_vertical = ("users",) - validate(ValidationTestModelAdmin, ValidationTestModel) + ValidationTestModelAdmin.validate(ValidationTestModel) def test_filter_horizontal_validation(self): @@ -740,8 +724,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.filter_horizontal' must be a list or tuple.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -751,8 +734,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.filter_horizontal' refers to field 'non_existent_field' that is missing from model 'modeladmin.ValidationTestModel'.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -762,15 +744,14 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.filter_horizontal\[0\]' must be a ManyToManyField.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) class ValidationTestModelAdmin(ModelAdmin): filter_horizontal = ("users",) - validate(ValidationTestModelAdmin, ValidationTestModel) + ValidationTestModelAdmin.validate(ValidationTestModel) def test_radio_fields_validation(self): @@ -780,8 +761,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.radio_fields' must be a dictionary.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -791,8 +771,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.radio_fields' refers to field 'non_existent_field' that is missing from model 'modeladmin.ValidationTestModel'.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -802,8 +781,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.radio_fields\['name'\]' is neither an instance of ForeignKey nor does have choices set.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -813,15 +791,14 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.radio_fields\['state'\]' is neither admin.HORIZONTAL nor admin.VERTICAL.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) class ValidationTestModelAdmin(ModelAdmin): radio_fields = {"state": VERTICAL} - validate(ValidationTestModelAdmin, ValidationTestModel) + ValidationTestModelAdmin.validate(ValidationTestModel) def test_prepopulated_fields_validation(self): @@ -831,8 +808,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.prepopulated_fields' must be a dictionary.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -842,8 +818,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.prepopulated_fields' refers to field 'non_existent_field' that is missing from model 'modeladmin.ValidationTestModel'.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -853,8 +828,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.prepopulated_fields\['slug'\]\[0\]' refers to field 'non_existent_field' that is missing from model 'modeladmin.ValidationTestModel'.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -864,15 +838,14 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.prepopulated_fields\['users'\]' is either a DateTimeField, ForeignKey or ManyToManyField. This isn't allowed.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) class ValidationTestModelAdmin(ModelAdmin): prepopulated_fields = {"slug": ("name",)} - validate(ValidationTestModelAdmin, ValidationTestModel) + ValidationTestModelAdmin.validate(ValidationTestModel) def test_list_display_validation(self): @@ -882,8 +855,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.list_display' must be a list or tuple.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -893,8 +865,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, str_prefix("ValidationTestModelAdmin.list_display\[0\], %(_)s'non_existent_field' is not a callable or an attribute of 'ValidationTestModelAdmin' or found in the model 'ValidationTestModel'."), - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -904,8 +875,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.list_display\[0\]', 'users' is a ManyToManyField which is not supported.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -917,7 +887,7 @@ class ValidationTests(unittest.TestCase): pass list_display = ('name', 'decade_published_in', 'a_method', a_callable) - validate(ValidationTestModelAdmin, ValidationTestModel) + ValidationTestModelAdmin.validate(ValidationTestModel) def test_list_display_links_validation(self): @@ -927,8 +897,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.list_display_links' must be a list or tuple.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -938,8 +907,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.list_display_links\[0\]' refers to 'non_existent_field' which is not defined in 'list_display'.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -949,8 +917,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.list_display_links\[0\]' refers to 'name' which is not defined in 'list_display'.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -963,7 +930,7 @@ class ValidationTests(unittest.TestCase): list_display = ('name', 'decade_published_in', 'a_method', a_callable) list_display_links = ('name', 'decade_published_in', 'a_method', a_callable) - validate(ValidationTestModelAdmin, ValidationTestModel) + ValidationTestModelAdmin.validate(ValidationTestModel) def test_list_filter_validation(self): @@ -973,8 +940,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.list_filter' must be a list or tuple.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -984,8 +950,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.list_filter\[0\]' refers to 'non_existent_field' which does not refer to a Field.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -998,8 +963,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.list_filter\[0\]' is 'RandomClass' which is not a descendant of ListFilter.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -1009,8 +973,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.list_filter\[0\]\[1\]' is 'RandomClass' which is not of type FieldListFilter.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -1028,8 +991,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.list_filter\[0\]\[1\]' is 'AwesomeFilter' which is not of type FieldListFilter.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -1039,8 +1001,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.list_filter\[0\]' is 'BooleanFieldListFilter' which is of type FieldListFilter but is not associated with a field name.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -1049,7 +1010,7 @@ class ValidationTests(unittest.TestCase): class ValidationTestModelAdmin(ModelAdmin): list_filter = ('is_active', AwesomeFilter, ('is_active', BooleanFieldListFilter), 'no') - validate(ValidationTestModelAdmin, ValidationTestModel) + ValidationTestModelAdmin.validate(ValidationTestModel) def test_list_per_page_validation(self): @@ -1058,16 +1019,15 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, - "'ValidationTestModelAdmin.list_per_page' should be a integer.", - validate, - ValidationTestModelAdmin, + "'ValidationTestModelAdmin.list_per_page' should be a int.", + ValidationTestModelAdmin.validate, ValidationTestModel, ) class ValidationTestModelAdmin(ModelAdmin): list_per_page = 100 - validate(ValidationTestModelAdmin, ValidationTestModel) + ValidationTestModelAdmin.validate(ValidationTestModel) def test_max_show_all_allowed_validation(self): @@ -1076,16 +1036,15 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, - "'ValidationTestModelAdmin.list_max_show_all' should be an integer.", - validate, - ValidationTestModelAdmin, + "'ValidationTestModelAdmin.list_max_show_all' should be a int.", + ValidationTestModelAdmin.validate, ValidationTestModel, ) class ValidationTestModelAdmin(ModelAdmin): list_max_show_all = 200 - validate(ValidationTestModelAdmin, ValidationTestModel) + ValidationTestModelAdmin.validate(ValidationTestModel) def test_search_fields_validation(self): @@ -1095,8 +1054,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.search_fields' must be a list or tuple.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -1108,8 +1066,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.date_hierarchy' refers to field 'non_existent_field' that is missing from model 'modeladmin.ValidationTestModel'.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -1119,15 +1076,14 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.date_hierarchy is neither an instance of DateField nor DateTimeField.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) class ValidationTestModelAdmin(ModelAdmin): date_hierarchy = 'pub_date' - validate(ValidationTestModelAdmin, ValidationTestModel) + ValidationTestModelAdmin.validate(ValidationTestModel) def test_ordering_validation(self): @@ -1137,8 +1093,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.ordering' must be a list or tuple.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -1148,8 +1103,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.ordering\[0\]' refers to field 'non_existent_field' that is missing from model 'modeladmin.ValidationTestModel'.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -1159,25 +1113,24 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.ordering' has the random ordering marker '\?', but contains other fields as well. Please either remove '\?' or the other fields.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) class ValidationTestModelAdmin(ModelAdmin): ordering = ('?',) - validate(ValidationTestModelAdmin, ValidationTestModel) + ValidationTestModelAdmin.validate(ValidationTestModel) class ValidationTestModelAdmin(ModelAdmin): ordering = ('band__name',) - validate(ValidationTestModelAdmin, ValidationTestModel) + ValidationTestModelAdmin.validate(ValidationTestModel) class ValidationTestModelAdmin(ModelAdmin): ordering = ('name',) - validate(ValidationTestModelAdmin, ValidationTestModel) + ValidationTestModelAdmin.validate(ValidationTestModel) def test_list_select_related_validation(self): @@ -1186,16 +1139,15 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, - "'ValidationTestModelAdmin.list_select_related' should be a boolean.", - validate, - ValidationTestModelAdmin, + "'ValidationTestModelAdmin.list_select_related' should be a bool.", + ValidationTestModelAdmin.validate, ValidationTestModel, ) class ValidationTestModelAdmin(ModelAdmin): list_select_related = False - validate(ValidationTestModelAdmin, ValidationTestModel) + ValidationTestModelAdmin.validate(ValidationTestModel) def test_save_as_validation(self): @@ -1204,16 +1156,15 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, - "'ValidationTestModelAdmin.save_as' should be a boolean.", - validate, - ValidationTestModelAdmin, + "'ValidationTestModelAdmin.save_as' should be a bool.", + ValidationTestModelAdmin.validate, ValidationTestModel, ) class ValidationTestModelAdmin(ModelAdmin): save_as = True - validate(ValidationTestModelAdmin, ValidationTestModel) + ValidationTestModelAdmin.validate(ValidationTestModel) def test_save_on_top_validation(self): @@ -1222,16 +1173,15 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, - "'ValidationTestModelAdmin.save_on_top' should be a boolean.", - validate, - ValidationTestModelAdmin, + "'ValidationTestModelAdmin.save_on_top' should be a bool.", + ValidationTestModelAdmin.validate, ValidationTestModel, ) class ValidationTestModelAdmin(ModelAdmin): save_on_top = True - validate(ValidationTestModelAdmin, ValidationTestModel) + ValidationTestModelAdmin.validate(ValidationTestModel) def test_inlines_validation(self): @@ -1241,8 +1191,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.inlines' must be a list or tuple.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -1255,8 +1204,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.inlines\[0\]' does not inherit from BaseModelAdmin.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -1269,8 +1217,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'model' is a required attribute of 'ValidationTestModelAdmin.inlines\[0\]'.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -1286,8 +1233,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestModelAdmin.inlines\[0\].model' does not inherit from models.Model.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -1297,7 +1243,7 @@ class ValidationTests(unittest.TestCase): class ValidationTestModelAdmin(ModelAdmin): inlines = [ValidationTestInline] - validate(ValidationTestModelAdmin, ValidationTestModel) + ValidationTestModelAdmin.validate(ValidationTestModel) def test_fields_validation(self): @@ -1311,8 +1257,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestInline.fields' must be a list or tuple.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -1328,8 +1273,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestInline.fk_name' refers to field 'non_existent_field' that is missing from model 'modeladmin.ValidationTestInlineModel'.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -1340,7 +1284,7 @@ class ValidationTests(unittest.TestCase): class ValidationTestModelAdmin(ModelAdmin): inlines = [ValidationTestInline] - validate(ValidationTestModelAdmin, ValidationTestModel) + ValidationTestModelAdmin.validate(ValidationTestModel) def test_extra_validation(self): @@ -1353,9 +1297,8 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, - "'ValidationTestInline.extra' should be a integer.", - validate, - ValidationTestModelAdmin, + "'ValidationTestInline.extra' should be a int.", + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -1366,7 +1309,7 @@ class ValidationTests(unittest.TestCase): class ValidationTestModelAdmin(ModelAdmin): inlines = [ValidationTestInline] - validate(ValidationTestModelAdmin, ValidationTestModel) + ValidationTestModelAdmin.validate(ValidationTestModel) def test_max_num_validation(self): @@ -1379,9 +1322,8 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, - "'ValidationTestInline.max_num' should be an integer or None \(default\).", - validate, - ValidationTestModelAdmin, + "'ValidationTestInline.max_num' should be a int.", + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -1392,7 +1334,7 @@ class ValidationTests(unittest.TestCase): class ValidationTestModelAdmin(ModelAdmin): inlines = [ValidationTestInline] - validate(ValidationTestModelAdmin, ValidationTestModel) + ValidationTestModelAdmin.validate(ValidationTestModel) def test_formset_validation(self): @@ -1409,8 +1351,7 @@ class ValidationTests(unittest.TestCase): six.assertRaisesRegex(self, ImproperlyConfigured, "'ValidationTestInline.formset' does not inherit from BaseModelFormSet.", - validate, - ValidationTestModelAdmin, + ValidationTestModelAdmin.validate, ValidationTestModel, ) @@ -1424,4 +1365,4 @@ class ValidationTests(unittest.TestCase): class ValidationTestModelAdmin(ModelAdmin): inlines = [ValidationTestInline] - validate(ValidationTestModelAdmin, ValidationTestModel) + ValidationTestModelAdmin.validate(ValidationTestModel) diff --git a/tests/requests/tests.py b/tests/requests/tests.py index 56d58c4c75..676cd05679 100644 --- a/tests/requests/tests.py +++ b/tests/requests/tests.py @@ -532,13 +532,13 @@ class RequestsTests(SimpleTestCase): # There are cases in which the multipart data is related instead of # being a binary upload, in which case it should still be accessible # via body. - payload_data = "\r\n".join([ - '--boundary', - 'Content-ID: id; name="name"', - '', - 'value', - '--boundary--' - '']) + payload_data = b"\r\n".join([ + b'--boundary', + b'Content-ID: id; name="name"', + b'', + b'value', + b'--boundary--' + b'']) payload = FakePayload(payload_data) request = WSGIRequest({'REQUEST_METHOD': 'POST', 'CONTENT_TYPE': 'multipart/related; boundary=boundary', diff --git a/tests/special_headers/fixtures/data.xml b/tests/special_headers/fixtures/data.xml deleted file mode 100644 index 7e60d45199..0000000000 --- a/tests/special_headers/fixtures/data.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="100" model="auth.user"> - <field type="CharField" name="username">super</field> - <field type="CharField" name="first_name">Super</field> - <field type="CharField" name="last_name">User</field> - <field type="CharField" name="email">super@example.com</field> - <field type="CharField" name="password">sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158</field> - <field type="BooleanField" name="is_staff">True</field> - <field type="BooleanField" name="is_active">True</field> - <field type="BooleanField" name="is_superuser">True</field> - <field type="DateTimeField" name="last_login">2007-05-30 13:20:10</field> - <field type="DateTimeField" name="date_joined">2007-05-30 13:20:10</field> - <field to="auth.group" name="groups" rel="ManyToManyRel"></field> - <field to="auth.permission" name="user_permissions" rel="ManyToManyRel"></field> - </object> - <object pk="1" model="special_headers.article"> - <field type="TextField" name="text">text</field> - </object> -</django-objects> diff --git a/tests/special_headers/models.py b/tests/special_headers/models.py deleted file mode 100644 index e05c5a6920..0000000000 --- a/tests/special_headers/models.py +++ /dev/null @@ -1,5 +0,0 @@ -from django.db import models - - -class Article(models.Model): - text = models.TextField() diff --git a/tests/special_headers/templates/special_headers/article_detail.html b/tests/special_headers/templates/special_headers/article_detail.html deleted file mode 100644 index 3cbd38cb7e..0000000000 --- a/tests/special_headers/templates/special_headers/article_detail.html +++ /dev/null @@ -1 +0,0 @@ -{{ object }} diff --git a/tests/special_headers/tests.py b/tests/special_headers/tests.py deleted file mode 100644 index b4b704ae21..0000000000 --- a/tests/special_headers/tests.py +++ /dev/null @@ -1,62 +0,0 @@ -from django.contrib.auth.models import User -from django.test import TestCase -from django.test.utils import override_settings - - -@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',)) -class SpecialHeadersTest(TestCase): - fixtures = ['data.xml'] - urls = 'special_headers.urls' - - def test_xheaders(self): - user = User.objects.get(username='super') - response = self.client.get('/special_headers/article/1/') - self.assertFalse('X-Object-Type' in response) - self.client.login(username='super', password='secret') - response = self.client.get('/special_headers/article/1/') - self.assertTrue('X-Object-Type' in response) - user.is_staff = False - user.save() - response = self.client.get('/special_headers/article/1/') - self.assertFalse('X-Object-Type' in response) - user.is_staff = True - user.is_active = False - user.save() - response = self.client.get('/special_headers/article/1/') - self.assertFalse('X-Object-Type' in response) - - def test_xview_func(self): - user = User.objects.get(username='super') - response = self.client.head('/special_headers/xview/func/') - self.assertFalse('X-View' in response) - self.client.login(username='super', password='secret') - response = self.client.head('/special_headers/xview/func/') - self.assertTrue('X-View' in response) - self.assertEqual(response['X-View'], 'special_headers.views.xview') - user.is_staff = False - user.save() - response = self.client.head('/special_headers/xview/func/') - self.assertFalse('X-View' in response) - user.is_staff = True - user.is_active = False - user.save() - response = self.client.head('/special_headers/xview/func/') - self.assertFalse('X-View' in response) - - def test_xview_class(self): - user = User.objects.get(username='super') - response = self.client.head('/special_headers/xview/class/') - self.assertFalse('X-View' in response) - self.client.login(username='super', password='secret') - response = self.client.head('/special_headers/xview/class/') - self.assertTrue('X-View' in response) - self.assertEqual(response['X-View'], 'special_headers.views.XViewClass') - user.is_staff = False - user.save() - response = self.client.head('/special_headers/xview/class/') - self.assertFalse('X-View' in response) - user.is_staff = True - user.is_active = False - user.save() - response = self.client.head('/special_headers/xview/class/') - self.assertFalse('X-View' in response) diff --git a/tests/special_headers/urls.py b/tests/special_headers/urls.py deleted file mode 100644 index f7ba141207..0000000000 --- a/tests/special_headers/urls.py +++ /dev/null @@ -1,13 +0,0 @@ -# coding: utf-8 -from __future__ import absolute_import - -from django.conf.urls import patterns - -from . import views -from .models import Article - -urlpatterns = patterns('', - (r'^special_headers/article/(?P<object_id>\d+)/$', views.xview_xheaders), - (r'^special_headers/xview/func/$', views.xview_dec(views.xview)), - (r'^special_headers/xview/class/$', views.xview_dec(views.XViewClass.as_view())), -) diff --git a/tests/special_headers/views.py b/tests/special_headers/views.py deleted file mode 100644 index a8bbd6542e..0000000000 --- a/tests/special_headers/views.py +++ /dev/null @@ -1,21 +0,0 @@ -from django.core.xheaders import populate_xheaders -from django.http import HttpResponse -from django.utils.decorators import decorator_from_middleware -from django.views.generic import View -from django.middleware.doc import XViewMiddleware - -from .models import Article - -xview_dec = decorator_from_middleware(XViewMiddleware) - -def xview(request): - return HttpResponse() - -def xview_xheaders(request, object_id): - response = HttpResponse() - populate_xheaders(request, response, Article, 1) - return response - -class XViewClass(View): - def get(self, request): - return HttpResponse() diff --git a/tests/template_tests/filters.py b/tests/template_tests/filters.py index 7ba1681fd5..68ef15d827 100644 --- a/tests/template_tests/filters.py +++ b/tests/template_tests/filters.py @@ -35,59 +35,60 @@ def get_filter_tests(): now_tz_i = datetime.now(FixedOffset((3 * 60) + 15)) # imaginary time zone today = date.today() + # NOTE: \xa0 avoids wrapping between value and unit return { # Default compare with datetime.now() - 'filter-timesince01' : ('{{ a|timesince }}', {'a': datetime.now() + timedelta(minutes=-1, seconds = -10)}, '1 minute'), - 'filter-timesince02' : ('{{ a|timesince }}', {'a': datetime.now() - timedelta(days=1, minutes = 1)}, '1 day'), - 'filter-timesince03' : ('{{ a|timesince }}', {'a': datetime.now() - timedelta(hours=1, minutes=25, seconds = 10)}, '1 hour, 25 minutes'), + 'filter-timesince01' : ('{{ a|timesince }}', {'a': datetime.now() + timedelta(minutes=-1, seconds = -10)}, '1\xa0minute'), + 'filter-timesince02' : ('{{ a|timesince }}', {'a': datetime.now() - timedelta(days=1, minutes = 1)}, '1\xa0day'), + 'filter-timesince03' : ('{{ a|timesince }}', {'a': datetime.now() - timedelta(hours=1, minutes=25, seconds = 10)}, '1\xa0hour, 25\xa0minutes'), # Compare to a given parameter - 'filter-timesince04' : ('{{ a|timesince:b }}', {'a':now - timedelta(days=2), 'b':now - timedelta(days=1)}, '1 day'), - 'filter-timesince05' : ('{{ a|timesince:b }}', {'a':now - timedelta(days=2, minutes=1), 'b':now - timedelta(days=2)}, '1 minute'), + 'filter-timesince04' : ('{{ a|timesince:b }}', {'a':now - timedelta(days=2), 'b':now - timedelta(days=1)}, '1\xa0day'), + 'filter-timesince05' : ('{{ a|timesince:b }}', {'a':now - timedelta(days=2, minutes=1), 'b':now - timedelta(days=2)}, '1\xa0minute'), # Check that timezone is respected - 'filter-timesince06' : ('{{ a|timesince:b }}', {'a':now_tz - timedelta(hours=8), 'b':now_tz}, '8 hours'), + 'filter-timesince06' : ('{{ a|timesince:b }}', {'a':now_tz - timedelta(hours=8), 'b':now_tz}, '8\xa0hours'), # Regression for #7443 - 'filter-timesince07': ('{{ earlier|timesince }}', { 'earlier': now - timedelta(days=7) }, '1 week'), - 'filter-timesince08': ('{{ earlier|timesince:now }}', { 'now': now, 'earlier': now - timedelta(days=7) }, '1 week'), - 'filter-timesince09': ('{{ later|timesince }}', { 'later': now + timedelta(days=7) }, '0 minutes'), - 'filter-timesince10': ('{{ later|timesince:now }}', { 'now': now, 'later': now + timedelta(days=7) }, '0 minutes'), + 'filter-timesince07': ('{{ earlier|timesince }}', { 'earlier': now - timedelta(days=7) }, '1\xa0week'), + 'filter-timesince08': ('{{ earlier|timesince:now }}', { 'now': now, 'earlier': now - timedelta(days=7) }, '1\xa0week'), + 'filter-timesince09': ('{{ later|timesince }}', { 'later': now + timedelta(days=7) }, '0\xa0minutes'), + 'filter-timesince10': ('{{ later|timesince:now }}', { 'now': now, 'later': now + timedelta(days=7) }, '0\xa0minutes'), # Ensures that differing timezones are calculated correctly - 'filter-timesince11' : ('{{ a|timesince }}', {'a': now}, '0 minutes'), - 'filter-timesince12' : ('{{ a|timesince }}', {'a': now_tz}, '0 minutes'), - 'filter-timesince13' : ('{{ a|timesince }}', {'a': now_tz_i}, '0 minutes'), - 'filter-timesince14' : ('{{ a|timesince:b }}', {'a': now_tz, 'b': now_tz_i}, '0 minutes'), + 'filter-timesince11' : ('{{ a|timesince }}', {'a': now}, '0\xa0minutes'), + 'filter-timesince12' : ('{{ a|timesince }}', {'a': now_tz}, '0\xa0minutes'), + 'filter-timesince13' : ('{{ a|timesince }}', {'a': now_tz_i}, '0\xa0minutes'), + 'filter-timesince14' : ('{{ a|timesince:b }}', {'a': now_tz, 'b': now_tz_i}, '0\xa0minutes'), 'filter-timesince15' : ('{{ a|timesince:b }}', {'a': now, 'b': now_tz_i}, ''), 'filter-timesince16' : ('{{ a|timesince:b }}', {'a': now_tz_i, 'b': now}, ''), # Regression for #9065 (two date objects). - 'filter-timesince17' : ('{{ a|timesince:b }}', {'a': today, 'b': today}, '0 minutes'), - 'filter-timesince18' : ('{{ a|timesince:b }}', {'a': today, 'b': today + timedelta(hours=24)}, '1 day'), + 'filter-timesince17' : ('{{ a|timesince:b }}', {'a': today, 'b': today}, '0\xa0minutes'), + 'filter-timesince18' : ('{{ a|timesince:b }}', {'a': today, 'b': today + timedelta(hours=24)}, '1\xa0day'), # Default compare with datetime.now() - 'filter-timeuntil01' : ('{{ a|timeuntil }}', {'a':datetime.now() + timedelta(minutes=2, seconds = 10)}, '2 minutes'), - 'filter-timeuntil02' : ('{{ a|timeuntil }}', {'a':(datetime.now() + timedelta(days=1, seconds = 10))}, '1 day'), - 'filter-timeuntil03' : ('{{ a|timeuntil }}', {'a':(datetime.now() + timedelta(hours=8, minutes=10, seconds = 10))}, '8 hours, 10 minutes'), + 'filter-timeuntil01' : ('{{ a|timeuntil }}', {'a':datetime.now() + timedelta(minutes=2, seconds = 10)}, '2\xa0minutes'), + 'filter-timeuntil02' : ('{{ a|timeuntil }}', {'a':(datetime.now() + timedelta(days=1, seconds = 10))}, '1\xa0day'), + 'filter-timeuntil03' : ('{{ a|timeuntil }}', {'a':(datetime.now() + timedelta(hours=8, minutes=10, seconds = 10))}, '8\xa0hours, 10\xa0minutes'), # Compare to a given parameter - 'filter-timeuntil04' : ('{{ a|timeuntil:b }}', {'a':now - timedelta(days=1), 'b':now - timedelta(days=2)}, '1 day'), - 'filter-timeuntil05' : ('{{ a|timeuntil:b }}', {'a':now - timedelta(days=2), 'b':now - timedelta(days=2, minutes=1)}, '1 minute'), + 'filter-timeuntil04' : ('{{ a|timeuntil:b }}', {'a':now - timedelta(days=1), 'b':now - timedelta(days=2)}, '1\xa0day'), + 'filter-timeuntil05' : ('{{ a|timeuntil:b }}', {'a':now - timedelta(days=2), 'b':now - timedelta(days=2, minutes=1)}, '1\xa0minute'), # Regression for #7443 - 'filter-timeuntil06': ('{{ earlier|timeuntil }}', { 'earlier': now - timedelta(days=7) }, '0 minutes'), - 'filter-timeuntil07': ('{{ earlier|timeuntil:now }}', { 'now': now, 'earlier': now - timedelta(days=7) }, '0 minutes'), - 'filter-timeuntil08': ('{{ later|timeuntil }}', { 'later': now + timedelta(days=7, hours=1) }, '1 week'), - 'filter-timeuntil09': ('{{ later|timeuntil:now }}', { 'now': now, 'later': now + timedelta(days=7) }, '1 week'), + 'filter-timeuntil06': ('{{ earlier|timeuntil }}', { 'earlier': now - timedelta(days=7) }, '0\xa0minutes'), + 'filter-timeuntil07': ('{{ earlier|timeuntil:now }}', { 'now': now, 'earlier': now - timedelta(days=7) }, '0\xa0minutes'), + 'filter-timeuntil08': ('{{ later|timeuntil }}', { 'later': now + timedelta(days=7, hours=1) }, '1\xa0week'), + 'filter-timeuntil09': ('{{ later|timeuntil:now }}', { 'now': now, 'later': now + timedelta(days=7) }, '1\xa0week'), # Ensures that differing timezones are calculated correctly - 'filter-timeuntil10' : ('{{ a|timeuntil }}', {'a': now_tz_i}, '0 minutes'), - 'filter-timeuntil11' : ('{{ a|timeuntil:b }}', {'a': now_tz_i, 'b': now_tz}, '0 minutes'), + 'filter-timeuntil10' : ('{{ a|timeuntil }}', {'a': now_tz_i}, '0\xa0minutes'), + 'filter-timeuntil11' : ('{{ a|timeuntil:b }}', {'a': now_tz_i, 'b': now_tz}, '0\xa0minutes'), # Regression for #9065 (two date objects). - 'filter-timeuntil12' : ('{{ a|timeuntil:b }}', {'a': today, 'b': today}, '0 minutes'), - 'filter-timeuntil13' : ('{{ a|timeuntil:b }}', {'a': today, 'b': today - timedelta(hours=24)}, '1 day'), + 'filter-timeuntil12' : ('{{ a|timeuntil:b }}', {'a': today, 'b': today}, '0\xa0minutes'), + 'filter-timeuntil13' : ('{{ a|timeuntil:b }}', {'a': today, 'b': today - timedelta(hours=24)}, '1\xa0day'), 'filter-addslash01': ("{% autoescape off %}{{ a|addslashes }} {{ b|addslashes }}{% endautoescape %}", {"a": "<a>'", "b": mark_safe("<a>'")}, r"<a>\' <a>\'"), 'filter-addslash02': ("{{ a|addslashes }} {{ b|addslashes }}", {"a": "<a>'", "b": mark_safe("<a>'")}, r"<a>\' <a>\'"), diff --git a/tests/transactions/tests.py b/tests/transactions/tests.py index aeb9bc3d2c..0f16a9c805 100644 --- a/tests/transactions/tests.py +++ b/tests/transactions/tests.py @@ -5,6 +5,7 @@ import warnings from django.db import connection, transaction, IntegrityError from django.test import TransactionTestCase, skipUnlessDBFeature +from django.test.utils import IgnorePendingDeprecationWarningsMixin from django.utils import six from django.utils.unittest import skipIf, skipUnless @@ -319,19 +320,6 @@ class AtomicMiscTests(TransactionTestCase): transaction.atomic(Callable()) -class IgnorePendingDeprecationWarningsMixin(object): - - def setUp(self): - super(IgnorePendingDeprecationWarningsMixin, self).setUp() - self.catch_warnings = warnings.catch_warnings() - self.catch_warnings.__enter__() - warnings.filterwarnings("ignore", category=PendingDeprecationWarning) - - def tearDown(self): - self.catch_warnings.__exit__(*sys.exc_info()) - super(IgnorePendingDeprecationWarningsMixin, self).tearDown() - - class TransactionTests(IgnorePendingDeprecationWarningsMixin, TransactionTestCase): def create_a_reporter_then_fail(self, first, last): diff --git a/tests/transactions_regress/tests.py b/tests/transactions_regress/tests.py index fb3f257dab..5339b4a8ea 100644 --- a/tests/transactions_regress/tests.py +++ b/tests/transactions_regress/tests.py @@ -4,11 +4,9 @@ from django.db import (connection, connections, transaction, DEFAULT_DB_ALIAS, D IntegrityError) from django.db.transaction import commit_on_success, commit_manually, TransactionManagementError from django.test import TransactionTestCase, skipUnlessDBFeature -from django.test.utils import override_settings +from django.test.utils import override_settings, IgnorePendingDeprecationWarningsMixin from django.utils.unittest import skipIf, skipUnless -from transactions.tests import IgnorePendingDeprecationWarningsMixin - from .models import Mod, M2mA, M2mB, SubMod class ModelInheritanceTests(TransactionTestCase): diff --git a/tests/utils_tests/test_timesince.py b/tests/utils_tests/test_timesince.py index 5e641a42c4..cdb95e6877 100644 --- a/tests/utils_tests/test_timesince.py +++ b/tests/utils_tests/test_timesince.py @@ -21,32 +21,33 @@ class TimesinceTests(unittest.TestCase): def test_equal_datetimes(self): """ equal datetimes. """ - self.assertEqual(timesince(self.t, self.t), '0 minutes') + # NOTE: \xa0 avoids wrapping between value and unit + self.assertEqual(timesince(self.t, self.t), '0\xa0minutes') def test_ignore_microseconds_and_seconds(self): """ Microseconds and seconds are ignored. """ self.assertEqual(timesince(self.t, self.t+self.onemicrosecond), - '0 minutes') + '0\xa0minutes') self.assertEqual(timesince(self.t, self.t+self.onesecond), - '0 minutes') + '0\xa0minutes') def test_other_units(self): """ Test other units. """ self.assertEqual(timesince(self.t, self.t+self.oneminute), - '1 minute') - self.assertEqual(timesince(self.t, self.t+self.onehour), '1 hour') - self.assertEqual(timesince(self.t, self.t+self.oneday), '1 day') - self.assertEqual(timesince(self.t, self.t+self.oneweek), '1 week') + '1\xa0minute') + self.assertEqual(timesince(self.t, self.t+self.onehour), '1\xa0hour') + self.assertEqual(timesince(self.t, self.t+self.oneday), '1\xa0day') + self.assertEqual(timesince(self.t, self.t+self.oneweek), '1\xa0week') self.assertEqual(timesince(self.t, self.t+self.onemonth), - '1 month') - self.assertEqual(timesince(self.t, self.t+self.oneyear), '1 year') + '1\xa0month') + self.assertEqual(timesince(self.t, self.t+self.oneyear), '1\xa0year') def test_multiple_units(self): """ Test multiple units. """ self.assertEqual(timesince(self.t, - self.t+2*self.oneday+6*self.onehour), '2 days, 6 hours') + self.t+2*self.oneday+6*self.onehour), '2\xa0days, 6\xa0hours') self.assertEqual(timesince(self.t, - self.t+2*self.oneweek+2*self.oneday), '2 weeks, 2 days') + self.t+2*self.oneweek+2*self.oneday), '2\xa0weeks, 2\xa0days') def test_display_first_unit(self): """ @@ -55,10 +56,10 @@ class TimesinceTests(unittest.TestCase): """ self.assertEqual(timesince(self.t, self.t+2*self.oneweek+3*self.onehour+4*self.oneminute), - '2 weeks') + '2\xa0weeks') self.assertEqual(timesince(self.t, - self.t+4*self.oneday+5*self.oneminute), '4 days') + self.t+4*self.oneday+5*self.oneminute), '4\xa0days') def test_display_second_before_first(self): """ @@ -66,30 +67,30 @@ class TimesinceTests(unittest.TestCase): get 0 minutes. """ self.assertEqual(timesince(self.t, self.t-self.onemicrosecond), - '0 minutes') + '0\xa0minutes') self.assertEqual(timesince(self.t, self.t-self.onesecond), - '0 minutes') + '0\xa0minutes') self.assertEqual(timesince(self.t, self.t-self.oneminute), - '0 minutes') + '0\xa0minutes') self.assertEqual(timesince(self.t, self.t-self.onehour), - '0 minutes') + '0\xa0minutes') self.assertEqual(timesince(self.t, self.t-self.oneday), - '0 minutes') + '0\xa0minutes') self.assertEqual(timesince(self.t, self.t-self.oneweek), - '0 minutes') + '0\xa0minutes') self.assertEqual(timesince(self.t, self.t-self.onemonth), - '0 minutes') + '0\xa0minutes') self.assertEqual(timesince(self.t, self.t-self.oneyear), - '0 minutes') + '0\xa0minutes') self.assertEqual(timesince(self.t, - self.t-2*self.oneday-6*self.onehour), '0 minutes') + self.t-2*self.oneday-6*self.onehour), '0\xa0minutes') self.assertEqual(timesince(self.t, - self.t-2*self.oneweek-2*self.oneday), '0 minutes') + self.t-2*self.oneweek-2*self.oneday), '0\xa0minutes') self.assertEqual(timesince(self.t, self.t-2*self.oneweek-3*self.onehour-4*self.oneminute), - '0 minutes') + '0\xa0minutes') self.assertEqual(timesince(self.t, - self.t-4*self.oneday-5*self.oneminute), '0 minutes') + self.t-4*self.oneday-5*self.oneminute), '0\xa0minutes') def test_different_timezones(self): """ When using two different timezones. """ @@ -97,28 +98,28 @@ class TimesinceTests(unittest.TestCase): now_tz = datetime.datetime.now(LocalTimezone(now)) now_tz_i = datetime.datetime.now(FixedOffset((3 * 60) + 15)) - self.assertEqual(timesince(now), '0 minutes') - self.assertEqual(timesince(now_tz), '0 minutes') - self.assertEqual(timeuntil(now_tz, now_tz_i), '0 minutes') + self.assertEqual(timesince(now), '0\xa0minutes') + self.assertEqual(timesince(now_tz), '0\xa0minutes') + self.assertEqual(timeuntil(now_tz, now_tz_i), '0\xa0minutes') def test_date_objects(self): """ Both timesince and timeuntil should work on date objects (#17937). """ today = datetime.date.today() - self.assertEqual(timesince(today + self.oneday), '0 minutes') - self.assertEqual(timeuntil(today - self.oneday), '0 minutes') + self.assertEqual(timesince(today + self.oneday), '0\xa0minutes') + self.assertEqual(timeuntil(today - self.oneday), '0\xa0minutes') def test_both_date_objects(self): """ Timesince should work with both date objects (#9672) """ today = datetime.date.today() - self.assertEqual(timeuntil(today + self.oneday, today), '1 day') - self.assertEqual(timeuntil(today - self.oneday, today), '0 minutes') - self.assertEqual(timeuntil(today + self.oneweek, today), '1 week') + self.assertEqual(timeuntil(today + self.oneday, today), '1\xa0day') + self.assertEqual(timeuntil(today - self.oneday, today), '0\xa0minutes') + self.assertEqual(timeuntil(today + self.oneweek, today), '1\xa0week') def test_naive_datetime_with_tzinfo_attribute(self): class naive(datetime.tzinfo): def utcoffset(self, dt): return None future = datetime.datetime(2080, 1, 1, tzinfo=naive()) - self.assertEqual(timesince(future), '0 minutes') + self.assertEqual(timesince(future), '0\xa0minutes') past = datetime.datetime(1980, 1, 1, tzinfo=naive()) - self.assertEqual(timeuntil(past), '0 minutes') + self.assertEqual(timeuntil(past), '0\xa0minutes') diff --git a/tests/view_tests/tests/test_debug.py b/tests/view_tests/tests/test_debug.py index b44cd88abe..a84b41959c 100644 --- a/tests/view_tests/tests/test_debug.py +++ b/tests/view_tests/tests/test_debug.py @@ -6,6 +6,7 @@ from __future__ import absolute_import, unicode_literals import inspect import os import sys +import tempfile from django.core import mail from django.core.files.uploadedfile import SimpleUploadedFile @@ -13,7 +14,7 @@ from django.core.urlresolvers import reverse from django.test import TestCase, RequestFactory from django.test.utils import (override_settings, setup_test_template_loader, restore_template_loaders) -from django.utils.encoding import force_text +from django.utils.encoding import force_text, force_bytes from django.views.debug import ExceptionReporter from .. import BrokenException, except_args @@ -122,6 +123,24 @@ class ExceptionReporterTests(TestCase): self.assertIn('<h2>Request information</h2>', html) self.assertIn('<p>Request data not supplied</p>', html) + def test_eol_support(self): + """Test that the ExceptionReporter supports Unix, Windows and Macintosh EOL markers""" + LINES = list('print %d' % i for i in range(1, 6)) + reporter = ExceptionReporter(None, None, None, None) + + for newline in ['\n','\r\n','\r']: + fd,filename = tempfile.mkstemp(text = False) + os.write(fd, force_bytes(newline.join(LINES)+newline)) + os.close(fd) + + try: + self.assertEqual( + reporter._get_lines_from_file(filename, 3, 2), + (1, LINES[1:3], LINES[3], LINES[4:]) + ) + finally: + os.unlink(filename) + def test_no_exception(self): "An exception report can be generated for just a request" request = self.rf.get('/test_view/') |
