From d6c90704e114a6d7d1a69b1f7000bf95fa806a9b Mon Sep 17 00:00:00 2001 From: EttoreM Date: Fri, 5 Dec 2025 12:30:03 +0000 Subject: [PATCH 01/13] First chunk of rules implemented. Missing rules that still need to be somehow clarified. --- .../five-safes-crate/must/12_check_phase.ttl | 99 ++++++++ .../should/12_check_phase.ttl | 222 ++++++++++++++++++ 2 files changed, 321 insertions(+) create mode 100644 rocrate_validator/profiles/five-safes-crate/must/12_check_phase.ttl create mode 100644 rocrate_validator/profiles/five-safes-crate/should/12_check_phase.ttl diff --git a/rocrate_validator/profiles/five-safes-crate/must/12_check_phase.ttl b/rocrate_validator/profiles/five-safes-crate/must/12_check_phase.ttl new file mode 100644 index 00000000..3cc7b599 --- /dev/null +++ b/rocrate_validator/profiles/five-safes-crate/must/12_check_phase.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 schema: . +@prefix purl: . +@prefix sh: . +@prefix validator: . +@prefix xsd: . + + +five-safes-crate:CheckValueObjectHasDescriptiveNameAndIsAssessAction + a sh:NodeShape ; + sh:name "CheckValue" ; + sh:description "CheckVAlue Object" ; + + sh:target [ + a sh:SPARQLTarget ; + sh:select """ + PREFIX schema: + PREFIX shp: + + SELECT ?this + WHERE { + ?this schema:additionalType shp:CheckValue . + } + """ ; + ] ; + + sh:property [ + sh:a sh:PropertyShape ; + sh:name "AssessAction" ; + sh:description "CheckValue MUST be a `schema:AssessAction`." ; + sh:path rdf:type ; + sh:minCount 1 ; + sh:hasValue schema:AssessAction; + sh:severity sh:Violation ; + sh:message "CheckValue MUST be a `schema:AssessAction`." ; + ] ; + + sh:property [ + sh:a sh:PropertyShape ; + sh:name "name" ; + sh:description "CheckValue MUST have a human readable name string of at least 20 characters." ; + sh:path schema:name ; + sh:datatype xsd:string ; + sh:minLength 20 ; + sh:severity sh:Violation ; + sh:message "CheckValue MUST have a human readable name string of at least 20 characters." ; + ] . + + +# five-safes-crate:DisclosureObjectHasActionStatus +# a sh:NodeShape ; +# sh:name "DisclosureCheck" ; +# sh:description "DisclosureCheck" ; + +# sh:target [ +# a sh:SPARQLTarget ; +# sh:select """ +# PREFIX schema: +# PREFIX shp: + +# SELECT ?this +# WHERE { +# ?this schema:additionalType shp:DisclosureCheck ; +# schema:actionStatus ?status . +# } +# """ ; +# ] ; + +# sh:property [ +# a sh:PropertyShape ; +# sh:name "actionStatus" ; +# sh:description "The value of actionStatus MUST be one of the allowed values." ; +# sh:path schema:actionStatus ; +# sh:in ( +# "http://schema.org/PotentialActionStatus" +# "http://schema.org/ActiveActionStatus" +# "http://schema.org/CompletedActionStatus" +# "http://schema.org/FailedActionStatus" +# ) ; +# sh:severity sh:Violation ; +# sh:message "The value of actionStatus MUST be one of the allowed values." ; +# ] . \ No newline at end of file diff --git a/rocrate_validator/profiles/five-safes-crate/should/12_check_phase.ttl b/rocrate_validator/profiles/five-safes-crate/should/12_check_phase.ttl new file mode 100644 index 00000000..e35f8676 --- /dev/null +++ b/rocrate_validator/profiles/five-safes-crate/should/12_check_phase.ttl @@ -0,0 +1,222 @@ +# 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 purl: . +@prefix sh: . +@prefix validator: . +@prefix xsd: . + + +five-safes-crate:RootDataEntityShouldMentionCheckValueObject + a sh:NodeShape ; + sh:name "RootDataEntity" ; + sh:targetClass ro-crate:RootDataEntity ; + sh:description "RootDataEntity SHOULD mention a check value object." ; + + sh:sparql [ + a sh:SPARQLConstraint ; + sh:name "mentions" ; + sh:description "RootDataEntity SHOULD mention a check value object." ; + sh:select """ + PREFIX schema: + PREFIX shp: + SELECT $this + WHERE { + FILTER NOT EXISTS{ + $this schema:mentions ?action . + ?action schema:additionalType shp:CheckValue . + } + } + """ ; + sh:severity sh:Warning ; + sh:message "RootDataEntity SHOULD mention a check value object." ; + ] . + + +five-safes-crate:CheckValueObjectShouldPointToRootDataEntity + a sh:NodeShape ; + sh:name "CheckValue" ; + sh:description "`CheckValue` --> `object` SHOULD point to the root of the RO-Crate" ; + sh:target [ + a sh:SPARQLTarget ; + sh:select """ + PREFIX schema: + PREFIX shp: + SELECT ?this + WHERE { + ?this schema:additionalType shp:CheckValue . + } + """ ; + ] ; + + sh:property [ + a sh:PropertyShape ; + sh:name "object" ; + sh:path schema:object ; + sh:minCount 1 ; + sh:hasValue <./> ; + sh:severity sh:Warning ; + sh:message "`CheckValue` --> `object` SHOULD point to the root of the RO-Crate" ; + ] . + + +five-safes-crate:CheckValueInstrumentShouldPointToEntityTypedDefinedTerm + a sh:NodeShape ; + sh:name "CheckValue" ; + sh:description "`CheckValue` --> `instrument` SHOULD point to an entity typed `schema:DefinedTerm`" ; + sh:target [ + a sh:SPARQLTarget ; + sh:select """ + PREFIX schema: + PREFIX shp: + SELECT ?this + WHERE { + ?this schema:additionalType shp:CheckValue . + } + """ ; + ] ; + + sh:property [ + a sh:PropertyShape ; + sh:name "instrument" ; + sh:path schema:instrument ; + sh:minCount 1 ; + sh:class schema:DefinedTerm ; + sh:severity sh:Warning ; + sh:message "`CheckValue` --> `instrument` SHOULD point to an entity typed `schema:DefinedTerm`" ; + ] . + + +five-safes-crate:CheckValueAgentShouldIdentifyTheAgentWhoPerformnedTheCheck + a sh:NodeShape ; + sh:name "CheckValue" ; + sh:description "`CheckValue` --> `agent` SHOULD reference the agent who initiated the check" ; + sh:target [ + a sh:SPARQLTarget ; + sh:select """ + PREFIX schema: + PREFIX shp: + SELECT ?this + WHERE { + ?this schema:additionalType shp:CheckValue . + } + """ ; + ] ; + + sh:property [ + a sh:PropertyShape ; + sh:name "agent" ; + sh:path schema:agent ; + sh:minCount 1 ; + sh:nodeKind sh:IRI ; + sh:severity sh:Warning ; + sh:message "`CheckValue` --> `agent` SHOULD reference the agent who initiated the check" ; + ] . + + +five-safes-crate:CheckValueEndTimeShouldFollowISOStandard + a sh:NodeShape ; + sh:name "CheckValue" ; + sh:description "`CheckValue` SHOULD have `endTime` property that follows the RFC 3339 standard." ; + sh:target [ + a sh:SPARQLTarget ; + sh:select """ + PREFIX schema: + PREFIX shp: + SELECT ?this + WHERE { + ?this schema:additionalType shp:CheckValue . + } + """ ; + ] ; + + 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}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|[+-][0-9]{2}:[0-9]{2})$" ; + sh:severity sh:Warning ; + sh:message "`CheckValue` SHOULD have `endTime` property that follows the RFC 3339 standard." ; + ] . + +# five-safes-crate:DisclosureObjectHasActionStatus +# a sh:NodeShape ; +# sh:name "DisclosureCheck" ; +# sh:description "DisclosureCheck" ; + +# sh:target [ +# a sh:SPARQLTarget ; +# sh:select """ +# PREFIX schema: +# PREFIX shp: + +# SELECT ?this +# WHERE { +# ?this schema:additionalType shp:DisclosureCheck . +# } +# """ ; +# ] ; + +# sh:property [ +# a sh:PropertyShape ; +# sh:name "ActionStatus" ; +# sh:description "The DisclosureCheck SHOULD have actionStatus property." ; +# sh:path schema:actionStatus ; +# sh:minCount 1 ; +# sh:severity sh:Warning ; +# sh:message "The DisclosureCheck SHOULD have actionStatus property." ; +# ] . + + +# five-safes-crate:DisclosureObjectHasEndTimeIfcompletedOrFailed +# a sh:NodeShape ; +# sh:name "DisclosureCheck" ; +# sh:description "DisclosureCheck" ; + +# sh:target [ +# a sh:SPARQLTarget ; +# sh:select """ +# PREFIX schema: +# PREFIX shp: + +# SELECT ?this +# WHERE { +# ?this schema:additionalType shp:DisclosureCheck ; +# schema:actionStatus ?status . +# FILTER(?status IN ( +# "http://schema.org/CompletedActionStatus", +# "http://schema.org/FailedActionStatus" +# )) +# } +# """ ; +# ] ; + +# 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}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|[+-][0-9]{2}:[0-9]{2})$" ; +# sh:severity sh:Warning ; +# sh:description "Disclosure object SHOULD have endTime property with a valid datetetime if action completed of failed." ; +# sh:message "Disclosure object SHOULD have endTime property with a valid datetime if action completed of failed." ; +# ] . \ No newline at end of file From 974b84d297d34a39b368f231d8af1120c73bd5b6 Mon Sep 17 00:00:00 2001 From: EttoreM Date: Fri, 5 Dec 2025 14:33:50 +0000 Subject: [PATCH 02/13] Added extra tests and added startDate in CheckValue entity of RO-Crate metadata file (result). --- .../five-safes-crate/may/12_check_phase.ttl | 50 +++++++ .../five-safes-crate/must/12_check_phase.ttl | 122 +++++++++++++----- .../should/12_check_phase.ttl | 107 ++++++--------- .../ro-crate-metadata.json | 4 +- 4 files changed, 176 insertions(+), 107 deletions(-) create mode 100644 rocrate_validator/profiles/five-safes-crate/may/12_check_phase.ttl diff --git a/rocrate_validator/profiles/five-safes-crate/may/12_check_phase.ttl b/rocrate_validator/profiles/five-safes-crate/may/12_check_phase.ttl new file mode 100644 index 00000000..83d4e4d1 --- /dev/null +++ b/rocrate_validator/profiles/five-safes-crate/may/12_check_phase.ttl @@ -0,0 +1,50 @@ +# 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 purl: . +@prefix sh: . +@prefix validator: . +@prefix xsd: . + + +five-safes-crate:CheckValueMayHaveStartTime + a sh:NodeShape ; + sh:name "CheckValue" ; + sh:description "" ; + sh:target [ + a sh:SPARQLTarget ; + sh:select """ + PREFIX schema: + PREFIX shp: + SELECT ?this + WHERE { + ?this schema:additionalType shp:CheckValue . + } + """ ; + ] ; + + sh:property [ + a sh:PropertyShape ; + sh:name "StartTime" ; + sh:path schema:startTime ; + sh:minCount 1 ; + sh:maxCount 1 ; + sh:severity sh:Info ; + sh:message "`CheckValue` MAY have the `startTime` property." ; + ] . diff --git a/rocrate_validator/profiles/five-safes-crate/must/12_check_phase.ttl b/rocrate_validator/profiles/five-safes-crate/must/12_check_phase.ttl index 3cc7b599..58b8ebc7 100644 --- a/rocrate_validator/profiles/five-safes-crate/must/12_check_phase.ttl +++ b/rocrate_validator/profiles/five-safes-crate/must/12_check_phase.ttl @@ -26,7 +26,7 @@ five-safes-crate:CheckValueObjectHasDescriptiveNameAndIsAssessAction a sh:NodeShape ; sh:name "CheckValue" ; - sh:description "CheckVAlue Object" ; + sh:description "" ; sh:target [ a sh:SPARQLTarget ; @@ -63,37 +63,91 @@ five-safes-crate:CheckValueObjectHasDescriptiveNameAndIsAssessAction sh:message "CheckValue MUST have a human readable name string of at least 20 characters." ; ] . +five-safes-crate:CheckValueStartTimeMustFollowISOStandard + a sh:NodeShape ; + sh:name "CheckValue" ; + sh:description "" ; + sh:target [ + a sh:SPARQLTarget ; + sh:select """ + PREFIX schema: + PREFIX shp: + SELECT ?this + WHERE { + ?this schema:additionalType shp:CheckValue ; + schema:startTime ?o + + } + """ ; + ] ; + + sh:property [ + a sh:PropertyShape ; + sh:name "StartTime" ; + sh:path schema:startTime ; + sh:pattern "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|[+-][0-9]{2}:[0-9]{2})$" ; + sh:severity sh:Violation ; + sh:message "`CheckValue` --> `startTime` MUST follows the RFC 3339 standard." ; + ] . + + +five-safes-crate:CheckValueEndTimeMustFollowISOStandard + a sh:NodeShape ; + sh:name "CheckValue" ; + sh:description "" ; + sh:target [ + a sh:SPARQLTarget ; + sh:select """ + PREFIX schema: + PREFIX shp: + SELECT ?this + WHERE { + ?this schema:additionalType shp:CheckValue ; + schema:endTime ?o -# five-safes-crate:DisclosureObjectHasActionStatus -# a sh:NodeShape ; -# sh:name "DisclosureCheck" ; -# sh:description "DisclosureCheck" ; - -# sh:target [ -# a sh:SPARQLTarget ; -# sh:select """ -# PREFIX schema: -# PREFIX shp: - -# SELECT ?this -# WHERE { -# ?this schema:additionalType shp:DisclosureCheck ; -# schema:actionStatus ?status . -# } -# """ ; -# ] ; - -# sh:property [ -# a sh:PropertyShape ; -# sh:name "actionStatus" ; -# sh:description "The value of actionStatus MUST be one of the allowed values." ; -# sh:path schema:actionStatus ; -# sh:in ( -# "http://schema.org/PotentialActionStatus" -# "http://schema.org/ActiveActionStatus" -# "http://schema.org/CompletedActionStatus" -# "http://schema.org/FailedActionStatus" -# ) ; -# sh:severity sh:Violation ; -# sh:message "The value of actionStatus MUST be one of the allowed values." ; -# ] . \ No newline at end of file + } + """ ; + ] ; + + sh:property [ + a sh:PropertyShape ; + sh:name "EndTime" ; + sh:path schema:endTime ; + sh:pattern "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|[+-][0-9]{2}:[0-9]{2})$" ; + sh:severity sh:Violation ; + sh:message "`CheckValue` --> `endTime` MUST follows the RFC 3339 standard." ; + ] . + + +five-safes-crate:CheckValueActionStatusMustHaveAllowedValues + a sh:NodeShape ; + sh:name "CheckValue" ; + sh:description "" ; + + sh:target [ + a sh:SPARQLTarget ; + sh:select """ + PREFIX schema: + PREFIX shp: + + SELECT ?this + WHERE { + ?this schema:additionalType shp:CheckValue ; + schema:actionStatus ?status . + } + """ ; + ] ; + + sh:property [ + a sh:PropertyShape ; + sh:name "ActionStatus" ; + sh:path schema:actionStatus ; + sh:in ( + "http://schema.org/PotentialActionStatus" + "http://schema.org/ActiveActionStatus" + "http://schema.org/CompletedActionStatus" + "http://schema.org/FailedActionStatus" + ) ; + sh:severity sh:Violation ; + sh:message "`CheckValue` --> `actionStatus` MUST have one of the allowed values." ; + ] . diff --git a/rocrate_validator/profiles/five-safes-crate/should/12_check_phase.ttl b/rocrate_validator/profiles/five-safes-crate/should/12_check_phase.ttl index e35f8676..adb86334 100644 --- a/rocrate_validator/profiles/five-safes-crate/should/12_check_phase.ttl +++ b/rocrate_validator/profiles/five-safes-crate/should/12_check_phase.ttl @@ -27,7 +27,7 @@ five-safes-crate:RootDataEntityShouldMentionCheckValueObject a sh:NodeShape ; sh:name "RootDataEntity" ; sh:targetClass ro-crate:RootDataEntity ; - sh:description "RootDataEntity SHOULD mention a check value object." ; + sh:description "" ; sh:sparql [ a sh:SPARQLConstraint ; @@ -52,7 +52,7 @@ five-safes-crate:RootDataEntityShouldMentionCheckValueObject five-safes-crate:CheckValueObjectShouldPointToRootDataEntity a sh:NodeShape ; sh:name "CheckValue" ; - sh:description "`CheckValue` --> `object` SHOULD point to the root of the RO-Crate" ; + sh:description "" ; sh:target [ a sh:SPARQLTarget ; sh:select """ @@ -79,7 +79,7 @@ five-safes-crate:CheckValueObjectShouldPointToRootDataEntity five-safes-crate:CheckValueInstrumentShouldPointToEntityTypedDefinedTerm a sh:NodeShape ; sh:name "CheckValue" ; - sh:description "`CheckValue` --> `instrument` SHOULD point to an entity typed `schema:DefinedTerm`" ; + sh:description "" ; sh:target [ a sh:SPARQLTarget ; sh:select """ @@ -106,7 +106,7 @@ five-safes-crate:CheckValueInstrumentShouldPointToEntityTypedDefinedTerm five-safes-crate:CheckValueAgentShouldIdentifyTheAgentWhoPerformnedTheCheck a sh:NodeShape ; sh:name "CheckValue" ; - sh:description "`CheckValue` --> `agent` SHOULD reference the agent who initiated the check" ; + sh:description "" ; sh:target [ a sh:SPARQLTarget ; sh:select """ @@ -130,10 +130,10 @@ five-safes-crate:CheckValueAgentShouldIdentifyTheAgentWhoPerformnedTheCheck ] . -five-safes-crate:CheckValueEndTimeShouldFollowISOStandard +five-safes-crate:CheckValueShouldHaveEndTime a sh:NodeShape ; sh:name "CheckValue" ; - sh:description "`CheckValue` SHOULD have `endTime` property that follows the RFC 3339 standard." ; + sh:description "" ; sh:target [ a sh:SPARQLTarget ; sh:select """ @@ -152,71 +152,36 @@ five-safes-crate:CheckValueEndTimeShouldFollowISOStandard sh:path schema:endTime ; sh:minCount 1 ; sh:maxCount 1 ; - sh:pattern "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|[+-][0-9]{2}:[0-9]{2})$" ; sh:severity sh:Warning ; - sh:message "`CheckValue` SHOULD have `endTime` property that follows the RFC 3339 standard." ; + sh:message "`CheckValue` SHOULD have the `endTime` property." ; + ] . + + +five-safes-crate:CheckValueShouldHaveActionStatus + a sh:NodeShape ; + sh:name "CheckValue" ; + sh:description "" ; + + sh:target [ + a sh:SPARQLTarget ; + sh:select """ + PREFIX schema: + PREFIX shp: + + SELECT ?this + WHERE { + ?this schema:additionalType shp:CheckValue . + } + """ ; + ] ; + + sh:property [ + a sh:PropertyShape ; + sh:name "ActionStatus" ; + sh:description "CheckValue SHOULD have actionStatus property." ; + sh:path schema:actionStatus ; + sh:minCount 1 ; + sh:severity sh:Warning ; + sh:message "CheckValue SHOULD have actionStatus property." ; ] . -# five-safes-crate:DisclosureObjectHasActionStatus -# a sh:NodeShape ; -# sh:name "DisclosureCheck" ; -# sh:description "DisclosureCheck" ; - -# sh:target [ -# a sh:SPARQLTarget ; -# sh:select """ -# PREFIX schema: -# PREFIX shp: - -# SELECT ?this -# WHERE { -# ?this schema:additionalType shp:DisclosureCheck . -# } -# """ ; -# ] ; - -# sh:property [ -# a sh:PropertyShape ; -# sh:name "ActionStatus" ; -# sh:description "The DisclosureCheck SHOULD have actionStatus property." ; -# sh:path schema:actionStatus ; -# sh:minCount 1 ; -# sh:severity sh:Warning ; -# sh:message "The DisclosureCheck SHOULD have actionStatus property." ; -# ] . - - -# five-safes-crate:DisclosureObjectHasEndTimeIfcompletedOrFailed -# a sh:NodeShape ; -# sh:name "DisclosureCheck" ; -# sh:description "DisclosureCheck" ; - -# sh:target [ -# a sh:SPARQLTarget ; -# sh:select """ -# PREFIX schema: -# PREFIX shp: - -# SELECT ?this -# WHERE { -# ?this schema:additionalType shp:DisclosureCheck ; -# schema:actionStatus ?status . -# FILTER(?status IN ( -# "http://schema.org/CompletedActionStatus", -# "http://schema.org/FailedActionStatus" -# )) -# } -# """ ; -# ] ; - -# 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}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|[+-][0-9]{2}:[0-9]{2})$" ; -# sh:severity sh:Warning ; -# sh:description "Disclosure object SHOULD have endTime property with a valid datetetime if action completed of failed." ; -# sh:message "Disclosure object SHOULD have endTime property with a valid datetime if action completed of failed." ; -# ] . \ 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 c5c50961..0edef934 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 @@ -220,6 +220,7 @@ "@id": "https://w3id.org/shp#CheckValue" }, "name": "BagIt checksum of Crate: OK", + "startTime": "2023-04-18T12:11:00+01:00", "endTime": "2023-04-18T12:11:45+01:00", "object": { "@id": "./" @@ -229,8 +230,7 @@ }, "agent": { "@id": "#validator-a4a66c63-2fe0-4c57-830d-268a40718313" - }, - "actionStatus": "http://schema.org/CompletedActionStatus" + } }, { "@id": "#validate-1146f640-819e-4c86-b029-b763a0040896", From a58d89eab0e312e05150d402d8c8e9a4bcd5b624 Mon Sep 17 00:00:00 2001 From: EttoreM Date: Fri, 5 Dec 2025 16:11:59 +0000 Subject: [PATCH 03/13] Added tests for rules 1-7. --- .../five-safes-crate/must/12_check_phase.ttl | 3 - .../test_5src_12_check_phase.py | 232 ++++++++++++++++++ 2 files changed, 232 insertions(+), 3 deletions(-) create mode 100644 tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py diff --git a/rocrate_validator/profiles/five-safes-crate/must/12_check_phase.ttl b/rocrate_validator/profiles/five-safes-crate/must/12_check_phase.ttl index 58b8ebc7..464e4700 100644 --- a/rocrate_validator/profiles/five-safes-crate/must/12_check_phase.ttl +++ b/rocrate_validator/profiles/five-safes-crate/must/12_check_phase.ttl @@ -42,9 +42,6 @@ five-safes-crate:CheckValueObjectHasDescriptiveNameAndIsAssessAction ] ; sh:property [ - sh:a sh:PropertyShape ; - sh:name "AssessAction" ; - sh:description "CheckValue MUST be a `schema:AssessAction`." ; sh:path rdf:type ; sh:minCount 1 ; sh:hasValue schema:AssessAction; diff --git a/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py b/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py new file mode 100644 index 00000000..19eb2810 --- /dev/null +++ b/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py @@ -0,0 +1,232 @@ +# 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 +from tests.shared import do_entity_test, SPARQL_PREFIXES + +# set up logging +logger = logging.getLogger(__name__) + + + +# ----- MUST fails tests + +# TO BE CHECKED AGAIN +def test_5src_check_value_not_of_type_assess_action(): + sparql = """ + PREFIX schema: + PREFIX shp: + PREFIX rdf: + + DELETE { + ?this rdf:type ?type . + } + INSERT { + ?this rdf:type . + } + WHERE { + ?this a schema:AssessAction ; + schema:additionalType shp:CheckValue ; + rdf:type ?type . + } + """ + + + do_entity_test( + rocrate_path=ValidROC().five_safes_crate_result, + requirement_severity=Severity.REQUIRED, + expected_validation_result=False, + expected_triggered_requirements=["CheckValue"], + expected_triggered_issues=["CheckValue MUST be a `schema:AssessAction`."], + profile_identifier="five-safes-crate", + rocrate_entity_mod_sparql=sparql, + ) + + +def test_5src_check_value_name_not_a_string(): + sparql = """ + PREFIX schema: + PREFIX shp: + PREFIX rdf: + + DELETE { + ?this schema:name ?name . + } + INSERT { + ?this schema:name 123 . + } + WHERE { + ?this schema:additionalType shp:CheckValue . + } + """ + + do_entity_test( + rocrate_path=ValidROC().five_safes_crate_result, + requirement_severity=Severity.REQUIRED, + expected_validation_result=False, + expected_triggered_requirements=["CheckValue"], + expected_triggered_issues=["CheckValue MUST have a human readable name string of at least 20 characters."], + profile_identifier="five-safes-crate", + rocrate_entity_mod_sparql=sparql, + ) + + + +def test_5src_check_value_name_not_long_enough(): + sparql = """ + PREFIX schema: + PREFIX shp: + PREFIX rdf: + + DELETE { + ?this schema:name ?name . + } + INSERT { + ?this schema:name "Short" . + } + WHERE { + ?this schema:additionalType shp:CheckValue . + } + """ + + do_entity_test( + rocrate_path=ValidROC().five_safes_crate_result, + requirement_severity=Severity.REQUIRED, + expected_validation_result=False, + expected_triggered_requirements=["CheckValue"], + expected_triggered_issues=["CheckValue MUST have a human readable name string of at least 20 characters."], + profile_identifier="five-safes-crate", + rocrate_entity_mod_sparql=sparql, + ) + + + + +# ----- SHOULD fails tests + + +def test_5src_root_data_entity_does_not_mention_check_value_entity(): + sparql = """ + PREFIX schema: + PREFIX shp: + + DELETE { + <./> schema:mentions ?o . + } + WHERE { + ?o schema:additionalType shp:CheckValue ; + } + """ + + do_entity_test( + rocrate_path=ValidROC().five_safes_crate_result, + requirement_severity=Severity.RECOMMENDED, + expected_validation_result=False, + expected_triggered_requirements=["RootDataEntity"], + expected_triggered_issues=["RootDataEntity SHOULD mention a check value object."], + profile_identifier="five-safes-crate", + rocrate_entity_mod_sparql=sparql, + ) + + + +def test_5src_check_value_object_does_not_point_to_root_data_entity(): + sparql = """ + PREFIX schema: + PREFIX shp: + + DELETE { + ?s schema:object <./> . + } + INSERT { + ?s schema:object "not the RootDataEntity" . + } + WHERE { + ?s schema:additionalType shp:CheckValue ; + } + """ + + do_entity_test( + rocrate_path=ValidROC().five_safes_crate_result, + requirement_severity=Severity.RECOMMENDED, + expected_validation_result=False, + expected_triggered_requirements=["CheckValue"], + expected_triggered_issues=["`CheckValue` --> `object` SHOULD point to the root of the RO-Crate"], + profile_identifier="five-safes-crate", + rocrate_entity_mod_sparql=sparql, + ) + + +def test_5src_check_value_instrument_does_not_point_to_entity_with_type_defined_term(): + sparql = """ + PREFIX schema: + PREFIX shp: + PREFIX rdf: + + DELETE { + ?s rdf:type schema:DefinedTerm . + } + INSERT { + ?s rdf:type schema:Persona . + } + WHERE { + ?cv schema:additionalType shp:CheckValue ; + schema:instrument ?s . + ?s rdf:type schema:DefinedTerm . + } + """ + + do_entity_test( + rocrate_path=ValidROC().five_safes_crate_result, + requirement_severity=Severity.RECOMMENDED, + expected_validation_result=False, + expected_triggered_requirements=["CheckValue"], + expected_triggered_issues=["`CheckValue` --> `instrument` SHOULD point to an entity typed `schema:DefinedTerm`"], + profile_identifier="five-safes-crate", + rocrate_entity_mod_sparql=sparql, + ) + + + + +# ----- MAY fails tests + + +def test_5src_check_value_does_not_have_start_time(): + sparql = """ + PREFIX schema: + PREFIX shp: + PREFIX rdf: + + DELETE { + ?c schema:startTime ?t . + } + WHERE { + ?c schema:additionalType shp:CheckValue ; + schema:startTime ?t . + } + """ + + do_entity_test( + rocrate_path=ValidROC().five_safes_crate_result, + requirement_severity=Severity.OPTIONAL, + expected_validation_result=False, + expected_triggered_requirements=["CheckValue"], + expected_triggered_issues=["`CheckValue` MAY have the `startTime` property."], + profile_identifier="five-safes-crate", + rocrate_entity_mod_sparql=sparql, + ) \ No newline at end of file From 8949a7a83e6132ecf49b5c7bb297edd904bcb550 Mon Sep 17 00:00:00 2001 From: EttoreM Date: Fri, 5 Dec 2025 17:26:36 +0000 Subject: [PATCH 04/13] Added the remaining python tests. --- .../should/12_check_phase.ttl | 1 - .../ro-crate-metadata.json | 3 +- .../test_5src_12_check_phase.py | 162 ++++++++++++++++++ 3 files changed, 164 insertions(+), 2 deletions(-) diff --git a/rocrate_validator/profiles/five-safes-crate/should/12_check_phase.ttl b/rocrate_validator/profiles/five-safes-crate/should/12_check_phase.ttl index adb86334..6e254a52 100644 --- a/rocrate_validator/profiles/five-safes-crate/should/12_check_phase.ttl +++ b/rocrate_validator/profiles/five-safes-crate/should/12_check_phase.ttl @@ -178,7 +178,6 @@ five-safes-crate:CheckValueShouldHaveActionStatus sh:property [ a sh:PropertyShape ; sh:name "ActionStatus" ; - sh:description "CheckValue SHOULD have actionStatus property." ; sh:path schema:actionStatus ; sh:minCount 1 ; sh:severity sh:Warning ; 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 0edef934..aa9b3adf 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 @@ -230,7 +230,8 @@ }, "agent": { "@id": "#validator-a4a66c63-2fe0-4c57-830d-268a40718313" - } + }, + "actionStatus": "http://schema.org/CompletedActionStatus" }, { "@id": "#validate-1146f640-819e-4c86-b029-b763a0040896", diff --git a/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py b/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py index 19eb2810..b7f02b97 100644 --- a/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py +++ b/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py @@ -115,6 +115,91 @@ def test_5src_check_value_name_not_long_enough(): +def test_5src_check_value_start_time_not_iso_standard(): + sparql = """ + PREFIX schema: + PREFIX shp: + PREFIX rdf: + + DELETE { + ?c schema:startTime ?t . + } + INSERT { + ?c schema:startTime "1st of Jan 2021" . + } + WHERE { + ?c schema:additionalType shp:CheckValue ; + schema:startTime ?t . + } + """ + + do_entity_test( + rocrate_path=ValidROC().five_safes_crate_result, + requirement_severity=Severity.REQUIRED, + expected_validation_result=False, + expected_triggered_requirements=["CheckValue"], + expected_triggered_issues=["`CheckValue` --> `startTime` MUST follows the RFC 3339 standard."], + profile_identifier="five-safes-crate", + rocrate_entity_mod_sparql=sparql, + ) + + +def test_5src_check_value_end_time_not_iso_standard(): + sparql = """ + PREFIX schema: + PREFIX shp: + PREFIX rdf: + + DELETE { + ?c schema:endTime ?t . + } + INSERT { + ?c schema:endTime "1st of Jan 2021" . + } + WHERE { + ?c schema:additionalType shp:CheckValue ; + schema:endTime ?t . + } + """ + + do_entity_test( + rocrate_path=ValidROC().five_safes_crate_result, + requirement_severity=Severity.REQUIRED, + expected_validation_result=False, + expected_triggered_requirements=["CheckValue"], + expected_triggered_issues=["`CheckValue` --> `endTime` MUST follows the RFC 3339 standard."], + profile_identifier="five-safes-crate", + rocrate_entity_mod_sparql=sparql, + ) + + +def test_5src_check_value_has_action_status_with_not_allowed_value(): + sparql = """ + PREFIX schema: + PREFIX shp: + PREFIX rdf: + + DELETE { + ?s schema:actionStatus ?o . + } + INSERT { + ?s schema:actionStatus "Not a good action status" . + } + WHERE { + ?s schema:additionalType ; + schema:actionStatus ?o . + } + """ + + do_entity_test( + rocrate_path=ValidROC().five_safes_crate_result, + requirement_severity=Severity.REQUIRED, + expected_validation_result=False, + expected_triggered_requirements=["CheckValue"], + expected_triggered_issues=["`CheckValue` --> `actionStatus` MUST have one of the allowed values."], + profile_identifier="five-safes-crate", + rocrate_entity_mod_sparql=sparql, + ) # ----- SHOULD fails tests @@ -201,6 +286,83 @@ def test_5src_check_value_instrument_does_not_point_to_entity_with_type_defined_ ) +def test_5src_check_value_does_not_have_start_time(): + sparql = """ + PREFIX schema: + PREFIX shp: + PREFIX rdf: + + DELETE { + ?c schema:endTime ?t . + } + WHERE { + ?c schema:additionalType shp:CheckValue ; + schema:endTime ?t . + } + """ + + do_entity_test( + rocrate_path=ValidROC().five_safes_crate_result, + requirement_severity=Severity.RECOMMENDED, + expected_validation_result=False, + expected_triggered_requirements=["CheckValue"], + expected_triggered_issues=["`CheckValue` SHOULD have the `endTime` property."], + profile_identifier="five-safes-crate", + rocrate_entity_mod_sparql=sparql, + ) + + +def test_5src_check_value_does_not_have_action_status_property(): + sparql = """ + PREFIX schema: + PREFIX shp: + PREFIX rdf: + + DELETE { + ?s schema:actionStatus ?o . + } + WHERE { + ?s schema:additionalType shp:CheckValue ; + schema:actionStatus ?o . + } + """ + + do_entity_test( + rocrate_path=ValidROC().five_safes_crate_result, + requirement_severity=Severity.RECOMMENDED, + expected_validation_result=False, + expected_triggered_requirements=["CheckValue"], + expected_triggered_issues=["CheckValue SHOULD have actionStatus property."], + profile_identifier="five-safes-crate", + rocrate_entity_mod_sparql=sparql, + ) + + + +def test_5src_check_value_does_not_point_to_an_agent(): + sparql = """ + PREFIX schema: + PREFIX shp: + PREFIX rdf: + + DELETE { + ?s schema:agent ?o . + } + WHERE { + ?s schema:additionalType shp:CheckValue ; + schema:agent ?o . + } + """ + + do_entity_test( + rocrate_path=ValidROC().five_safes_crate_result, + requirement_severity=Severity.RECOMMENDED, + expected_validation_result=False, + expected_triggered_requirements=["CheckValue"], + expected_triggered_issues=["`CheckValue` --> `agent` SHOULD reference the agent who initiated the check"], + profile_identifier="five-safes-crate", + rocrate_entity_mod_sparql=sparql, + ) # ----- MAY fails tests From 3bebd0426e7d3d5343a4902d8825f6d936dc0117 Mon Sep 17 00:00:00 2001 From: EttoreM Date: Fri, 5 Dec 2025 17:28:55 +0000 Subject: [PATCH 05/13] Ammended linting errors --- .../profiles/five-safes-crate/test_5src_12_check_phase.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py b/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py index b7f02b97..c12f04e2 100644 --- a/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py +++ b/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py @@ -391,4 +391,4 @@ def test_5src_check_value_does_not_have_start_time(): expected_triggered_issues=["`CheckValue` MAY have the `startTime` property."], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, - ) \ No newline at end of file + ) From c8a70b27dc1572069af0702a6c685e115c43fb90 Mon Sep 17 00:00:00 2001 From: EttoreM Date: Fri, 5 Dec 2025 17:30:51 +0000 Subject: [PATCH 06/13] Ammended duplicated name for tests. --- .../profiles/five-safes-crate/test_5src_12_check_phase.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py b/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py index c12f04e2..ac45612f 100644 --- a/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py +++ b/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py @@ -286,7 +286,7 @@ def test_5src_check_value_instrument_does_not_point_to_entity_with_type_defined_ ) -def test_5src_check_value_does_not_have_start_time(): +def test_5src_check_value_does_not_have_end_time(): sparql = """ PREFIX schema: PREFIX shp: From 08070ac6b4ffed5143c274dc9a174e65a87e1fe1 Mon Sep 17 00:00:00 2001 From: EttoreM Date: Fri, 5 Dec 2025 17:32:45 +0000 Subject: [PATCH 07/13] Removed linting error --- .../five-safes-crate/test_5src_12_check_phase.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py b/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py index ac45612f..05490b0e 100644 --- a/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py +++ b/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py @@ -22,7 +22,6 @@ logger = logging.getLogger(__name__) - # ----- MUST fails tests # TO BE CHECKED AGAIN @@ -45,7 +44,6 @@ def test_5src_check_value_not_of_type_assess_action(): } """ - do_entity_test( rocrate_path=ValidROC().five_safes_crate_result, requirement_severity=Severity.REQUIRED, @@ -85,7 +83,6 @@ def test_5src_check_value_name_not_a_string(): ) - def test_5src_check_value_name_not_long_enough(): sparql = """ PREFIX schema: @@ -114,7 +111,6 @@ def test_5src_check_value_name_not_long_enough(): ) - def test_5src_check_value_start_time_not_iso_standard(): sparql = """ PREFIX schema: @@ -201,8 +197,8 @@ def test_5src_check_value_has_action_status_with_not_allowed_value(): rocrate_entity_mod_sparql=sparql, ) -# ----- SHOULD fails tests +# ----- SHOULD fails tests def test_5src_root_data_entity_does_not_mention_check_value_entity(): sparql = """ @@ -228,7 +224,6 @@ def test_5src_root_data_entity_does_not_mention_check_value_entity(): ) - def test_5src_check_value_object_does_not_point_to_root_data_entity(): sparql = """ PREFIX schema: @@ -338,7 +333,6 @@ def test_5src_check_value_does_not_have_action_status_property(): ) - def test_5src_check_value_does_not_point_to_an_agent(): sparql = """ PREFIX schema: @@ -367,7 +361,6 @@ def test_5src_check_value_does_not_point_to_an_agent(): # ----- MAY fails tests - def test_5src_check_value_does_not_have_start_time(): sparql = """ PREFIX schema: From 18898b00880f69d645defcd847b76f0eb5eee2da Mon Sep 17 00:00:00 2001 From: EttoreM Date: Fri, 5 Dec 2025 17:34:07 +0000 Subject: [PATCH 08/13] Removed linting error - 2 --- .../profiles/five-safes-crate/test_5src_12_check_phase.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py b/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py index 05490b0e..8b11bc1a 100644 --- a/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py +++ b/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py @@ -275,7 +275,9 @@ def test_5src_check_value_instrument_does_not_point_to_entity_with_type_defined_ requirement_severity=Severity.RECOMMENDED, expected_validation_result=False, expected_triggered_requirements=["CheckValue"], - expected_triggered_issues=["`CheckValue` --> `instrument` SHOULD point to an entity typed `schema:DefinedTerm`"], + expected_triggered_issues=[ + "`CheckValue` --> `instrument` SHOULD point to an entity typed `schema:DefinedTerm`" + ], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, ) From e080c23fb46470d7c78310816e1e8f4d687c24e9 Mon Sep 17 00:00:00 2001 From: EttoreM Date: Fri, 5 Dec 2025 17:35:30 +0000 Subject: [PATCH 09/13] Removed linting error - 3 --- .../profiles/five-safes-crate/test_5src_12_check_phase.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py b/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py index 8b11bc1a..fe6bff0e 100644 --- a/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py +++ b/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py @@ -16,7 +16,7 @@ from rocrate_validator.models import Severity from tests.ro_crates import ValidROC -from tests.shared import do_entity_test, SPARQL_PREFIXES +from tests.shared import do_entity_test # set up logging logger = logging.getLogger(__name__) @@ -40,10 +40,10 @@ def test_5src_check_value_not_of_type_assess_action(): WHERE { ?this a schema:AssessAction ; schema:additionalType shp:CheckValue ; - rdf:type ?type . + rdf:type ?type . } """ - + do_entity_test( rocrate_path=ValidROC().five_safes_crate_result, requirement_severity=Severity.REQUIRED, From 88a050ee29711aa80515adcc0e80abad63f6bdf3 Mon Sep 17 00:00:00 2001 From: EttoreM Date: Mon, 8 Dec 2025 09:44:43 +0000 Subject: [PATCH 10/13] Added condition for the MAY have startTime and SHOULD have endTime. --- .../profiles/five-safes-crate/may/12_check_phase.ttl | 8 +++++++- .../profiles/five-safes-crate/should/12_check_phase.ttl | 7 ++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/rocrate_validator/profiles/five-safes-crate/may/12_check_phase.ttl b/rocrate_validator/profiles/five-safes-crate/may/12_check_phase.ttl index 83d4e4d1..0e741f6c 100644 --- a/rocrate_validator/profiles/five-safes-crate/may/12_check_phase.ttl +++ b/rocrate_validator/profiles/five-safes-crate/may/12_check_phase.ttl @@ -34,7 +34,13 @@ five-safes-crate:CheckValueMayHaveStartTime PREFIX shp: SELECT ?this WHERE { - ?this schema:additionalType shp:CheckValue . + ?this schema:additionalType shp:CheckValue ; + schema:actionStatus ?status . + FILTER(?status IN ( + "http://schema.org/CompletedActionStatus", + "http://schema.org/FailedActionStatus", + "http://schema.org/ActiveActionStatus" + )) } """ ; ] ; diff --git a/rocrate_validator/profiles/five-safes-crate/should/12_check_phase.ttl b/rocrate_validator/profiles/five-safes-crate/should/12_check_phase.ttl index 6e254a52..0560cc15 100644 --- a/rocrate_validator/profiles/five-safes-crate/should/12_check_phase.ttl +++ b/rocrate_validator/profiles/five-safes-crate/should/12_check_phase.ttl @@ -141,7 +141,12 @@ five-safes-crate:CheckValueShouldHaveEndTime PREFIX shp: SELECT ?this WHERE { - ?this schema:additionalType shp:CheckValue . + ?this schema:additionalType shp:CheckValue ; + schema:actionStatus ?status . + FILTER(?status IN ( + "http://schema.org/CompletedActionStatus", + "http://schema.org/FailedActionStatus" + )) } """ ; ] ; From c4292692a0a7ecfeb7bdf48a1ca342a580b5d507 Mon Sep 17 00:00:00 2001 From: EttoreM Date: Mon, 8 Dec 2025 13:40:14 +0000 Subject: [PATCH 11/13] Provided RFC 339 pattern for timestamps in relevant messages. --- .../profiles/five-safes-crate/must/12_check_phase.ttl | 8 ++++---- .../five-safes-crate/test_5src_12_check_phase.py | 10 ++++++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/rocrate_validator/profiles/five-safes-crate/must/12_check_phase.ttl b/rocrate_validator/profiles/five-safes-crate/must/12_check_phase.ttl index 464e4700..5567c82b 100644 --- a/rocrate_validator/profiles/five-safes-crate/must/12_check_phase.ttl +++ b/rocrate_validator/profiles/five-safes-crate/must/12_check_phase.ttl @@ -82,9 +82,9 @@ five-safes-crate:CheckValueStartTimeMustFollowISOStandard a sh:PropertyShape ; sh:name "StartTime" ; sh:path schema:startTime ; - sh:pattern "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|[+-][0-9]{2}:[0-9]{2})$" ; + 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 "`CheckValue` --> `startTime` MUST follows the RFC 3339 standard." ; + sh:message "`CheckValue` --> `startTime` MUST follows the RFC 3339 standard (YYYY-MM-DD'T'hh:mm:ss[.fraction](Z | ±hh:mm))." ; ] . @@ -110,9 +110,9 @@ five-safes-crate:CheckValueEndTimeMustFollowISOStandard a sh:PropertyShape ; sh:name "EndTime" ; sh:path schema:endTime ; - sh:pattern "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|[+-][0-9]{2}:[0-9]{2})$" ; + 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 "`CheckValue` --> `endTime` MUST follows the RFC 3339 standard." ; + sh:message "`CheckValue` --> `endTime` MUST follows the RFC 3339 standard (YYYY-MM-DD'T'hh:mm:ss[.fraction](Z | ±hh:mm))." ; ] . diff --git a/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py b/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py index fe6bff0e..5cc974cc 100644 --- a/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py +++ b/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py @@ -134,7 +134,10 @@ def test_5src_check_value_start_time_not_iso_standard(): requirement_severity=Severity.REQUIRED, expected_validation_result=False, expected_triggered_requirements=["CheckValue"], - expected_triggered_issues=["`CheckValue` --> `startTime` MUST follows the RFC 3339 standard."], + expected_triggered_issues=[( + "`CheckValue` --> `startTime` MUST follows the RFC 3339 standard " + "(YYYY-MM-DD'T'hh:mm:ss[.fraction](Z | ±hh:mm))." + )], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, ) @@ -163,7 +166,10 @@ def test_5src_check_value_end_time_not_iso_standard(): requirement_severity=Severity.REQUIRED, expected_validation_result=False, expected_triggered_requirements=["CheckValue"], - expected_triggered_issues=["`CheckValue` --> `endTime` MUST follows the RFC 3339 standard."], + expected_triggered_issues=[( + "`CheckValue` --> `endTime` MUST follows the RFC 3339 standard " + "(YYYY-MM-DD'T'hh:mm:ss[.fraction](Z | ±hh:mm))." + )], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, ) From 6635be988ef847bfbf0dc6613d42534e9ba50357 Mon Sep 17 00:00:00 2001 From: EttoreM Date: Wed, 10 Dec 2025 08:25:40 +0000 Subject: [PATCH 12/13] Allowed for comma to separate seconds from fractions of seconds in timestamps. --- .../profiles/five-safes-crate/must/12_check_phase.ttl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rocrate_validator/profiles/five-safes-crate/must/12_check_phase.ttl b/rocrate_validator/profiles/five-safes-crate/must/12_check_phase.ttl index 5567c82b..00cacdb5 100644 --- a/rocrate_validator/profiles/five-safes-crate/must/12_check_phase.ttl +++ b/rocrate_validator/profiles/five-safes-crate/must/12_check_phase.ttl @@ -82,7 +82,7 @@ five-safes-crate:CheckValueStartTimeMustFollowISOStandard a sh:PropertyShape ; sh:name "StartTime" ; sh:path schema:startTime ; - 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: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 "`CheckValue` --> `startTime` MUST follows the RFC 3339 standard (YYYY-MM-DD'T'hh:mm:ss[.fraction](Z | ±hh:mm))." ; ] . @@ -110,7 +110,7 @@ five-safes-crate:CheckValueEndTimeMustFollowISOStandard a sh:PropertyShape ; sh:name "EndTime" ; sh:path schema:endTime ; - 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: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 "`CheckValue` --> `endTime` MUST follows the RFC 3339 standard (YYYY-MM-DD'T'hh:mm:ss[.fraction](Z | ±hh:mm))." ; ] . From eb5384a84709c21b38c61f2f661c0a28ff84a6a5 Mon Sep 17 00:00:00 2001 From: EttoreM Date: Thu, 25 Dec 2025 16:29:56 +0000 Subject: [PATCH 13/13] Addressed Doug's comments on this PR. --- .../five-safes-crate/must/12_check_phase.ttl | 5 +- .../should/12_check_phase.ttl | 2 +- .../test_5src_12_check_phase.py | 75 ++++++++----------- 3 files changed, 35 insertions(+), 47 deletions(-) diff --git a/rocrate_validator/profiles/five-safes-crate/must/12_check_phase.ttl b/rocrate_validator/profiles/five-safes-crate/must/12_check_phase.ttl index 00cacdb5..b64c29c6 100644 --- a/rocrate_validator/profiles/five-safes-crate/must/12_check_phase.ttl +++ b/rocrate_validator/profiles/five-safes-crate/must/12_check_phase.ttl @@ -52,12 +52,11 @@ five-safes-crate:CheckValueObjectHasDescriptiveNameAndIsAssessAction sh:property [ sh:a sh:PropertyShape ; sh:name "name" ; - sh:description "CheckValue MUST have a human readable name string of at least 20 characters." ; + sh:description "CheckValue MUST have a human readable name string." ; sh:path schema:name ; sh:datatype xsd:string ; - sh:minLength 20 ; sh:severity sh:Violation ; - sh:message "CheckValue MUST have a human readable name string of at least 20 characters." ; + sh:message "CheckValue MUST have a human readable name string." ; ] . five-safes-crate:CheckValueStartTimeMustFollowISOStandard diff --git a/rocrate_validator/profiles/five-safes-crate/should/12_check_phase.ttl b/rocrate_validator/profiles/five-safes-crate/should/12_check_phase.ttl index 0560cc15..4cd77608 100644 --- a/rocrate_validator/profiles/five-safes-crate/should/12_check_phase.ttl +++ b/rocrate_validator/profiles/five-safes-crate/should/12_check_phase.ttl @@ -70,7 +70,7 @@ five-safes-crate:CheckValueObjectShouldPointToRootDataEntity sh:name "object" ; sh:path schema:object ; sh:minCount 1 ; - sh:hasValue <./> ; + sh:hasValue ro-crate:RootDataEntity ; sh:severity sh:Warning ; sh:message "`CheckValue` --> `object` SHOULD point to the root of the RO-Crate" ; ] . diff --git a/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py b/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py index 5cc974cc..08dceba5 100644 --- a/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py +++ b/tests/integration/profiles/five-safes-crate/test_5src_12_check_phase.py @@ -24,6 +24,7 @@ # ----- MUST fails tests + # TO BE CHECKED AGAIN def test_5src_check_value_not_of_type_assess_action(): sparql = """ @@ -65,7 +66,7 @@ def test_5src_check_value_name_not_a_string(): ?this schema:name ?name . } INSERT { - ?this schema:name 123 . + ?this schema:name "123"^^xsd:integer . } WHERE { ?this schema:additionalType shp:CheckValue . @@ -77,35 +78,9 @@ def test_5src_check_value_name_not_a_string(): requirement_severity=Severity.REQUIRED, expected_validation_result=False, expected_triggered_requirements=["CheckValue"], - expected_triggered_issues=["CheckValue MUST have a human readable name string of at least 20 characters."], - profile_identifier="five-safes-crate", - rocrate_entity_mod_sparql=sparql, - ) - - -def test_5src_check_value_name_not_long_enough(): - sparql = """ - PREFIX schema: - PREFIX shp: - PREFIX rdf: - - DELETE { - ?this schema:name ?name . - } - INSERT { - ?this schema:name "Short" . - } - WHERE { - ?this schema:additionalType shp:CheckValue . - } - """ - - do_entity_test( - rocrate_path=ValidROC().five_safes_crate_result, - requirement_severity=Severity.REQUIRED, - expected_validation_result=False, - expected_triggered_requirements=["CheckValue"], - expected_triggered_issues=["CheckValue MUST have a human readable name string of at least 20 characters."], + expected_triggered_issues=[ + "CheckValue MUST have a human readable name string." + ], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, ) @@ -134,10 +109,12 @@ def test_5src_check_value_start_time_not_iso_standard(): requirement_severity=Severity.REQUIRED, expected_validation_result=False, expected_triggered_requirements=["CheckValue"], - expected_triggered_issues=[( - "`CheckValue` --> `startTime` MUST follows the RFC 3339 standard " - "(YYYY-MM-DD'T'hh:mm:ss[.fraction](Z | ±hh:mm))." - )], + expected_triggered_issues=[ + ( + "`CheckValue` --> `startTime` MUST follows the RFC 3339 standard " + "(YYYY-MM-DD'T'hh:mm:ss[.fraction](Z | ±hh:mm))." + ) + ], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, ) @@ -166,10 +143,12 @@ def test_5src_check_value_end_time_not_iso_standard(): requirement_severity=Severity.REQUIRED, expected_validation_result=False, expected_triggered_requirements=["CheckValue"], - expected_triggered_issues=[( - "`CheckValue` --> `endTime` MUST follows the RFC 3339 standard " - "(YYYY-MM-DD'T'hh:mm:ss[.fraction](Z | ±hh:mm))." - )], + expected_triggered_issues=[ + ( + "`CheckValue` --> `endTime` MUST follows the RFC 3339 standard " + "(YYYY-MM-DD'T'hh:mm:ss[.fraction](Z | ±hh:mm))." + ) + ], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, ) @@ -198,7 +177,9 @@ def test_5src_check_value_has_action_status_with_not_allowed_value(): requirement_severity=Severity.REQUIRED, expected_validation_result=False, expected_triggered_requirements=["CheckValue"], - expected_triggered_issues=["`CheckValue` --> `actionStatus` MUST have one of the allowed values."], + expected_triggered_issues=[ + "`CheckValue` --> `actionStatus` MUST have one of the allowed values." + ], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, ) @@ -206,6 +187,7 @@ def test_5src_check_value_has_action_status_with_not_allowed_value(): # ----- SHOULD fails tests + def test_5src_root_data_entity_does_not_mention_check_value_entity(): sparql = """ PREFIX schema: @@ -224,7 +206,9 @@ def test_5src_root_data_entity_does_not_mention_check_value_entity(): requirement_severity=Severity.RECOMMENDED, expected_validation_result=False, expected_triggered_requirements=["RootDataEntity"], - expected_triggered_issues=["RootDataEntity SHOULD mention a check value object."], + expected_triggered_issues=[ + "RootDataEntity SHOULD mention a check value object." + ], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, ) @@ -251,7 +235,9 @@ def test_5src_check_value_object_does_not_point_to_root_data_entity(): requirement_severity=Severity.RECOMMENDED, expected_validation_result=False, expected_triggered_requirements=["CheckValue"], - expected_triggered_issues=["`CheckValue` --> `object` SHOULD point to the root of the RO-Crate"], + expected_triggered_issues=[ + "`CheckValue` --> `object` SHOULD point to the root of the RO-Crate" + ], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, ) @@ -283,7 +269,7 @@ def test_5src_check_value_instrument_does_not_point_to_entity_with_type_defined_ expected_triggered_requirements=["CheckValue"], expected_triggered_issues=[ "`CheckValue` --> `instrument` SHOULD point to an entity typed `schema:DefinedTerm`" - ], + ], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, ) @@ -361,7 +347,9 @@ def test_5src_check_value_does_not_point_to_an_agent(): requirement_severity=Severity.RECOMMENDED, expected_validation_result=False, expected_triggered_requirements=["CheckValue"], - expected_triggered_issues=["`CheckValue` --> `agent` SHOULD reference the agent who initiated the check"], + expected_triggered_issues=[ + "`CheckValue` --> `agent` SHOULD reference the agent who initiated the check" + ], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, ) @@ -369,6 +357,7 @@ def test_5src_check_value_does_not_point_to_an_agent(): # ----- MAY fails tests + def test_5src_check_value_does_not_have_start_time(): sparql = """ PREFIX schema: