From 2e4793e1911e131bbfe2cb652e64574eac9b5844 Mon Sep 17 00:00:00 2001 From: Valeryi Savich Date: Thu, 3 Nov 2016 00:44:47 +0300 Subject: [PATCH] Added tests for fields module --- tests/db/orm/django/__init__.py | 43 ++ tests/db/orm/django/test_fields.py | 792 ++++++++++++++++++++ tests/db/orm/sqlalchemy/test_serializers.py | 2 + 3 files changed, 837 insertions(+) create mode 100644 tests/db/orm/django/__init__.py create mode 100644 tests/db/orm/django/test_fields.py diff --git a/tests/db/orm/django/__init__.py b/tests/db/orm/django/__init__.py new file mode 100644 index 0000000..131d641 --- /dev/null +++ b/tests/db/orm/django/__init__.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +import unittest + +from django.apps import apps +from django.conf import settings +from django.db import connections + + +if not settings.configured: + settings.configure( + DATABASES={ + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': ':memory:', + } + }, + ) + + +class DjangoUnitTest(unittest.TestCase): + + models = [] + apps = () + + @classmethod + def setUpClass(cls): + super(DjangoUnitTest, cls).setUpClass() + if apps: + apps.populate(cls.apps) + + conn = connections['default'] + with conn.schema_editor() as editor: + for model in cls.models: + editor.create_model(model) + + @classmethod + def tearDownClass(cls): + super(DjangoUnitTest, cls).tearDownClass() + + conn = connections['default'] + with conn.schema_editor() as editor: + for model in cls.models: + editor.delete_model(model) diff --git a/tests/db/orm/django/test_fields.py b/tests/db/orm/django/test_fields.py new file mode 100644 index 0000000..1b523d8 --- /dev/null +++ b/tests/db/orm/django/test_fields.py @@ -0,0 +1,792 @@ +# -*- coding: utf-8 -*- +import datetime +from decimal import Decimal + +from aiorest_ws.conf import settings +from aiorest_ws.db.orm.abstract import empty +from aiorest_ws.db.orm.django import fields +from aiorest_ws.db.orm.exceptions import ValidationError +from aiorest_ws.utils.date import timezone + +from tests.db.orm.django import DjangoUnitTest + + +class TestIntegerField(DjangoUnitTest): + + def test_init_without_borders(self): + instance = fields.IntegerField() + self.assertIsNone(instance.max_value) + self.assertIsNone(instance.min_value) + + def test_init_with_min_value(self): + instance = fields.IntegerField(min_value=10) + self.assertEqual(instance.min_value, 10) + self.assertIsNone(instance.max_value) + + def test_init_with_max_value(self): + instance = fields.IntegerField(max_value=10) + self.assertIsNone(instance.min_value) + self.assertEqual(instance.max_value, 10) + + def test_init_with_min_and_max_values(self): + instance = fields.IntegerField(min_value=1, max_value=10) + self.assertEqual(instance.min_value, 1) + self.assertEqual(instance.max_value, 10) + + def test_to_internal_value(self): + instance = fields.IntegerField() + self.assertEqual(instance.to_internal_value(1), 1) + + def test_to_internal_value_raises_max_string_length_exception(self): + instance = fields.IntegerField() + + with self.assertRaises(ValidationError): + data = 'value' * 250 + instance.to_internal_value(data) + + def test_to_internal_value_raises_validate_exception(self): + instance = fields.IntegerField() + + with self.assertRaises(ValidationError): + instance.to_internal_value('object') + + def test_to_to_representation(self): + instance = fields.IntegerField() + self.assertEqual(instance.to_representation('1'), 1) + + +class TestBooleanField(DjangoUnitTest): + + def test_init_raises_assertion_error(self): + with self.assertRaises(AssertionError): + fields.BooleanField(allow_null=True) + + def test_to_internal_value_returns_true_value(self): + instance = fields.BooleanField() + + for value in instance.TRUE_VALUES: + self.assertTrue(instance.to_internal_value(value)) + + def test_to_internal_value_returns_false_value(self): + instance = fields.BooleanField() + + for value in instance.FALSE_VALUES: + self.assertFalse(instance.to_internal_value(value)) + + def test_to_internal_value_raises_validate_exception(self): + instance = fields.BooleanField() + + with self.assertRaises(ValidationError): + instance.to_internal_value(object()) + + def test_to_internal_value_with_unhashable_value(self): + instance = fields.BooleanField() + + with self.assertRaises(ValidationError): + instance.to_internal_value({}) + + def test_to_representation_returns_true_value(self): + instance = fields.BooleanField() + + for value in instance.TRUE_VALUES: + self.assertTrue(instance.to_representation(value)) + + def test_to_representation_returns_false_value(self): + instance = fields.BooleanField() + + for value in instance.FALSE_VALUES: + self.assertFalse(instance.to_representation(value)) + + def test_to_representation_return_true_for_not_defined_values(self): + instance = fields.BooleanField() + self.assertTrue(instance.to_representation(object())) + self.assertTrue(instance.to_representation("value")) + + def test_to_representation_return_false_for_not_defined_values(self): + instance = fields.BooleanField() + self.assertFalse(instance.to_representation(())) + self.assertFalse(instance.to_representation("")) + + +class TestNullBooleanField(DjangoUnitTest): + + def test_to_internal_value_returns_true_value(self): + instance = fields.NullBooleanField() + + for value in instance.TRUE_VALUES: + self.assertTrue(instance.to_internal_value(value)) + + def test_to_internal_value_returns_false_value(self): + instance = fields.NullBooleanField() + + for value in instance.FALSE_VALUES: + self.assertFalse(instance.to_internal_value(value)) + + def test_to_internal_value_returns_none_value(self): + instance = fields.NullBooleanField() + + for value in instance.NULL_VALUES: + self.assertIsNone(instance.to_internal_value(value)) + + def test_to_internal_value_raises_validate_exception(self): + instance = fields.NullBooleanField() + + with self.assertRaises(ValidationError): + instance.to_internal_value(object()) + + def test_to_representation_returns_true_value(self): + instance = fields.NullBooleanField() + + for value in instance.TRUE_VALUES: + self.assertTrue(instance.to_representation(value)) + + def test_to_representation_returns_false_value(self): + instance = fields.NullBooleanField() + + for value in instance.FALSE_VALUES: + self.assertFalse(instance.to_representation(value)) + + def test_to_representation_returns_none_value(self): + instance = fields.NullBooleanField() + + for value in instance.NULL_VALUES: + self.assertIsNone(instance.to_representation(value)) + + def test_to_representation_return_true_for_not_defined_values(self): + instance = fields.NullBooleanField() + self.assertTrue(instance.to_representation(object())) + self.assertTrue(instance.to_representation("value")) + + def test_to_representation_return_false_for_not_defined_values(self): + instance = fields.NullBooleanField() + self.assertFalse(instance.to_representation(())) + self.assertFalse(instance.to_representation("")) + + +class TestCharField(DjangoUnitTest): + + def test_init_default(self): + instance = fields.CharField() + self.assertFalse(instance.allow_blank) + self.assertTrue(instance.trim_whitespace) + self.assertIsNone(instance.min_length) + self.assertIsNone(instance.max_length) + + def test_run_validation(self): + instance = fields.CharField() + self.assertEqual(instance.to_internal_value('test'), 'test') + + def test_run_validation_raise_validation_error_for_too_short_string(self): + instance = fields.CharField(min_length=5) + + with self.assertRaises(ValidationError): + instance.run_validation('test') + + def test_run_validation_raise_validation_error_for_too_long_string(self): + instance = fields.CharField(max_length=3) + + with self.assertRaises(ValidationError): + instance.run_validation('test') + + def test_run_validation_raise_validation_error_for_blank_field(self): + instance = fields.CharField(allow_blank=False) + + with self.assertRaises(ValidationError): + instance.run_validation('') + + def test_run_validation_returns_empty_string(self): + instance = fields.CharField(allow_blank=True) + self.assertEqual(instance.run_validation(''), '') + + def test_to_internal_value(self): + instance = fields.CharField() + self.assertEqual(instance.to_internal_value(' value '), 'value') + + def test_to_internal_value_without_trim_whitespace(self): + instance = fields.CharField(trim_whitespace=False) + self.assertEqual(instance.to_internal_value(' value '), ' value ') + + def test_disallow_blank_with_trim_whitespace(self): + instance = fields.CharField(allow_blank=False, trim_whitespace=True) + + with self.assertRaises(ValidationError): + instance.run_validation(' ') + + def test_to_representation(self): + instance = fields.CharField() + self.assertEqual(instance.to_representation('test'), 'test') + + +class TestChoiceField(DjangoUnitTest): + + choices = ( + (1, 'one'), + (2, 'two'), + (3, 'three') + ) + + def test_to_internal_value(self): + instance = fields.ChoiceField(choices=self.choices) + self.assertEqual(instance.to_internal_value(1), 1) + + def test_to_internal_value_for_empty_string(self): + instance = fields.ChoiceField(self.choices, allow_blank=True) + self.assertEqual(instance.to_internal_value(''), '') + + def test_to_internal_value_raise_validation_error(self): + instance = fields.ChoiceField(self.choices) + + with self.assertRaises(ValidationError): + instance.to_internal_value(4) + + def test_to_representation(self): + instance = fields.ChoiceField(self.choices) + self.assertEqual(instance.to_representation(2), 2) + + def test_to_representation_empty_string(self): + instance = fields.ChoiceField(self.choices) + self.assertEqual(instance.to_representation(''), '') + + def test_to_representation_none_value(self): + instance = fields.ChoiceField(self.choices) + self.assertEqual(instance.to_representation(None), None) + + def test_to_representation_not_found_key(self): + instance = fields.ChoiceField(self.choices) + self.assertEqual(instance.to_representation(4), 4) + + +class TestMultipleChoiceField(DjangoUnitTest): + + choices = ( + (1, 'one'), + (2, 'two'), + (3, 'three') + ) + + def test_get_value_returns_empty(self): + + class FakeSerializer(): + parent = None + partial = True + + instance = fields.MultipleChoiceField(self.choices) + instance.bind('choice', self) + instance.parent = FakeSerializer() + self.assertEqual(instance.get_value({}), empty) + + def test_get_value_returns_value_from_dictionary(self): + instance = fields.MultipleChoiceField(self.choices) + instance.bind('choice', self) + self.assertEqual(instance.get_value({'choice': 1}), 1) + + def test_to_internal_value(self): + instance = fields.MultipleChoiceField(self.choices) + instance.bind('choice', self) + self.assertEqual(instance.get_value({'choice': 1}), 1) + + def test_to_internal_value_raises_not_a_list_error(self): + instance = fields.MultipleChoiceField(self.choices) + instance.bind('choice', self) + self.assertRaises( + ValidationError, + instance.to_internal_value, '' + ) + + def test_to_internal_value_raises_empty_error(self): + instance = fields.MultipleChoiceField(self.choices) + instance.bind('choice', self) + self.assertRaises( + ValidationError, + instance.to_internal_value, empty + ) + + def test_to_representation_returns_dictionary(self): + instance = fields.MultipleChoiceField(self.choices) + instance.bind('choice', self) + self.assertEqual(instance.to_representation((1, )), {1}) + + +class TestFloatField(DjangoUnitTest): + + def test_init_default(self): + instance = fields.FloatField() + self.assertIsNone(instance.min_value) + self.assertIsNone(instance.max_value) + + def test_run_validation_without_borders(self): + instance = fields.FloatField() + self.assertEqual(instance.run_validation(5.0), 5.0) + + def test_run_validation_with_defined_min_value(self): + instance = fields.FloatField(min_value=10.0) + + with self.assertRaises(ValidationError): + instance.run_validation(5.0) + + def test_run_validation_with_defined_max_value(self): + instance = fields.FloatField(max_value=10.0) + + with self.assertRaises(ValidationError): + instance.run_validation(11.0) + + def test_to_internal_value(self): + instance = fields.FloatField() + self.assertEqual(instance.to_internal_value(5), 5) + + def test_to_internal_value_raises_validation_error(self): + instance = fields.FloatField() + + with self.assertRaises(ValidationError): + instance.to_internal_value(None) + + def test_to_internal_value_raises_validation_error_for_too_long_str(self): + instance = fields.FloatField(max_value=10) + + with self.assertRaises(ValidationError): + instance.to_internal_value('test' * 255) + + def test_to_representation(self): + instance = fields.FloatField() + self.assertEqual(instance.to_representation(5), 5.0) + + +class TestDecimalField(DjangoUnitTest): + + def test_init_default(self): + instance = fields.DecimalField(max_digits=5, decimal_places=2) + self.assertEqual(instance.max_digits, 5) + self.assertEqual(instance.decimal_places, 2) + self.assertEqual(instance.max_whole_digits, 3) + + def test_init_with_not_defined_max_whole_digits(self): + instance = fields.DecimalField(max_digits=None, decimal_places=None) + self.assertIsNone(instance.max_digits) + self.assertIsNone(instance.decimal_places) + self.assertIsNone(instance.max_whole_digits) + + def test_run_validation(self): + instance = fields.DecimalField(max_digits=5, decimal_places=2) + self.assertEqual(instance.run_validation(99), 99) + + def test_run_validation_raises_validation_error_for_gt_max_value(self): + instance = fields.DecimalField( + max_digits=5, decimal_places=2, max_value=90 + ) + + with self.assertRaises(ValidationError): + instance.run_validation(99) + + def test_run_validation_raises_validation_error_for_lt_min_value(self): + instance = fields.DecimalField( + max_digits=5, decimal_places=2, min_value=10, + ) + + with self.assertRaises(ValidationError): + instance.run_validation(9) + + def test_validate_precision_with_exponent(self): + instance = fields.DecimalField(max_digits=5, decimal_places=0) + + value = Decimal('12345') + self.assertEqual(instance.validate_precision(value), value) + + def test_validate_precision_with_digittuple(self): + instance = fields.DecimalField(max_digits=7, decimal_places=2) + + value = Decimal('12345.0') + self.assertEqual(instance.validate_precision(value), value) + + def test_validate_precision_with_fraction(self): + instance = fields.DecimalField(max_digits=7, decimal_places=5) + + value = Decimal('0.01234') + self.assertEqual(instance.validate_precision(value), value) + + def test_validate_precision_raise_validation_exc_max_digits(self): + instance = fields.DecimalField(max_digits=5, decimal_places=2) + + with self.assertRaises(ValidationError): + instance.validate_precision(Decimal('1234500.0')) + + def test_validate_precision_raise_validation_exc_max_decimal_places(self): + instance = fields.DecimalField(max_digits=9, decimal_places=0) + + with self.assertRaises(ValidationError): + instance.validate_precision(Decimal('1234500.0')) + + def test_validate_precision_raise_validation_exc_max_whole_digits(self): + instance = fields.DecimalField(max_digits=9, decimal_places=7) + + with self.assertRaises(ValidationError): + instance.validate_precision(Decimal('1234500.0')) + + def test_to_internal_value(self): + instance = fields.DecimalField(max_digits=10, decimal_places=5) + self.assertEqual( + instance.to_internal_value(12345.0), Decimal('12345.0') + ) + + def test_to_internal_value_raises_validation_error_for_max_length(self): + instance = fields.DecimalField(max_digits=10, decimal_places=5) + + with self.assertRaises(ValidationError): + instance.to_internal_value('test' * 255) + + def test_to_internal_value_raises_validation_error_for_not_decimal(self): + instance = fields.DecimalField(max_digits=10, decimal_places=5) + + with self.assertRaises(ValidationError): + instance.to_internal_value('None') + + def test_to_internal_value_raises_validation_error_for_NaN(self): + instance = fields.DecimalField(max_digits=10, decimal_places=5) + + with self.assertRaises(ValidationError): + instance.to_internal_value('NaN') + + def test_to_internal_value_raises_validation_error_for_infinity(self): + instance = fields.DecimalField(max_digits=10, decimal_places=5) + + with self.assertRaises(ValidationError): + instance.to_internal_value(float('inf')) # positive infinite + instance.to_internal_value(-float('inf')) # negative infinite + + def test_to_representation_with_decimal_as_a_string(self): + instance = fields.DecimalField(max_digits=10, decimal_places=5) + self.assertEqual(instance.to_representation('12345.0'), '12345.00000') + + def test_to_representation_without_coerce_to_string(self): + instance = fields.DecimalField( + max_digits=10, decimal_places=5, coerce_to_string=False + ) + value = Decimal('12345.0') + self.assertEqual(instance.to_representation(value), value) + + def test_quantize(self): + instance = fields.DecimalField(max_digits=10, decimal_places=5) + + value = Decimal('12345.0') + self.assertEqual(instance.quantize(value), value) + + +class TestTimeField(DjangoUnitTest): + + def test_run_validation_raise_validation_error(self): + instance = fields.TimeField() + + with self.assertRaises(ValidationError): + instance.run_validation('value') + + def test_to_internal_value_string(self): + instance = fields.TimeField() + self.assertEqual( + instance.to_internal_value('03:00'), + datetime.time(3, 0) + ) + + def test_to_internal_value_time(self): + instance = fields.TimeField() + self.assertEqual( + instance.to_internal_value(datetime.time(3, 0)), + datetime.time(3, 0) + ) + + def test_to_internal_value_for_non_iso8601(self): + instance = fields.TimeField(input_formats=('%H:%M', )) + self.assertEqual( + instance.to_internal_value('10:00'), + datetime.time(10, 0) + ) + + def test_to_internal_value_raises_validation_error_with_empty_format(self): + instance = fields.TimeField(input_formats=()) + + with self.assertRaises(ValidationError): + instance.to_internal_value('99:99') + + def test_to_internal_value_raises_validation_error_for_a_wrong_type(self): + instance = fields.TimeField() + + with self.assertRaises(ValidationError): + instance.to_internal_value(None) + + def test_to_internal_value_raises_error_for_wrong_value_and_format(self): + instance = fields.TimeField(input_formats=('%H:%M',)) + + with self.assertRaises(ValidationError): + instance.to_internal_value('99:99') + + def test_to_internal_value_raises_error_for_none_value_and_format(self): + instance = fields.TimeField(input_formats=('%H:%M',)) + + with self.assertRaises(ValidationError): + instance.to_internal_value(None) + + def test_to_internal_value_raises_validation_error_for_wrong_value(self): + instance = fields.TimeField() + + with self.assertRaises(ValidationError): + instance.to_internal_value('99:99') + + def test_to_representation(self): + instance = fields.TimeField(format='%H:%M:%S') + timestamp = datetime.time(3, 0) + self.assertEqual( + instance.to_representation(timestamp), '03:00:00' + ) + + def test_to_representation_returns_none_for_empty_string(self): + instance = fields.TimeField() + self.assertIsNone(instance.to_representation('')) + + def test_to_representation_returns_none(self): + instance = fields.TimeField() + self.assertIsNone(instance.to_representation(None)) + + def test_to_representation_return_value(self): + instance = fields.TimeField(format=None) + timestamp = datetime.time(13, 0) + self.assertEqual(instance.to_representation(timestamp), timestamp) + + def test_to_representation_parse_string_into_iso8601_string(self): + instance = fields.TimeField() + self.assertEqual( + instance.to_representation('10:00:00'), '10:00:00' + ) + + def test_to_representation_parse_time_into_iso8601_string(self): + instance = fields.TimeField() + self.assertEqual( + instance.to_representation(datetime.time(10, 0)), '10:00:00' + ) + + def test_to_representation_raise_assertion_error(self): + instance = fields.TimeField(format=settings.ISO_8601) + with self.assertRaises(AssertionError): + instance.to_representation(datetime.datetime(2000, 1, 1, 10, 00)) + + +class TestDateFields(DjangoUnitTest): + + def test_run_validation_raises_validation_error_for_wrong_value(self): + instance = fields.DateField() + + with self.assertRaises(ValidationError): + instance.run_validation('value') + + def test_run_validation_raises_validation_error_for_wrong_datetime(self): + instance = fields.DateField() + + with self.assertRaises(ValidationError): + instance.run_validation('2001-99-99') + + def test_run_validation_raises_validation_error_for_a_wrong_type(self): + instance = fields.DateField() + + with self.assertRaises(ValidationError): + instance.run_validation(datetime.datetime(2000, 1, 1, 1, 0)) + + def test_to_internal_value_raises_validation_error_for_wrong_type(self): + instance = fields.DateField() + + with self.assertRaises(ValidationError): + instance.to_internal_value(datetime.datetime(2000, 1, 1, 1, 0)) + + def test_to_internal_value_returns_date_instance(self): + instance = fields.DateField() + value = datetime.date(2000, 1, 1) + self.assertEqual(instance.to_internal_value(value), value) + + def test_to_internal_value_returns_parsed_string_for_iso8601(self): + instance = fields.DateField() + self.assertEqual( + instance.to_internal_value('2000-01-01'), + datetime.date(2000, 1, 1) + ) + + def test_to_internal_value_raises_validation_error_for_wrong_date(self): + instance = fields.DateField() + + with self.assertRaises(ValidationError): + instance.to_internal_value('2000-99-99') + + def test_to_internal_value_raises_validation_error_for_wrong_value(self): + instance = fields.DateField() + + with self.assertRaises(ValidationError): + instance.to_internal_value(None) + + def test_to_internal_value_with_user_format(self): + instance = fields.DateField(input_formats=('%Y-%m-%d', )) + self.assertEqual( + instance.to_internal_value('2000-01-01'), + datetime.date(2000, 1, 1) + ) + + def test_to_internal_value_with_format_raises_error_for_wrong_value(self): + instance = fields.DateField(input_formats=('%Y-%m-%d', )) + + with self.assertRaises(ValidationError): + instance.to_internal_value('2000-99-99') + + def test_to_internal_value_with_format_raises_error_for_wrong_type(self): + instance = fields.DateField(input_formats=('%Y-%m-%d', )) + + with self.assertRaises(ValidationError): + instance.to_internal_value(None) + + def test_to_representation_returns_none(self): + instance = fields.DateField() + self.assertIsNone(instance.to_representation(None)) + + def test_to_representation_returns_empty_string(self): + instance = fields.DateField() + self.assertEqual(instance.to_representation(''), None) + + def test_to_representation_with_none_output_format(self): + instance = fields.DateField(format=None) + self.assertEqual( + instance.to_representation('2000-01-01'), '2000-01-01' + ) + + def test_to_representation_raises_assertion_error_for_a_wrong_type(self): + instance = fields.DateField() + + with self.assertRaises(AssertionError): + instance.to_representation(datetime.datetime(2000, 1, 1)) + + def test_to_representation_returns_value_in_uso8601_for_string(self): + instance = fields.DateField() + self.assertEqual( + instance.to_representation('2000-01-01'), '2000-01-01' + ) + + def test_to_representation_returns_value_in_uso8601_for_date(self): + instance = fields.DateField() + self.assertEqual( + instance.to_representation(datetime.date(2000, 1, 1)), '2000-01-01' + ) + + def test_to_representation_with_custom_date_format(self): + instance = fields.DateField(format="%Y-%m-%d") + self.assertEqual( + instance.to_representation(datetime.date(2000, 1, 1)), '2000-01-01' + ) + + +class TestDateTimeField(DjangoUnitTest): + + def test_run_validation_raises_validation_error_for_a_wrong_type(self): + instance = fields.DateTimeField() + + with self.assertRaises(ValidationError): + instance.run_validation(None) + + def test_run_validation_raises_validation_error_for_a_wrong_value(self): + instance = fields.DateTimeField() + + with self.assertRaises(ValidationError): + instance.run_validation('value') + + def test_enforce_timezone_returns_naive_datetime(self): + instance = fields.DateTimeField() + value = datetime.datetime(2000, 1, 1, 10, 0) + self.assertEqual(instance.enforce_timezone(value), value) + + def test_enforce_timezone_returns_aware_datetime_with_utc_timezone(self): + instance = fields.DateTimeField(default_timezone=timezone.UTC()) + self.assertEqual( + instance.enforce_timezone(datetime.datetime(2000, 1, 1, 10, 0)), + datetime.datetime(2000, 1, 1, 10, 0, tzinfo=timezone.UTC()) + ) + + def test_enforce_timezone_returns_naive_datetime_with_utc_timezone(self): + instance = fields.DateTimeField() + value = datetime.datetime(2000, 1, 1, 10, 0, tzinfo=timezone.UTC()) + self.assertEqual( + instance.enforce_timezone(value), + datetime.datetime(2000, 1, 1, 10, 0) + ) + + def test_to_internal_value_returns_datetime_with_enforce_datetime(self): + instance = fields.DateTimeField() + self.assertEqual( + instance.to_internal_value(datetime.datetime(2000, 1, 1)), + datetime.datetime(2000, 1, 1) + ) + + def test_to_internal_value_raises_validation_error_for_date_type(self): + instance = fields.DateTimeField() + + with self.assertRaises(ValidationError): + instance.to_internal_value(datetime.date(2000, 1, 1)) + + def test_to_internal_value_returns_datetime_in_iso8601(self): + instance = fields.DateTimeField() + + self.assertEqual( + instance.to_internal_value('2000-01-01 10:00'), + datetime.datetime(2000, 1, 1, 10, 0) + ) + + def test_to_internal_value_raises_validation_error_with_a_wrong_type(self): + instance = fields.DateTimeField() + + with self.assertRaises(ValidationError): + instance.to_internal_value(None) + + def test_to_internal_value_raises_validation_error_for_invalid_value(self): + instance = fields.DateTimeField() + + with self.assertRaises(ValidationError): + instance.to_internal_value('2000-99-99 10:00') + + def test_to_internal_value_with_format_returns_datetime(self): + instance = fields.DateTimeField(input_formats=("%Y-%m-%d %H:%M", )) + self.assertEqual( + instance.to_internal_value('2000-01-01 10:00'), + datetime.datetime(2000, 1, 1, 10, 0) + ) + + def test_to_internal_value_with_format_raises_exc_for_a_wrong_type(self): + instance = fields.DateTimeField(input_formats=("%Y-%m-%d %H:%M",)) + + with self.assertRaises(ValidationError): + instance.to_internal_value(None) + + def test_to_internal_value_with_format_raises_exc_for_invalid_value(self): + instance = fields.DateTimeField(input_formats=("%Y-%m-%d %H:%M",)) + + with self.assertRaises(ValidationError): + instance.to_internal_value('2000-99-99 10:00') + + def test_to_representation_returns_none_for_empty_string(self): + instance = fields.DateTimeField() + self.assertIsNone(instance.to_representation('')) + + def test_to_representation_returns_none_for_none_type(self): + instance = fields.DateTimeField() + self.assertIsNone(instance.to_representation(None)) + + def test_to_representation_with_none_output_format_returns_value(self): + instance = fields.DateTimeField(format=None) + self.assertEqual( + instance.to_representation('2000-01-01T10:00:00Z'), + '2000-01-01T10:00:00Z' + ) + + def test_to_representation_returns_value_in_iso8601(self): + instance = fields.DateTimeField() + value = datetime.datetime(2000, 1, 1, 10, 0, tzinfo=timezone.UTC()) + self.assertEqual( + instance.to_representation(value), + '2000-01-01T10:00:00Z' + ) + + def test_to_representation_returns_value_in_custom_format(self): + instance = fields.DateTimeField(format="%Y-%m-%d %H:%M") + self.assertEqual( + instance.to_representation(datetime.datetime(2000, 1, 1, 10, 0)), + '2000-01-01 10:00' + ) diff --git a/tests/db/orm/sqlalchemy/test_serializers.py b/tests/db/orm/sqlalchemy/test_serializers.py index ca52fd2..accecee 100644 --- a/tests/db/orm/sqlalchemy/test_serializers.py +++ b/tests/db/orm/sqlalchemy/test_serializers.py @@ -459,6 +459,7 @@ class Meta: self.assertIsNone(instance.run_validation(None)) + @override_settings(SQLALCHEMY_SESSION=SESSION) def test_run_validation_raises_error_for_assert(self): class UserSerializer(ModelSerializer): @@ -482,6 +483,7 @@ def validate(self, data): self.assertRaises(ValidationError, instance.run_validation, data) + @override_settings(SQLALCHEMY_SESSION=SESSION) def test_run_validation_raises_error_for_validation_error(self): class AdminNameValidator(BaseValidator):