From 9584ab7549ecf7ab20fe1e6db28f3c900d9a5392 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Mon, 12 Jun 2023 09:12:40 +0200 Subject: [PATCH] fix: Make root storage subject of storage description --- src/server/description/StorageDescriptionHandler.ts | 12 ++++++++++-- test/integration/WebHookChannel2023.test.ts | 2 +- test/integration/WebSocketChannel2023.test.ts | 2 +- .../description/StorageDescriptionHandler.test.ts | 4 ++-- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/server/description/StorageDescriptionHandler.ts b/src/server/description/StorageDescriptionHandler.ts index 27169d658..244a9904f 100644 --- a/src/server/description/StorageDescriptionHandler.ts +++ b/src/server/description/StorageDescriptionHandler.ts @@ -1,6 +1,7 @@ import { OkResponseDescription } from '../../http/output/response/OkResponseDescription'; import type { ResponseDescription } from '../../http/output/response/ResponseDescription'; import { BasicRepresentation } from '../../http/representation/BasicRepresentation'; +import type { ResourceIdentifier } from '../../http/representation/ResourceIdentifier'; import type { ResourceStore } from '../../storage/ResourceStore'; import { INTERNAL_QUADS } from '../../util/ContentTypes'; import { MethodNotAllowedHttpError } from '../../util/errors/MethodNotAllowedHttpError'; @@ -32,7 +33,7 @@ export class StorageDescriptionHandler extends OperationHttpHandler { if (method !== 'GET') { throw new MethodNotAllowedHttpError([ method ], `Only GET requests can target the storage description.`); } - const container = { path: ensureTrailingSlash(target.path.slice(0, -this.path.length)) }; + const container = this.getStorageIdentifier(target); const representation = await this.store.getRepresentation(container, {}); representation.data.destroy(); if (!representation.metadata.has(RDF.terms.type, PIM.terms.Storage)) { @@ -43,10 +44,17 @@ export class StorageDescriptionHandler extends OperationHttpHandler { } public async handle({ operation: { target }}: OperationHttpHandlerInput): Promise { - const quads = await this.describer.handle(target); + const quads = await this.describer.handle(this.getStorageIdentifier(target)); const representation = new BasicRepresentation(quads, INTERNAL_QUADS); return new OkResponseDescription(representation.metadata, representation.data); } + + /** + * Determine the identifier of the root storage based on the identifier of the root storage description resource. + */ + protected getStorageIdentifier(descriptionIdentifier: ResourceIdentifier): ResourceIdentifier { + return { path: ensureTrailingSlash(descriptionIdentifier.path.slice(0, -this.path.length)) }; + } } diff --git a/test/integration/WebHookChannel2023.test.ts b/test/integration/WebHookChannel2023.test.ts index 41f1853da..e55d5a3c8 100644 --- a/test/integration/WebHookChannel2023.test.ts +++ b/test/integration/WebHookChannel2023.test.ts @@ -97,7 +97,7 @@ describe.each(stores)('A server supporting WebHookChannel2023 using %s', (name, const quads = new Store(new Parser().parse(await response.text())); // Find the notification channel for websockets - const subscriptions = quads.getObjects(storageDescriptionUrl, NOTIFY.terms.subscription, null); + const subscriptions = quads.getObjects(null, NOTIFY.terms.subscription, null); const webhookSubscriptions = subscriptions.filter((channel): boolean => quads.has( quad(channel as NamedNode, NOTIFY.terms.channelType, namedNode(`${NOTIFY.namespace}WebHookChannel2023`)), )); diff --git a/test/integration/WebSocketChannel2023.test.ts b/test/integration/WebSocketChannel2023.test.ts index 4d896fd1e..c01979b77 100644 --- a/test/integration/WebSocketChannel2023.test.ts +++ b/test/integration/WebSocketChannel2023.test.ts @@ -86,7 +86,7 @@ describe.each(stores)('A server supporting WebSocketChannel2023 using %s', (name const quads = new Store(new Parser().parse(await response.text())); // Find the notification channel for websockets - const subscriptions = quads.getObjects(storageDescriptionUrl, NOTIFY.terms.subscription, null); + const subscriptions = quads.getObjects(null, NOTIFY.terms.subscription, null); const websocketSubscriptions = subscriptions.filter((channel): boolean => quads.has( quad(channel as NamedNode, NOTIFY.terms.channelType, namedNode(`${NOTIFY.namespace}WebSocketChannel2023`)), )); diff --git a/test/unit/server/description/StorageDescriptionHandler.test.ts b/test/unit/server/description/StorageDescriptionHandler.test.ts index 54f1409e0..6703cdaaa 100644 --- a/test/unit/server/description/StorageDescriptionHandler.test.ts +++ b/test/unit/server/description/StorageDescriptionHandler.test.ts @@ -83,8 +83,8 @@ describe('A StorageDescriptionHandler', (): void => { expect(result.metadata?.contentType).toBe('internal/quads'); expect(result.data).toBeDefined(); const quads = await readableToQuads(result.data!); - expect(quads.countQuads(operation.target.path, RDF.terms.type, PIM.terms.Storage, null)).toBe(1); + expect(quads.countQuads('http://example.com/', RDF.terms.type, PIM.terms.Storage, null)).toBe(1); expect(describer.handle).toHaveBeenCalledTimes(1); - expect(describer.handle).toHaveBeenLastCalledWith(operation.target); + expect(describer.handle).toHaveBeenLastCalledWith({ path: 'http://example.com/' }); }); });