diff --git a/rocrate_validator/profiles/five-safes-crate/must/1_funder.ttl b/rocrate_validator/profiles/five-safes-crate/must/1_funder.ttl new file mode 100644 index 00000000..247faa90 --- /dev/null +++ b/rocrate_validator/profiles/five-safes-crate/must/1_funder.ttl @@ -0,0 +1,35 @@ +# 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. + +@prefix ro: <./> . +@prefix ro-crate: . +@prefix five-safes-crate: . +@prefix schema_org: . +@prefix sh: . +@prefix bioschemas: . + +five-safes-crate:FundingBody a sh:NodeShape ; + sh:name "Funding body Project" ; + sh:description "Project which is funding this work" ; + sh:targetClass schema_org:Project ; + sh:property [ + a sh:PropertyShape ; + sh:name "Project Name" ; + sh:description """Check if the Project Entity `name` (as specified by schema.org) + to clearly identify the dataset and distinguish it from other projects.""" ; + sh:minCount 1 ; + sh:nodeKind sh:Literal ; + sh:path schema_org:name; + sh:message "The Project Entity MUST have a `name` property (as specified by schema.org)" ; + ] . diff --git a/rocrate_validator/profiles/five-safes-crate/must/1_root_data_entity_metadata.ttl b/rocrate_validator/profiles/five-safes-crate/must/1_root_data_entity_metadata.ttl new file mode 100644 index 00000000..645f5dd0 --- /dev/null +++ b/rocrate_validator/profiles/five-safes-crate/must/1_root_data_entity_metadata.ttl @@ -0,0 +1,39 @@ +# 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. + +@prefix ro: <./> . +@prefix ro-crate: . +@prefix five-safes-crate: . +@prefix rdf: . +@prefix schema_org: . +@prefix sh: . +@prefix validator: . +@prefix xsd: . + + +five-safes-crate:RootDataEntityRequiredProperties + a sh:NodeShape ; + sh:name "Five Safes Crate Root Data Entity REQUIRED properties" ; + sh:description "The Root Data Entity MUST have a `sourceOrganisation`" ; + sh:targetClass ro-crate:RootDataEntity ; + sh:property [ + a sh:PropertyShape ; + sh:name "Root Data Entity: `sourceOrganization` property" ; + sh:description """Check if the Root Data Entity includes a `sourceOrganization` (as specified by schema.org).""" ; + sh:path schema_org:sourceOrganization; + sh:minCount 1 ; + sh:class ro-crate:ContextualEntity ; + sh:message """The Root Data Entity MUST have a `sourceOrganization` property (as specified by schema.org). + SHOULD link to a Contextual Entity in the RO-Crate Metadata File with a name.""" ; + ] . diff --git a/rocrate_validator/profiles/five-safes-crate/must/2_requesting_agent.ttl b/rocrate_validator/profiles/five-safes-crate/must/2_requesting_agent.ttl new file mode 100644 index 00000000..71b4fe1b --- /dev/null +++ b/rocrate_validator/profiles/five-safes-crate/must/2_requesting_agent.ttl @@ -0,0 +1,63 @@ +# 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: <./> . +@prefix ro-crate: . +@prefix five-safes-crate: . +@prefix rdf: . +@prefix schema: . +@prefix sh: . +@prefix validator: . +@prefix xsd: . + + + +five-safes-crate:CreateActionHasAgent + a sh:NodeShape ; + sh:name "CreateAction" ; + sh:targetClass schema:CreateAction ; + sh:description "Checks that a CreateAction has an agent and that each agent is a schema:Person." ; + + # CreateAction entity MUST have an agent (IRI) + sh:property [ + a sh:PropertyShape ; + sh:name "Has Agent" ; + sh:path schema:agent ; + sh:minCount 1 ; + sh:nodeKind sh:IRI ; + sh:severity sh:Violation ; + sh:message "CreateAction MUST have at least one schema:agent that is an IRI." ; + ] ; + + # The agent of a CreateAction entity MUST be a Person + sh:property [ + a sh:PropertyShape ; + sh:name "Agent is a Person" ; + sh:path schema:agent ; + sh:nodeKind sh:IRI ; + sh:class schema:Person ; + sh:severity sh:Violation ; + sh:message "Each CreateAction agent MUST be typed as schema:Person and be an IRI." ; + ] ; + + # If any agent affiliation exists, it MUST be an Organization (IRI) + sh:property [ + a sh:PropertyShape ; + sh:name "Affiliation is an Organization" ; + sh:path ( schema:agent schema:affiliation ) ; + sh:class schema:Organization ; + sh:nodeKind sh:IRI ; + sh:severity sh:Violation ; + sh:message "The affiliation (if any) of a CreateAction's agent MUST be a schema:Organization and be an IRI." ; + ] . \ No newline at end of file diff --git a/rocrate_validator/profiles/five-safes-crate/profile.ttl b/rocrate_validator/profiles/five-safes-crate/profile.ttl new file mode 100644 index 00000000..75946bfe --- /dev/null +++ b/rocrate_validator/profiles/five-safes-crate/profile.ttl @@ -0,0 +1,81 @@ +# Copyright (c) 2024-2025 CRS4, 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 dct: . +@prefix prof: . +@prefix role: . +@prefix rdfs: . + + + a prof:Profile ; + + # the Profile's label + rdfs:label "Five Safes RO-Crate 0.4" ; + + # regular metadata, a basic description of the Profile + rdfs:comment """Five Safes RO-Crate Metadata Specification 0.4"""@en ; + + # URI of the publisher of the Metadata Specification + dct:publisher ; + + # This profile is an extension of Workflow Run Crate for use in Trusted Research Environments (TRE) + prof:isProfileOf ; + + # This profile is a transitive profile of the RO-Crate Metadata Specification + prof:isTransitiveProfileOf , + , + ; + + # this profile has a JSON-LD context resource + prof:hasResource [ + a prof:ResourceDescriptor ; + + # it's in JSON-LD format + dct:format ; + + # it conforms to JSON-LD, here refered to by its namespace URI as a Profile + dct:conformsTo ; + + # this profile resource plays the role of "Vocabulary" + # described in this ontology's accompanying Roles vocabulary + prof:hasRole role:Vocabulary ; + + # this profile resource's actual file + prof:hasArtifact ; + ] ; + + # this profile has a human-readable documentation resource + prof:hasResource [ + a prof:ResourceDescriptor ; + + # it's in HTML format + dct:format ; + + # it conforms to HTML, here refered to by its namespace URI as a Profile + dct:conformsTo ; + + # this profile resource plays the role of "Specification" + # described in this ontology's accompanying Roles vocabulary + prof:hasRole role:Specification ; + + # this profile resource's actual file + prof:hasArtifact ; + + # this profile is inherited from Workflow Run profile + prof:isInheritedFrom ; + ] ; + + # a short code to refer to the Profile with when a URI can't be used + prof:hasToken "five-safes-crate" ; +. diff --git a/rocrate_validator/profiles/five-safes-crate/should/2_requesting_agent.ttl b/rocrate_validator/profiles/five-safes-crate/should/2_requesting_agent.ttl new file mode 100644 index 00000000..8aee0a20 --- /dev/null +++ b/rocrate_validator/profiles/five-safes-crate/should/2_requesting_agent.ttl @@ -0,0 +1,64 @@ +# 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: <./> . +@prefix ro-crate: . +@prefix five-safes-crate: . +@prefix rdf: . +@prefix schema: . +@prefix sh: . +@prefix validator: . +@prefix xsd: . + + +# Person who is the agent of a CreateAction SHOULD have an affiliation +five-safes-crate:PersonAgentHasAffiliation + a sh:NodeShape ; + sh:name "Agent of CreateAction" ; + sh:description "The agent of a CreateAction entity" ; + sh:target [ + a sh:SPARQLTarget ; + sh:prefixes ro-crate:sparqlPrefixes ; + sh:select """ + SELECT DISTINCT ?this WHERE { + ?action a schema:CreateAction ; + schema:agent ?this . + } + """ + ] ; + + # The agent of a CreateAction entity SHOULD have an affiliation + sh:property [ + a sh:PropertyShape ; + sh:name "Presence of affiliations" ; + sh:path schema:affiliation ; + sh:minCount 1 ; + sh:severity sh:Warning ; + sh:message "The agent of a CreateAction entity SHOULD have an affiliation" ; + ] ; + + # If the agent has an affiliation, validate the affiliation node's IRI + sh:property [ + a sh:PropertyShape ; + sh:name "Affiliation IRI" ; + sh:path schema:affiliation ; + sh:nodeKind sh:IRI ; + sh:or ( + [ sh:pattern "^https://ror\\.org/0[0-9a-hjkmnp-tv-z]{6}[0-9]{2}$" ; sh:flags "i"] + [ sh:pattern "^https://isni\\.org/isni/\\d{15}[\\dX]$" ; sh:flags "i"] + [ sh:pattern "^https://(?:www\\.)?wikidata\\.org/entity/Q\\d+$" ; sh:flags "i"] + ) ; + sh:severity sh:Warning ; + sh:message "Affiliation Organization @id SHOULD be a permalink (ROR/ISNI/Wikidata)." ; + ] . \ No newline at end of file diff --git a/rocrate_validator/profiles/five-safes-crate/should/5_profile_conformance.ttl b/rocrate_validator/profiles/five-safes-crate/should/5_profile_conformance.ttl new file mode 100644 index 00000000..ea2a4fd8 --- /dev/null +++ b/rocrate_validator/profiles/five-safes-crate/should/5_profile_conformance.ttl @@ -0,0 +1,81 @@ +# 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: <./> . +@prefix ro-crate: . +@prefix five-safes-crate: . +@prefix rdf: . +@prefix schema: . +@prefix sh: . +@prefix validator: . +@prefix xsd: . + +# Root Dataset SHOULD declare conformsTo Five Safes profile +five-safes-crate:RootDatasetConformsToFiveSafes + a sh:NodeShape ; + sh:name "Root Dataset Five Safes RO-Crate profile conformance" ; + sh:description "The Root Data Entity (./) SHOULD declare conformsTo the Five Safes RO-Crate profile." ; + sh:targetNode ro: ; + sh:property [ + a sh:PropertyShape ; + sh:name "conformsTo Five Safes profile" ; + sh:description "Root Dataset SHOULD include schema:conformsTo https://w3id.org/5s-crate/0.4" ; + sh:path schema:conformsTo ; + sh:qualifiedValueShape [ + sh:hasValue + ] ; + sh:qualifiedMinCount 1 ; + sh:severity sh:Warning ; + sh:message "Profile Conformance: Root Dataset SHOULD include schema:conformsTo with @id https://w3id.org/5s-crate/0.4" ; + ] . + +five-safes-crate:RootDatasetDatePublishedWhenPublished + a sh:NodeShape ; + sh:name "datePublished present on published crates" ; + sh:description "If the root dataset is published (has schema:publisher), it SHOULD have schema:datePublished." ; + sh:targetNode ro: ; + sh:severity sh:Warning ; + sh:message "Published crates SHOULD include schema:datePublished." ; + sh:or ( + # datePublished not required if no publisher: + [ sh:not [ sh:property [ + sh:path schema:publisher ; + sh:minCount 1 ; + ]]] + # datePublished required if publisher present: + [ sh:property [ + sh:path schema:datePublished ; + sh:minCount 1 ; + ]] + ) . + +five-safes-crate:RootDatasetLicenseWhenPublished + a sh:NodeShape ; + sh:name "License present on published crates" ; + sh:description "If the root dataset is published (has schema:publisher), it SHOULD declare a license." ; + sh:targetNode ro: ; + sh:severity sh:Warning ; + sh:message "Profile Conformance: Published crates SHOULD include a license." ; + sh:or ( + # license not required if no publisher: + [ sh:not [ sh:property [ + sh:path schema:publisher ; + sh:minCount 1 ; + ]]] + # license required if publisher present: + [ sh:property [ + sh:path schema:license ; + sh:minCount 1 ; + ]] + ) . \ No newline at end of file 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 new file mode 100644 index 00000000..9fb0d7bf --- /dev/null +++ b/tests/data/crates/valid/five-safes-crate-request/ro-crate-metadata.json @@ -0,0 +1,164 @@ +{ + "@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.1" + } + }, + { + "@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": "#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" + } + ] +} \ 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 new file mode 100644 index 00000000..a6475f63 --- /dev/null +++ b/tests/data/crates/valid/five-safes-crate-result/ro-crate-metadata.json @@ -0,0 +1,401 @@ +{ + "@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.1" + } + }, + { + "@id": "./", + "@type": "Dataset", + "name": "5-Safe RO-Crate Result", + "description": "example 5-Safe RO-Crate result metadata for testing", + "datePublished": "2025-09-20T14:45:00+00:00", + "conformsTo": { + "@id": "https://w3id.org/5s-crate/0.4" + }, + "hasPart": [ + { + "@id": "https://workflowhub.eu/workflows/289?version=1" + }, + { + "@id": "input1.txt" + }, + { + "@id": "outputs/qa.csv" + }, + { + "@id": "outputs/diagrams/" + }, + { + "@id": "workflow/289/" + } + ], + "mainEntity": { + "@id": "https://workflowhub.eu/workflows/289?version=1" + }, + "mentions": [ + { + "@id": "#query-37252371-c937-43bd-a0a7-3680b48c0538" + }, + { + "@id": "#check-f33fe90c-0c22-4c72-b299-de509028410e" + }, + { + "@id": "#validate-1146f640-819e-4c86-b029-b763a0040896" + }, + { + "@id": "#download-8b51bf57-6b29-44da-b24b-638c8df91639" + }, + { + "@id": "#signoff-3b741265-cfef-49ea-8138-a2fa149bf2f0" + }, + { + "@id": "#disclosure-b16c1f0a-ae7f-4582-9b28-7d9df3313e27" + }, + { + "@id": "#bagit-ce785c0b-c988-4043-8cbd-1489dcebc14f" + } + ], + "sourceOrganization": { + "@id": "#project-be6ffb55-4f5a-4c14-b60e-47e0951090c70" + }, + "publisher": { + "@id": "https://tre72.example.com/" + }, + "license": { + "@id": "http://spdx.org/licenses/CC-BY-4.0" + } + }, + { + "@id": "https://w3id.org/5s-crate/0.4", + "@type": "Profile", + "name": "Five Safes RO-Crate profile" + }, + { + "@id": "https://spdx.org/licenses/CC-BY-4.0", + "@type": "CreativeWork", + "name": "Creative Commons Attribution 4.0 International", + "identifier": "CC-BY-4.0" + }, + { + "@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/CompleteActionStatus", + "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" + } + ], + "result": [ + { + "@id": "outputs/qa.csv" + }, + { + "@id": "outputs/diagrams/" + }, + { + "@id": "urn:uuid:07b81e0f-7ac4-5428-9940-878b241e2397" + } + ] + }, + { + "@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": "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" + }, + { + "@id": "outputs/qa.csv", + "@type": "File", + "encodingFormat": "text/csv", + "name": "Tabular listing of quality assessment" + }, + { + "@id": "outputs/diagrams/", + "@type": "Dataset", + "name": "Diagrams of regions of interest" + }, + { + "@id": "workflow/289/", + "sameAs": { + "@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": "#check-f33fe90c-0c22-4c72-b299-de509028410e", + "@type": "AssessAction", + "additionalType": { + "@id": "https://w3id.org/shp#CheckValue" + }, + "name": "BagIt checksum of Crate: OK", + "endTime": "2023-04-18T12:11:45+01:00", + "object": { + "@id": "./" + }, + "instrument": { + "@id": "https://www.iana.org/assignments/named-information#sha-512" + }, + "agent": { + "@id": "#validator-a4a66c63-2fe0-4c57-830d-268a40718313" + }, + "actionStatus": "http://schema.org/CompletedActionStatus" + }, + { + "@id": "#validate-1146f640-819e-4c86-b029-b763a0040896", + "@type": "AssessAction", + "additionalType": { + "@id": "https://w3id.org/shp#ValidationCheck" + }, + "name": "Validation against Five Safes RO-Crate profile: approved", + "startTime": "2023-04-18T12:11:46+01:00", + "endTime": "2023-04-18T12:11:49+01:00", + "object": { + "@id": "./" + }, + "instrument": { + "@id": "https://w3id.org/5s-crate/0.4" + }, + "agent": { + "@id": "#validator-a4a66c63-2fe0-4c57-830d-268a40718313" + }, + "actionStatus": "http://schema.org/CompletedActionStatus" + }, + { + "@id": "#download-8b51bf57-6b29-44da-b24b-638c8df91639", + "@type": "DownloadAction", + "name": "Downloaded workflow RO-Crate via proxy", + "startTime": "2023-04-18T12:11:50+01:00", + "endTime": "2023-04-18T12:11:52+01:00", + "object": { + "@id": "https://workflowhub.eu/workflows/289/ro_crate?version=1" + }, + "result": { + "@id": "workflow/289/" + }, + "agent": { + "@id": "http://proxy.example.com/" + }, + "actionStatus": "http://schema.org/CompletedActionStatus" + }, + { + "@id": "#signoff-3b741265-cfef-49ea-8138-a2fa149bf2f0", + "@type": "AssessAction", + "additionalType": { + "@id": "https://w3id.org/shp#SignOff" + }, + "name": "Sign-off of execution according to Agreement policy: approved", + "endTime": "2023-04-19T17:15:12+01:00", + "object": [ + { + "@id": "./" + }, + { + "@id": "https://workflowhub.eu/workflows/289?version=1" + }, + { + "@id": "#project-be6ffb55-4f5a-4c14-b60e-47e0951090c70" + } + ], + "instrument": { + "@id": "https://tre72.example.com/agreement-policy/81" + }, + "agent": { + "@id": "https://orcid.org/0000-0002-1825-0097" + }, + "actionStatus": "http://schema.org/CompletedActionStatus" + }, + { + "@id": "#disclosure-b16c1f0a-ae7f-4582-9b28-7d9df3313e27", + "@type": "AssessAction", + "additionalType": { + "@id": "https://w3id.org/shp#DisclosureCheck" + }, + "name": "Disclosure check of workflow results: approved", + "endTime": "2023-04-25T16:00:00+01:00", + "object": { + "@id": "./" + }, + "agent": { + "@id": "https://orcid.org/0000-0002-1825-0097" + }, + "actionStatus": "http://schema.org/CompletedActionStatus" + }, + { + "@id": "#bagit-ce785c0b-c988-4043-8cbd-1489dcebc14f", + "@type": "UpdateAction", + "startTime": "2023-04-29T12:12:25+01:00", + "additionalType": { + "@id": "https://w3id.org/shp#GenerateCheckValue" + }, + "name": "BagIt manifests of Crate updated", + "object": { + "@id": "./" + }, + "instrument": { + "@id": "https://www.iana.org/assignments/named-information#sha-512" + }, + "agent": { + "@id": "#validator-a4a66c63-2fe0-4c57-830d-268a40718313" + }, + "actionStatus": "http://schema.org/CompletedActionStatus" + }, + { + "@id": "urn:uuid:07b81e0f-7ac4-5428-9940-878b241e2397", + "@type": "DigitalDocument", + "encodingFormat": "text/csv", + "name": "Patient measurement 07b81e0f-7ac4-5428-9940-878b241e2397", + "hasDigitalDocumentPermission": { + "@id": "#permissions-07b81e0f" + } + }, + { + "@id": "#permissions-07b81e0f", + "@type": "DigitalDocumentPermission", + "permissionType": "http://schema.org/ReadPermission", + "grantee": { + "@id": "#project-be6ffb55-4f5a-4c14-b60e-47e0951090c70" + } + }, + { + "@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://gtr.ukri.org/projects?ref=10038961", + "@type": "Grant", + "name": "EOSC4Cancer" + }, + { + "@id": "https://tre72.example.com/", + "@type": "Organization", + "name": "TRE 72 trusted research environment at The University of Manchester", + "parentOrganization": { + "@id": "https://ror.org/027m9bs27" + } + }, + { + "@id": "https://tre72.example.com/#crate-validator", + "@type": "SoftwareApplication", + "name": "RO-Crate validator at TRE72", + "provider": { + "@id": "https://tre72.example.com/" + } + }, + { + "@id": "https://tre72.example.com/agreement-policy/81", + "@type": "CreativeWork", + "name": "Agreement policy for TRE72 for project 81" + }, + { + "@id": "https://www.iana.org/assignments/named-information#sha-512", + "@type": "DefinedTerm", + "name": "sha-512 algorithm" + } + ] +} \ No newline at end of file diff --git a/tests/data/crates/valid/five-safes-profile-crate/ro-crate-metadata.json b/tests/data/crates/valid/five-safes-profile-crate/ro-crate-metadata.json new file mode 100644 index 00000000..5ca7ea11 --- /dev/null +++ b/tests/data/crates/valid/five-safes-profile-crate/ro-crate-metadata.json @@ -0,0 +1,461 @@ +{ + "@context": "https://w3id.org/ro/crate/1.1/context", + "@graph": [ + { + "@type": "CreativeWork", + "@id": "ro-crate-metadata.json", + "about": { + "@id": "https://w3id.org/5s-crate/0.4" + }, + "licence": { + "@id": "http://spdx.org/licenses/CC0-1.0" + }, + "conformsTo": { + "@id": "https://w3id.org/ro/crate/1.1" + } + }, + { + "@id": "https://w3id.org/5s-crate/0.4", + "@type": [ + "Dataset", + "Profile" + ], + "name": "Five Safes RO-Crate profile", + "cite-as": "https://w3id.org/5s-crate/0.4", + "version": "0.4", + "datePublished": "2023-05-15T10:32:00Z", + "licence": { + "@id": "http://spdx.org/licenses/MIT" + }, + "copyrightHolder": { + "@id": "https://ror.org/027m9bs27" + }, + "copyrightYear": 2023, + "hasPart": [ + { + "@id": "https://trefx.uk/5s-crate/0.4/index.html" + }, + { + "@id": "https://trefx.uk/5s-crate/0.4/example-request.bagit.zip" + }, + { + "@id": "https://trefx.uk/5s-crate/0.4/example-request/data/" + }, + { + "@id": "https://trefx.uk/5s-crate/0.4/example-result.bagit.zip" + }, + { + "@id": "https://trefx.uk/5s-crate/0.4/example-result/data/" + }, + { + "@id": "http://schema.org/PotentialActionStatus" + }, + { + "@id": "http://schema.org/CompletedActionStatus" + }, + { + "@id": "http://schema.org/ActiveActionStatus" + }, + { + "@id": "http://schema.org/FailedActionStatus" + }, + { + "@id": "http://schema.org/CreateAction" + }, + { + "@id": "http://schema.org/AssessAction" + }, + { + "@id": "http://schema.org/DownloadAction" + }, + { + "@id": "http://schema.org/UpdateAction" + }, + { + "@id": "http://schema.org/grantee" + }, + { + "@id": "http://schema.org/DigitalDocument" + }, + { + "@id": "http://schema.org/DigitalDocumentPermission" + }, + { + "@id": "http://schema.org/hasDigitalDocumentPermission" + }, + { + "@id": "http://schema.org/ReadPermission" + }, + { + "@id": "https://bioschemas.org/FormalParameter" + }, + { + "@id": "https://w3id.org/shp#CheckValue" + }, + { + "@id": "https://w3id.org/shp#ValidationCheck" + }, + { + "@id": "https://w3id.org/shp#SignOff" + }, + { + "@id": "https://w3id.org/shp#DisclosureCheck" + }, + { + "@id": "https://w3id.org/shp#GenerateCheckValue" + } + ], + "hasResource": [ + { + "@id": "#hasSpecification" + }, + { + "@id": "#hasExampleRequest" + }, + { + "@id": "#hasExampleResult" + }, + { + "@id": "#usesSHP" + } + ], + "publisher": { + "@id": "https://trefx.uk/" + }, + "funding": { + "@id": "https://gtr.ukri.org/projects?ref=MC_PC_23007" + }, + "author": [ + { + "@id": "https://orcid.org/0000-0001-9842-9718" + }, + { + "@id": "https://orcid.org/0009-0003-2419-1964" + } + ] + }, + { + "@id": "https://trefx.uk/5s-crate/0.4/index.html", + "@type": "CreativeWork", + "name": "Five Safes RO-Crate profile (specification)" + }, + { + "@id": "https://trefx.uk/5s-crate/0.4/example-request/data/", + "@type": "Dataset", + "name": "Example Crate in Request state", + "conformsTo": { + "@id": "https://w3id.org/5s-crate/0.4" + }, + "subjectOf": [ + { + "@id": "https://trefx.uk/5s-crate/0.4/example-request/data/ro-crate-metadata.json" + }, + { + "@id": "https://trefx.uk/5s-crate/0.4/example-request/data/ro-crate-preview.html" + } + ], + "distribution": { + "@id": "https://trefx.uk/5s-crate/0.4/example-request.bagit.zip" + } + }, + { + "@id": "https://trefx.uk/5s-crate/0.4/example-result/data/", + "@type": "Dataset", + "name": "Example Crate in Request state", + "conformsTo": { + "@id": "https://w3id.org/5s-crate/0.4" + }, + "subjectOf": [ + { + "@id": "https://trefx.uk/5s-crate/0.4/example-result/data/ro-crate-metadata.json" + }, + { + "@id": "https://trefx.uk/5s-crate/0.4/example-result/data/ro-crate-preview.html" + } + ], + "distribution": { + "@id": "https://trefx.uk/5s-crate/0.4/example-result.bagit.zip" + } + }, + { + "@id": "https://trefx.uk/5s-crate/0.4/example-result.bagit.zip", + "@type": "DataDownload", + "name": "example-result.bagit.zip", + "description": "Example Result following the 5s-crate profile, archived as BagIt ZIP", + "encodingFormat": "application/zip", + "conformsTo": { + "@id": "https://w3id.org/ro/crate" + } + }, + { + "@id": "https://trefx.uk/5s-crate/0.4/example-request.bagit.zip", + "@type": "DataDownload", + "name": "example-request.bagit.zip", + "description": "Example Request following the 5s-crate profile, archived as BagIt ZIP", + "encodingFormat": "application/zip", + "conformsTo": { + "@id": "https://w3id.org/ro/crate" + } + }, + { + "@id": "https://trefx.uk/5s-crate/0.4/example-request/data/ro-crate-metadata.json", + "@type": "CreativeWork", + "encodingFormat": "application/ld+json" + }, + { + "@id": "https://trefx.uk/5s-crate/0.4/example-request/data/ro-crate-preview.html", + "@type": "CreativeWork", + "encodingFormat": "text/html" + }, + { + "@id": "https://trefx.uk/5s-crate/0.4/example-result/data/ro-crate-metadata.json", + "@type": "CreativeWork", + "encodingFormat": "application/ld+json" + }, + { + "@id": "https://trefx.uk/5s-crate/0.4/example-result/data/ro-crate-preview.html", + "@type": "CreativeWork", + "encodingFormat": "text/html" + }, + { + "@id": "https://bioschemas.org/FormalParameter", + "@type": "DefinedTerm" + }, + { + "@id": "https://w3id.org/shp", + "@type": "DefinedTermSet", + "name": "The Safe Haven Provenance (SHP) Ontology", + "version": "0.1" + }, + { + "@id": "https://w3id.org/shp#CheckValue", + "@type": "DefinedTerm", + "inDefinedTermSet": { + "@id": "https://w3id.org/shp" + } + }, + { + "@id": "https://w3id.org/shp#ValidationCheck", + "@type": "DefinedTerm", + "inDefinedTermSet": { + "@id": "https://w3id.org/shp" + } + }, + { + "@id": "https://w3id.org/shp#SignOff", + "@type": "DefinedTerm", + "inDefinedTermSet": { + "@id": "https://w3id.org/shp" + } + }, + { + "@id": "https://w3id.org/shp#DisclosureCheck", + "@type": "DefinedTerm", + "inDefinedTermSet": { + "@id": "https://w3id.org/shp" + } + }, + { + "@id": "https://w3id.org/shp#GenerateCheckValue", + "@type": "DefinedTerm", + "inDefinedTermSet": { + "@id": "https://w3id.org/shp" + } + }, + { + "@id": "https://w3id.org/shp#CheckValue", + "@type": "DefinedTerm", + "inDefinedTermSet": { + "@id": "https://w3id.org/shp" + } + }, + { + "@id": "https://w3id.org/shp#ValidationCheck", + "@type": "DefinedTerm", + "inDefinedTermSet": { + "@id": "https://w3id.org/shp" + } + }, + { + "@id": "https://w3id.org/shp#SignOff", + "@type": "DefinedTerm", + "inDefinedTermSet": { + "@id": "https://w3id.org/shp" + } + }, + { + "@id": "https://w3id.org/shp#DisclosureCheck", + "@type": "DefinedTerm", + "inDefinedTermSet": { + "@id": "https://w3id.org/shp" + } + }, + { + "@id": "https://w3id.org/shp#GenerateCheckValue", + "@type": "DefinedTerm", + "inDefinedTermSet": { + "@id": "https://w3id.org/shp" + } + }, + { + "@id": "https://www.iana.org/assignments/named-information#sha-512", + "@type": "DefinedTerm", + "name": "sha-512 algorithm" + }, + { + "@id": "#usesSHP", + "name": "uses vocabulary SHP", + "@type": "ResourceDescriptor", + "hasRole": { + "@id": "http://www.w3.org/ns/dx/prof/role/vocabulary" + }, + "hasArtifact": { + "@id": "https://w3id.org/shp" + } + }, + { + "@id": "#hasSpecification", + "@type": "ResourceDescriptor", + "name": "has specification", + "hasRole": { + "@id": "http://www.w3.org/ns/dx/prof/role/specification" + }, + "hasArtifact": { + "@id": "https://trefx.uk/5s-crate/0.4/index.html" + } + }, + { + "@id": "#hasExampleRequest", + "@type": "ResourceDescriptor", + "name": "has example: Request", + "hasRole": { + "@id": "http://www.w3.org/ns/dx/prof/role/example" + }, + "hasArtifact": { + "@id": "https://trefx.uk/5s-crate/0.4/example-request/data/" + } + }, + { + "@id": "#hasExampleResult", + "@type": "ResourceDescriptor", + "name": "has example: Result", + "hasRole": { + "@id": "http://www.w3.org/ns/dx/prof/role/example" + }, + "hasArtifact": { + "@id": "https://trefx.uk/5s-crate/0.4/example-result/data/" + } + }, + + { + "@id": "http://www.w3.org/ns/dx/prof/role/example", + "@type": [ + "DefinedTerm", + "ResourceRole" + ], + "name": "Example", + "description": "Sample instance data conforming to the profile" + }, + { + "@id": "http://www.w3.org/ns/dx/prof/role/specification", + "@type": [ + "DefinedTerm", + "ResourceRole" + ], + "name": "Specification", + "description": "Defining the profile in human-readable form" + }, + { + "@id": "http://www.w3.org/ns/dx/prof/role/vocabulary", + "@type": [ + "DefinedTerm", + "ResourceRole" + ], + "name": "Vocabulary", + "description": "Defines terms used in the profile specification" + }, + { + "@id": "http://spdx.org/licenses/CC0-1.0", + "@type": "CreativeWork", + "name": "Creative Commons Zero v1.0 Universal", + "identifier": "CC0-1.0", + "url": "https://creativecommons.org/publicdomain/zero/1.0/" + }, + { + "@id": "http://spdx.org/licenses/MIT", + "@type": "CreativeWork", + "name": "MIT Licence", + "identifier": "MIT" + }, + { + "@id": "https://gtr.ukri.org/projects?ref=MC_PC_23007", + "@type": "Grant", + "identifier": { + "@id": "_:ukri:MC_PC_23007" + }, + "name": "DARE-FX: Delivering a federated network of TREs to enable safe analytics", + "description": "", + "funder": { + "@id": "https://ror.org/001aqnf71" + }, + "sponsor": { + "@id": "https://dareuk.org.uk/" + } + }, + { + "@id": "https://dareuk.org.uk/", + "@type": "FundingScheme", + "name": "DARE UK", + "funder": { + "@id": "https://ror.org/001aqnf71" + } + }, + { + "@id": "_:ukri:MC_PC_23007", + "@type": "PropertyValue", + "name": "UKRI", + "value": "MC_PC_23007" + }, + { + "@id": "https://trefx.uk/", + "@type": "ResearchProject", + "name": "TRE-FX", + "description": "Delivering a federated network of TREs to enable safe analytics", + "funding": { + "@id": "https://gtr.ukri.org/projects?ref=MC_PC_23007" + } + }, + { + "@id": "https://ror.org/001aqnf71", + "@type": "FundingAgency", + "name": "UK Research and Innovation", + "alternateName": "UKRI", + "url": "https://www.ukri.org/" + }, + { + "@id": "https://orcid.org/0000-0001-9842-9718", + "@type": "Person", + "name": "Stian Soiland-Reyes", + "affiliation": { + "@id": "https://ror.org/027m9bs27" + }, + "memberOf": { + "@id": "https://trefx.uk/" + } + }, + { + "@id": "https://ror.org/027m9bs27", + "@type": "CollegeOrUniversity", + "name": "The University of Manchester", + "url": "https://www.manchester.ac.uk/" + }, + { + "@id": "https://orcid.org/0009-0003-2419-1964", + "@type": "Person", + "name": "Stuart Wheater", + "memberOf": { + "@id": "https://trefx.uk/" + } + } + ] +} \ No newline at end of file diff --git a/tests/integration/profiles/five-safes-crate/test_valid_5src.py b/tests/integration/profiles/five-safes-crate/test_valid_5src.py new file mode 100644 index 00000000..1cc503b0 --- /dev/null +++ b/tests/integration/profiles/five-safes-crate/test_valid_5src.py @@ -0,0 +1,44 @@ +# 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.conftest import SKIP_LOCAL_DATA_ENTITY_EXISTENCE_CHECK_IDENTIFIER +from tests.ro_crates import ValidROC +from tests.shared import do_entity_test + +logger = logging.getLogger(__name__) +logger.setLevel(logging.DEBUG) + + +def test_valid_five_safes_crate_request_required(): + """Test a valid Workflow Run Crate.""" + do_entity_test( + ValidROC().five_safes_crate_request, + Severity.REQUIRED, + True, + profile_identifier="five-safes-crate", + skip_checks=[SKIP_LOCAL_DATA_ENTITY_EXISTENCE_CHECK_IDENTIFIER] + ) + +def test_valid_five_safes_crate_result_required(): + """Test a valid Workflow Run Crate.""" + do_entity_test( + ValidROC().five_safes_crate_result, + 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 1c3d03a9..6ecc64ab 100644 --- a/tests/ro_crates.py +++ b/tests/ro_crates.py @@ -91,6 +91,14 @@ def provenance_run_crate(self) -> Path: def multi_profile_crate(self) -> Path: return VALID_CRATES_DATA_PATH / "multi-profile-crate" + @property + def five_safes_crate_request(self) -> Path: + return VALID_CRATES_DATA_PATH / "five-safes-crate-request" + + @property + def five_safes_crate_result(self) -> Path: + return VALID_CRATES_DATA_PATH / "five-safes-crate-result" + class InvalidFileDescriptor: