From 482991cb9a94bd2b77b7ad64e0fc11edf5db1c50 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Wed, 22 Jul 2020 13:43:26 +0200 Subject: [PATCH] feat: Add OperationHandler for PATCH --- .../operations/SimplePatchOperationHandler.ts | 26 +++++++++++++++++++ .../SimplePatchOperationHandler.test.ts | 24 +++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 src/ldp/operations/SimplePatchOperationHandler.ts create mode 100644 test/unit/ldp/operations/SimplePatchOperationHandler.test.ts diff --git a/src/ldp/operations/SimplePatchOperationHandler.ts b/src/ldp/operations/SimplePatchOperationHandler.ts new file mode 100644 index 000000000..532ed5281 --- /dev/null +++ b/src/ldp/operations/SimplePatchOperationHandler.ts @@ -0,0 +1,26 @@ +import { Operation } from './Operation'; +import { OperationHandler } from './OperationHandler'; +import { Patch } from '../http/Patch'; +import { ResourceStore } from '../../storage/ResourceStore'; +import { ResponseDescription } from './ResponseDescription'; +import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError'; + +export class SimplePatchOperationHandler extends OperationHandler { + private readonly store: ResourceStore; + + public constructor(store: ResourceStore) { + super(); + this.store = store; + } + + public async canHandle(input: Operation): Promise { + if (input.method !== 'PATCH') { + throw new UnsupportedHttpError('This handler only supports PATCH operations.'); + } + } + + public async handle(input: Operation): Promise { + await this.store.modifyResource(input.target, input.body as Patch); + return { identifier: input.target }; + } +} diff --git a/test/unit/ldp/operations/SimplePatchOperationHandler.test.ts b/test/unit/ldp/operations/SimplePatchOperationHandler.test.ts new file mode 100644 index 000000000..1b51b1c96 --- /dev/null +++ b/test/unit/ldp/operations/SimplePatchOperationHandler.test.ts @@ -0,0 +1,24 @@ +import { Operation } from '../../../../src/ldp/operations/Operation'; +import { ResourceStore } from '../../../../src/storage/ResourceStore'; +import { SimplePatchOperationHandler } from '../../../../src/ldp/operations/SimplePatchOperationHandler'; +import { UnsupportedHttpError } from '../../../../src/util/errors/UnsupportedHttpError'; + +describe('A SimplePatchOperationHandler', (): void => { + const store = {} as unknown as ResourceStore; + const handler = new SimplePatchOperationHandler(store); + beforeEach(async(): Promise => { + store.modifyResource = jest.fn(async(): Promise => undefined); + }); + + it('only supports GET operations.', async(): Promise => { + await expect(handler.canHandle({ method: 'PATCH' } as Operation)).resolves.toBeUndefined(); + await expect(handler.canHandle({ method: 'GET' } as Operation)).rejects.toThrow(UnsupportedHttpError); + }); + + it('deletes the resource from the store and returns its identifier.', async(): Promise => { + await expect(handler.handle({ target: { path: 'url' }, body: { dataType: 'patch' }} as Operation)) + .resolves.toEqual({ identifier: { path: 'url' }}); + expect(store.modifyResource).toHaveBeenCalledTimes(1); + expect(store.modifyResource).toHaveBeenLastCalledWith({ path: 'url' }, { dataType: 'patch' }); + }); +});