import type { ResourceIdentifier } from '../../../../src/http/representation/ResourceIdentifier'; import type { BaseRouterHandlerArgs } from '../../../../src/server/util/BaseRouterHandler'; import { BaseRouterHandler } from '../../../../src/server/util/BaseRouterHandler'; import type { AsyncHandler } from '../../../../src/util/handlers/AsyncHandler'; class SimpleRouterHandler extends BaseRouterHandler> { public constructor(args: BaseRouterHandlerArgs>) { super(args); } public async canHandle(input: { method: string; target: ResourceIdentifier }): Promise { await this.canHandleInput(input, input.method, input.target); } } describe('A BaseRouterHandler', (): void => { const baseUrl = 'http://example.com/'; const method = 'GET'; const target: ResourceIdentifier = { path: 'http://example.com/foo' }; let handler: jest.Mocked>; let router: SimpleRouterHandler; beforeEach(async(): Promise => { handler = { canHandle: jest.fn(), handle: jest.fn().mockResolvedValue('result'), } as any; router = new SimpleRouterHandler({ baseUrl, handler, allowedPathNames: [ '^/foo$', '^/bar$' ], allowedMethods: [ 'GET', 'HEAD' ], }); }); it('requires the correct method.', async(): Promise => { await expect(router.canHandle({ method: 'POST', target })).rejects.toThrow('POST is not allowed'); }); it('requires the path to match a given regex.', async(): Promise => { await expect(router.canHandle({ method, target: { path: 'http://example.com/baz' }})) .rejects.toThrow('Cannot handle route /baz'); }); it('accepts valid input.', async(): Promise => { await expect(router.canHandle({ method, target })).resolves.toBeUndefined(); }); it('requires the source handler to accept the input.', async(): Promise => { handler.canHandle.mockRejectedValue(new Error('bad input')); await expect(router.canHandle({ method, target })).rejects.toThrow('bad input'); }); it('accepts all methods if no restrictions are defined.', async(): Promise => { router = new SimpleRouterHandler({ baseUrl, handler, allowedPathNames: [ '^/foo$', '^/bar$' ], }); await expect(router.canHandle({ method: 'POST', target })).resolves.toBeUndefined(); }); it('accepts all paths if no restrictions are defined.', async(): Promise => { router = new SimpleRouterHandler({ handler, allowedMethods: [ 'GET', 'HEAD' ], }); await expect(router.canHandle({ method, target: { path: 'http://example.com/baz' }})).resolves.toBeUndefined(); }); it('requires a baseUrl input if there is a path restriction.', async(): Promise => { expect((): any => new SimpleRouterHandler({ handler, allowedPathNames: [ '^/foo$', '^/bar$' ], })).toThrow('A value for allowedPathNames requires baseUrl to be defined.'); }); it('calls the source handler.', async(): Promise => { await expect(router.handle({ method, target })).resolves.toBe('result'); expect(handler.handle).toHaveBeenCalledTimes(1); expect(handler.handle).toHaveBeenLastCalledWith({ method, target }); }); });