diff --git a/openapi_schema_validator/_format.py b/openapi_schema_validator/_format.py index 415f556..0fb9e97 100644 --- a/openapi_schema_validator/_format.py +++ b/openapi_schema_validator/_format.py @@ -7,6 +7,7 @@ from jsonschema.exceptions import FormatError from six import binary_type, text_type, integer_types +DATETIME_HAS_RFC3339_VALIDATOR = False DATETIME_HAS_STRICT_RFC3339 = False DATETIME_HAS_ISODATE = False DATETIME_RAISES = () @@ -19,6 +20,14 @@ DATETIME_HAS_ISODATE = True DATETIME_RAISES += (ValueError, isodate.ISO8601Error) +try: + from rfc3339_validator import validate_rfc3339 +except ImportError: + pass +else: + DATETIME_HAS_RFC3339_VALIDATOR = True + DATETIME_RAISES += (ValueError, TypeError) + try: import strict_rfc3339 except ImportError: @@ -64,6 +73,9 @@ def is_datetime(instance): if not isinstance(instance, (binary_type, text_type)): return False + if DATETIME_HAS_RFC3339_VALIDATOR: + return validate_rfc3339(instance) + if DATETIME_HAS_STRICT_RFC3339: return strict_rfc3339.validate_rfc3339(instance) diff --git a/requirements.txt b/requirements.txt index b66d10e..6643606 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ isodate jsonschema six -strict_rfc3339 +strict-rfc3339 +rfc3339-validator diff --git a/setup.cfg b/setup.cfg index b6efdbe..0755699 100644 --- a/setup.cfg +++ b/setup.cfg @@ -29,13 +29,20 @@ install_requires = isodate jsonschema>=3.0.0 six - strict_rfc3339 tests_require = mock; python_version<"3.0" pytest pytest-flake8 pytest-cov +[options.extras_require] +rfc3339-validator = + rfc3339-validator +strict-rfc3339 = + strict-rfc3339 +isodate = + isodate + [options.packages.find] exclude = tests diff --git a/tests/integration/test_validators.py b/tests/integration/test_validators.py index 8c50aa8..6ab8f8c 100644 --- a/tests/integration/test_validators.py +++ b/tests/integration/test_validators.py @@ -35,6 +35,60 @@ def test_nullable(self, schema_type): u('1989-01-02T00:00:00Z'), u('2018-01-02T23:59:59Z'), ]) + @mock.patch( + 'openapi_schema_validator._format.' + 'DATETIME_HAS_RFC3339_VALIDATOR', False + ) + @mock.patch( + 'openapi_schema_validator._format.' + 'DATETIME_HAS_STRICT_RFC3339', False + ) + @mock.patch( + 'openapi_schema_validator._format.' + 'DATETIME_HAS_ISODATE', False + ) + def test_string_format_no_datetime_validator(self, value): + schema = {"type": 'string', "format": 'date-time'} + validator = OAS30Validator( + schema, format_checker=oas30_format_checker) + + result = validator.validate(value) + + assert result is None + + @pytest.mark.parametrize('value', [ + u('1989-01-02T00:00:00Z'), + u('2018-01-02T23:59:59Z'), + ]) + @mock.patch( + 'openapi_schema_validator._format.' + 'DATETIME_HAS_RFC3339_VALIDATOR', True + ) + @mock.patch( + 'openapi_schema_validator._format.' + 'DATETIME_HAS_STRICT_RFC3339', False + ) + @mock.patch( + 'openapi_schema_validator._format.' + 'DATETIME_HAS_ISODATE', False + ) + def test_string_format_datetime_rfc3339_validator(self, value): + schema = {"type": 'string', "format": 'date-time'} + validator = OAS30Validator( + schema, format_checker=oas30_format_checker) + + result = validator.validate(value) + + assert result is None + + @pytest.mark.parametrize('value', [ + u('1989-01-02T00:00:00Z'), + u('2018-01-02T23:59:59Z'), + ]) + @mock.patch( + 'openapi_schema_validator._format.' + 'DATETIME_HAS_RFC3339_VALIDATOR', False + ) @mock.patch( 'openapi_schema_validator._format.' 'DATETIME_HAS_STRICT_RFC3339', True @@ -56,6 +110,10 @@ def test_string_format_datetime_strict_rfc3339(self, value): u('1989-01-02T00:00:00Z'), u('2018-01-02T23:59:59Z'), ]) + @mock.patch( + 'openapi_schema_validator._format.' + 'DATETIME_HAS_RFC3339_VALIDATOR', False + ) @mock.patch( 'openapi_schema_validator._format.' 'DATETIME_HAS_STRICT_RFC3339', False