From d42b3635254a8b7677063fba5a78e39754250bc0 Mon Sep 17 00:00:00 2001 From: Nora-Olivia-Ammann <103038637+Nora-Olivia-Ammann@users.noreply.github.com> Date: Fri, 8 Nov 2024 15:38:50 +0100 Subject: [PATCH] refactor(validate-data): include onotlogy name in LinkValue violation message (DEV-4275) (#1262) --- .../validate_data/models/validation.py | 2 +- .../reformat_validaton_result.py | 28 ++++++++++--------- .../validate_data/sparql/value_shacl.py | 3 +- .../fixtures/validation_result.py | 8 +++--- .../test_reformat_validaton_result.py | 6 ++-- 5 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/dsp_tools/commands/validate_data/models/validation.py b/src/dsp_tools/commands/validate_data/models/validation.py index f4910db35b..918eabd28c 100644 --- a/src/dsp_tools/commands/validate_data/models/validation.py +++ b/src/dsp_tools/commands/validate_data/models/validation.py @@ -91,7 +91,7 @@ class ResultGenericViolation(ValidationResult): @dataclass class ResultLinkTargetViolation(ValidationResult): - results_message: str + expected_type: Node target_iri: Node target_resource_type: Node | None diff --git a/src/dsp_tools/commands/validate_data/reformat_validaton_result.py b/src/dsp_tools/commands/validate_data/reformat_validaton_result.py index f311e10510..f5b5411260 100644 --- a/src/dsp_tools/commands/validate_data/reformat_validaton_result.py +++ b/src/dsp_tools/commands/validate_data/reformat_validaton_result.py @@ -284,12 +284,12 @@ def _query_for_link_value_target_violation( target_rdf_type: Node | None = None if target_type := list(data_graph.objects(target_iri, RDF.type)): target_rdf_type = target_type[0] - msg = next(results_and_onto.objects(detail_info.detail_bn, SH.resultMessage)) + expected_type = next(results_and_onto.objects(detail_info.detail_bn, SH.resultMessage)) return ResultLinkTargetViolation( res_iri=base_info.resource_iri, res_class=base_info.res_class_type, property=base_info.result_path, - results_message=str(msg), + expected_type=expected_type, target_iri=target_iri, target_resource_type=target_rdf_type, ) @@ -361,7 +361,7 @@ def _reformat_one_validation_result(validation_result: ValidationResult) -> Inpu def _reformat_value_type_violation_result(result: ResultValueTypeViolation) -> ValueTypeProblem: iris = _reformat_main_iris(result) - actual_type = _reformat_onto_iri(str(result.actual_value_type)) + actual_type = _reformat_onto_iri(result.actual_value_type) return ValueTypeProblem( res_id=iris.res_id, res_type=iris.res_type, @@ -387,7 +387,7 @@ def _reformat_pattern_violation_result(result: ResultPatternViolation) -> Conten def _reformat_link_target_violation_result(result: ResultLinkTargetViolation) -> InputProblem: iris = _reformat_main_iris(result) - target_id = _reformat_data_iri(str(result.target_iri)) + target_id = _reformat_data_iri(result.target_iri) if not result.target_resource_type: return LinkedResourceDoesNotExistProblem( res_id=iris.res_id, @@ -395,14 +395,15 @@ def _reformat_link_target_violation_result(result: ResultLinkTargetViolation) -> prop_name=iris.prop_name, link_target_id=target_id, ) - actual_type = _reformat_onto_iri(str(result.target_resource_type)) + actual_type = _reformat_onto_iri(result.target_resource_type) + expected_type = _reformat_onto_iri(result.expected_type) return LinkTargetTypeMismatchProblem( res_id=iris.res_id, res_type=iris.res_type, prop_name=iris.prop_name, link_target_id=target_id, actual_type=actual_type, - expected_type=result.results_message, + expected_type=expected_type, ) @@ -411,7 +412,7 @@ def _reformat_unique_value_violation_result(result: ResultUniqueValueViolation) if isinstance(result.actual_value, Literal): actual_value = str(result.actual_value) else: - actual_value = _reformat_data_iri(str(result.actual_value)) + actual_value = _reformat_data_iri(result.actual_value) return DuplicateValueProblem( res_id=iris.res_id, res_type=iris.res_type, @@ -421,13 +422,14 @@ def _reformat_unique_value_violation_result(result: ResultUniqueValueViolation) def _reformat_main_iris(result: ValidationResult) -> ReformattedIRI: - subject_id = _reformat_data_iri(str(result.res_iri)) - prop_name = _reformat_onto_iri(str(result.property)) - res_type = _reformat_onto_iri(str(result.res_class)) + subject_id = _reformat_data_iri(result.res_iri) + prop_name = _reformat_onto_iri(result.property) + res_type = _reformat_onto_iri(result.res_class) return ReformattedIRI(res_id=subject_id, res_type=res_type, prop_name=prop_name) -def _reformat_onto_iri(iri_str: str) -> str: +def _reformat_onto_iri(iri: Node) -> str: + iri_str = str(iri) if "http://www.w3.org/2000/01/rdf-schema#" in iri_str: return f'rdfs:{iri_str.split("#")[-1]}' onto = iri_str.split("/")[-2] @@ -437,5 +439,5 @@ def _reformat_onto_iri(iri_str: str) -> str: return f"{onto}:{ending}" -def _reformat_data_iri(iri: str) -> str: - return iri.replace("http://data/", "") +def _reformat_data_iri(iri: Node) -> str: + return str(iri).replace("http://data/", "") diff --git a/src/dsp_tools/commands/validate_data/sparql/value_shacl.py b/src/dsp_tools/commands/validate_data/sparql/value_shacl.py index 0121aa3c3a..b018d8c7ae 100644 --- a/src/dsp_tools/commands/validate_data/sparql/value_shacl.py +++ b/src/dsp_tools/commands/validate_data/sparql/value_shacl.py @@ -151,7 +151,7 @@ def _construct_link_value_node_shape(onto: Graph) -> Graph: a sh:PropertyShape ; sh:path api-shapes:linkValueHasTargetID ; sh:class ?rangeClass ; - sh:message ?rangeString ; + sh:message ?rangeClass ; ] ; sh:severity sh:Violation . @@ -162,7 +162,6 @@ def _construct_link_value_node_shape(onto: Graph) -> Graph: knora-api:objectType ?rangeClass . BIND(IRI(CONCAT(str(?prop), "_NodeShape")) AS ?nodeShapeIRI) - BIND(STRAFTER(STR(?rangeClass), "#") AS ?rangeString ) } """ if results_graph := onto.query(query_s).graph: diff --git a/test/unittests/commands/validate_data/fixtures/validation_result.py b/test/unittests/commands/validate_data/fixtures/validation_result.py index 4f7dfc0432..1399e5697b 100644 --- a/test/unittests/commands/validate_data/fixtures/validation_result.py +++ b/test/unittests/commands/validate_data/fixtures/validation_result.py @@ -303,7 +303,7 @@ def report_link_target_non_existent(onto_graph: Graph) -> tuple[Graph, Graph, Va _:bn_link_target_non_existent a sh:ValidationResult ; sh:focusNode ; - sh:resultMessage "Resource" ; + sh:resultMessage ; sh:resultPath api-shapes:linkValueHasTargetID ; sh:resultSeverity sh:Violation ; sh:sourceConstraintComponent sh:ClassConstraintComponent ; @@ -347,7 +347,7 @@ def extracted_link_target_non_existent() -> ResultLinkTargetViolation: res_iri=DATA.link_target_non_existent, res_class=ONTO.ClassWithEverything, property=ONTO.testHasLinkTo, - results_message="Resource", + expected_type=KNORA_API.Resource, target_iri=DATA.other, target_resource_type=None, ) @@ -368,7 +368,7 @@ def report_link_target_wrong_class(onto_graph: Graph) -> tuple[Graph, Graph, Val _:bn_link_target_wrong_class a sh:ValidationResult ; sh:focusNode ; - sh:resultMessage "CardOneResource" ; + sh:resultMessage ; sh:resultPath api-shapes:linkValueHasTargetID ; sh:resultSeverity sh:Violation ; sh:sourceConstraintComponent sh:ClassConstraintComponent ; @@ -415,7 +415,7 @@ def extracted_link_target_wrong_class() -> ResultLinkTargetViolation: res_iri=DATA.link_target_wrong_class, res_class=ONTO.ClassWithEverything, property=ONTO.testHasLinkToCardOneResource, - results_message="CardOneResource", + expected_type=ONTO.CardOneResource, target_iri=DATA.id_9_target, target_resource_type=ONTO.ClassWithEverything, ) diff --git a/test/unittests/commands/validate_data/test_reformat_validaton_result.py b/test/unittests/commands/validate_data/test_reformat_validaton_result.py index f3948732f5..76e8c8ceec 100644 --- a/test/unittests/commands/validate_data/test_reformat_validaton_result.py +++ b/test/unittests/commands/validate_data/test_reformat_validaton_result.py @@ -240,7 +240,7 @@ def test_link_target_non_existent( assert result.res_iri == info.resource_iri assert result.res_class == info.res_class_type assert result.property == ONTO.testHasLinkTo - assert result.results_message == "Resource" + assert result.expected_type == KNORA_API.Resource assert result.target_iri == URIRef("http://data/other") assert not result.target_resource_type @@ -253,7 +253,7 @@ def test_link_target_wrong_class( assert result.res_iri == info.resource_iri assert result.res_class == info.res_class_type assert result.property == ONTO.testHasLinkToCardOneResource - assert result.results_message == "CardOneResource" + assert result.expected_type == ONTO.CardOneResource assert result.target_iri == URIRef("http://data/id_9_target") assert result.target_resource_type == ONTO.ClassWithEverything @@ -357,7 +357,7 @@ def test_link_target_wrong_class(self, extracted_link_target_wrong_class: Result assert result.res_type == "onto:ClassWithEverything" assert result.prop_name == "onto:testHasLinkToCardOneResource" assert result.link_target_id == "id_9_target" - assert result.expected_type == "CardOneResource" + assert result.expected_type == "onto:CardOneResource" assert result.actual_type == "onto:ClassWithEverything" def test_unique_value_literal(self, extracted_unique_value_literal: ResultUniqueValueViolation) -> None: