From 2d4d9d19ac55537517018e3e1e5c2a1ae017bd26 Mon Sep 17 00:00:00 2001 From: Tomasz Pluskiewicz Date: Tue, 5 Nov 2024 10:55:15 +0100 Subject: [PATCH 1/4] feat(shared-dimension): contributors --- .changeset/big-humans-obey.md | 5 + apis/core/README.md | 1 + apis/core/lib/auth.ts | 5 + apis/shared-dimensions/hydra/index.ttl | 2 +- .../lib/domain/shared-dimension.ts | 30 +- .../lib/handlers/resource.ts | 22 +- .../lib/handlers/shared-dimension.ts | 26 +- .../lib/handlers/shared-dimensions.ts | 1 + .../lib/shapes/shared-dimension.ts | 22 ++ apis/shared-dimensions/lib/store/shapes.ttl | 14 + .../test/lib/domain/managed-dimension.test.ts | 289 +++++++++++++++++- e2e-tests/shared-dimensions/term-set.hydra | 5 + 12 files changed, 388 insertions(+), 34 deletions(-) create mode 100644 .changeset/big-humans-obey.md diff --git a/.changeset/big-humans-obey.md b/.changeset/big-humans-obey.md new file mode 100644 index 000000000..3be176e8d --- /dev/null +++ b/.changeset/big-humans-obey.md @@ -0,0 +1,5 @@ +--- +"@cube-creator/shared-dimensions-api": patch +--- + +Added `Contributors` to shared dimension diff --git a/apis/core/README.md b/apis/core/README.md index cbe915631..71e2bfaa8 100644 --- a/apis/core/README.md +++ b/apis/core/README.md @@ -20,6 +20,7 @@ The API is secured with a JWT middleware. To configure set these environment var In the local environment it is possible to authorize requests with HTTP headers serving as a testing backdoor - `X-USER` - the user id +- `X-EMAIL` - the user email - `X-PERMISSION` - authorized permissions (multiple values allowed) ### Debugging diff --git a/apis/core/lib/auth.ts b/apis/core/lib/auth.ts index 1cd43a8bb..d37b6fd24 100644 --- a/apis/core/lib/auth.ts +++ b/apis/core/lib/auth.ts @@ -14,6 +14,7 @@ declare module '@hydrofoil/labyrinth' { export interface User { sub: string name: string + email?: string permissions: string[] } } @@ -46,11 +47,15 @@ function devAuthHandler(req: Request, res: Response, next: NextFunction) { if (sub) { const permissionHeader = req.headers['x-permission'] + const emailHeader = req.headers['x-email'] + const permissions = typeof permissionHeader === 'string' ? permissionHeader.split(',').map(s => s.trim()) : permissionHeader || [] + const email = typeof emailHeader === 'string' ? emailHeader : (emailHeader || []).shift() req.user = { sub, name: sub, + email, permissions, } diff --git a/apis/shared-dimensions/hydra/index.ttl b/apis/shared-dimensions/hydra/index.ttl index aa45cd689..d55331b2a 100644 --- a/apis/shared-dimensions/hydra/index.ttl +++ b/apis/shared-dimensions/hydra/index.ttl @@ -263,7 +263,7 @@ md:SharedDimension code:implementedBy [ a code:EcmaScript ; - code:link ; + code:link ; ] ; ] ; . diff --git a/apis/shared-dimensions/lib/domain/shared-dimension.ts b/apis/shared-dimensions/lib/domain/shared-dimension.ts index 29f556a59..8e3c071fe 100644 --- a/apis/shared-dimensions/lib/domain/shared-dimension.ts +++ b/apis/shared-dimensions/lib/domain/shared-dimension.ts @@ -21,9 +21,13 @@ export { importDimension } from './shared-dimension/import' interface CreateSharedDimension { resource: GraphPointer store: SharedDimensionsStore + contributor: { + name: string + email?: string + } } -export async function create({ resource, store }: CreateSharedDimension): Promise { +export async function create({ resource, store, contributor }: CreateSharedDimension): Promise { const identifier = resource.out(dcterms.identifier).value if (!identifier) { throw new DomainError('Missing dimension identifier') @@ -40,6 +44,8 @@ export async function create({ resource, store }: CreateSharedDimension): Promis .addOut(rdf.type, [hydra.Resource, schema.DefinedTermSet, meta.SharedDimension, md.SharedDimension]) .deleteOut(md.createAs) + setDefaultContributor(termSet, contributor) + await store.save(termSet) return termSet } @@ -81,6 +87,10 @@ interface UpdateSharedDimension { store: SharedDimensionsStore shape: MultiPointer | undefined queries?: typeof queries + contributor: { + name: string + email?: string + } } function removeSubgraph(pointer: GraphPointer, predicate?: Term) { @@ -92,7 +102,7 @@ function removeSubgraph(pointer: GraphPointer, predicate?: Term) { } } -export async function update({ resource, store, shape, queries }: UpdateSharedDimension): Promise { +export async function update({ resource, store, shape, queries, contributor }: UpdateSharedDimension): Promise { const ignoredProperties = shape ?.out(sh.ignoredProperties) .list() || [] @@ -107,6 +117,8 @@ export async function update({ resource, store, shape, queries }: UpdateSharedDi deletedProperties.delete(prop) } + setDefaultContributor(resource, contributor) + await store.save(resource) await queries?.deleteDynamicTerms({ dimension: resource.term, @@ -116,6 +128,20 @@ export async function update({ resource, store, shape, queries }: UpdateSharedDi return resource } +function setDefaultContributor(termSet: GraphPointer, contributor: { + name: string + email?: string +}) { + if (termSet.out(dcterms.contributor).terms.length === 0) { + termSet.addOut(dcterms.contributor, contributorPtr => { + contributorPtr.addOut(schema.name, contributor.name) + if (contributor.email) { + contributorPtr.addOut(schema.email, contributor.email) + } + }) + } +} + interface GetExportedDimension { resource: NamedNode store: SharedDimensionsStore diff --git a/apis/shared-dimensions/lib/handlers/resource.ts b/apis/shared-dimensions/lib/handlers/resource.ts index 25cdc8a3b..0d49520d8 100644 --- a/apis/shared-dimensions/lib/handlers/resource.ts +++ b/apis/shared-dimensions/lib/handlers/resource.ts @@ -1,15 +1,11 @@ import asyncMiddleware from 'middleware-async' import { NO_CONTENT } from 'http-status' -import clownface, { GraphPointer } from 'clownface' +import clownface from 'clownface' import { protectedResource } from '@hydrofoil/labyrinth/resource' -import { hydra } from '@tpluscode/rdf-ns-builders/strict' import { store } from '../store' import { cascadeDelete } from '../domain/resource' import { shaclValidate } from '../middleware/shacl' -import shapes from '../shapes/index' -import { update } from '../domain/shared-dimension' import { rewrite } from '../rewrite' -import * as queries from '../domain/shared-dimension/queries' export const DELETE = protectedResource(asyncMiddleware(async (req, res) => { await cascadeDelete({ @@ -22,18 +18,8 @@ export const DELETE = protectedResource(asyncMiddleware(async (req, res) => { })) export const put = protectedResource(shaclValidate, asyncMiddleware(async (req, res) => { - const hydraExpects = req.hydra.operation.out(hydra.expects).term - let shape: GraphPointer | undefined - if (hydraExpects?.termType === 'NamedNode') { - shape = await shapes.get(hydraExpects)?.(req) - } + const resource = rewrite(await req.resource()) + await store().save(resource) - const dimension = await update({ - resource: rewrite(await req.resource()), - store: store(), - shape, - queries, - }) - - return res.dataset(dimension.dataset) + return res.dataset(resource.dataset) })) diff --git a/apis/shared-dimensions/lib/handlers/shared-dimension.ts b/apis/shared-dimensions/lib/handlers/shared-dimension.ts index f32dc5ade..339560b8c 100644 --- a/apis/shared-dimensions/lib/handlers/shared-dimension.ts +++ b/apis/shared-dimensions/lib/handlers/shared-dimension.ts @@ -1,17 +1,19 @@ import asyncMiddleware from 'middleware-async' import { protectedResource } from '@hydrofoil/labyrinth/resource' -import clownface from 'clownface' +import clownface, { GraphPointer } from 'clownface' import { schema } from '@tpluscode/rdf-ns-builders/strict' import cors from 'cors' import { serializers } from '@rdfjs-elements/formats-pretty' import error from 'http-errors' import { md, meta } from '@cube-creator/core/namespace' import * as ns from '@tpluscode/rdf-ns-builders' -import { oa } from '@tpluscode/rdf-ns-builders' -import { createTerm, getExportedDimension } from '../domain/shared-dimension' +import { hydra, oa } from '@tpluscode/rdf-ns-builders' +import { createTerm, getExportedDimension, update } from '../domain/shared-dimension' import { store } from '../store' import { shaclValidate } from '../middleware/shacl' import { rewrite } from '../rewrite' +import shapes from '../shapes' +import * as queries from '../domain/shared-dimension/queries' export const post = protectedResource(shaclValidate, asyncMiddleware(async (req, res) => { const term = await createTerm({ @@ -27,6 +29,24 @@ export const post = protectedResource(shaclValidate, asyncMiddleware(async (req, return res.dataset(term.dataset) })) +export const put = protectedResource(shaclValidate, asyncMiddleware(async (req, res) => { + const hydraExpects = req.hydra.operation.out(hydra.expects).term + let shape: GraphPointer | undefined + if (hydraExpects?.termType === 'NamedNode') { + shape = await shapes.get(hydraExpects)?.(req) + } + + const dimension = await update({ + resource: rewrite(await req.resource()), + store: store(), + shape, + queries, + contributor: req.user!, + }) + + return res.dataset(dimension.dataset) +})) + export const getExport = protectedResource(cors({ exposedHeaders: 'content-disposition' }), asyncMiddleware(async (req, res, next) => { if (!req.dataset) { return next(new error.BadRequest()) diff --git a/apis/shared-dimensions/lib/handlers/shared-dimensions.ts b/apis/shared-dimensions/lib/handlers/shared-dimensions.ts index 7c57917d6..00047987f 100644 --- a/apis/shared-dimensions/lib/handlers/shared-dimensions.ts +++ b/apis/shared-dimensions/lib/handlers/shared-dimensions.ts @@ -108,6 +108,7 @@ const postDirect = protectedResource(shaclValidate, asyncMiddleware(async (req, const pointer = await create({ resource: rewrite(await req.resource()), store: store(), + contributor: req.user!, }) res.setHeader('Location', pointer.value) diff --git a/apis/shared-dimensions/lib/shapes/shared-dimension.ts b/apis/shared-dimensions/lib/shapes/shared-dimension.ts index b8fc2bd7f..4e99dc4db 100644 --- a/apis/shared-dimensions/lib/shapes/shared-dimension.ts +++ b/apis/shared-dimensions/lib/shapes/shared-dimension.ts @@ -297,6 +297,28 @@ const properties: Initializer[] = [{ }], })], }, +}, { + name: 'Contributors', + description: 'Currently logged-in user will be used, if not set', + path: dcterms.contributor, + order: 50, + nodeKind: sh.BlankNode, + group: propertyGroup({ + label: 'Contributors', + }), + node: { + property: [{ + name: 'Name', + path: schema.name, + minCount: 1, + maxCount: 1, + }, { + name: 'Email', + path: schema.email, + minCount: 1, + maxCount: 1, + }], + }, }] export const create = (): Initializer => ({ diff --git a/apis/shared-dimensions/lib/store/shapes.ttl b/apis/shared-dimensions/lib/store/shapes.ttl index ee0e261bc..550b1409f 100644 --- a/apis/shared-dimensions/lib/store/shapes.ttl +++ b/apis/shared-dimensions/lib/store/shapes.ttl @@ -1,3 +1,4 @@ +PREFIX dcterm: PREFIX time: PREFIX qudt: PREFIX meta: @@ -82,6 +83,19 @@ PREFIX sh: sh:path sh:languageIn ; ] ; ] ; + ], + [ + sh:path dcterm:contributor ; + sh:node + [ + sh:property + [ + sh:path schema:name ; + ] , + [ + sh:path schema:email ; + ] ; + ] ] ; ] . diff --git a/apis/shared-dimensions/test/lib/domain/managed-dimension.test.ts b/apis/shared-dimensions/test/lib/domain/managed-dimension.test.ts index d134ae19a..08aa6d743 100644 --- a/apis/shared-dimensions/test/lib/domain/managed-dimension.test.ts +++ b/apis/shared-dimensions/test/lib/domain/managed-dimension.test.ts @@ -9,7 +9,7 @@ import { md, meta } from '@cube-creator/core/namespace' import $rdf from 'rdf-ext' import httpError from 'http-errors' import clownface from 'clownface' -import sinon from 'sinon' +import sinon, { SinonSpy } from 'sinon' import { ex } from '@cube-creator/testing/lib/namespace' import { create, createTerm, update, getExportedDimension } from '../../../lib/domain/shared-dimension' import { SharedDimensionsStore } from '../../../lib/store' @@ -19,9 +19,17 @@ import { validateTermSet } from '../../../lib/domain/shared-dimension/import' describe('@cube-creator/shared-dimensions-api/lib/domain/shared-dimension', () => { describe('create', () => { let store: SharedDimensionsStore + let contributor: { + name: string + email?: string + } beforeEach(() => { store = testStore() + contributor = { + name: 'John Doe', + email: 'john@doe.tech', + } }) it('creates id using provided identifier', async () => { @@ -30,19 +38,120 @@ describe('@cube-creator/shared-dimensions-api/lib/domain/shared-dimension', () = .addOut(dcterms.identifier, 'canton') // when - const termSet = await create({ resource, store }) + const termSet = await create({ resource, store, contributor }) // then expect(termSet.value).to.eq('https://ld.admin.ch/cube/dimension/canton') }) + it('sets default contributor', async () => { + // given + const resource = namedNode('') + .addOut(dcterms.identifier, 'canton') + + // when + const termSet = await create({ resource, store, contributor }) + + // then + expect(termSet).to.matchShape({ + property: [{ + path: [ + dcterms.contributor, + schema.name, + ], + hasValue: 'John Doe', + minCount: 1, + maxCount: 1, + }, { + path: [ + dcterms.contributor, + schema.email, + ], + hasValue: 'john@doe.tech', + minCount: 1, + maxCount: 1, + }], + }) + }) + + it('default contributor can have no email', async () => { + // given + const resource = namedNode('') + .addOut(dcterms.identifier, 'canton') + + // when + const termSet = await create({ + resource, + store, + contributor: { + name: 'John Doe', + }, + }) + + // then + expect(termSet).to.matchShape({ + property: [{ + path: [ + dcterms.contributor, + schema.name, + ], + hasValue: 'John Doe', + minCount: 1, + maxCount: 1, + }, { + path: [ + dcterms.contributor, + schema.email, + ], + maxCount: 0, + }], + }) + }) + + it('keeps payload contributor if present', async () => { + // given + const resource = namedNode('') + .addOut(dcterms.identifier, 'canton') + .addOut(dcterms.contributor, contributorPtr => { + contributorPtr.addOut(schema.name, 'Jane Doe') + contributorPtr.addOut(schema.email, 'jane@doe.tv') + }) + + // when + const termSet = await create({ resource, store, contributor }) + + // then + expect(termSet).to.matchShape({ + property: [{ + path: dcterms.contributor, + maxCount: 1, + }, { + path: [ + dcterms.contributor, + schema.name, + ], + hasValue: 'Jane Doe', + minCount: 1, + maxCount: 1, + }, { + path: [ + dcterms.contributor, + schema.email, + ], + hasValue: 'jane@doe.tv', + minCount: 1, + maxCount: 1, + }], + }) + }) + it('saves to the store', async () => { // given const resource = namedNode('') .addOut(dcterms.identifier, 'canton') // when - await create({ resource, store }) + await create({ resource, store, contributor }) // then expect(store.save).to.have.been.called @@ -54,7 +163,7 @@ describe('@cube-creator/shared-dimensions-api/lib/domain/shared-dimension', () = .addOut(dcterms.identifier, 'canton') // when - const termSet = await create({ resource, store }) + const termSet = await create({ resource, store, contributor }) // then expect(termSet).to.matchShape({ @@ -74,7 +183,7 @@ describe('@cube-creator/shared-dimensions-api/lib/domain/shared-dimension', () = .addOut(md.createAs, 'Import') // when - const termSet = await create({ resource, store }) + const termSet = await create({ resource, store, contributor }) // then expect(termSet).to.matchShape({ @@ -92,7 +201,7 @@ describe('@cube-creator/shared-dimensions-api/lib/domain/shared-dimension', () = .addOut(dcterms.identifier, 'canton') // when - const promise = create({ resource, store }) + const promise = create({ resource, store, contributor }) // then expect(promise).eventually.rejectedWith(httpError.Conflict) @@ -176,11 +285,26 @@ describe('@cube-creator/shared-dimensions-api/lib/domain/shared-dimension', () = }) describe('update', () => { - it('deletes term properties triples when removed from dimensions', async () => { - // given - const queries = { + let store: SharedDimensionsStore + let contributor: { + name: string + email?: string + } + let queries: { deleteDynamicTerms: SinonSpy } + + beforeEach(() => { + queries = { deleteDynamicTerms: sinon.spy(), } + store = testStore() + contributor = { + name: 'John Doe', + email: 'john@doe.tech', + } + }) + + it('deletes term properties triples when removed from dimensions', async () => { + // given const before = namedNode('') .addOut(dcterms.identifier, 'foo') .addOut(schema.name, 'Term set') @@ -190,7 +314,6 @@ describe('@cube-creator/shared-dimensions-api/lib/domain/shared-dimension', () = .addOut(dcterms.identifier, 'foo') .addOut(schema.name, 'Term set') .addOut(schema.additionalProperty, dyn => dyn.addOut(rdf.predicate, ex.bar)) - const store = testStore() await store.save(before) // when @@ -199,6 +322,7 @@ describe('@cube-creator/shared-dimensions-api/lib/domain/shared-dimension', () = shape: blankNode(), resource: after, queries, + contributor, }) // then @@ -208,6 +332,151 @@ describe('@cube-creator/shared-dimensions-api/lib/domain/shared-dimension', () = graph: 'https://lindas.admin.ch/cube/dimension', }) }) + + it('sets default contributor', async () => { + // given + const before = namedNode('') + .addOut(dcterms.identifier, 'foo') + .addOut(schema.name, 'Term set') + .addOut(dcterms.contributor, contributorPtr => { + contributorPtr.addOut(schema.name, 'Jane Doe') + contributorPtr.addOut(schema.email, 'jane@doe.tv') + }) + const after = namedNode('') + .addOut(dcterms.identifier, 'foo') + .addOut(schema.name, 'Term set') + await store.save(before) + + // when + await update({ + store, + shape: blankNode(), + resource: after, + queries, + contributor, + }) + + // then + const termSet = await store.load(after.term) + expect(termSet).to.matchShape({ + property: [{ + path: [ + dcterms.contributor, + schema.name, + ], + hasValue: 'John Doe', + minCount: 1, + maxCount: 1, + }, { + path: [ + dcterms.contributor, + schema.email, + ], + hasValue: 'john@doe.tech', + minCount: 1, + maxCount: 1, + }], + }) + }) + + it('default contributor can have no email', async () => { + // given + const before = namedNode('') + .addOut(dcterms.identifier, 'foo') + .addOut(schema.name, 'Term set') + .addOut(dcterms.contributor, contributorPtr => { + contributorPtr.addOut(schema.name, 'Jane Doe') + contributorPtr.addOut(schema.email, 'jane@doe.tv') + }) + const after = namedNode('') + .addOut(dcterms.identifier, 'foo') + .addOut(schema.name, 'Term set') + await store.save(before) + + // when + await update({ + store, + shape: blankNode(), + resource: after, + queries, + contributor: { + name: 'John Doe', + }, + }) + + // then + const termSet = await store.load(after.term) + expect(termSet).to.matchShape({ + property: [{ + path: [ + dcterms.contributor, + schema.name, + ], + hasValue: 'John Doe', + minCount: 1, + maxCount: 1, + }, { + path: [ + dcterms.contributor, + schema.email, + ], + maxCount: 0, + }], + }) + }) + + it('keeps payload contributor if present', async () => { + // given + const before = namedNode('') + .addOut(dcterms.identifier, 'foo') + .addOut(schema.name, 'Term set') + .addOut(dcterms.contributor, contributorPtr => { + contributorPtr.addOut(schema.name, 'John Doe') + contributorPtr.addOut(schema.email, 'john@doe.tech') + }) + const after = namedNode('') + .addOut(dcterms.identifier, 'foo') + .addOut(schema.name, 'Term set') + .addOut(dcterms.contributor, contributorPtr => { + contributorPtr.addOut(schema.name, 'Jane Doe') + contributorPtr.addOut(schema.email, 'jane@doe.tv') + }) + await store.save(before) + + // when + await update({ + store, + shape: blankNode(), + resource: after, + queries, + contributor, + }) + + // then + const termSet = await store.load(after.term) + expect(termSet).to.matchShape({ + property: [{ + path: dcterms.contributor, + maxCount: 1, + }, { + path: [ + dcterms.contributor, + schema.name, + ], + hasValue: 'Jane Doe', + minCount: 1, + maxCount: 1, + }, { + path: [ + dcterms.contributor, + schema.email, + ], + hasValue: 'jane@doe.tv', + minCount: 1, + maxCount: 1, + }], + }) + }) }) describe('getExportedDimension @SPARQL', () => { diff --git a/e2e-tests/shared-dimensions/term-set.hydra b/e2e-tests/shared-dimensions/term-set.hydra index 6666e6c11..acd7c7189 100644 --- a/e2e-tests/shared-dimensions/term-set.hydra +++ b/e2e-tests/shared-dimensions/term-set.hydra @@ -11,6 +11,7 @@ ENTRYPOINT "dimension/technologies" HEADERS { x-user "john-doe" x-permission "pipelines:write" + x-email "john@doe.tech" } With Class meta:SharedDimension { @@ -43,6 +44,10 @@ With Class meta:SharedDimension { Expect Property oa:canonical { Expect Id } + Expect Property dcterms:contributor { + Expect Property schema:name "John Doe" + Expect Property schema:email "john@doe.tech" + } } Invoke { From 7db0fad1d10609db23bb473bd754b280e175c6f3 Mon Sep 17 00:00:00 2001 From: Tomasz Pluskiewicz Date: Tue, 5 Nov 2024 10:58:33 +0100 Subject: [PATCH 2/4] refactor: extract interface --- .../lib/domain/shared-dimension.ts | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/apis/shared-dimensions/lib/domain/shared-dimension.ts b/apis/shared-dimensions/lib/domain/shared-dimension.ts index 8e3c071fe..2f723a5eb 100644 --- a/apis/shared-dimensions/lib/domain/shared-dimension.ts +++ b/apis/shared-dimensions/lib/domain/shared-dimension.ts @@ -18,13 +18,15 @@ import * as queries from './shared-dimension/queries' export { importDimension } from './shared-dimension/import' +interface Contributor { + name: string + email?: string +} + interface CreateSharedDimension { resource: GraphPointer store: SharedDimensionsStore - contributor: { - name: string - email?: string - } + contributor: Contributor } export async function create({ resource, store, contributor }: CreateSharedDimension): Promise { @@ -87,10 +89,7 @@ interface UpdateSharedDimension { store: SharedDimensionsStore shape: MultiPointer | undefined queries?: typeof queries - contributor: { - name: string - email?: string - } + contributor: Contributor } function removeSubgraph(pointer: GraphPointer, predicate?: Term) { @@ -128,10 +127,7 @@ export async function update({ resource, store, shape, queries, contributor }: U return resource } -function setDefaultContributor(termSet: GraphPointer, contributor: { - name: string - email?: string -}) { +function setDefaultContributor(termSet: GraphPointer, contributor: Contributor) { if (termSet.out(dcterms.contributor).terms.length === 0) { termSet.addOut(dcterms.contributor, contributorPtr => { contributorPtr.addOut(schema.name, contributor.name) From f57c64ae300f74d350234fa5cc1579b027892cc8 Mon Sep 17 00:00:00 2001 From: Tomasz Pluskiewicz Date: Tue, 5 Nov 2024 11:08:02 +0100 Subject: [PATCH 3/4] test: prefix --- e2e-tests/shared-dimensions/term-set.hydra | 1 + 1 file changed, 1 insertion(+) diff --git a/e2e-tests/shared-dimensions/term-set.hydra b/e2e-tests/shared-dimensions/term-set.hydra index acd7c7189..d8a99916b 100644 --- a/e2e-tests/shared-dimensions/term-set.hydra +++ b/e2e-tests/shared-dimensions/term-set.hydra @@ -5,6 +5,7 @@ PREFIX qudt: PREFIX meta: PREFIX sh: PREFIX oa: +PREFIX dcterms: ENTRYPOINT "dimension/technologies" From fd6bba25ae7ee39ecc02f96a70ec03fb7f74023d Mon Sep 17 00:00:00 2001 From: Tomasz Pluskiewicz Date: Tue, 5 Nov 2024 11:33:37 +0100 Subject: [PATCH 4/4] test(e2e): fix contributor assertions --- e2e-tests/shared-dimensions/term-set.hydra | 13 ++++++++----- e2e-tests/shared-dimensions/term-sets.hydra | 6 ++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/e2e-tests/shared-dimensions/term-set.hydra b/e2e-tests/shared-dimensions/term-set.hydra index d8a99916b..d522ea81b 100644 --- a/e2e-tests/shared-dimensions/term-set.hydra +++ b/e2e-tests/shared-dimensions/term-set.hydra @@ -12,7 +12,6 @@ ENTRYPOINT "dimension/technologies" HEADERS { x-user "john-doe" x-permission "pipelines:write" - x-email "john@doe.tech" } With Class meta:SharedDimension { @@ -45,10 +44,6 @@ With Class meta:SharedDimension { Expect Property oa:canonical { Expect Id } - Expect Property dcterms:contributor { - Expect Property schema:name "John Doe" - Expect Property schema:email "john@doe.tech" - } } Invoke { @@ -92,11 +87,19 @@ With Class meta:SharedDimension { schema:validFrom "2021-01-20T23:59:59Z"^^xsd:dateTime ; schema:validThrough "2022-01-20T23:59:59Z"^^xsd:dateTime ; sh:property [ ] ; + dcterms:contributor [ + schema:name "Jane Doe" ; + schema:email "jane@doe.tech" ; + ] ; . ``` } => { Expect Status 200 Expect Property schema:validThrough + Expect Property dcterms:contributor { + Expect Property schema:name "Jane Doe" + Expect Property schema:email "jane@doe.tech" + } } } } diff --git a/e2e-tests/shared-dimensions/term-sets.hydra b/e2e-tests/shared-dimensions/term-sets.hydra index 3981b6e08..2a1327ef2 100644 --- a/e2e-tests/shared-dimensions/term-sets.hydra +++ b/e2e-tests/shared-dimensions/term-sets.hydra @@ -4,12 +4,14 @@ PREFIX schema: PREFIX qudt: PREFIX meta: PREFIX sh: +PREFIX dcterms: ENTRYPOINT "dimension/" HEADERS { x-user "john-doe" x-permission "pipelines:write" + x-email "john@doe.tech" } With Class hydra:Resource { @@ -53,6 +55,10 @@ With Class hydra:Resource { Expect Property qudt:scaleType Expect Property meta:dataKind } + Expect Property dcterms:contributor { + Expect Property schema:name "john-doe" + Expect Property schema:email "john@doe.tech" + } } Invoke {