From d51f2cc5d667944bdef67364d1cc3ada89c9b0d0 Mon Sep 17 00:00:00 2001 From: Hendrik Huyskens Date: Mon, 17 Jun 2024 16:03:40 +0200 Subject: [PATCH] Add validation for multiple invalid metadata files --- .pre-commit-config.yaml | 1 + src/omi/validation.py | 74 +++- .../invalid_metadata}/additional_key.json | 0 .../invalid_metadata}/duplicate_key.json | 0 .../invalid_metadata}/missing_fields.json | 0 .../invalid_metadata}/wrong_datatype.json | 0 .../invalid_metadata}/wrong_json_syntax.json | 0 .../invalid_metadata}/wrong_key.json | 0 .../invalid_metadata}/wrong_nesting.json | 0 .../invalid_metadata}/wrong_structure.json | 0 .../invalid_metadata}/wrong_version.json | 0 .../wrongly_placed_null_value.json | 0 .../invalid_oep_metadata_example.json | 413 ------------------ tests/test_data/wrong.json | 40 -- tests/test_metadata_validation.py | 59 ++- 15 files changed, 114 insertions(+), 473 deletions(-) rename tests/test_data/{ => validation/invalid_metadata}/additional_key.json (100%) rename tests/test_data/{ => validation/invalid_metadata}/duplicate_key.json (100%) rename tests/test_data/{ => validation/invalid_metadata}/missing_fields.json (100%) rename tests/test_data/{ => validation/invalid_metadata}/wrong_datatype.json (100%) rename tests/test_data/{ => validation/invalid_metadata}/wrong_json_syntax.json (100%) rename tests/test_data/{ => validation/invalid_metadata}/wrong_key.json (100%) rename tests/test_data/{ => validation/invalid_metadata}/wrong_nesting.json (100%) rename tests/test_data/{ => validation/invalid_metadata}/wrong_structure.json (100%) rename tests/test_data/{ => validation/invalid_metadata}/wrong_version.json (100%) rename tests/test_data/{ => validation/invalid_metadata}/wrongly_placed_null_value.json (100%) delete mode 100644 tests/test_data/validation/invalid_oep_metadata_example.json delete mode 100644 tests/test_data/wrong.json diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 18e7de9..15e34db 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,6 +7,7 @@ repos: rev: v4.4.0 hooks: - id: check-json + exclude: tests/test_data/validation/invalid_metadata/* - id: end-of-file-fixer - id: trailing-whitespace - id: check-added-large-files diff --git a/src/omi/validation.py b/src/omi/validation.py index d9d71aa..579d3f1 100644 --- a/src/omi/validation.py +++ b/src/omi/validation.py @@ -2,6 +2,7 @@ from __future__ import annotations +import json import warnings import jsonschema @@ -49,30 +50,35 @@ class ValidationError(Exception): """Exception raised when a validation fails.""" -def validate_metadata(metadata: dict) -> None: +def validate_metadata(metadata: dict | str) -> None: """ Validate metadata against related metadata schema. Parameters ---------- - metadata: dict - Metadata + metadata: dict | str + Metadata as dict or as JSON string Returns ------- None if metadata schema is valid. Otherwise it raises an exception. """ + if isinstance(metadata, str): + metadata = parse_metadata(metadata) metadata_version = get_metadata_version(metadata) metadata_schema = get_metadata_specification(metadata_version) - jsonschema.validate(metadata, metadata_schema.schema) + try: + jsonschema.validate(metadata, metadata_schema.schema) + except jsonschema.exceptions.ValidationError as ve: + raise ValidationError(f"Error validating metadata against related metadata schema: {ve.message}") from ve license.validate_oemetadata_licenses(metadata) def validate_data( data: pd.DataFrame, *, - metadata: dict | None = None, + metadata: dict | str | None = None, oep_table: str | None = None, oep_schema: str | None = None, return_report: bool = False, @@ -84,7 +90,7 @@ def validate_data( ---------- data: pd.DataFrame Data to validate - metadata: dict | None + metadata: dict | str | None Metadata in OEMetadata format. If given, data is validated against metadata schema. oep_table: str | None Table name on OEP. If given, data is validated against OEP table. @@ -122,6 +128,8 @@ def validate_data( ) if metadata: + if isinstance(metadata, str): + metadata = parse_metadata(metadata) return validate_data_against_metadata(data, metadata, return_report=return_report) return validate_data_against_oep_table(data, oep_table, oep_schema, return_report=return_report) @@ -182,7 +190,7 @@ def validate_data_against_oep_table( def validate_data_against_metadata( data: pd.DataFrame, - metadata: dict, + metadata: dict | str, *, return_report: bool = True, ) -> None | Report: @@ -193,7 +201,7 @@ def validate_data_against_metadata( ---------- data: pandas.DataFrame Data to validate - metadata: dict + metadata: dict | str Metadata in OEMetadata format. return_report: bool If set to True, report is returned instead of raising an error. @@ -203,6 +211,8 @@ def validate_data_against_metadata( Report Frictionless report if `return_report` is set to True, otherwise None is returned. """ + if isinstance(metadata, str): + metadata = parse_metadata(metadata) metadata_fields = __get_fields_from_metadata(metadata) report = __validate_data_against_schema(data, metadata_fields) if not report.valid: @@ -215,7 +225,7 @@ def validate_data_against_metadata( def validate_oep_table_against_metadata( # noqa: C901 oep_table: str, oep_schema: str, - metadata: dict | None = None, + metadata: dict | str | None = None, ) -> None: """ Validate OEP table against given metadata. @@ -226,7 +236,7 @@ def validate_oep_table_against_metadata( # noqa: C901 OEP table name oep_schema: str OEP schema name - metadata: dict | None + metadata: dict | str | None Metadata in OEMetadata format. If no metadata is given, metadata defined for OEP table on OEP is used. Raises @@ -239,6 +249,8 @@ def validate_oep_table_against_metadata( # noqa: C901 None if everything is valid. Otherwise, it raises an exception. """ + if isinstance(metadata, str): + metadata = parse_metadata(metadata) if metadata is None: metadata = get_metadata_from_oep_table(oep_table, oep_schema) @@ -295,6 +307,48 @@ def validate_oep_table_against_metadata( # noqa: C901 raise ValidationError(errors) +def parse_metadata(metadata_string: str) -> dict: + """ + Parse metadata string into a dictionary. + + Parameters + ---------- + metadata_string: str + Metadata given as JSOn string + + Returns + ------- + dict + Metadata as dictionary + """ + + def dict_raise_on_duplicates(ordered_pairs: dict) -> dict: + """ + Reject duplicate keys. + + From https://stackoverflow.com/a/14902564/5804947 + """ + d = {} + for k, v in ordered_pairs: + if k in d: + raise ValidationError(f"Duplicate keys in metadata: '{k}'") + d[k] = v + return d + + try: + json.loads(metadata_string, object_pairs_hook=dict_raise_on_duplicates) + except json.JSONDecodeError as jde: + start = max(0, jde.pos - 10) + end = min(len(metadata_string), jde.pos + 10) + context = metadata_string[start:end] + error_message = ( + f"Failed to decode JSON: " + f"{jde.msg} at line {jde.lineno}, column {jde.colno}, position {jde.pos}. " + f"Context around this position: '{context}'" + ) + raise ValidationError(error_message) from jde + + def __validate_data_against_schema(data: pd.DataFrame, fields: dict[str, str]) -> Report: """ Validate data against related schema definition and return frictionless report. diff --git a/tests/test_data/additional_key.json b/tests/test_data/validation/invalid_metadata/additional_key.json similarity index 100% rename from tests/test_data/additional_key.json rename to tests/test_data/validation/invalid_metadata/additional_key.json diff --git a/tests/test_data/duplicate_key.json b/tests/test_data/validation/invalid_metadata/duplicate_key.json similarity index 100% rename from tests/test_data/duplicate_key.json rename to tests/test_data/validation/invalid_metadata/duplicate_key.json diff --git a/tests/test_data/missing_fields.json b/tests/test_data/validation/invalid_metadata/missing_fields.json similarity index 100% rename from tests/test_data/missing_fields.json rename to tests/test_data/validation/invalid_metadata/missing_fields.json diff --git a/tests/test_data/wrong_datatype.json b/tests/test_data/validation/invalid_metadata/wrong_datatype.json similarity index 100% rename from tests/test_data/wrong_datatype.json rename to tests/test_data/validation/invalid_metadata/wrong_datatype.json diff --git a/tests/test_data/wrong_json_syntax.json b/tests/test_data/validation/invalid_metadata/wrong_json_syntax.json similarity index 100% rename from tests/test_data/wrong_json_syntax.json rename to tests/test_data/validation/invalid_metadata/wrong_json_syntax.json diff --git a/tests/test_data/wrong_key.json b/tests/test_data/validation/invalid_metadata/wrong_key.json similarity index 100% rename from tests/test_data/wrong_key.json rename to tests/test_data/validation/invalid_metadata/wrong_key.json diff --git a/tests/test_data/wrong_nesting.json b/tests/test_data/validation/invalid_metadata/wrong_nesting.json similarity index 100% rename from tests/test_data/wrong_nesting.json rename to tests/test_data/validation/invalid_metadata/wrong_nesting.json diff --git a/tests/test_data/wrong_structure.json b/tests/test_data/validation/invalid_metadata/wrong_structure.json similarity index 100% rename from tests/test_data/wrong_structure.json rename to tests/test_data/validation/invalid_metadata/wrong_structure.json diff --git a/tests/test_data/wrong_version.json b/tests/test_data/validation/invalid_metadata/wrong_version.json similarity index 100% rename from tests/test_data/wrong_version.json rename to tests/test_data/validation/invalid_metadata/wrong_version.json diff --git a/tests/test_data/wrongly_placed_null_value.json b/tests/test_data/validation/invalid_metadata/wrongly_placed_null_value.json similarity index 100% rename from tests/test_data/wrongly_placed_null_value.json rename to tests/test_data/validation/invalid_metadata/wrongly_placed_null_value.json diff --git a/tests/test_data/validation/invalid_oep_metadata_example.json b/tests/test_data/validation/invalid_oep_metadata_example.json deleted file mode 100644 index b307d98..0000000 --- a/tests/test_data/validation/invalid_oep_metadata_example.json +++ /dev/null @@ -1,413 +0,0 @@ -{ - "unsupported_keyword": "invalid", - "title": "Example title for metadata example - Version 1.6.0", - "id": "http://openenergyplatform.org/dataedit/view/model_draft/oep_metadata_table_example_v160", - "description": "This is an metadata example for example data. There is a corresponding table on the OEP for each metadata version.", - "language": [ - "en-GB", - "en-US", - "de-DE", - "fr-FR" - ], - "subject": [ - { - "name": "energy", - "path": "https://openenergy-platform.org/ontology/oeo/OEO_00000150" - }, - { - "name": "test dataset", - "path": "https://openenergy-platform.org/ontology/oeo/OEO_00000408" - } - ], - "keywords": [ - "energy", - "example", - "template", - "test" - ], - "publicationDate": "2022-02-15", - "context": { - "homepage": "https://reiner-lemoine-institut.de/lod-geoss/", - "documentation": "https://openenergy-platform.org/tutorials/jupyter/OEMetadata/", - "sourceCode": "https://github.com/OpenEnergyPlatform/oemetadata/tree/master", - "contact": "https://github.com/Ludee", - "grantNo": "03EI1005", - "fundingAgency": "Bundesministerium für Wirtschaft und Klimaschutz", - "fundingAgencyLogo": "https://commons.wikimedia.org/wiki/File:BMWi_Logo_2021.svg#/media/File:BMWi_Logo_2021.svg", - "publisherLogo": "https://reiner-lemoine-institut.de//wp-content/uploads/2015/09/rlilogo.png" - }, - "spatial": { - "location": null, - "extent": "europe", - "resolution": "100 m" - }, - "temporal": { - "referenceDate": "2016-01-01", - "timeseries": [ - { - "start": "2017-01-01T00:00+01", - "end": "2017-12-31T23:00+01", - "resolution": "1 h", - "alignment": "left", - "aggregationType": "sum" - }, - { - "start": "2018-01-01T00:00+01", - "end": "2019-06-01T23:00+01", - "resolution": "15 min", - "alignment": "right", - "aggregationType": "sum" - } - ] - }, - "sources": [ - { - "title": "OpenEnergyPlatform Metadata Example", - "description": "Metadata description", - "path": "https://github.com/OpenEnergyPlatform", - "licenses": [ - { - "name": "CC0-1.0", - "title": "Creative Commons Zero v1.0 Universal", - "path": "https://creativecommons.org/publicdomain/zero/1.0/legalcode", - "instruction": "You are free: To Share, To Create, To Adapt", - "attribution": "© Reiner Lemoine Institut" - } - ] - }, - { - "title": "OpenStreetMap", - "description": "A collaborative project to create a free editable map of the world", - "path": "https://www.openstreetmap.org/", - "licenses": [ - { - "name": "ODbL-1.0", - "title": "Open Data Commons Open Database License 1.0", - "path": "https://opendatacommons.org/licenses/odbl/1.0/index.html", - "instruction": "You are free: To Share, To Create, To Adapt; As long as you: Attribute, Share-Alike, Keep open!", - "attribution": "© OpenStreetMap contributors" - } - ] - } - ], - "licenses": [ - { - "name": "ODbL-1.0", - "title": "Open Data Commons Open Database License 1.0", - "path": "https://opendatacommons.org/licenses/odbl/1.0/", - "instruction": "You are free: To Share, To Create, To Adapt; As long as you: Attribute, Share-Alike, Keep open!", - "attribution": "© Reiner Lemoine Institut © OpenStreetMap contributors" - } - ], - "contributors": [ - { - "title": "Ludee", - "email": null, - "date": "2016-06-16", - "object": "metadata", - "comment": "Create metadata" - }, - { - "title": "Ludee", - "email": null, - "date": "2016-11-22", - "object": "metadata", - "comment": "Update metadata" - }, - { - "title": "Ludee", - "email": null, - "date": "2016-11-22", - "object": "metadata", - "comment": "Update header and license" - }, - { - "title": "Ludee", - "email": null, - "date": "2017-03-16", - "object": "metadata", - "comment": "Add license to source" - }, - { - "title": "Ludee", - "email": null, - "date": "2017-03-28", - "object": "metadata", - "comment": "Add copyright to source and license" - }, - { - "title": "Ludee", - "email": null, - "date": "2017-05-30", - "object": "metadata", - "comment": "Release metadata version 1.3" - }, - { - "title": "Ludee", - "email": null, - "date": "2017-06-26", - "object": "metadata", - "comment": "Move referenceDate into temporal and remove array" - }, - { - "title": "Ludee", - "email": null, - "date": "2018-07-19", - "object": "metadata", - "comment": "Start metadata version 1.4" - }, - { - "title": "Ludee", - "email": null, - "date": "2018-07-26", - "object": "data", - "comment": "Rename table and files" - }, - { - "title": "Ludee", - "email": null, - "date": "2018-10-18", - "object": "metadata", - "comment": "Add contribution object" - }, - { - "title": "christian-rli", - "email": null, - "date": "2018-10-18", - "object": "metadata", - "comment": "Add datapackage compatibility" - }, - { - "title": "Ludee", - "email": null, - "date": "2018-11-02", - "object": "metadata", - "comment": "Release metadata version 1.4" - }, - { - "title": "christian-rli", - "email": null, - "date": "2019-02-05", - "object": "metadata", - "comment": "Apply template structure to example" - }, - { - "title": "Ludee", - "email": null, - "date": "2019-03-22", - "object": "metadata", - "comment": "Hotfix foreignKeys" - }, - { - "title": "Ludee", - "email": null, - "date": "2019-07-09", - "object": "metadata", - "comment": "Release metadata version OEP-1.3.0" - }, - { - "title": "Ludee", - "email": null, - "date": "2021-11-15", - "object": "metadata", - "comment": "Release metadata version OEP-1.5.0" - }, - { - "title": "Ludee", - "email": null, - "date": "2022-02-15", - "object": "metadata", - "comment": "Release metadata version OEP-1.5.1" - }, - { - "title": "jh-RLI", - "email": null, - "date": "2022-11-18", - "object": "metadata", - "comment": "Release metadata version OEP-1.5.2" - }, - { - "title": "christian-rli", - "email": null, - "date": "2023-05-30", - "object": "metadata", - "comment": "Release metadata version OEP-1.6.0" - } - ], - "resources": [ - { - "profile": "tabular-data-resource", - "name": "model_draft.oep_metadata_table_example_v160", - "path": "http://openenergyplatform.org/dataedit/view/model_draft/oep_metadata_table_example_v160", - "format": "PostgreSQL", - "encoding": "UTF-8", - "schema": { - "fields": [ - { - "name": "id", - "description": "Unique identifier", - "type": "serial", - "unit": null, - "isAbout": [ - { - "name": null, - "path": null - } - ], - "valueReference": [ - { - "value": null, - "name": null, - "path": null - } - ] - }, - { - "name": "name", - "description": "Example name", - "type": "text", - "unit": null, - "isAbout": [ - { - "name": "written name", - "path": "https://openenergy-platform.org/ontology/oeo/IAO_0000590" - } - ], - "valueReference": [ - { - "value": null, - "name": null, - "path": null - } - ] - }, - { - "name": "type", - "description": "Type of wind farm", - "type": "text", - "unit": null, - "isAbout": [ - { - "name": "wind farm", - "path": "https://openenergy-platform.org/ontology/oeo/OEO_00000447" - } - ], - "valueReference": [ - { - "value": "onshore ", - "name": "onshore wind farm", - "path": "https://openenergy-platform.org/ontology/oeo/OEO_00000311" - }, - { - "value": "offshore ", - "name": "offshore wind farm", - "path": "https://openenergy-platform.org/ontology/oeo/OEO_00000308" - } - ] - }, - { - "name": "year", - "description": "Reference year", - "type": "integer", - "unit": null, - "isAbout": [ - { - "name": "year", - "path": "https://openenergy-platform.org/ontology/oeo/UO_0000036" - } - ], - "valueReference": [ - { - "value": null, - "name": null, - "path": null - } - ] - }, - { - "name": "value", - "description": "Example value", - "type": "double precision", - "unit": "MW", - "isAbout": [ - { - "name": "quantity value", - "path": "https://openenergy-platform.org/ontology/oeo/OEO_00000350" - } - ], - "valueReference": [ - { - "value": null, - "name": null, - "path": null - } - ] - }, - { - "name": "geom", - "description": "Geometry", - "type": "geometry(Point, 4326)", - "unit": null, - "isAbout": [ - { - "name": "spatial region", - "path": "https://openenergy-platform.org/ontology/oeo/BFO_0000006" - } - ], - "valueReference": [ - { - "value": null, - "name": null, - "path": null - } - ] - } - ], - "primaryKey": [ - "id" - ], - "foreignKeys": [ - { - "fields": [ - "year" - ], - "reference": { - "resource": "schema.table", - "fields": [ - "year" - ] - } - } - ] - }, - "dialect": { - "delimiter": null, - "decimalSeparator": "." - } - } - ], - "@id": "https://databus.dbpedia.org/kurzum/mastr/bnetza-mastr/01.04.00", - "@context": "https://raw.githubusercontent.com/OpenEnergyPlatform/oemetadata/develop/metadata/latest/context.json", - "review": { - "path": "https://github.com/OpenEnergyPlatform/data-preprocessing/issues", - "badge": "Platinum" - }, - "metaMetadata": { - "metadataVersion": "OEP-1.6.0", - "metadataLicense": { - "name": "CC0-1.0", - "title": "Creative Commons Zero v1.0 Universal", - "path": "https://creativecommons.org/publicdomain/zero/1.0/" - } - }, - "_comment": { - "metadata": "Metadata documentation and explanation (https://github.com/OpenEnergyPlatform/oemetadata)", - "dates": "Dates and time must follow the ISO8601 including time zone (YYYY-MM-DD or YYYY-MM-DDThh:mm:ss±hh)", - "units": "Use a space between numbers and units (100 m)", - "languages": "Languages must follow the IETF (BCP47) format (en-GB, en-US, de-DE)", - "licenses": "License name must follow the SPDX License List (https://spdx.org/licenses/)", - "review": "Following the OEP Data Review (https://github.com/OpenEnergyPlatform/data-preprocessing/blob/master/data-review/manual/review_manual.md)", - "null": "If not applicable use: null", - "todo": "If a value is not yet available, use: todo" - } -} diff --git a/tests/test_data/wrong.json b/tests/test_data/wrong.json deleted file mode 100644 index bc5d9c8..0000000 --- a/tests/test_data/wrong.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "title": "title", - "id": "http://such.tld/name", - "description": "These Metadata use a wrong date format in publication date.", - "licenses": [ - { - "name": "ODbL-1.0", - "title": "Open Data Commons Open Database License 1.0" - } - ], - "resources": [ - { - "profile": "tabular-data-resource", - "name": "very.name", - "path": "http://such.tld/name", - "format": "PostgreSQL", - "encoding": "UTF-8", - "schema": { - "fields": [ - { - "name": "id", - "description": "Unique identifier", - "type": "serial" - }, - { - "name": "name", - "description": "Example name", - "type": "text" - } - ], - "primaryKey": [ - "id" - ] - } - } - ], - "metaMetadata": { - "metadataVersion": "OEP-1.6.0" - } -} diff --git a/tests/test_metadata_validation.py b/tests/test_metadata_validation.py index 6a9dae9..c4b8db5 100644 --- a/tests/test_metadata_validation.py +++ b/tests/test_metadata_validation.py @@ -2,17 +2,16 @@ import json import pathlib +import re -import jsonschema import pytest -from jsonschema.exceptions import ValidationError -from omi import base, validation +from omi import base, license, validation TEST_VALIDATION_DATA_PATH = pathlib.Path(__file__).parent / "test_data" / "validation" +INVALID_METADAT_PATH = TEST_VALIDATION_DATA_PATH / "invalid_metadata" UNSUPPORTED_OEP_METADATA_EXAMPLE_FILE = TEST_VALIDATION_DATA_PATH / "unsupported_oep_metadata_example.json" -INVALID_OEP_METADATA_EXAMPLE_FILE = TEST_VALIDATION_DATA_PATH / "invalid_oep_metadata_example.json" def test_validation_of_oep_metadata(): @@ -23,12 +22,52 @@ def test_validation_of_oep_metadata(): validation.validate_metadata(metadata_schema.example) -def test_invalid_oep_metadata_version(): - """Test if validation error is raised for invalid OEP metadata.""" - with INVALID_OEP_METADATA_EXAMPLE_FILE.open("r") as f: +def test_invalid_oep_metadata(): + """Test if validation error is raised for different invalid OEP metadata.""" + with (INVALID_METADAT_PATH / "additional_key.json").open("r") as f: invalid_oep_metadata = json.load(f) - with pytest.raises(ValidationError): - validation.validate_metadata(invalid_oep_metadata) + # `re.escape` must be used, otherwise quotes around 'universe' are not detected correctly + with pytest.raises( + validation.ValidationError, + match=re.escape("Additional properties are not allowed ('universe' was unexpected)"), + ): + validation.validate_metadata(invalid_oep_metadata) + + with (INVALID_METADAT_PATH / "missing_fields.json").open("r") as f: + invalid_oep_metadata = json.load(f) + with pytest.raises(license.LicenseError, match="No license information available in the metadata."): + validation.validate_metadata(invalid_oep_metadata) + + with (INVALID_METADAT_PATH / "wrongly_placed_null_value.json").open("r") as f: + invalid_oep_metadata = json.load(f) + with pytest.raises(validation.ValidationError, match="None is not of type 'object'"): + validation.validate_metadata(invalid_oep_metadata) + + +def test_invalid_oep_metadata_caused_by_invalid_json(): + """Test if validation error is raised for invalid OEP metadata due to invalid JSOn syntax.""" + with (INVALID_METADAT_PATH / "duplicate_key.json").open("r") as f: + invalid_metadata_string = f.read() + with pytest.raises(validation.ValidationError, match="Duplicate keys in metadata: 'description'"): + validation.validate_metadata(invalid_metadata_string) + + with (INVALID_METADAT_PATH / "wrong_json_syntax.json").open("r") as f: + invalid_metadata_string = f.read() + with pytest.raises(validation.ValidationError, match="Failed to decode JSON: Expecting value"): + validation.validate_metadata(invalid_metadata_string) + + with (INVALID_METADAT_PATH / "wrong_nesting.json").open("r") as f: + invalid_metadata_string = f.read() + with pytest.raises( + validation.ValidationError, + match="Failed to decode JSON: Expecting property name enclosed in double quotes", + ): + validation.validate_metadata(invalid_metadata_string) + + with (INVALID_METADAT_PATH / "wrong_structure.json").open("r") as f: + invalid_metadata_string = f.read() + with pytest.raises(validation.ValidationError, match="Failed to decode JSON: Expecting ',' delimiter"): + validation.validate_metadata(invalid_metadata_string) def test_unsupported_oep_metadata_version(): @@ -71,7 +110,7 @@ def test_metadata_against_oep_table(): def test_metadata_against_oep_table_using_metadata_from_oep(): """Test OEP table definition against OEP metadata, where metadata is taken from OEP.""" table = "x2x_p2gas_soec_1" - with pytest.raises(jsonschema.exceptions.ValidationError, match="None is not of type 'object'"): + with pytest.raises(validation.ValidationError, match="None is not of type 'object'"): validation.validate_oep_table_against_metadata(oep_table=table, oep_schema="model_draft")