diff --git a/rocrate_validator/profiles/five-safes-crate/may/4_sign_off.ttl b/rocrate_validator/profiles/five-safes-crate/may/4_sign_off.ttl index b30dedc2..ebb55b45 100644 --- a/rocrate_validator/profiles/five-safes-crate/may/4_sign_off.ttl +++ b/rocrate_validator/profiles/five-safes-crate/may/4_sign_off.ttl @@ -25,34 +25,15 @@ five-safes-crate:SignOffPhaseStartTime a sh:NodeShape ; - sh:name "SignOffPhaseStartTime" ; - - sh:target [ - a sh:SPARQLTarget ; - sh:select """ - PREFIX schema: - PREFIX shp: - SELECT ?this - WHERE { - ?this schema:additionalType shp:SignOff ; - schema:actionStatus ?status . - FILTER(?status IN ( - "http://schema.org/ActiveActionStatus", - "http://schema.org/CompletedActionStatus", - "http://schema.org/FailedActionStatus" - )) - } - """ ; + sh:description "Sign Off start time check" ; + sh:severity sh:Info ; + sh:target [ + a five-safes-crate:ActionActiveCompFailSearch ; + five-safes-crate:addtype shp:SignOff ; ] ; - sh:property [ - a sh:PropertyShape ; - sh:name "StartTime" ; sh:path schema:startTime ; sh:minCount 1 ; sh:maxCount 1 ; - sh:pattern "^[0-9]{4}-[0-9]{2}-[0-9]{2}[Tt][0-9]{2}:[0-9]{2}:[0-9]{2}([.|,][0-9]+)?(Z|z|[+-][0-9]{2}:[0-9]{2})$" ; - sh:severity sh:Info ; - sh:description "Sign Off object MAY have a startTime property if action is active, completed or failed. This must follow ISO-8601 syntax" ; - sh:message "Sign Off object MAY have a startTime property if action is active, completed or failed. This must follow ISO-8601 syntax" ; + sh:message "Sign Off phase MAY have a startTime if action is active, completed or failed." ; ] . diff --git a/rocrate_validator/profiles/five-safes-crate/must/11_workflow_execution_phase.ttl b/rocrate_validator/profiles/five-safes-crate/must/11_workflow_execution_phase.ttl index 4551da6c..bf10ac56 100644 --- a/rocrate_validator/profiles/five-safes-crate/must/11_workflow_execution_phase.ttl +++ b/rocrate_validator/profiles/five-safes-crate/must/11_workflow_execution_phase.ttl @@ -72,7 +72,9 @@ five-safes-crate:WorkflowexecutionObjectHasCompliantEndTimeFormat sh:pattern "^[0-9]{4}-[0-9]{2}-[0-9]{2}[Tt][0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]+)?(Z|z|[+-][0-9]{2}:[0-9]{2})$" ; sh:severity sh:Violation ; sh:message "The endTime of the workflow execution object MUST follow the RFC 3339 standard (YYYY-MM-DD'T'hh:mm:ss[.fraction](Z | ±hh:mm))." ; - ] . + ] ; + + sh:node five-safes-crate:EndTimeStamp . five-safes-crate:WorkflowMustHaveActionStatusWithAllowedValues diff --git a/rocrate_validator/profiles/five-safes-crate/must/4_sign_off.ttl b/rocrate_validator/profiles/five-safes-crate/must/4_sign_off.ttl index 2b61a259..854cd9e6 100644 --- a/rocrate_validator/profiles/five-safes-crate/must/4_sign_off.ttl +++ b/rocrate_validator/profiles/five-safes-crate/must/4_sign_off.ttl @@ -21,6 +21,7 @@ @prefix sh: . @prefix validator: . @prefix xsd: . +@prefix shp: . five-safes-crate:SignOffObjectActionAndName a sh:NodeShape ; @@ -53,7 +54,11 @@ five-safes-crate:SignOffObjectActionAndName sh:hasValue schema:AssessAction; sh:severity sh:Violation ; sh:message "Sign Off phase MUST be a `schema:AssessAction`." ; - ] . + ] ; + + sh:node five-safes-crate:StartTimeStamp ; + + sh:node five-safes-crate:EndTimeStamp . five-safes-crate:SignOffObjectHasActionStatus a sh:NodeShape ; diff --git a/rocrate_validator/profiles/five-safes-crate/shape_library.ttl b/rocrate_validator/profiles/five-safes-crate/shape_library.ttl new file mode 100644 index 00000000..6607e3bc --- /dev/null +++ b/rocrate_validator/profiles/five-safes-crate/shape_library.ttl @@ -0,0 +1,99 @@ +# 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 rdfs: . +@prefix schema: . +@prefix sh: . +@prefix validator: . +@prefix xsd: . +@prefix shp: . + + +five-safes-crate:EndTimeStamp + a sh:NodeShape ; + sh:property [ + sh:datatype xsd:string ; + sh:pattern "^[0-9]{4}-[0-9]{2}-[0-9]{2}[Tt][0-9]{2}:[0-9]{2}:[0-9]{2}([.|,][0-9]+)?(Z|z|[+-][0-9]{2}:[0-9]{2})$" ; + sh:description "End Time Check" ; + sh:path schema:endTime ; + sh:minCount 0 ; + sh:name "EndTimeStamp" ; + sh:message "endTime property MUST follow ISO-8601 syntax. e.g. 2023-04-19T10:15:12+01:00" ; + sh:severity sh:Violation ; + ] . + + +five-safes-crate:StartTimeStamp + a sh:NodeShape ; + sh:property [ + sh:datatype xsd:string ; + sh:pattern "^[0-9]{4}-[0-9]{2}-[0-9]{2}[Tt][0-9]{2}:[0-9]{2}:[0-9]{2}([.|,][0-9]+)?(Z|z|[+-][0-9]{2}:[0-9]{2})$" ; + sh:description "Start Time Check" ; + sh:path schema:startTime ; + sh:minCount 0 ; + sh:name "StartTimeStamp" ; + sh:message "startTime property MUST follow ISO-8601 syntax. e.g. 2023-04-19T10:15:12+01:00" ; + sh:severity sh:Violation ; + ] . + + +five-safes-crate:ActionCompFailSearch + a sh:SPARQLTargetType ; + rdfs:subClassOf sh:Target ; + sh:parameter [ + sh:path five-safes-crate:addtype ; + sh:description "Additional Type for Class" ; + sh:class sh:additionalType ; + ] ; + sh:select """ + PREFIX schema: + PREFIX shp: + SELECT ?this + WHERE { + ?this schema:additionalType $addtype ; + schema:actionStatus ?status . + FILTER(?status IN ( + "http://schema.org/CompletedActionStatus", + "http://schema.org/FailedActionStatus" + )) + } + """ . + + +five-safes-crate:ActionActiveCompFailSearch + a sh:SPARQLTargetType ; + rdfs:subClassOf sh:Target ; + sh:parameter [ + sh:path five-safes-crate:addtype ; + sh:description "Additional Type for Class" ; + sh:class sh:additionalType ; + ] ; + sh:select """ + PREFIX schema: + PREFIX shp: + SELECT ?this + WHERE { + ?this schema:additionalType $addtype ; + schema:actionStatus ?status . + FILTER(?status IN ( + "http://schema.org/ActiveActionStatus", + "http://schema.org/CompletedActionStatus", + "http://schema.org/FailedActionStatus" + )) + } + """ . diff --git a/rocrate_validator/profiles/five-safes-crate/should/4_sign_off.ttl b/rocrate_validator/profiles/five-safes-crate/should/4_sign_off.ttl index d671a0d9..30cc15fc 100644 --- a/rocrate_validator/profiles/five-safes-crate/should/4_sign_off.ttl +++ b/rocrate_validator/profiles/five-safes-crate/should/4_sign_off.ttl @@ -22,6 +22,9 @@ @prefix xsd: . @prefix shp: . +<> a sh:ShapesGraph ; + sh:import <../shape_library.ttl> . + # There SHOULD be a Sign-Off Phase five-safes-crate:SignOffPhase @@ -147,32 +150,13 @@ five-safes-crate:SignOffPhaseProperties five-safes-crate:SignOffPhaseEndTime a sh:NodeShape ; sh:description "Sign Off end time check" ; - - sh:target [ - a sh:SPARQLTarget ; - sh:select """ - PREFIX schema: - PREFIX shp: - SELECT ?this - WHERE { - ?this schema:additionalType shp:SignOff ; - schema:actionStatus ?status . - FILTER(?status IN ( - "http://schema.org/CompletedActionStatus", - "http://schema.org/FailedActionStatus" - )) - } - """ ; + sh:node five-safes-crate:EndTimeStamp ; + sh:severity sh:Warning ; + sh:target [ + a five-safes-crate:ActionCompFailSearch ; + five-safes-crate:addtype shp:SignOff ; ] ; + sh:message "Sign Off phase SHOULD have a compliant endTime if action completed or failed." + . + - sh:property [ - a sh:PropertyShape ; - sh:name "EndTime" ; - sh:path schema:endTime ; - sh:minCount 1 ; - sh:maxCount 1 ; - sh:pattern "^[0-9]{4}-[0-9]{2}-[0-9]{2}[Tt][0-9]{2}:[0-9]{2}:[0-9]{2}([.|,][0-9]+)?(Z|z|[+-][0-9]{2}:[0-9]{2})$" ; - sh:severity sh:Warning ; - sh:description "Sign Off object SHOULD have endTime property if action completed or failed. This must follow ISO-8601 syntax" ; - sh:message "Sign Off object SHOULD have endTime property if action completed or failed. This must follow ISO-8601 syntax" ; - ] . diff --git a/tests/integration/profiles/five-safes-crate/test_5src_4_signoff_phase.py b/tests/integration/profiles/five-safes-crate/test_5src_4_signoff_phase.py index 7f9cd8f3..5f4fdb86 100644 --- a/tests/integration/profiles/five-safes-crate/test_5src_4_signoff_phase.py +++ b/tests/integration/profiles/five-safes-crate/test_5src_4_signoff_phase.py @@ -206,10 +206,10 @@ def test_5src_signoff_phase_no_endtime(): rocrate_path=ValidROC().five_safes_crate_result, requirement_severity=Severity.RECOMMENDED, expected_validation_result=False, - expected_triggered_requirements=["SignOffPhaseEndTime"], + expected_triggered_requirements=["SignOffPhaseEndTime", "EndTimeStamp"], expected_triggered_issues=[ - "Sign Off object SHOULD have endTime property if action completed or failed." - + " This must follow ISO-8601 syntax" + "Sign Off phase SHOULD have a compliant endTime if action completed or failed.", + "endTime property MUST follow ISO-8601 syntax. e.g. 2023-04-19T10:15:12+01:00" ], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, @@ -242,10 +242,10 @@ def test_5src_signoff_phase_malformed_endtime(): rocrate_path=ValidROC().five_safes_crate_result, requirement_severity=Severity.RECOMMENDED, expected_validation_result=False, - expected_triggered_requirements=["SignOffPhaseEndTime"], + expected_triggered_requirements=["SignOffPhaseEndTime", "EndTimeStamp"], expected_triggered_issues=[ - "Sign Off object SHOULD have endTime property if action completed or failed." - + " This must follow ISO-8601 syntax" + "Sign Off phase SHOULD have a compliant endTime if action completed or failed.", + "endTime property MUST follow ISO-8601 syntax. e.g. 2023-04-19T10:15:12+01:00" ], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, @@ -274,10 +274,10 @@ def test_5src_signoff_phase_no_starttime(): rocrate_path=ValidROC().five_safes_crate_result, requirement_severity=Severity.OPTIONAL, expected_validation_result=False, - expected_triggered_requirements=["SignOffPhaseStartTime"], + expected_triggered_requirements=["SignOffPhaseStartTime", "StartTimeStamp"], expected_triggered_issues=[ - "Sign Off object MAY have a startTime property if action is active, completed or failed." - + " This must follow ISO-8601 syntax" + "Sign Off phase MAY have a compliant startTime if action is active, completed or failed.", + "startTime property MUST follow ISO-8601 syntax. e.g. 2023-04-19T10:15:12+01:00" ], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, @@ -310,10 +310,10 @@ def test_5src_signoff_phase_malformed_starttime(): rocrate_path=ValidROC().five_safes_crate_result, requirement_severity=Severity.OPTIONAL, expected_validation_result=False, - expected_triggered_requirements=["SignOffPhaseStartTime"], + expected_triggered_requirements=["SignOffPhaseStartTime", "StartTimeStamp"], expected_triggered_issues=[ - "Sign Off object MAY have a startTime property if action is active, completed or failed." - + " This must follow ISO-8601 syntax" + "Sign Off phase MAY have a compliant startTime if action is active, completed or failed.", + "startTime property MUST follow ISO-8601 syntax. e.g. 2023-04-19T10:15:12+01:00" ], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql,