diff --git a/setup.py b/setup.py index e0773165..14afd9c0 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ zip_safe=False, include_package_data=True, install_requires=[ - "jsonschema[format]>=3.2.0", + "jsonschema[format]>=4.21.0", "python-slugify", ], extras_require={ diff --git a/spidermon/contrib/pytest/plugins/filter_monitors.py b/spidermon/contrib/pytest/plugins/filter_monitors.py index 8a7e783a..00ffacb3 100644 --- a/spidermon/contrib/pytest/plugins/filter_monitors.py +++ b/spidermon/contrib/pytest/plugins/filter_monitors.py @@ -7,7 +7,7 @@ def pytest_report_header(config): return "Spidermon monitor filtering" -@pytest.mark.trylast +@pytest.hookimpl(trylast=True) def pytest_collection_modifyitems(session, config, items): items[:] = [ item diff --git a/spidermon/contrib/validation/jsonschema/translator.py b/spidermon/contrib/validation/jsonschema/translator.py index e6142dee..c1ef6d57 100644 --- a/spidermon/contrib/validation/jsonschema/translator.py +++ b/spidermon/contrib/validation/jsonschema/translator.py @@ -38,6 +38,7 @@ class JSONSchemaMessageTranslator(MessageTranslator): r"^.* is not allowed for .*$": messages.NOT_ALLOWED_VALUE, r"^.+ is too short$": messages.FIELD_TOO_SHORT, r"^.+ is too long$": messages.FIELD_TOO_LONG, + r"^.+ should be non-empty$": messages.SHOULD_BE_NON_EMPTY, r"^.+ does not match .*$": messages.REGEX_NOT_MATCHED, r"^.+ has non-unique elements$": messages.NOT_UNIQUE, } diff --git a/spidermon/contrib/validation/messages.py b/spidermon/contrib/validation/messages.py index d9a2323b..129c8303 100644 --- a/spidermon/contrib/validation/messages.py +++ b/spidermon/contrib/validation/messages.py @@ -44,3 +44,4 @@ NOT_MULTIPLE_OF = "Not multiple of" NOT_ALLOWED_VALUE = "Not allowed value" NOT_UNIQUE = "Not unique" +SHOULD_BE_NON_EMPTY = "should be non-empty" diff --git a/tests/contrib/scrapy/test_pipelines.py b/tests/contrib/scrapy/test_pipelines.py index d2a7ff99..b4e55f51 100644 --- a/tests/contrib/scrapy/test_pipelines.py +++ b/tests/contrib/scrapy/test_pipelines.py @@ -88,7 +88,7 @@ class PipelineJSONSchemaValidator(PipelineTest): settings={SETTING_SCHEMAS: [test_schema]}, cases=[ f"'{STATS_ITEM_ERRORS}' not in {{stats}}", - f"{{stats}}['{STATS_AMOUNTS}'] is 1", + f"{{stats}}['{STATS_AMOUNTS}'] == 1", assert_type_in_stats(Item), ], ), @@ -183,8 +183,8 @@ class PipelineJSONSchemaValidator(PipelineTest): item=TestItem(), settings={SETTING_SCHEMAS: {TestItem: [test_schema, tree_schema]}}, cases=[ - f"{{stats}}['{STATS_AMOUNTS}'] is 2", - f"{{stats}}['{STATS_ITEM_ERRORS}'] is 2", + f"{{stats}}['{STATS_AMOUNTS}'] == 2", + f"{{stats}}['{STATS_ITEM_ERRORS}'] == 2", ], ), DataTest( @@ -198,7 +198,7 @@ class PipelineJSONSchemaValidator(PipelineTest): item=TreeItem(), settings={SETTING_SCHEMAS: {TestItem: test_schema, TreeItem: tree_schema}}, cases=[ - f"{{stats}}['{STATS_MISSINGS}'] is 1", + f"{{stats}}['{STATS_MISSINGS}'] == 1", assert_type_in_stats(TestItem), assert_type_in_stats(TreeItem), ], diff --git a/tests/test_validators_jsonschema.py b/tests/test_validators_jsonschema.py index 341b42fb..572946d3 100644 --- a/tests/test_validators_jsonschema.py +++ b/tests/test_validators_jsonschema.py @@ -907,13 +907,13 @@ class Maximum(SchemaTest): class MinItems(SchemaTest): - schema = {"minItems": 1} + schema = {"minItems": 2} data_tests = [ - DataTest(name="longer is valid", data=[1, 2], valid=True), - DataTest(name="exact length is valid", data=[1], valid=True), + DataTest(name="longer is valid", data=[1, 2, 3], valid=True), + DataTest(name="exact length is valid", data=[1, 2], valid=True), DataTest( name="too short is invalid", - data=[], + data=[1], valid=False, expected_errors={"": [messages.FIELD_TOO_SHORT]}, ), @@ -921,14 +921,28 @@ class MinItems(SchemaTest): ] +class EmptyItems(SchemaTest): + schema = {"minItems": 1} + data_tests = [ + DataTest( + name="empty is invalid", + data=list(), + valid=False, + expected_errors={"": [messages.SHOULD_BE_NON_EMPTY]}, + ) + ] + + class MinProperties(SchemaTest): - schema = {"minProperties": 1} + schema = {"minProperties": 2} data_tests = [ - DataTest(name="longer is valid", data={"foo": 1, "bar": 2}, valid=True), - DataTest(name="exact length is valid", data={"foo": 1}, valid=True), + DataTest( + name="longer is valid", data={"foo": 1, "bar": 2, "foobar": 3}, valid=True + ), + DataTest(name="exact length is valid", data={"foo": 1, "bar": 2}, valid=True), DataTest( name="too short is invalid", - data={}, + data={"foo": 1}, valid=False, expected_errors={"": [messages.NOT_ENOUGH_PROPERTIES]}, ), @@ -936,6 +950,18 @@ class MinProperties(SchemaTest): ] +class EmptyProperties(SchemaTest): + schema = {"minProperties": 1} + data_tests = [ + DataTest( + name="empty is invalid", + data=dict(), + valid=False, + expected_errors={"": [messages.SHOULD_BE_NON_EMPTY]}, + ) + ] + + class Minimum(SchemaTest): # exclusiveMinimum behaviour changed from draft-04 to draft-06 # http://json-schema.org/draft-06/json-schema-release-notes.html#backwards-incompatible-changes diff --git a/tox.ini b/tox.ini index 7debb442..8f5145aa 100644 --- a/tox.ini +++ b/tox.ini @@ -22,10 +22,10 @@ commands = pytest -s --ignore=./tests/contrib --ignore=./tests/utils/test_zyte.p basepython = python3.8 deps = {[testenv]deps} - jsonschema[format]==3.2.0 + jsonschema[format]==4.21.0 [testenv:docs] -deps = +deps = -r {toxinidir}/docs/requirements-docs.txt changedir = docs commands =