def test_evaluate_jsonpointer(value, testkey): resolved_pointers = {} def generate_pointers(ptr, val): resolved_pointers[ptr] = val if isinstance(val, list): for i, item in enumerate(val): generate_pointers(f'{ptr}/{i}', item) elif isinstance(val, dict): for k, item in val.items(): generate_pointers(f"{ptr}/{jsonpointer_escape(k)}", item) assert JSONPointer().evaluate(value) == value assert JSONPointer().evaluate(JSON(value)) == value generate_pointers('', value) for pointer, target in resolved_pointers.items(): assert JSONPointer(pointer).evaluate(value) == target assert JSONPointer(pointer).evaluate(JSON(value)) == target if isinstance(value, list): with pytest.raises(JSONPointerError): JSONPointer(f'/{len(value)}').evaluate(value) with pytest.raises(JSONPointerError): JSONPointer('/-').evaluate(value) with pytest.raises(JSONPointerError): JSONPointer('/').evaluate(value) elif isinstance(value, dict): if testkey not in value: with pytest.raises(JSONPointerError): JSONPointer(f'/{jsonpointer_escape(testkey)}').evaluate(value) else: with pytest.raises(JSONPointerError): JSONPointer(f'/{value}').evaluate(value)
def test_validity(): input_schema = catalog.get_schema( URI('https://odp.saeon.ac.za/schema/metadata/saeon/iso19115')) input_json = catalog.load_json( URI('https://odp.saeon.ac.za/schema/metadata/saeon/iso19115-example')) output_schema = catalog.get_schema( URI('https://odp.saeon.ac.za/schema/metadata/saeon/datacite4')) output_json = catalog.load_json( URI('https://odp.saeon.ac.za/schema/metadata/saeon/datacite4-example-translated' )) assert input_schema.validate().valid assert input_schema.evaluate(JSON(input_json)).valid assert output_schema.validate().valid assert output_schema.evaluate(JSON(output_json)).valid
def test_translate_iso19115_to_datacite(): input_schema = catalog.get_schema( URI('https://odp.saeon.ac.za/schema/metadata/saeon/iso19115')) input_json = catalog.load_json( URI('https://odp.saeon.ac.za/schema/metadata/saeon/iso19115-example.json' )) output_json = catalog.load_json( URI('https://odp.saeon.ac.za/schema/metadata/saeon/datacite4-example-translated.json' )) result = input_schema.evaluate(JSON(input_json)) patch = result.output('patch', scheme='saeon/datacite4') translation = result.output('translation', scheme='saeon/datacite4') assert JSONPatch(*patch).evaluate(None) == translation # work in progress # assert translation == output_json assert translation.keys() == output_json.keys() for k in translation: if k == 'contributors': # todo: resolve leftover empty arrays/objects when there are # no source values to fill them continue assert translation[k] == output_json[k]
def test_load_json_from_file(value): s = jsonlib.dumps(value) with tempfile.NamedTemporaryFile() as f: f.write(s.encode()) f.flush() instance = JSON.loadf(f.name) assert_json_node(instance, value, None, None, '')
def test_contains(minmax, instval): min_contains = min(minmax) max_contains = max(minmax) contains_count = len( list(filter(lambda item: JSON(item).type == "boolean", instval))) schema = JSONSchema( { "contains": { "type": "boolean" }, "minContains": min_contains, "maxContains": max_contains, }, metaschema_uri=metaschema_uri_2019_09) scope = schema.evaluate(JSON(instval)) assert scope.valid == (min_contains <= contains_count <= max_contains)
def validate(schema, part, standard): if standard in legacy: cls = legacy[standard] try: jsonschema.validate(part.json, schema.json, cls=cls) return (True, '') except jsonschema.ValidationError as e: return (False, str(e)) except jsonschema.SchemaError as e: raise ValueError("Schema is invalid:\n{0}\n\n{1}".format( str(e), schema.content)) return (is_valid, message) else: catalogue = create_catalog('2019-09', '2020-12') compiled_schema = JSONSchema(schema.json, metaschema_uri=URI(standard)) if not compiled_schema.validate().valid: raise ValueError("Schema is invalid:\n{0}\n\n{1}".format( "INVALID SCHEMA", schema.content)) elif part.json == (1+1j): return (False, 'INVALID JSON') else: jsonValue = JSON.loads(part.content) validation_result = compiled_schema.evaluate(jsonValue) if validation_result.valid: return (True, ''); else: return (False, 'VALIDATION ERROR');
def test_annotate(key, value): result = JSONSchema({ key: value }, metaschema_uri=metaschema_uri_2020_12).evaluate(JSON("")) assert result.valid is True assert result.children[key].valid is True assert result.children[key]._assert is False try: assert result.children[key].annotations[key].value == value except KeyError: assert value is None
def test_content_schema(): example = { "contentMediaType": "application/json", "contentSchema": { "required": ["foo"], "properties": { "foo": { "type": "string" } } }, } result = JSONSchema(example, metaschema_uri=metaschema_uri_2020_12).evaluate( JSON("")) assert result.children["contentSchema"].annotations[ "contentSchema"].value == example["contentSchema"] del example["contentMediaType"] result = JSONSchema(example, metaschema_uri=metaschema_uri_2020_12).evaluate( JSON("")) assert "contentSchema" not in result.children
def _evaluate_record(self, record_id: str, timestamp: datetime) -> bool: """Evaluate a record model (API) against the publication schema for a catalog, and commit the result to the catalog_record table. The catalog_record entry is stamped with the `timestamp` of the latest contributing change (from catalog/record/record_tag/collection_tag). """ catalog = Session.get(Catalog, self.catalog_id) record = Session.get(Record, record_id) catalog_record = (Session.get(CatalogRecord, (self.catalog_id, record_id)) or CatalogRecord(catalog_id=self.catalog_id, record_id=record_id)) record_model = output_record_model(record) record_json = JSON(record_model.dict()) publication_schema = schema_catalog.get_schema(URI(catalog.schema.uri)) if (result := publication_schema.evaluate(record_json)).valid: catalog_record.validity = result.output('flag') catalog_record.published = True catalog_record.published_record = self._create_published_record(record_model).dict() self._save_published_doi(record_model)
def evaluate(format_attr, instval, assert_=True): FormatKeyword(schema := JSONSchema(True), format_attr).evaluate(JSON(instval), scope := Scope(schema)) assert scope.annotations["format"].value == format_attr assert scope._assert is assert_ return scope.valid
def test_evaluate_json(benchmark, request, value): json = JSON(value) schema = JSONSchema(example_schema, metaschema_uri=metaschema_uri_2020_12) scope = benchmark(schema.evaluate, json) assert scope.valid is (True if '[valid]' in request.node.name else False)
def test_recursive_schema_extension_2020_12(): tree_schema = JSONSchema(tree_2020_12) strict_tree_schema = JSONSchema(strict_tree_2020_12) tree_json = JSON(tree_instance_2020_12) assert tree_schema.evaluate(tree_json).valid is True assert strict_tree_schema.evaluate(tree_json).valid is False
from hypothesis import given from pytest import param as p from jschon import Catalogue, JSON, JSONPointer, JSONSchema, URI, JSONSchemaError from tests import metaschema_uri_2019_09, metaschema_uri_2020_12, example_schema, example_valid, example_invalid from tests.strategies import * schema_tests = ( p(False, False, False, id='false'), p(True, True, True, id='true'), p({}, True, True, id='empty'), p({"not": {}}, False, False, id='not'), p({"const": example_valid}, True, False, id='simple'), p(example_schema, True, False, id='complex'), ) json1 = JSON(example_valid) json2 = JSON(example_invalid) @pytest.mark.parametrize('example, json1_valid, json2_valid', schema_tests) def test_schema_examples(example, json1_valid, json2_valid): schema = JSONSchema(example, metaschema_uri=metaschema_uri_2020_12) schema.validate() assert schema.value == example assert schema.type == "boolean" if isinstance(example, bool) else "object" assert schema.parent is None assert schema.key is None assert not schema.path assert schema.metaschema_uri == metaschema_uri_2020_12 assert schema.evaluate(json1).valid is json1_valid assert schema.evaluate(json2).valid is json2_valid
def evaluate(kwclass, kwvalue, instval): schema = JSONSchema(True) kwclass(schema, kwvalue).evaluate(JSON(instval), scope := Scope(schema)) return scope.valid
def test_load_json_from_string(value): s = jsonlib.dumps(value) instance = JSON.loads(s) assert_json_node(instance, value, None, None, '')
elif tag.cardinality == TagCardinality.multi: command = AuditCommand.insert else: assert False if command == AuditCommand.insert: record_tag = RecordTag( record_id=record_id, tag_id=tag_instance_in.tag_id, tag_type=TagType.record, user_id=auth.user_id, ) if record_tag.data != tag_instance_in.data: validity = tag_schema.evaluate(JSON( tag_instance_in.data)).output('detailed') if not validity['valid']: raise HTTPException(HTTP_422_UNPROCESSABLE_ENTITY, validity) record_tag.data = tag_instance_in.data record_tag.timestamp = (timestamp := datetime.now(timezone.utc)) record_tag.save() record.timestamp = timestamp record.save() RecordTagAudit( client_id=auth.client_id, user_id=auth.user_id, command=command, timestamp=timestamp,
def test_validate(metaschema_uri, schema, data, valid): json_schema = JSONSchema(schema, metaschema_uri=metaschema_uri) json_data = JSON(data) json_evaluator = JSONEvaluator(json_schema) result = json_evaluator.evaluate_instance(json_data) assert result['valid'] is valid
def get_validity(metadata: dict[str, Any], schema: JSONSchema) -> Any: if (result := schema.evaluate(JSON(metadata))).valid: return result.output('flag')
def test_create_json(value): instance = JSON(value) assert_json_node(instance, value, None, None, '')