diff --git a/config/presets/storage-wrapper.json b/config/presets/storage-wrapper.json index 4d8eb4296c..58177e9a2e 100644 --- a/config/presets/storage-wrapper.json +++ b/config/presets/storage-wrapper.json @@ -6,9 +6,6 @@ "@type": "MonitoringStore", "MonitoringStore:_source": { "@id": "urn:solid-server:default:ResourceStore_Locking" - }, - "MonitoringStore:_identifierStrategy": { - "@id": "urn:solid-server:default:IdentifierStrategy" } }, diff --git a/src/storage/DataAccessorBasedStore.ts b/src/storage/DataAccessorBasedStore.ts index c0cf73759d..5a904a47a6 100644 --- a/src/storage/DataAccessorBasedStore.ts +++ b/src/storage/DataAccessorBasedStore.ts @@ -200,13 +200,12 @@ export class DataAccessorBasedStore implements ResourceStore { // Solid, ยง5.4: "When a contained resource is deleted, the server MUST also delete the associated auxiliary // resources" // https://solid.github.io/specification/protocol#deleting-resources - const deleted = []; + const deleted = [ identifier ]; if (!this.auxiliaryStrategy.isAuxiliaryIdentifier(identifier)) { const auxiliaries = this.auxiliaryStrategy.getAuxiliaryIdentifiers(identifier); deleted.push(...await this.safelyDeleteAuxiliaryResources(auxiliaries)); } - - deleted.unshift(...await this.accessor.deleteResource(identifier)); + await this.accessor.deleteResource(identifier); return deleted; } diff --git a/src/storage/MonitoringStore.ts b/src/storage/MonitoringStore.ts index 43647fbbb2..25a1bb42a0 100644 --- a/src/storage/MonitoringStore.ts +++ b/src/storage/MonitoringStore.ts @@ -3,7 +3,6 @@ import type { Patch } from '../ldp/http/Patch'; import type { Representation } from '../ldp/representation/Representation'; import type { RepresentationPreferences } from '../ldp/representation/RepresentationPreferences'; import type { ResourceIdentifier } from '../ldp/representation/ResourceIdentifier'; -import type { IdentifierStrategy } from '../util/identifiers/IdentifierStrategy'; import type { Conditions } from './Conditions'; import type { ResourceStore } from './ResourceStore'; @@ -14,55 +13,43 @@ import type { ResourceStore } from './ResourceStore'; export class MonitoringStore extends EventEmitter implements ResourceStore { private readonly source: T; - private readonly identifierStrategy: IdentifierStrategy; - public constructor(source: T, identifierStrategy: IdentifierStrategy) { + public constructor(source: T) { super(); this.source = source; - this.identifierStrategy = identifierStrategy; + } + + public async getRepresentation(identifier: ResourceIdentifier, preferences: RepresentationPreferences, + conditions?: Conditions): Promise { + return this.source.getRepresentation(identifier, preferences, conditions); } public async addResource(container: ResourceIdentifier, representation: Representation, conditions?: Conditions): Promise { const identifier = await this.source.addResource(container, representation, conditions); - - // Both the container contents and the resource itself have changed - this.emit('changed', container); - this.emit('changed', identifier); - + this.emitChanged([ container, identifier ]); return identifier; } public async deleteResource(identifier: ResourceIdentifier, conditions?: Conditions): Promise { - const modified = await this.source.deleteResource(identifier, conditions); - - // Both the container contents and the resource itself have changed - if (!this.identifierStrategy.isRootContainer(identifier)) { - const container = this.identifierStrategy.getParentContainer(identifier); - this.emit('changed', container); - } - this.emit('changed', identifier); - - return modified; + return this.emitChanged(await this.source.deleteResource(identifier, conditions)); } - public async getRepresentation(identifier: ResourceIdentifier, preferences: RepresentationPreferences, - conditions?: Conditions): Promise { - return this.source.getRepresentation(identifier, preferences, conditions); + public async setRepresentation(identifier: ResourceIdentifier, representation: Representation, + conditions?: Conditions): Promise { + return this.emitChanged(await this.source.setRepresentation(identifier, representation, conditions)); } public async modifyResource(identifier: ResourceIdentifier, patch: Patch, conditions?: Conditions): Promise { - const modified = await this.source.modifyResource(identifier, patch, conditions); - this.emit('changed', identifier); - return modified; + return this.emitChanged(await this.source.modifyResource(identifier, patch, conditions)); } - public async setRepresentation(identifier: ResourceIdentifier, representation: Representation, - conditions?: Conditions): Promise { - const modified = await this.source.setRepresentation(identifier, representation, conditions); - this.emit('changed', identifier); - return modified; + private emitChanged(identifiers: ResourceIdentifier[]): typeof identifiers { + for (const identifier of identifiers) { + this.emit('changed', identifier); + } + return identifiers; } } diff --git a/src/storage/accessors/DataAccessor.ts b/src/storage/accessors/DataAccessor.ts index cc72e3ce98..616fb2482f 100644 --- a/src/storage/accessors/DataAccessor.ts +++ b/src/storage/accessors/DataAccessor.ts @@ -63,8 +63,6 @@ export interface DataAccessor { * https://solid.github.io/specification/protocol#deleting-resources * * @param identifier - Resource to delete. - * - * @returns Identifiers of resources that were possibly modified. */ - deleteResource: (identifier: ResourceIdentifier) => Promise; + deleteResource: (identifier: ResourceIdentifier) => Promise; } diff --git a/src/storage/accessors/FileDataAccessor.ts b/src/storage/accessors/FileDataAccessor.ts index 1fb49937dc..bdccaa6741 100644 --- a/src/storage/accessors/FileDataAccessor.ts +++ b/src/storage/accessors/FileDataAccessor.ts @@ -117,15 +117,12 @@ export class FileDataAccessor implements DataAccessor { /** * Removes the corresponding file/folder (and metadata file). */ - public async deleteResource(identifier: ResourceIdentifier): Promise { + public async deleteResource(identifier: ResourceIdentifier): Promise { const link = await this.resourceMapper.mapUrlToFilePath(identifier); - const metadataLink = await this.getMetadataLink(link.identifier); const stats = await this.getStats(link.filePath); - const modified: ResourceIdentifier[] = [ identifier ]; try { - await fsPromises.unlink(metadataLink.filePath); - modified.push(metadataLink.identifier); + await fsPromises.unlink((await this.getMetadataLink(link.identifier)).filePath); } catch (error: unknown) { // Ignore if it doesn't exist if (!isSystemError(error) || error.code !== 'ENOENT') { @@ -140,8 +137,6 @@ export class FileDataAccessor implements DataAccessor { } else { throw new NotFoundHttpError(); } - - return modified; } /** diff --git a/src/storage/accessors/InMemoryDataAccessor.ts b/src/storage/accessors/InMemoryDataAccessor.ts index 86ad32177b..1938cb430b 100644 --- a/src/storage/accessors/InMemoryDataAccessor.ts +++ b/src/storage/accessors/InMemoryDataAccessor.ts @@ -83,14 +83,13 @@ export class InMemoryDataAccessor implements DataAccessor { } } - public async deleteResource(identifier: ResourceIdentifier): Promise { + public async deleteResource(identifier: ResourceIdentifier): Promise { const { parent, name } = this.getParentEntry(identifier); if (!parent.entries[name]) { throw new NotFoundHttpError(); } // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete parent.entries[name]; - return [ identifier ]; } private isDataEntry(entry: CacheEntry): entry is DataEntry { diff --git a/src/storage/accessors/SparqlDataAccessor.ts b/src/storage/accessors/SparqlDataAccessor.ts index 071ffd5d52..d311259418 100644 --- a/src/storage/accessors/SparqlDataAccessor.ts +++ b/src/storage/accessors/SparqlDataAccessor.ts @@ -134,10 +134,9 @@ export class SparqlDataAccessor implements DataAccessor { /** * Removes all graph data relevant to the given identifier. */ - public async deleteResource(identifier: ResourceIdentifier): Promise { + public async deleteResource(identifier: ResourceIdentifier): Promise { const { name, parent } = this.getRelatedNames(identifier); - await this.sendSparqlUpdate(this.sparqlDelete(name, parent)); - return [ identifier ]; + return this.sendSparqlUpdate(this.sparqlDelete(name, parent)); } /** diff --git a/src/storage/patch/SparqlUpdatePatchHandler.ts b/src/storage/patch/SparqlUpdatePatchHandler.ts index 85824ce9d5..9ecb38575e 100644 --- a/src/storage/patch/SparqlUpdatePatchHandler.ts +++ b/src/storage/patch/SparqlUpdatePatchHandler.ts @@ -41,8 +41,7 @@ export class SparqlUpdatePatchHandler extends PatchHandler { const op = patch.algebra; this.validateUpdate(op); - await this.applyPatch(identifier, op); - return [ identifier ]; + return this.applyPatch(identifier, op); } private isDeleteInsert(op: Algebra.Operation): op is Algebra.DeleteInsert { @@ -109,7 +108,7 @@ export class SparqlUpdatePatchHandler extends PatchHandler { /** * Apply the given algebra operation to the given identifier. */ - private async applyPatch(identifier: ResourceIdentifier, op: Algebra.Operation): Promise { + private async applyPatch(identifier: ResourceIdentifier, op: Algebra.Operation): Promise { const store = new Store(); try { // Read the quads of the current representation @@ -134,7 +133,8 @@ export class SparqlUpdatePatchHandler extends PatchHandler { this.logger.debug(`${store.size} quads will be stored to ${identifier.path}.`); // Write the result - await this.source.setRepresentation(identifier, new BasicRepresentation(store.match() as Readable, INTERNAL_QUADS)); + const patched = new BasicRepresentation(store.match() as Readable, INTERNAL_QUADS); + return this.source.setRepresentation(identifier, patched); } /** diff --git a/test/integration/WebSocketsProtocol.test.ts b/test/integration/WebSocketsProtocol.test.ts index f437a80471..51307b2192 100644 --- a/test/integration/WebSocketsProtocol.test.ts +++ b/test/integration/WebSocketsProtocol.test.ts @@ -68,14 +68,20 @@ describe('A server with the Solid WebSockets API behind a proxy', (): void => { ]); }); - describe('when the client subscribes to a resource', (): void => { + describe('when the client subscribes to resources', (): void => { beforeAll(async(): Promise => { - client.send(`sub https://example.pod/my-resource`); + client.send('sub https://example.pod/my-resource'); + client.send('sub https://example.pod/other-resource'); + client.send('sub https://example.pod/'); await new Promise((resolve): any => client.once('message', resolve)); }); it('acknowledges the subscription.', async(): Promise => { - expect(messages).toEqual([ `ack https://example.pod/my-resource` ]); + expect(messages).toEqual([ + 'ack https://example.pod/my-resource', + 'ack https://example.pod/other-resource', + 'ack https://example.pod/', + ]); }); it('notifies the client of resource updates.', async(): Promise => { @@ -87,7 +93,10 @@ describe('A server with the Solid WebSockets API behind a proxy', (): void => { }, body: '{}', }); - expect(messages).toEqual([ `pub https://example.pod/my-resource` ]); + expect(messages).toEqual([ + 'pub https://example.pod/', + 'pub https://example.pod/my-resource', + ]); }); }); }); diff --git a/test/unit/storage/DataAccessorBasedStore.test.ts b/test/unit/storage/DataAccessorBasedStore.test.ts index f1ebacf82f..a2026fbfda 100644 --- a/test/unit/storage/DataAccessorBasedStore.test.ts +++ b/test/unit/storage/DataAccessorBasedStore.test.ts @@ -40,11 +40,10 @@ class SimpleDataAccessor implements DataAccessor { } } - public async deleteResource(identifier: ResourceIdentifier): Promise { + public async deleteResource(identifier: ResourceIdentifier): Promise { this.checkExists(identifier); // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete this.data[identifier.path]; - return [ identifier ]; } public async getData(identifier: ResourceIdentifier): Promise> { @@ -563,12 +562,11 @@ describe('A DataAccessorBasedStore', (): void => { accessor.data[`${root}resource`] = representation; accessor.data[`${root}resource.dummy`] = representation; const deleteFn = accessor.deleteResource; - accessor.deleteResource = jest.fn(async(identifier: ResourceIdentifier): Promise => { + accessor.deleteResource = jest.fn(async(identifier: ResourceIdentifier): Promise => { if (auxStrategy.isAuxiliaryIdentifier(identifier)) { throw new Error('auxiliary error!'); } await deleteFn.call(accessor, identifier); - return [ identifier ]; }); const { logger } = store as any; logger.error = jest.fn(); @@ -587,12 +585,11 @@ describe('A DataAccessorBasedStore', (): void => { accessor.data[`${root}resource`] = representation; accessor.data[`${root}resource.dummy`] = representation; const deleteFn = accessor.deleteResource; - accessor.deleteResource = jest.fn(async(identifier: ResourceIdentifier): Promise => { + accessor.deleteResource = jest.fn(async(identifier: ResourceIdentifier): Promise => { if (auxStrategy.isAuxiliaryIdentifier(identifier)) { throw 'auxiliary error!'; } await deleteFn.call(accessor, identifier); - return [ identifier ]; }); const { logger } = store as any; logger.error = jest.fn(); diff --git a/test/unit/storage/MonitoringStore.test.ts b/test/unit/storage/MonitoringStore.test.ts index f9aab4ee58..b217ea4599 100644 --- a/test/unit/storage/MonitoringStore.test.ts +++ b/test/unit/storage/MonitoringStore.test.ts @@ -2,23 +2,25 @@ import type { Patch } from '../../../src/ldp/http/Patch'; import type { Representation } from '../../../src/ldp/representation/Representation'; import { MonitoringStore } from '../../../src/storage/MonitoringStore'; import type { ResourceStore } from '../../../src/storage/ResourceStore'; -import { SingleRootIdentifierStrategy } from '../../../src/util/identifiers/SingleRootIdentifierStrategy'; describe('A MonitoringStore', (): void => { let store: MonitoringStore; let source: ResourceStore; - const identifierStrategy = new SingleRootIdentifierStrategy('http://example.org/'); let changedCallback: () => void; + const modified = [ + { path: 'http://example.org/modified/1' }, + { path: 'http://example.org/modified/2' }, + ]; beforeEach(async(): Promise => { source = { getRepresentation: jest.fn(async(): Promise => ({ success: true })), addResource: jest.fn(async(): Promise => ({ path: 'http://example.org/foo/bar/new' })), - setRepresentation: jest.fn(async(): Promise => undefined), - deleteResource: jest.fn(async(): Promise => undefined), - modifyResource: jest.fn(async(): Promise => undefined), + setRepresentation: jest.fn(async(): Promise => modified), + deleteResource: jest.fn(async(): Promise => modified), + modifyResource: jest.fn(async(): Promise => modified), }; - store = new MonitoringStore(source, identifierStrategy); + store = new MonitoringStore(source); changedCallback = jest.fn(); store.on('changed', changedCallback); }); @@ -33,7 +35,7 @@ describe('A MonitoringStore', (): void => { expect(source.getRepresentation).toHaveBeenLastCalledWith({ path: 'getPath' }, {}, undefined); }); - it('does not fire a change event after completing getRepresentation.', async(): Promise => { + it('does not fire a change event after getRepresentation.', async(): Promise => { expect(changedCallback).toHaveBeenCalledTimes(0); await store.getRepresentation({ path: 'http://example.org/foo/bar' }, {}); expect(changedCallback).toHaveBeenCalledTimes(0); @@ -46,65 +48,60 @@ describe('A MonitoringStore', (): void => { expect(source.addResource).toHaveBeenLastCalledWith({ path: 'http://example.org/foo/bar' }, {}, undefined); }); - it('fires resource and container change events after completing addResource.', async(): Promise => { - const result = store.addResource({ path: 'http://example.org/foo/bar' }, {} as Representation); + it('fires container and resource change events after addResource.', async(): Promise => { + const result = store.addResource({ path: 'http://example.org/foo/bar/' }, {} as Representation); expect(changedCallback).toHaveBeenCalledTimes(0); await result; expect(changedCallback).toHaveBeenCalledTimes(2); - expect(changedCallback).toHaveBeenCalledWith({ path: 'http://example.org/foo/bar' }); + expect(changedCallback).toHaveBeenCalledWith({ path: 'http://example.org/foo/bar/' }); expect(changedCallback).toHaveBeenCalledWith({ path: 'http://example.org/foo/bar/new' }); }); it('calls setRepresentation directly from the source.', async(): Promise => { await expect(store.setRepresentation({ path: 'http://example.org/foo/bar' }, {} as Representation)) - .resolves.toBeUndefined(); + .resolves.toEqual(modified); expect(source.setRepresentation).toHaveBeenCalledTimes(1); expect(source.setRepresentation).toHaveBeenLastCalledWith({ path: 'http://example.org/foo/bar' }, {}, undefined); }); - it('fires a resource change event after completing setRepresentation.', async(): Promise => { + it('fires all modified change events after setRepresentation.', async(): Promise => { const result = store.setRepresentation({ path: 'http://example.org/foo/bar' }, {} as Representation); expect(changedCallback).toHaveBeenCalledTimes(0); await result; - expect(changedCallback).toHaveBeenCalledTimes(1); - expect(changedCallback).toHaveBeenCalledWith({ path: 'http://example.org/foo/bar' }); + expect(changedCallback).toHaveBeenCalledTimes(2); + expect(changedCallback).toHaveBeenCalledWith({ path: 'http://example.org/modified/1' }); + expect(changedCallback).toHaveBeenCalledWith({ path: 'http://example.org/modified/2' }); }); it('calls deleteResource directly from the source.', async(): Promise => { - await expect(store.deleteResource({ path: 'http://example.org/foo/bar' })).resolves.toBeUndefined(); + await expect(store.deleteResource({ path: 'http://example.org/foo/bar' })) + .resolves.toEqual(modified); expect(source.deleteResource).toHaveBeenCalledTimes(1); expect(source.deleteResource).toHaveBeenLastCalledWith({ path: 'http://example.org/foo/bar' }, undefined); }); - it('fires resource and container change events after completing deleteResource.', async(): Promise => { + it('fires all modified change events after deleteResource.', async(): Promise => { const result = store.deleteResource({ path: 'http://example.org/foo/bar' }); expect(changedCallback).toHaveBeenCalledTimes(0); await result; expect(changedCallback).toHaveBeenCalledTimes(2); - expect(changedCallback).toHaveBeenCalledWith({ path: 'http://example.org/foo/' }); - expect(changedCallback).toHaveBeenCalledWith({ path: 'http://example.org/foo/bar' }); - }); - - it('fires a resource change event after completing deleteResource on the root.', async(): Promise => { - const result = store.deleteResource({ path: 'http://example.org/' }); - expect(changedCallback).toHaveBeenCalledTimes(0); - await result; - expect(changedCallback).toHaveBeenCalledTimes(1); - expect(changedCallback).toHaveBeenCalledWith({ path: 'http://example.org/' }); + expect(changedCallback).toHaveBeenCalledWith({ path: 'http://example.org/modified/1' }); + expect(changedCallback).toHaveBeenCalledWith({ path: 'http://example.org/modified/2' }); }); it('calls modifyResource directly from the source.', async(): Promise => { await expect(store.modifyResource({ path: 'http://example.org/foo/bar' }, {} as Patch)) - .resolves.toBeUndefined(); + .resolves.toEqual(modified); expect(source.modifyResource).toHaveBeenCalledTimes(1); expect(source.modifyResource).toHaveBeenLastCalledWith({ path: 'http://example.org/foo/bar' }, {}, undefined); }); - it('fires a resource change event after completing modifyResource.', async(): Promise => { + it('fires all modified change events after modifyResource.', async(): Promise => { const result = store.modifyResource({ path: 'http://example.org/foo/bar' }, {} as Patch); expect(changedCallback).toHaveBeenCalledTimes(0); await result; - expect(changedCallback).toHaveBeenCalledTimes(1); - expect(changedCallback).toHaveBeenCalledWith({ path: 'http://example.org/foo/bar' }); + expect(changedCallback).toHaveBeenCalledTimes(2); + expect(changedCallback).toHaveBeenCalledWith({ path: 'http://example.org/modified/1' }); + expect(changedCallback).toHaveBeenCalledWith({ path: 'http://example.org/modified/2' }); }); }); diff --git a/test/unit/storage/accessors/FileDataAccessor.test.ts b/test/unit/storage/accessors/FileDataAccessor.test.ts index 689f3b9640..7042d97a22 100644 --- a/test/unit/storage/accessors/FileDataAccessor.test.ts +++ b/test/unit/storage/accessors/FileDataAccessor.test.ts @@ -333,8 +333,7 @@ describe('A FileDataAccessor', (): void => { it('deletes the corresponding file for document.', async(): Promise => { cache.data = { resource: 'apple' }; - await expect(accessor.deleteResource({ path: `${base}resource` })).resolves - .toEqual([{ path: `${base}resource` }]); + await expect(accessor.deleteResource({ path: `${base}resource` })).resolves.toBeUndefined(); expect(cache.data.resource).toBeUndefined(); }); @@ -345,31 +344,22 @@ describe('A FileDataAccessor', (): void => { it('removes the corresponding folder for containers.', async(): Promise => { cache.data = { container: {}}; - await expect(accessor.deleteResource({ path: `${base}container/` })).resolves - .toEqual([{ path: `${base}container/` }]); + await expect(accessor.deleteResource({ path: `${base}container/` })).resolves.toBeUndefined(); expect(cache.data.container).toBeUndefined(); }); it('removes the corresponding metadata.', async(): Promise => { cache.data = { container: { resource: 'apple', 'resource.meta': 'metaApple', '.meta': 'metadata' }}; - await expect(accessor.deleteResource({ path: `${base}container/resource` })).resolves.toEqual([ - { path: `${base}container/resource` }, - { path: `${base}container/resource.meta` }, - ]); + await expect(accessor.deleteResource({ path: `${base}container/resource` })).resolves.toBeUndefined(); expect(cache.data.container.resource).toBeUndefined(); expect(cache.data.container['resource.meta']).toBeUndefined(); - await expect(accessor.deleteResource({ path: `${base}container/` })).resolves.toEqual([ - { path: `${base}container/` }, - { path: `${base}container/.meta` }, - ]); + await expect(accessor.deleteResource({ path: `${base}container/` })).resolves.toBeUndefined(); expect(cache.data.container).toBeUndefined(); }); it('can delete the root container.', async(): Promise => { cache.data = { }; - await expect(accessor.deleteResource({ path: `${base}` })).resolves.toEqual([ - { path: base }, - ]); + await expect(accessor.deleteResource({ path: `${base}` })).resolves.toBeUndefined(); expect(cache.data).toBeUndefined(); }); }); diff --git a/test/unit/storage/accessors/InMemoryDataAccessor.test.ts b/test/unit/storage/accessors/InMemoryDataAccessor.test.ts index fc855a75e7..c6efff3383 100644 --- a/test/unit/storage/accessors/InMemoryDataAccessor.test.ts +++ b/test/unit/storage/accessors/InMemoryDataAccessor.test.ts @@ -170,20 +170,17 @@ describe('An InMemoryDataAccessor', (): void => { it('removes the corresponding resource.', async(): Promise => { await expect(accessor.writeDocument({ path: `${base}resource` }, data, metadata)).resolves.toBeUndefined(); await expect(accessor.writeContainer({ path: `${base}container/` }, metadata)).resolves.toBeUndefined(); - await expect(accessor.deleteResource({ path: `${base}resource` })).resolves - .toEqual([{ path: 'http://test.com/resource' }]); - await expect(accessor.deleteResource({ path: `${base}container/` })).resolves - .toEqual([{ path: 'http://test.com/container/' }]); + await expect(accessor.deleteResource({ path: `${base}resource` })).resolves.toBeUndefined(); + await expect(accessor.deleteResource({ path: `${base}container/` })).resolves.toBeUndefined(); await expect(accessor.getMetadata({ path: `${base}resource` })).rejects.toThrow(NotFoundHttpError); await expect(accessor.getMetadata({ path: `${base}container/` })).rejects.toThrow(NotFoundHttpError); }); it('can delete the root container and write to it again.', async(): Promise => { - await expect(accessor.deleteResource({ path: base })).resolves - .toEqual([{ path: base }]); - await expect(accessor.getMetadata({ path: base })).rejects.toThrow(NotFoundHttpError); + await expect(accessor.deleteResource({ path: `${base}` })).resolves.toBeUndefined(); + await expect(accessor.getMetadata({ path: `${base}` })).rejects.toThrow(NotFoundHttpError); await expect(accessor.getMetadata({ path: `${base}test/` })).rejects.toThrow(NotFoundHttpError); - await expect(accessor.writeContainer({ path: base }, metadata)).resolves.toBeUndefined(); + await expect(accessor.writeContainer({ path: `${base}` }, metadata)).resolves.toBeUndefined(); const resultMetadata = await accessor.getMetadata({ path: `${base}` }); expect(resultMetadata.quads()).toBeRdfIsomorphic(metadata.quads()); }); diff --git a/test/unit/storage/accessors/SparqlDataAccessor.test.ts b/test/unit/storage/accessors/SparqlDataAccessor.test.ts index abfe972df6..f1742b55b7 100644 --- a/test/unit/storage/accessors/SparqlDataAccessor.test.ts +++ b/test/unit/storage/accessors/SparqlDataAccessor.test.ts @@ -210,8 +210,7 @@ describe('A SparqlDataAccessor', (): void => { it('removes all references when deleting a resource.', async(): Promise => { metadata = new RepresentationMetadata({ path: 'http://test.com/container/' }, { [RDF.type]: [ LDP.terms.Resource, LDP.terms.Container ]}); - await expect(accessor.deleteResource({ path: 'http://test.com/container/' })).resolves - .toEqual([{ path: 'http://test.com/container/' }]); + await expect(accessor.deleteResource({ path: 'http://test.com/container/' })).resolves.toBeUndefined(); expect(fetchUpdate).toHaveBeenCalledTimes(1); expect(fetchUpdate.mock.calls[0][0]).toBe(endpoint); @@ -225,8 +224,7 @@ describe('A SparqlDataAccessor', (): void => { it('does not try to remove containment triples when deleting a root container.', async(): Promise => { metadata = new RepresentationMetadata({ path: 'http://test.com/' }, { [RDF.type]: [ LDP.terms.Resource, LDP.terms.Container ]}); - await expect(accessor.deleteResource({ path: 'http://test.com/' })).resolves - .toEqual([{ path: 'http://test.com/' }]); + await expect(accessor.deleteResource({ path: 'http://test.com/' })).resolves.toBeUndefined(); expect(fetchUpdate).toHaveBeenCalledTimes(1); expect(fetchUpdate.mock.calls[0][0]).toBe(endpoint); diff --git a/test/unit/storage/patch/SparqlUpdatePatchHandler.test.ts b/test/unit/storage/patch/SparqlUpdatePatchHandler.test.ts index 67602d7e3d..13af2ad80d 100644 --- a/test/unit/storage/patch/SparqlUpdatePatchHandler.test.ts +++ b/test/unit/storage/patch/SparqlUpdatePatchHandler.test.ts @@ -59,7 +59,7 @@ describe('A SparqlUpdatePatchHandler', (): void => { async function handle(query: string): Promise { const sparqlPrefix = 'prefix : \n'; - return handler.handle({ identifier: { path: 'path' }, + await handler.handle({ identifier: { path: 'path' }, patch: { algebra: translate(sparqlPrefix.concat(query), { quads: true }) } as SparqlUpdatePatch }); }