Closed danaivach closed 8 months ago
Example test in ArtifactProfileGraphWriterTest
:
@Test
public void testWriteArtifactProfileWithSignifier() throws IOException {
String expectedProfile = PREFIXES +
".\n" +
"<urn:profile> a hmas:ResourceProfile ;\n" +
" hmas:isProfileOf [ a hmas:Artifact ];\n" +
" hmas:exposesSignifier [ a hmas:Signifier ;\n" +
" hmas:signifies [ a sh:NodeShape ;\n" +
" sh:class hmas:ActionExecution ;\n" +
" sh:property [\n" +
" sh:path prov:used ;\n" +
" sh:minCount 1 ;\n" +
" sh:maxCount 1;\n" +
" sh:hasValue <urn:3g6lpq9v> ;\n" +
" ]\n" +
" ]\n" +
"] .\n" +
"<urn:3g6lpq9v> a hctl:Form ;\n" + //here the URN is randomly generated
" hctl:hasTarget <https://example.org/resource> .";
ActionSpecification actionSpec = new ActionSpecification.Builder(BASIC_FORM).build();
ArtifactProfile profile =
new ArtifactProfile.Builder(new Artifact.Builder().build())
.setIRIAsString("urn:profile")
.exposeSignifier(new Signifier.Builder(actionSpec).build())
.build();
assertIsomorphicGraphs(expectedProfile, profile);
}
Example test in ArtifactProfileGraphReaderTest
:
@Test
public void testReadActionSpecWithHTTPMethod() {
String expectedProfile = PREFIXES +
".\n" +
"<urn:profile> a hmas:ResourceProfile ;\n" +
" hmas:isProfileOf [ a hmas:Artifact ];\n" +
" hmas:exposesSignifier [ a hmas:Signifier ;\n" +
" hmas:signifies [ a sh:NodeShape ;\n" +
" sh:class hmas:ActionExecution ;\n" +
" sh:property [\n" +
" sh:path prov:used ;\n" +
" sh:minCount 1 ;\n" +
" sh:maxCount 1;\n" +
" sh:hasValue <urn:3g6lpq9v> ;\n" +
" ]\n" +
" ]\n" +
"] .\n" +
"<urn:3g6lpq9v> a hctl:Form ;\n" + //here the URN is randomly generated
" hctl:hasTarget <https://example.org/resource> .";
ArtifactProfile profile =
ArtifactProfileGraphReader.readFromString(expectedProfile);
Artifact artifact = profile.getArtifact();
assertEquals(ARTIFACT, artifact.getTypeAsIRI());
assertFalse(artifact.getIRI().isPresent());
assertEquals(1, profile.getExposedSignifiers().size());
Set<Signifier> signifiers = profile.getExposedSignifiers();
List<Signifier> signifiersList = new ArrayList<>(signifiers);
Signifier signifier = signifiersList.get(0);
assertEquals(0, signifier.getRecommendedAbilities().size());
ActionSpecification actionSpec = (ActionSpecification) signifier.getBehavioralSpecification();
Set<Form> forms = actionSpec.getForms();
assertEquals(1, forms.size());
Form form = new ArrayList<>(forms).get(0);
assertEquals("https://example.org/resource", form.getTarget());
assertEquals("urn:3g6lpq9v", form.getIRIAsString());
}
Example test in ArtifactProfileGraphWriterTest
with multiple forms:
@Test
public void testWriteArtifactProfileMultipleForms() throws IOException {
String expectedProfile = PREFIXES +
".\n" +
"<urn:profile> a hmas:ResourceProfile ;\n" +
" hmas:isProfileOf [ a hmas:Artifact ];\n" +
" hmas:exposesSignifier [ a hmas:Signifier ;\n" +
" hmas:signifies [ a sh:NodeShape ;\n" +
" sh:class hmas:ActionExecution ;\n" +
" sh:property [\n" +
" sh:path prov:used ;\n" +
" sh:minCount 1 ;\n" +
" sh:maxCount 1;\n" +
" sh:or (;\n" +
" [ sh:hasValue <urn:3g6lpq9v> ]\n" +
" [ sh:hasValue <urn:x7aym3hn> ]\n" +
" ) ;\n" +
" ]\n" +
" ]\n" +
"] .\n" +
"<urn:3g6lpq9v> a hctl:Form ;\n" + //here the URN is randomly generated
" hctl:hasTarget <https://example.org/resource> .\n" +
"<urn:x7aym3hn> a hctl:Form ;\n" + //here the URN is randomly generated
" hctl:hasTarget <coaps://example.org/resource> .";
Form coapForm = new Form.Builder("coaps://example.org/resource").build();
Set<Form> forms = new HashSet<>(Arrays.asList(BASIC_FORM, coapForm));
ActionSpecification actionSpec = new ActionSpecification.Builder(forms).build();
ArtifactProfile profile =
new ArtifactProfile.Builder(new Artifact.Builder().build())
.setIRIAsString("urn:profile")
.exposeSignifier(new Signifier.Builder(actionSpec).build())
.build();
assertIsomorphicGraphs(expectedProfile, profile);
}
Example test in ArtifactProfileGraphReaderTest
with multiple forms:
@Test
public void testReadArtifactProfileMultipleForms() throws IOException {
String expectedProfile = PREFIXES +
".\n" +
"<urn:profile> a hmas:ResourceProfile ;\n" +
" hmas:isProfileOf [ a hmas:Artifact ];\n" +
" hmas:exposesSignifier [ a hmas:Signifier ;\n" +
" hmas:signifies [ a sh:NodeShape ;\n" +
" sh:class hmas:ActionExecution ;\n" +
" sh:property [\n" +
" sh:path prov:used ;\n" +
" sh:minCount 1 ;\n" +
" sh:maxCount 1;\n" +
" sh:or (;\n" +
" [ sh:hasValue <urn:3g6lpq9v> ]\n" +
" [ sh:hasValue <urn:x7aym3hn> ]\n" +
" ) ;\n" +
" ]\n" +
" ]\n" +
"] .\n" +
"<urn:3g6lpq9v> a hctl:Form ;\n" + //here the URN is randomly generated
" hctl:hasTarget <https://example.org/resource> .\n" +
"<urn:x7aym3hn> a hctl:Form ;\n" + //here the URN is randomly generated
" hctl:hasTarget <coaps://example.org/resource> .";
ArtifactProfile profile =
ArtifactProfileGraphReader.readFromString(expectedProfile);
Artifact artifact = profile.getArtifact();
assertEquals(ARTIFACT, artifact.getTypeAsIRI());
assertFalse(artifact.getIRI().isPresent());
assertEquals(1, profile.getExposedSignifiers().size());
Set<Signifier> signifiers = profile.getExposedSignifiers();
List<Signifier> signifiersList = new ArrayList<>(signifiers);
Signifier signifier = signifiersList.get(0);
assertEquals(0, signifier.getRecommendedAbilities().size());
ActionSpecification actionSpec = (ActionSpecification) signifier.getBehavioralSpecification();
Set<Form> forms = actionSpec.getForms();
assertEquals(2, forms.size());
assertTrue(forms.stream().anyMatch(form ->
"https://example.org/resource".equals(form.getTarget()) && "urn:3g6lpq9v".equals(form.getIRIAsString()) ));
assertTrue(forms.stream().anyMatch(form ->
"coaps://example.org/resource".equals(form.getTarget()) && "urn:x7aym3hn".equals(form.getIRIAsString()) ));
}
An option (presented in the examples above) is to create a class ActionSpecification
(maybe subclass of AbstractResource
, with the type
attribute set by default to SHACL.TERM.NODESHAPE
), that can be initialized with minimum one Form
(later, optionally with an input etc.).
When serializing an ActionSpecification
(along with its forms, input etc.) the SHACL and PROV vocabularies are used).
@alessandro-marcantoni, let me know of any alternatives you are considering. You can write here a couple of example tests (e.g. one for the reader and one for the writer), like the ones provided above, that use your proposed abstractions!
@alessandro-marcantoni, please, also test how this hmas:ActionExecution
validates against the relevant ActionSpecification
: https://github.com/HyperAgents/hmas/issues/116#issuecomment-1609123326
Feature: read and write a signifier like the following: