diff --git a/rocrate_validator/profiles/five-safes-crate/must/15_metadata_file.py b/rocrate_validator/profiles/five-safes-crate/must/15_metadata_file.py new file mode 100644 index 00000000..7fd46ccf --- /dev/null +++ b/rocrate_validator/profiles/five-safes-crate/must/15_metadata_file.py @@ -0,0 +1,64 @@ +# Copyright (c) 2024-2025 CRS4 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import re + +import rocrate_validator.log as logging +from rocrate_validator.models import Severity, ValidationContext +from rocrate_validator.requirements.python import PyFunctionCheck, check, requirement + +# set up logging +logger = logging.getLogger(__name__) + + +@requirement(name="RO-Crate context version") +class FileDescriptorContextVersion(PyFunctionCheck): + """The RO-Crate metadata file MUST include the RO-Crate context version 1.2 + (or later minor version) in `@context`""" + + @check(name="RO-Crate context version", severity=Severity.REQUIRED) + def test_existence(self, context: ValidationContext) -> bool: + """ + The RO-Crate metadata file MUST include the RO-Crate context version 1.2 + (or later minor version) in `@context` + """ + try: + json_dict = context.ro_crate.metadata.as_dict() + context_value = json_dict["@context"] + pattern = re.compile( + r"https://w3id\.org/ro/crate/1\.[2-9](-DRAFT)?/context" + ) + passed = True + if isinstance(context_value, list): + if not any( + pattern.match(item) + for item in context_value + if isinstance(item, str) + ): + passed = False + else: + if not pattern.match(context_value): + passed = False + if not passed: + context.result.add_issue( + "The RO-Crate metadata file MUST include the RO-Crate context " + "version 1.2 (or later minor version) in `@context`", + self, + ) + return passed + + except Exception as e: + if logger.isEnabledFor(logging.DEBUG): + logger.exception(e) + return True diff --git a/rocrate_validator/profiles/five-safes-crate/must/15_metadata_file.ttl b/rocrate_validator/profiles/five-safes-crate/must/15_metadata_file.ttl new file mode 100644 index 00000000..14d939f0 --- /dev/null +++ b/rocrate_validator/profiles/five-safes-crate/must/15_metadata_file.ttl @@ -0,0 +1,41 @@ +# Copyright (c) 2025 eScience Lab, The University of Manchester +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +@prefix ro-crate: . +@prefix five-safes-crate: . +@prefix rdf: . +@prefix schema: . +@prefix purl: . +@prefix sh: . +@prefix validator: . +@prefix xsd: . +@prefix dct: . + +five-safes-crate:MetadataFileDescriptorProperties a sh:NodeShape ; + sh:name "RO-Crate conforms to 1.2 or later minor version" ; + sh:description """The RO-Crate metadata file descriptor MUST have a `conformsTo` property with RO-Crate specification version 1.2 or later minor version"""; + sh:targetClass ro-crate:ROCrateMetadataFileDescriptor ; + sh:property [ + a sh:PropertyShape ; + sh:name "RO-Crate conforms to 1.2 or later minor version" ; + sh:description "The RO-Crate metadata file descriptor MUST have a `conformsTo` property with RO-Crate specification version 1.2 or later minor version" ; + sh:minCount 1 ; + sh:nodeKind sh:IRI ; + sh:path dct:conformsTo ; + sh:pattern "https://w3id\\.org/ro/crate/(1\\.[2-9](-DRAFT)?)" ; + sh:severity sh:Violation; + sh:message "The RO-Crate metadata file descriptor MUST have a `conformsTo` property with RO-Crate specification version 1.2 or later minor version" ; + ] . + +ro-crate:conformsToROCrateSpec sh:deactivated true . diff --git a/rocrate_validator/profiles/ro-crate/must/1_file-descriptor_metadata.ttl b/rocrate_validator/profiles/ro-crate/must/1_file-descriptor_metadata.ttl index 075f5f21..fee8c135 100644 --- a/rocrate_validator/profiles/ro-crate/must/1_file-descriptor_metadata.ttl +++ b/rocrate_validator/profiles/ro-crate/must/1_file-descriptor_metadata.ttl @@ -89,13 +89,12 @@ ro-crate:ROCrateMetadataFileDescriptorRecommendedProperties a sh:NodeShape ; sh:class schema_org:Dataset ; sh:message "The RO-Crate metadata file descriptor MUST have an `about` property referencing the Root Data Entity" ; ] ; - sh:property [ - a sh:PropertyShape ; - sh:name "Metadata File Descriptor entity: `conformsTo` property" ; - sh:description """Check if the RO-Crate Metadata File Descriptor has a `conformsTo` property which points to the RO-Crate specification version""" ; - sh:minCount 1 ; - sh:nodeKind sh:IRI ; - sh:path dct:conformsTo ; - sh:hasValue ; - sh:message "The RO-Crate metadata file descriptor MUST have a `conformsTo` property with the RO-Crate specification version" ; - ] . + sh:property ro-crate:conformsToROCrateSpec . + +ro-crate:conformsToROCrateSpec sh:name "Metadata File Descriptor entity: `conformsTo` property" ; + sh:description """Check if the RO-Crate Metadata File Descriptor has a `conformsTo` property which points to the RO-Crate specification version""" ; + sh:minCount 1 ; + sh:nodeKind sh:IRI ; + sh:path dct:conformsTo ; + sh:hasValue ; + sh:message "The RO-Crate metadata file descriptor MUST have a `conformsTo` property with the RO-Crate specification version" . diff --git a/tests/data/crates/invalid/five_safes_crate/context_multiple_wrong_version/ro-crate-metadata.json b/tests/data/crates/invalid/five_safes_crate/context_multiple_wrong_version/ro-crate-metadata.json new file mode 100644 index 00000000..79733fa7 --- /dev/null +++ b/tests/data/crates/invalid/five_safes_crate/context_multiple_wrong_version/ro-crate-metadata.json @@ -0,0 +1,169 @@ +{ + "@context": ["https://w3id.org/ro/crate/1.1/context", "http://schema.org", {"test": "http://schema.org/test"}], + "@graph": [ + { + "@type": "CreativeWork", + "@id": "ro-crate-metadata.json", + "about": { + "@id": "./" + }, + "conformsTo": { + "@id": "https://w3id.org/ro/crate/1.2" + } + }, + { + "@id": "./", + "@type": "Dataset", + "name": "5-Safe RO-Crate Request", + "description": "example 5-Safe RO-Crate request metadata for testing", + "license": "Apache-2.0", + "datePublished": "2025-09-20T14:38:00+00:00", + "conformsTo": { + "@id": "https://w3id.org/5s-crate/0.4" + }, + "hasPart": [ + { + "@id": "https://workflowhub.eu/workflows/289?version=1" + }, + { + "@id": "input1.txt" + } + ], + "mainEntity": { + "@id": "https://workflowhub.eu/workflows/289?version=1" + }, + "mentions": { + "@id": "#query-37252371-c937-43bd-a0a7-3680b48c0538" + }, + "sourceOrganization": { + "@id": "#project-be6ffb55-4f5a-4c14-b60e-47e0951090c70" + } + }, + { + "@id": "https://w3id.org/5s-crate/0.4", + "@type": "Profile", + "name": "Five Safes RO-Crate profile" + }, + { + "@id": "https://workflowhub.eu/workflows/289?version=1", + "@type": "Dataset", + "name": "CWL Protein MD Setup tutorial with mutations", + "conformsTo": { + "@id": "https://w3id.org/workflowhub/workflow-ro-crate/1.0" + }, + "distribution": { + "@id": "https://workflowhub.eu/workflows/289/ro_crate?version=1" + } + }, + { + "@id": "https://workflowhub.eu/workflows/289/ro_crate?version=1", + "@type": "DataDownload", + "conformsTo": { + "@id": "https://w3id.org/ro/crate" + }, + "encodingFormat": "application/zip" + }, + { + "@id": "#query-37252371-c937-43bd-a0a7-3680b48c0538", + "@type": "CreateAction", + "actionStatus": "http://schema.org/PotentialActionStatus", + "agent": { + "@id": "https://orcid.org/0000-0001-9842-9718" + }, + "instrument": { + "@id": "https://workflowhub.eu/workflows/289?version=1" + }, + "name": "Execute query 12389 on workflow ", + "object": [ + { + "@id": "input1.txt" + }, + { + "@id": "#enableFastMode" + } + ] + }, + { + "@id": "https://orcid.org/0000-0001-9842-9718", + "@type": "Person", + "name": "Stian Soiland-Reyes", + "affiliation": { + "@id": "https://ror.org/027m9bs27" + }, + "memberOf": [ + { + "@id": "#project-be6ffb55-4f5a-4c14-b60e-47e0951090c70" + } + ] + }, + { + "@id": "https://ror.org/027m9bs27", + "@type": "Organization", + "name": "The University of Manchester" + }, + { + "@id": "https://ror.org/01ee9ar58", + "@type": "Organization", + "name": "University of Nottingham" + }, + { + "@id": "#project-be6ffb55-4f5a-4c14-b60e-47e0951090c70", + "@type": "Project", + "name": "Investigation of cancer (TRE72 project 81)", + "identifier": [ + { + "@id": "_:localid:tre72:project81" + } + ], + "funding": { + "@id": "https://gtr.ukri.org/projects?ref=10038961" + }, + "member": [ + { + "@id": "https://ror.org/027m9bs27" + }, + { + "@id": "https://ror.org/01ee9ar58" + } + ] + }, + { + "@id": "_:localid:tre72:project81", + "@type": "PropertyValue", + "name": "tre72", + "value": "project81" + }, + { + "@id": "https://gtr.ukri.org/projects?ref=10038961", + "@type": "Grant", + "name": "EOSC4Cancer" + }, + { + "@id": "input1.txt", + "@type": "File", + "name": "input1", + "exampleOfWork": { + "@id": "#sequence" + } + }, + { + "@id": "#enableFastMode", + "@type": "PropertyValue", + "name": "--fast-mode", + "value": "True", + "exampleOfWork": { + "@id": "#fast" + } + }, + { + "@id": "#sequence", + "@type": "FormalParameter", + "name": "input-sequence" + }, + { + "@id": "#fast", + "@type": "FormalParameter", + "name": "fast-mode" + } + ] +} diff --git a/tests/data/crates/invalid/five_safes_crate/context_single_wrong_version/ro-crate-metadata.json b/tests/data/crates/invalid/five_safes_crate/context_single_wrong_version/ro-crate-metadata.json new file mode 100644 index 00000000..beba6839 --- /dev/null +++ b/tests/data/crates/invalid/five_safes_crate/context_single_wrong_version/ro-crate-metadata.json @@ -0,0 +1,169 @@ +{ + "@context": "https://w3id.org/ro/crate/1.1/context", + "@graph": [ + { + "@type": "CreativeWork", + "@id": "ro-crate-metadata.json", + "about": { + "@id": "./" + }, + "conformsTo": { + "@id": "https://w3id.org/ro/crate/1.2" + } + }, + { + "@id": "./", + "@type": "Dataset", + "name": "5-Safe RO-Crate Request", + "description": "example 5-Safe RO-Crate request metadata for testing", + "license": "Apache-2.0", + "datePublished": "2025-09-20T14:38:00+00:00", + "conformsTo": { + "@id": "https://w3id.org/5s-crate/0.4" + }, + "hasPart": [ + { + "@id": "https://workflowhub.eu/workflows/289?version=1" + }, + { + "@id": "input1.txt" + } + ], + "mainEntity": { + "@id": "https://workflowhub.eu/workflows/289?version=1" + }, + "mentions": { + "@id": "#query-37252371-c937-43bd-a0a7-3680b48c0538" + }, + "sourceOrganization": { + "@id": "#project-be6ffb55-4f5a-4c14-b60e-47e0951090c70" + } + }, + { + "@id": "https://w3id.org/5s-crate/0.4", + "@type": "Profile", + "name": "Five Safes RO-Crate profile" + }, + { + "@id": "https://workflowhub.eu/workflows/289?version=1", + "@type": "Dataset", + "name": "CWL Protein MD Setup tutorial with mutations", + "conformsTo": { + "@id": "https://w3id.org/workflowhub/workflow-ro-crate/1.0" + }, + "distribution": { + "@id": "https://workflowhub.eu/workflows/289/ro_crate?version=1" + } + }, + { + "@id": "https://workflowhub.eu/workflows/289/ro_crate?version=1", + "@type": "DataDownload", + "conformsTo": { + "@id": "https://w3id.org/ro/crate" + }, + "encodingFormat": "application/zip" + }, + { + "@id": "#query-37252371-c937-43bd-a0a7-3680b48c0538", + "@type": "CreateAction", + "actionStatus": "http://schema.org/PotentialActionStatus", + "agent": { + "@id": "https://orcid.org/0000-0001-9842-9718" + }, + "instrument": { + "@id": "https://workflowhub.eu/workflows/289?version=1" + }, + "name": "Execute query 12389 on workflow ", + "object": [ + { + "@id": "input1.txt" + }, + { + "@id": "#enableFastMode" + } + ] + }, + { + "@id": "https://orcid.org/0000-0001-9842-9718", + "@type": "Person", + "name": "Stian Soiland-Reyes", + "affiliation": { + "@id": "https://ror.org/027m9bs27" + }, + "memberOf": [ + { + "@id": "#project-be6ffb55-4f5a-4c14-b60e-47e0951090c70" + } + ] + }, + { + "@id": "https://ror.org/027m9bs27", + "@type": "Organization", + "name": "The University of Manchester" + }, + { + "@id": "https://ror.org/01ee9ar58", + "@type": "Organization", + "name": "University of Nottingham" + }, + { + "@id": "#project-be6ffb55-4f5a-4c14-b60e-47e0951090c70", + "@type": "Project", + "name": "Investigation of cancer (TRE72 project 81)", + "identifier": [ + { + "@id": "_:localid:tre72:project81" + } + ], + "funding": { + "@id": "https://gtr.ukri.org/projects?ref=10038961" + }, + "member": [ + { + "@id": "https://ror.org/027m9bs27" + }, + { + "@id": "https://ror.org/01ee9ar58" + } + ] + }, + { + "@id": "_:localid:tre72:project81", + "@type": "PropertyValue", + "name": "tre72", + "value": "project81" + }, + { + "@id": "https://gtr.ukri.org/projects?ref=10038961", + "@type": "Grant", + "name": "EOSC4Cancer" + }, + { + "@id": "input1.txt", + "@type": "File", + "name": "input1", + "exampleOfWork": { + "@id": "#sequence" + } + }, + { + "@id": "#enableFastMode", + "@type": "PropertyValue", + "name": "--fast-mode", + "value": "True", + "exampleOfWork": { + "@id": "#fast" + } + }, + { + "@id": "#sequence", + "@type": "FormalParameter", + "name": "input-sequence" + }, + { + "@id": "#fast", + "@type": "FormalParameter", + "name": "fast-mode" + } + ] +} diff --git a/tests/data/crates/valid/five-safes-crate-multiple-context/ro-crate-metadata.json b/tests/data/crates/valid/five-safes-crate-multiple-context/ro-crate-metadata.json new file mode 100644 index 00000000..89813ee6 --- /dev/null +++ b/tests/data/crates/valid/five-safes-crate-multiple-context/ro-crate-metadata.json @@ -0,0 +1,169 @@ +{ + "@context": ["https://w3id.org/ro/crate/1.2/context", "https://w3id.org/ro/terms/workflow-run/context", {"test": "http://schema.org/test"}], + "@graph": [ + { + "@type": "CreativeWork", + "@id": "ro-crate-metadata.json", + "about": { + "@id": "./" + }, + "conformsTo": { + "@id": "https://w3id.org/ro/crate/1.2" + } + }, + { + "@id": "./", + "@type": "Dataset", + "name": "5-Safe RO-Crate Request", + "description": "example 5-Safe RO-Crate request metadata for testing", + "license": "Apache-2.0", + "datePublished": "2025-09-20T14:38:00+00:00", + "conformsTo": { + "@id": "https://w3id.org/5s-crate/0.4" + }, + "hasPart": [ + { + "@id": "https://workflowhub.eu/workflows/289?version=1" + }, + { + "@id": "input1.txt" + } + ], + "mainEntity": { + "@id": "https://workflowhub.eu/workflows/289?version=1" + }, + "mentions": { + "@id": "#query-37252371-c937-43bd-a0a7-3680b48c0538" + }, + "sourceOrganization": { + "@id": "#project-be6ffb55-4f5a-4c14-b60e-47e0951090c70" + } + }, + { + "@id": "https://w3id.org/5s-crate/0.4", + "@type": "Profile", + "name": "Five Safes RO-Crate profile" + }, + { + "@id": "https://workflowhub.eu/workflows/289?version=1", + "@type": "Dataset", + "name": "CWL Protein MD Setup tutorial with mutations", + "conformsTo": { + "@id": "https://w3id.org/workflowhub/workflow-ro-crate/1.0" + }, + "distribution": { + "@id": "https://workflowhub.eu/workflows/289/ro_crate?version=1" + } + }, + { + "@id": "https://workflowhub.eu/workflows/289/ro_crate?version=1", + "@type": "DataDownload", + "conformsTo": { + "@id": "https://w3id.org/ro/crate" + }, + "encodingFormat": "application/zip" + }, + { + "@id": "#query-37252371-c937-43bd-a0a7-3680b48c0538", + "@type": "CreateAction", + "actionStatus": "http://schema.org/PotentialActionStatus", + "agent": { + "@id": "https://orcid.org/0000-0001-9842-9718" + }, + "instrument": { + "@id": "https://workflowhub.eu/workflows/289?version=1" + }, + "name": "Execute query 12389 on workflow ", + "object": [ + { + "@id": "input1.txt" + }, + { + "@id": "#enableFastMode" + } + ] + }, + { + "@id": "https://orcid.org/0000-0001-9842-9718", + "@type": "Person", + "name": "Stian Soiland-Reyes", + "affiliation": { + "@id": "https://ror.org/027m9bs27" + }, + "memberOf": [ + { + "@id": "#project-be6ffb55-4f5a-4c14-b60e-47e0951090c70" + } + ] + }, + { + "@id": "https://ror.org/027m9bs27", + "@type": "Organization", + "name": "The University of Manchester" + }, + { + "@id": "https://ror.org/01ee9ar58", + "@type": "Organization", + "name": "University of Nottingham" + }, + { + "@id": "#project-be6ffb55-4f5a-4c14-b60e-47e0951090c70", + "@type": "Project", + "name": "Investigation of cancer (TRE72 project 81)", + "identifier": [ + { + "@id": "_:localid:tre72:project81" + } + ], + "funding": { + "@id": "https://gtr.ukri.org/projects?ref=10038961" + }, + "member": [ + { + "@id": "https://ror.org/027m9bs27" + }, + { + "@id": "https://ror.org/01ee9ar58" + } + ] + }, + { + "@id": "_:localid:tre72:project81", + "@type": "PropertyValue", + "name": "tre72", + "value": "project81" + }, + { + "@id": "https://gtr.ukri.org/projects?ref=10038961", + "@type": "Grant", + "name": "EOSC4Cancer" + }, + { + "@id": "input1.txt", + "@type": "File", + "name": "input1", + "exampleOfWork": { + "@id": "#sequence" + } + }, + { + "@id": "#enableFastMode", + "@type": "PropertyValue", + "name": "--fast-mode", + "value": "True", + "exampleOfWork": { + "@id": "#fast" + } + }, + { + "@id": "#sequence", + "@type": "FormalParameter", + "name": "input-sequence" + }, + { + "@id": "#fast", + "@type": "FormalParameter", + "name": "fast-mode" + } + ] +} diff --git a/tests/data/crates/valid/five-safes-crate-request/ro-crate-metadata.json b/tests/data/crates/valid/five-safes-crate-request/ro-crate-metadata.json index 73285401..a53902d4 100644 --- a/tests/data/crates/valid/five-safes-crate-request/ro-crate-metadata.json +++ b/tests/data/crates/valid/five-safes-crate-request/ro-crate-metadata.json @@ -1,5 +1,5 @@ { - "@context": "https://w3id.org/ro/crate/1.1/context", + "@context": "https://w3id.org/ro/crate/1.2/context", "@graph": [ { "@type": "CreativeWork", @@ -8,7 +8,7 @@ "@id": "./" }, "conformsTo": { - "@id": "https://w3id.org/ro/crate/1.1" + "@id": "https://w3id.org/ro/crate/1.2" } }, { @@ -166,4 +166,4 @@ "name": "fast-mode" } ] -} \ No newline at end of file +} diff --git a/tests/data/crates/valid/five-safes-crate-result/ro-crate-metadata.json b/tests/data/crates/valid/five-safes-crate-result/ro-crate-metadata.json index e4aa7f03..38e74f08 100644 --- a/tests/data/crates/valid/five-safes-crate-result/ro-crate-metadata.json +++ b/tests/data/crates/valid/five-safes-crate-result/ro-crate-metadata.json @@ -1,5 +1,5 @@ { - "@context": "https://w3id.org/ro/crate/1.1/context", + "@context": "https://w3id.org/ro/crate/1.2/context", "@graph": [ { "@type": "CreativeWork", @@ -8,7 +8,7 @@ "@id": "./" }, "conformsTo": { - "@id": "https://w3id.org/ro/crate/1.1" + "@id": "https://w3id.org/ro/crate/1.2" } }, { @@ -406,4 +406,4 @@ "name": "sha-512 algorithm" } ] -} \ No newline at end of file +} diff --git a/tests/integration/profiles/five-safes-crate/test_5src_15_metadata_file.py b/tests/integration/profiles/five-safes-crate/test_5src_15_metadata_file.py new file mode 100644 index 00000000..52cdce45 --- /dev/null +++ b/tests/integration/profiles/five-safes-crate/test_5src_15_metadata_file.py @@ -0,0 +1,86 @@ +# Copyright (c) 2024-2025 CRS4 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging + +from rocrate_validator.models import Severity +from tests.ro_crates import ValidROC, Invalid5sROC +from tests.shared import do_entity_test, SPARQL_PREFIXES + +# set up logging +logger = logging.getLogger(__name__) + + +# ----- MUST fails tests + + +def test_5src_conforms_to_old_version(): + sparql = ( + SPARQL_PREFIXES + + """ + DELETE { + ?this dct:conformsTo ?version . + } + INSERT { + ?this dct:conformsTo . + } + WHERE { + ?this dct:conformsTo ?version ; + schema:about <./> . + } + """ + ) + + do_entity_test( + rocrate_path=ValidROC().five_safes_crate_request, + requirement_severity=Severity.REQUIRED, + expected_validation_result=False, + expected_triggered_requirements=[ + "RO-Crate conforms to 1.2 or later minor version" + ], + expected_triggered_issues=[ + "The RO-Crate metadata file descriptor MUST have a `conformsTo` property with " + "RO-Crate specification version 1.2 or later minor version" + ], + profile_identifier="five-safes-crate", + rocrate_entity_mod_sparql=sparql, + ) + + +def test_5src_context_single_wrong_version(): + do_entity_test( + rocrate_path=Invalid5sROC().context_single_wrong_version, + requirement_severity=Severity.REQUIRED, + expected_validation_result=False, + expected_triggered_requirements=["RO-Crate context version"], + expected_triggered_issues=[ + "The RO-Crate metadata file MUST include the RO-Crate context version 1.2 " + "(or later minor version) in `@context`" + ], + profile_identifier="five-safes-crate", + ) + + +def test_5src_context_multiple_wrong_version(): + do_entity_test( + rocrate_path=Invalid5sROC().context_multiple_wrong_version, + requirement_severity=Severity.REQUIRED, + expected_validation_result=False, + expected_triggered_requirements=["RO-Crate context version"], + expected_triggered_issues=[ + "The RO-Crate metadata file MUST include the RO-Crate context version 1.2 " + "(or later minor version) in `@context`" + ], + profile_identifier="five-safes-crate", + ) diff --git a/tests/integration/profiles/five-safes-crate/test_valid_5src.py b/tests/integration/profiles/five-safes-crate/test_valid_5src.py index cfc5aa53..7de8c869 100644 --- a/tests/integration/profiles/five-safes-crate/test_valid_5src.py +++ b/tests/integration/profiles/five-safes-crate/test_valid_5src.py @@ -30,7 +30,9 @@ def test_valid_five_safes_crate_request_required(): Severity.REQUIRED, True, profile_identifier="five-safes-crate", - skip_checks=[SKIP_LOCAL_DATA_ENTITY_EXISTENCE_CHECK_IDENTIFIER], + skip_checks=[ + SKIP_LOCAL_DATA_ENTITY_EXISTENCE_CHECK_IDENTIFIER, + ], ) @@ -41,5 +43,20 @@ def test_valid_five_safes_crate_result_required(): Severity.REQUIRED, True, profile_identifier="five-safes-crate", - skip_checks=[SKIP_LOCAL_DATA_ENTITY_EXISTENCE_CHECK_IDENTIFIER], + skip_checks=[ + SKIP_LOCAL_DATA_ENTITY_EXISTENCE_CHECK_IDENTIFIER, + ], + ) + + +def test_valid_five_safes_crate_multiple_context(): + """Test a valid Five Safes Crate representing a result.""" + do_entity_test( + ValidROC().five_safes_crate_multiple_context, + Severity.REQUIRED, + True, + profile_identifier="five-safes-crate", + skip_checks=[ + SKIP_LOCAL_DATA_ENTITY_EXISTENCE_CHECK_IDENTIFIER, + ], ) diff --git a/tests/ro_crates.py b/tests/ro_crates.py index 53f77259..b78d9880 100644 --- a/tests/ro_crates.py +++ b/tests/ro_crates.py @@ -99,6 +99,10 @@ def five_safes_crate_request(self) -> Path: def five_safes_crate_result(self) -> Path: return VALID_CRATES_DATA_PATH / "five-safes-crate-result" + @property + def five_safes_crate_multiple_context(self) -> Path: + return VALID_CRATES_DATA_PATH / "five-safes-crate-multiple-context" + class InvalidFileDescriptor: @@ -980,19 +984,15 @@ def propertyvalue_no_unitcode(self) -> Path: class Invalid5sROC: - base_path = INVALID_CRATES_DATA_PATH / "6_five_safes_crate/" - - @property - def funding_project_no_name(self) -> Path: - return self.base_path / "funding_project_no_name" + base_path = INVALID_CRATES_DATA_PATH / "five_safes_crate/" @property - def root_data_entity_no_source_organization(self) -> Path: - return self.base_path / "root_data_entity_no_source_organization" + def context_multiple_wrong_version(self) -> Path: + return self.base_path / "context_multiple_wrong_version" @property - def root_data_entity_source_organization_not_entity(self) -> Path: - return self.base_path / "root_data_entity_source_organization_not_entity" + def context_single_wrong_version(self) -> Path: + return self.base_path / "context_single_wrong_version" class InvalidMultiProfileROC: diff --git a/tests/shared.py b/tests/shared.py index b82d4ade..7a9dca32 100644 --- a/tests/shared.py +++ b/tests/shared.py @@ -36,6 +36,7 @@ SPARQL_PREFIXES = """ PREFIX schema: +PREFIX dct: PREFIX shp: PREFIX rdf: """