mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
refactor: Create multiple composite handlers
This commit is contained in:
parent
1260c5c14e
commit
840965cdef
@ -122,7 +122,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
* [feat: add typed readable](https://github.com/solid/community-server/commit/e0d74fd68af3575f267f8abc87c51a6fbab28d12)
|
* [feat: add typed readable](https://github.com/solid/community-server/commit/e0d74fd68af3575f267f8abc87c51a6fbab28d12)
|
||||||
* [feat: Add README with architecture links](https://github.com/solid/community-server/commit/aaf3f8e3aa890219e2a147622605ba2b62b729ee)
|
* [feat: Add README with architecture links](https://github.com/solid/community-server/commit/aaf3f8e3aa890219e2a147622605ba2b62b729ee)
|
||||||
* [feat: add AuthenticatedLdpHandler](https://github.com/solid/community-server/commit/3e2cfaf11ee13c2ae3cb3e46f4df78c13c9d19cf)
|
* [feat: add AuthenticatedLdpHandler](https://github.com/solid/community-server/commit/3e2cfaf11ee13c2ae3cb3e46f4df78c13c9d19cf)
|
||||||
* [feat: add CompositeAsyncHandler to support multiple handlers](https://github.com/solid/community-server/commit/4229932a3ac75c2532da4e495e96b779fc5b6c92)
|
* [feat: add FirstCompositeHandler to support multiple handlers](https://github.com/solid/community-server/commit/4229932a3ac75c2532da4e495e96b779fc5b6c92)
|
||||||
* [feat: add custom errors](https://github.com/solid/community-server/commit/57405f3e2695f3a82628e02052695314d656af95)
|
* [feat: add custom errors](https://github.com/solid/community-server/commit/57405f3e2695f3a82628e02052695314d656af95)
|
||||||
* [feat: add additional supported interfaces](https://github.com/solid/community-server/commit/a4f2b3995c3e8cfeacf5fe3dbbc0eeb8020f9c9e)
|
* [feat: add additional supported interfaces](https://github.com/solid/community-server/commit/a4f2b3995c3e8cfeacf5fe3dbbc0eeb8020f9c9e)
|
||||||
* [Initial configuration](https://github.com/solid/community-server/commit/b949b6cf5eade549b91731edcd1c4d931537a42e)
|
* [Initial configuration](https://github.com/solid/community-server/commit/b949b6cf5eade549b91731edcd1c4d931537a42e)
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
"@graph": [
|
"@graph": [
|
||||||
{
|
{
|
||||||
"@id": "urn:solid-server:default:OperationHandler",
|
"@id": "urn:solid-server:default:OperationHandler",
|
||||||
"@type": "CompositeAsyncHandler",
|
"@type": "FirstCompositeHandler",
|
||||||
"CompositeAsyncHandler:_handlers": [
|
"FirstCompositeHandler:_handlers": [
|
||||||
{
|
{
|
||||||
"@type": "DeleteOperationHandler",
|
"@type": "DeleteOperationHandler",
|
||||||
"DeleteOperationHandler:_store": {
|
"DeleteOperationHandler:_store": {
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
"@graph": [
|
"@graph": [
|
||||||
{
|
{
|
||||||
"@id": "urn:solid-server:default:PermissionsExtractor",
|
"@id": "urn:solid-server:default:PermissionsExtractor",
|
||||||
"@type": "CompositeAsyncHandler",
|
"@type": "FirstCompositeHandler",
|
||||||
"CompositeAsyncHandler:_handlers": [
|
"FirstCompositeHandler:_handlers": [
|
||||||
{
|
{
|
||||||
"@type": "MethodPermissionsExtractor"
|
"@type": "MethodPermissionsExtractor"
|
||||||
},
|
},
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
"@id": "urn:solid-server:default:MetadataExtractor"
|
"@id": "urn:solid-server:default:MetadataExtractor"
|
||||||
},
|
},
|
||||||
"BasicRequestParser:_bodyParser": {
|
"BasicRequestParser:_bodyParser": {
|
||||||
"@type": "CompositeAsyncHandler",
|
"@type": "FirstCompositeHandler",
|
||||||
"CompositeAsyncHandler:_handlers": [
|
"FirstCompositeHandler:_handlers": [
|
||||||
{
|
{
|
||||||
"@type": "SparqlUpdateBodyParser"
|
"@type": "SparqlUpdateBodyParser"
|
||||||
},
|
},
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
"@graph": [
|
"@graph": [
|
||||||
{
|
{
|
||||||
"@id": "urn:solid-server:default:ResponseWriter",
|
"@id": "urn:solid-server:default:ResponseWriter",
|
||||||
"@type": "CompositeAsyncHandler",
|
"@type": "FirstCompositeHandler",
|
||||||
"CompositeAsyncHandler:_handlers": [
|
"FirstCompositeHandler:_handlers": [
|
||||||
{
|
{
|
||||||
"@type": "ErrorResponseWriter"
|
"@type": "ErrorResponseWriter"
|
||||||
},
|
},
|
||||||
|
@ -26,8 +26,8 @@
|
|||||||
|
|
||||||
{
|
{
|
||||||
"@id": "urn:solid-server:default:RepresentationConverter",
|
"@id": "urn:solid-server:default:RepresentationConverter",
|
||||||
"@type": "CompositeAsyncHandler",
|
"@type": "FirstCompositeHandler",
|
||||||
"CompositeAsyncHandler:_handlers": [
|
"FirstCompositeHandler:_handlers": [
|
||||||
{
|
{
|
||||||
"@id": "urn:solid-server:default:RdfToQuadConverter"
|
"@id": "urn:solid-server:default:RdfToQuadConverter"
|
||||||
},
|
},
|
||||||
|
5
index.ts
5
index.ts
@ -139,8 +139,9 @@ export * from './src/util/errors/UnsupportedHttpError';
|
|||||||
export * from './src/util/errors/UnsupportedMediaTypeHttpError';
|
export * from './src/util/errors/UnsupportedMediaTypeHttpError';
|
||||||
|
|
||||||
// Util
|
// Util
|
||||||
export * from './src/util/HeaderUtil';
|
export * from './src/util/AllVoidCompositeHandler';
|
||||||
export * from './src/util/AsyncHandler';
|
export * from './src/util/AsyncHandler';
|
||||||
export * from './src/util/CompositeAsyncHandler';
|
export * from './src/util/FirstCompositeHandler';
|
||||||
|
export * from './src/util/HeaderUtil';
|
||||||
export * from './src/util/MetadataController';
|
export * from './src/util/MetadataController';
|
||||||
export * from './src/util/Util';
|
export * from './src/util/Util';
|
||||||
|
24
src/util/AllVoidCompositeHandler.ts
Normal file
24
src/util/AllVoidCompositeHandler.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { AsyncHandler } from './AsyncHandler';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A composite handler that runs all of its handlers independent of their result.
|
||||||
|
* The `canHandle` check of this handler will always succeed.
|
||||||
|
*/
|
||||||
|
export class AllVoidCompositeHandler<TIn> extends AsyncHandler<TIn> {
|
||||||
|
private readonly handlers: AsyncHandler<TIn>[];
|
||||||
|
|
||||||
|
public constructor(handlers: AsyncHandler<TIn>[]) {
|
||||||
|
super();
|
||||||
|
this.handlers = handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async handle(input: TIn): Promise<void> {
|
||||||
|
for (const handler of this.handlers) {
|
||||||
|
try {
|
||||||
|
await handler.handleSafe(input);
|
||||||
|
} catch {
|
||||||
|
// Ignore errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,13 +10,13 @@ import { UnsupportedHttpError } from './errors/UnsupportedHttpError';
|
|||||||
* The handlers will be checked in the order they appear in the input array,
|
* The handlers will be checked in the order they appear in the input array,
|
||||||
* allowing for more fine-grained handlers to check before catch-all handlers.
|
* allowing for more fine-grained handlers to check before catch-all handlers.
|
||||||
*/
|
*/
|
||||||
export class CompositeAsyncHandler<TIn, TOut> implements AsyncHandler<TIn, TOut> {
|
export class FirstCompositeHandler<TIn, TOut> implements AsyncHandler<TIn, TOut> {
|
||||||
protected readonly logger = getLoggerFor(this);
|
protected readonly logger = getLoggerFor(this);
|
||||||
|
|
||||||
private readonly handlers: AsyncHandler<TIn, TOut>[];
|
private readonly handlers: AsyncHandler<TIn, TOut>[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new CompositeAsyncHandler that stores the given handlers.
|
* Creates a new FirstCompositeHandler that stores the given handlers.
|
||||||
* @param handlers - Handlers over which it will run.
|
* @param handlers - Handlers over which it will run.
|
||||||
*/
|
*/
|
||||||
public constructor(handlers: AsyncHandler<TIn, TOut>[]) {
|
public constructor(handlers: AsyncHandler<TIn, TOut>[]) {
|
@ -5,7 +5,7 @@ import type {
|
|||||||
} from '../../index';
|
} from '../../index';
|
||||||
import {
|
import {
|
||||||
AuthenticatedLdpHandler,
|
AuthenticatedLdpHandler,
|
||||||
CompositeAsyncHandler,
|
FirstCompositeHandler,
|
||||||
MethodPermissionsExtractor,
|
MethodPermissionsExtractor,
|
||||||
RdfToQuadConverter,
|
RdfToQuadConverter,
|
||||||
UnsecureWebIdExtractor,
|
UnsecureWebIdExtractor,
|
||||||
@ -44,7 +44,7 @@ export class AuthenticatedDataAccessorBasedConfig implements ServerConfig {
|
|||||||
const requestParser = getBasicRequestParser();
|
const requestParser = getBasicRequestParser();
|
||||||
|
|
||||||
const credentialsExtractor = new UnsecureWebIdExtractor();
|
const credentialsExtractor = new UnsecureWebIdExtractor();
|
||||||
const permissionsExtractor = new CompositeAsyncHandler([
|
const permissionsExtractor = new FirstCompositeHandler([
|
||||||
new MethodPermissionsExtractor(),
|
new MethodPermissionsExtractor(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import type { HttpHandler,
|
|||||||
import {
|
import {
|
||||||
AllowEverythingAuthorizer,
|
AllowEverythingAuthorizer,
|
||||||
AuthenticatedLdpHandler,
|
AuthenticatedLdpHandler,
|
||||||
CompositeAsyncHandler,
|
FirstCompositeHandler,
|
||||||
MethodPermissionsExtractor,
|
MethodPermissionsExtractor,
|
||||||
QuadToRdfConverter,
|
QuadToRdfConverter,
|
||||||
RawBodyParser,
|
RawBodyParser,
|
||||||
@ -48,7 +48,7 @@ export class BasicHandlersConfig implements ServerConfig {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
const credentialsExtractor = new UnsecureWebIdExtractor();
|
const credentialsExtractor = new UnsecureWebIdExtractor();
|
||||||
const permissionsExtractor = new CompositeAsyncHandler([
|
const permissionsExtractor = new FirstCompositeHandler([
|
||||||
new MethodPermissionsExtractor(),
|
new MethodPermissionsExtractor(),
|
||||||
new SparqlPatchPermissionsExtractor(),
|
new SparqlPatchPermissionsExtractor(),
|
||||||
]);
|
]);
|
||||||
|
@ -2,7 +2,7 @@ import type { HttpHandler,
|
|||||||
ResourceStore } from '../../index';
|
ResourceStore } from '../../index';
|
||||||
import {
|
import {
|
||||||
AuthenticatedLdpHandler,
|
AuthenticatedLdpHandler,
|
||||||
CompositeAsyncHandler,
|
FirstCompositeHandler,
|
||||||
MethodPermissionsExtractor,
|
MethodPermissionsExtractor,
|
||||||
RdfToQuadConverter,
|
RdfToQuadConverter,
|
||||||
UnsecureWebIdExtractor,
|
UnsecureWebIdExtractor,
|
||||||
@ -40,7 +40,7 @@ export class BasicHandlersWithAclConfig implements ServerConfig {
|
|||||||
const requestParser = getBasicRequestParser();
|
const requestParser = getBasicRequestParser();
|
||||||
|
|
||||||
const credentialsExtractor = new UnsecureWebIdExtractor();
|
const credentialsExtractor = new UnsecureWebIdExtractor();
|
||||||
const permissionsExtractor = new CompositeAsyncHandler([
|
const permissionsExtractor = new FirstCompositeHandler([
|
||||||
new MethodPermissionsExtractor(),
|
new MethodPermissionsExtractor(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import type {
|
|||||||
import {
|
import {
|
||||||
AllowEverythingAuthorizer,
|
AllowEverythingAuthorizer,
|
||||||
AuthenticatedLdpHandler,
|
AuthenticatedLdpHandler,
|
||||||
CompositeAsyncHandler,
|
FirstCompositeHandler,
|
||||||
MethodPermissionsExtractor,
|
MethodPermissionsExtractor,
|
||||||
QuadToRdfConverter,
|
QuadToRdfConverter,
|
||||||
RawBodyParser,
|
RawBodyParser,
|
||||||
@ -44,7 +44,7 @@ export class DataAccessorBasedConfig implements ServerConfig {
|
|||||||
const requestParser = getBasicRequestParser([ new RawBodyParser() ]);
|
const requestParser = getBasicRequestParser([ new RawBodyParser() ]);
|
||||||
|
|
||||||
const credentialsExtractor = new UnsecureWebIdExtractor();
|
const credentialsExtractor = new UnsecureWebIdExtractor();
|
||||||
const permissionsExtractor = new CompositeAsyncHandler([
|
const permissionsExtractor = new FirstCompositeHandler([
|
||||||
new MethodPermissionsExtractor(),
|
new MethodPermissionsExtractor(),
|
||||||
]);
|
]);
|
||||||
const authorizer = new AllowEverythingAuthorizer();
|
const authorizer = new AllowEverythingAuthorizer();
|
||||||
|
@ -8,6 +8,7 @@ import type {
|
|||||||
ResponseDescription,
|
ResponseDescription,
|
||||||
HttpResponse,
|
HttpResponse,
|
||||||
ResponseWriter,
|
ResponseWriter,
|
||||||
|
OperationHandler,
|
||||||
} from '../../index';
|
} from '../../index';
|
||||||
import {
|
import {
|
||||||
AcceptPreferenceParser,
|
AcceptPreferenceParser,
|
||||||
@ -15,7 +16,7 @@ import {
|
|||||||
BasicRequestParser,
|
BasicRequestParser,
|
||||||
BasicResponseWriter,
|
BasicResponseWriter,
|
||||||
BasicTargetExtractor,
|
BasicTargetExtractor,
|
||||||
CompositeAsyncHandler,
|
FirstCompositeHandler,
|
||||||
ContentTypeParser,
|
ContentTypeParser,
|
||||||
DataAccessorBasedStore,
|
DataAccessorBasedStore,
|
||||||
DeleteOperationHandler,
|
DeleteOperationHandler,
|
||||||
@ -82,8 +83,8 @@ export const getConvertingStore =
|
|||||||
(store: ResourceStore, converters: RepresentationConverter[], inType?: string):
|
(store: ResourceStore, converters: RepresentationConverter[], inType?: string):
|
||||||
RepresentationConvertingStore =>
|
RepresentationConvertingStore =>
|
||||||
new RepresentationConvertingStore(store, {
|
new RepresentationConvertingStore(store, {
|
||||||
inConverter: new CompositeAsyncHandler(converters),
|
inConverter: new FirstCompositeHandler(converters),
|
||||||
outConverter: new CompositeAsyncHandler(converters),
|
outConverter: new FirstCompositeHandler(converters),
|
||||||
inType,
|
inType,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -105,7 +106,7 @@ export const getPatchingStore = (store: ResourceStore): PatchingStore => {
|
|||||||
*
|
*
|
||||||
* @returns The operation handler.
|
* @returns The operation handler.
|
||||||
*/
|
*/
|
||||||
export const getOperationHandler = (store: ResourceStore): CompositeAsyncHandler<Operation, ResponseDescription> => {
|
export const getOperationHandler = (store: ResourceStore): OperationHandler => {
|
||||||
const handlers = [
|
const handlers = [
|
||||||
new GetOperationHandler(store),
|
new GetOperationHandler(store),
|
||||||
new HeadOperationHandler(store),
|
new HeadOperationHandler(store),
|
||||||
@ -114,11 +115,11 @@ export const getOperationHandler = (store: ResourceStore): CompositeAsyncHandler
|
|||||||
new PatchOperationHandler(store),
|
new PatchOperationHandler(store),
|
||||||
new DeleteOperationHandler(store),
|
new DeleteOperationHandler(store),
|
||||||
];
|
];
|
||||||
return new CompositeAsyncHandler<Operation, ResponseDescription>(handlers);
|
return new FirstCompositeHandler<Operation, ResponseDescription>(handlers);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getResponseWriter = (): ResponseWriter =>
|
export const getResponseWriter = (): ResponseWriter =>
|
||||||
new CompositeAsyncHandler<{ response: HttpResponse; result: ResponseDescription | Error }, void>([
|
new FirstCompositeHandler<{ response: HttpResponse; result: ResponseDescription | Error }, void>([
|
||||||
new ErrorResponseWriter(),
|
new ErrorResponseWriter(),
|
||||||
new BasicResponseWriter(),
|
new BasicResponseWriter(),
|
||||||
]);
|
]);
|
||||||
@ -146,7 +147,7 @@ export const getBasicRequestParser = (bodyParsers: BodyParser[] = []): BasicRequ
|
|||||||
// If no body parser is given (array is empty), default to RawBodyParser
|
// If no body parser is given (array is empty), default to RawBodyParser
|
||||||
bodyParser = new RawBodyParser();
|
bodyParser = new RawBodyParser();
|
||||||
} else {
|
} else {
|
||||||
bodyParser = new CompositeAsyncHandler(bodyParsers);
|
bodyParser = new FirstCompositeHandler(bodyParsers);
|
||||||
}
|
}
|
||||||
return new BasicRequestParser({
|
return new BasicRequestParser({
|
||||||
targetExtractor: new BasicTargetExtractor(),
|
targetExtractor: new BasicTargetExtractor(),
|
||||||
|
30
test/unit/util/AllVoidCompositeHandler.test.ts
Normal file
30
test/unit/util/AllVoidCompositeHandler.test.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { AllVoidCompositeHandler } from '../../../src/util/AllVoidCompositeHandler';
|
||||||
|
import type { AsyncHandler } from '../../../src/util/AsyncHandler';
|
||||||
|
|
||||||
|
describe('An AllVoidCompositeHandler', (): void => {
|
||||||
|
let handler1: AsyncHandler<string>;
|
||||||
|
let handler2: AsyncHandler<string>;
|
||||||
|
let composite: AllVoidCompositeHandler<string>;
|
||||||
|
|
||||||
|
beforeEach(async(): Promise<void> => {
|
||||||
|
handler1 = { handleSafe: jest.fn() } as any;
|
||||||
|
handler2 = { handleSafe: jest.fn() } as any;
|
||||||
|
|
||||||
|
composite = new AllVoidCompositeHandler<string>([ handler1, handler2 ]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can handle all input.', async(): Promise<void> => {
|
||||||
|
await expect(composite.canHandle('test')).resolves.toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('runs all handlers without caring about their result.', async(): Promise<void> => {
|
||||||
|
handler1.handleSafe = jest.fn(async(): Promise<void> => {
|
||||||
|
throw new Error('error');
|
||||||
|
});
|
||||||
|
await expect(composite.handleSafe('test')).resolves.toBeUndefined();
|
||||||
|
expect(handler1.handleSafe).toHaveBeenCalledTimes(1);
|
||||||
|
expect(handler1.handleSafe).toHaveBeenLastCalledWith('test');
|
||||||
|
expect(handler2.handleSafe).toHaveBeenCalledTimes(1);
|
||||||
|
expect(handler2.handleSafe).toHaveBeenLastCalledWith('test');
|
||||||
|
});
|
||||||
|
});
|
@ -1,19 +1,19 @@
|
|||||||
import type { AsyncHandler } from '../../../src/util/AsyncHandler';
|
import type { AsyncHandler } from '../../../src/util/AsyncHandler';
|
||||||
import { CompositeAsyncHandler } from '../../../src/util/CompositeAsyncHandler';
|
|
||||||
import { HttpError } from '../../../src/util/errors/HttpError';
|
import { HttpError } from '../../../src/util/errors/HttpError';
|
||||||
import { UnsupportedHttpError } from '../../../src/util/errors/UnsupportedHttpError';
|
import { UnsupportedHttpError } from '../../../src/util/errors/UnsupportedHttpError';
|
||||||
|
import { FirstCompositeHandler } from '../../../src/util/FirstCompositeHandler';
|
||||||
import { StaticAsyncHandler } from '../../util/StaticAsyncHandler';
|
import { StaticAsyncHandler } from '../../util/StaticAsyncHandler';
|
||||||
|
|
||||||
describe('A CompositeAsyncHandler', (): void => {
|
describe('A FirstCompositeHandler', (): void => {
|
||||||
describe('with no handlers', (): void => {
|
describe('with no handlers', (): void => {
|
||||||
it('can never handle data.', async(): Promise<void> => {
|
it('can never handle data.', async(): Promise<void> => {
|
||||||
const handler = new CompositeAsyncHandler([]);
|
const handler = new FirstCompositeHandler([]);
|
||||||
|
|
||||||
await expect(handler.canHandle(null)).rejects.toThrow(Error);
|
await expect(handler.canHandle(null)).rejects.toThrow(Error);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('errors if its handle function is called.', async(): Promise<void> => {
|
it('errors if its handle function is called.', async(): Promise<void> => {
|
||||||
const handler = new CompositeAsyncHandler([]);
|
const handler = new FirstCompositeHandler([]);
|
||||||
|
|
||||||
await expect(handler.handle(null)).rejects.toThrow(Error);
|
await expect(handler.handle(null)).rejects.toThrow(Error);
|
||||||
});
|
});
|
||||||
@ -36,13 +36,13 @@ describe('A CompositeAsyncHandler', (): void => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('can handle data if a handler supports it.', async(): Promise<void> => {
|
it('can handle data if a handler supports it.', async(): Promise<void> => {
|
||||||
const handler = new CompositeAsyncHandler([ handlerFalse, handlerTrue ]);
|
const handler = new FirstCompositeHandler([ handlerFalse, handlerTrue ]);
|
||||||
|
|
||||||
await expect(handler.canHandle(null)).resolves.toBeUndefined();
|
await expect(handler.canHandle(null)).resolves.toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can not handle data if no handler supports it.', async(): Promise<void> => {
|
it('can not handle data if no handler supports it.', async(): Promise<void> => {
|
||||||
const handler = new CompositeAsyncHandler([ handlerFalse, handlerFalse ]);
|
const handler = new FirstCompositeHandler([ handlerFalse, handlerFalse ]);
|
||||||
|
|
||||||
await expect(handler.canHandle(null)).rejects.toThrow('[Not supported, Not supported]');
|
await expect(handler.canHandle(null)).rejects.toThrow('[Not supported, Not supported]');
|
||||||
});
|
});
|
||||||
@ -51,13 +51,13 @@ describe('A CompositeAsyncHandler', (): void => {
|
|||||||
handlerFalse.canHandle = async(): Promise<void> => {
|
handlerFalse.canHandle = async(): Promise<void> => {
|
||||||
throw 'apple';
|
throw 'apple';
|
||||||
};
|
};
|
||||||
const handler = new CompositeAsyncHandler([ handlerFalse, handlerFalse ]);
|
const handler = new FirstCompositeHandler([ handlerFalse, handlerFalse ]);
|
||||||
|
|
||||||
await expect(handler.canHandle(null)).rejects.toThrow('[Unknown error, Unknown error]');
|
await expect(handler.canHandle(null)).rejects.toThrow('[Unknown error, Unknown error]');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('handles data if a handler supports it.', async(): Promise<void> => {
|
it('handles data if a handler supports it.', async(): Promise<void> => {
|
||||||
const handler = new CompositeAsyncHandler([ handlerFalse, handlerTrue ]);
|
const handler = new FirstCompositeHandler([ handlerFalse, handlerTrue ]);
|
||||||
|
|
||||||
await expect(handler.handle('test')).resolves.toEqual('test');
|
await expect(handler.handle('test')).resolves.toEqual('test');
|
||||||
expect(canHandleFn).toHaveBeenCalledTimes(1);
|
expect(canHandleFn).toHaveBeenCalledTimes(1);
|
||||||
@ -65,13 +65,13 @@ describe('A CompositeAsyncHandler', (): void => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('errors if the handle function is called but no handler supports the data.', async(): Promise<void> => {
|
it('errors if the handle function is called but no handler supports the data.', async(): Promise<void> => {
|
||||||
const handler = new CompositeAsyncHandler([ handlerFalse, handlerFalse ]);
|
const handler = new FirstCompositeHandler([ handlerFalse, handlerFalse ]);
|
||||||
|
|
||||||
await expect(handler.handle('test')).rejects.toThrow('All handlers failed');
|
await expect(handler.handle('test')).rejects.toThrow('All handlers failed');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('only calls the canHandle function once of its handlers when handleSafe is called.', async(): Promise<void> => {
|
it('only calls the canHandle function once of its handlers when handleSafe is called.', async(): Promise<void> => {
|
||||||
const handler = new CompositeAsyncHandler([ handlerFalse, handlerTrue ]);
|
const handler = new FirstCompositeHandler([ handlerFalse, handlerTrue ]);
|
||||||
|
|
||||||
await expect(handler.handleSafe('test')).resolves.toEqual('test');
|
await expect(handler.handleSafe('test')).resolves.toEqual('test');
|
||||||
expect(canHandleFn).toHaveBeenCalledTimes(1);
|
expect(canHandleFn).toHaveBeenCalledTimes(1);
|
||||||
@ -79,7 +79,7 @@ describe('A CompositeAsyncHandler', (): void => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('throws the canHandle error when calling handleSafe if the data is not supported.', async(): Promise<void> => {
|
it('throws the canHandle error when calling handleSafe if the data is not supported.', async(): Promise<void> => {
|
||||||
const handler = new CompositeAsyncHandler([ handlerFalse, handlerFalse ]);
|
const handler = new FirstCompositeHandler([ handlerFalse, handlerFalse ]);
|
||||||
|
|
||||||
await expect(handler.handleSafe(null)).rejects.toThrow('[Not supported, Not supported]');
|
await expect(handler.handleSafe(null)).rejects.toThrow('[Not supported, Not supported]');
|
||||||
});
|
});
|
||||||
@ -88,7 +88,7 @@ describe('A CompositeAsyncHandler', (): void => {
|
|||||||
handlerTrue.canHandle = async(): Promise<void> => {
|
handlerTrue.canHandle = async(): Promise<void> => {
|
||||||
throw new HttpError(401, 'UnauthorizedHttpError');
|
throw new HttpError(401, 'UnauthorizedHttpError');
|
||||||
};
|
};
|
||||||
const handler = new CompositeAsyncHandler([ handlerTrue, handlerTrue ]);
|
const handler = new FirstCompositeHandler([ handlerTrue, handlerTrue ]);
|
||||||
|
|
||||||
await expect(handler.canHandle(null)).rejects.toMatchObject({
|
await expect(handler.canHandle(null)).rejects.toMatchObject({
|
||||||
statusCode: 401,
|
statusCode: 401,
|
||||||
@ -103,7 +103,7 @@ describe('A CompositeAsyncHandler', (): void => {
|
|||||||
handlerFalse.canHandle = async(): Promise<void> => {
|
handlerFalse.canHandle = async(): Promise<void> => {
|
||||||
throw new Error('Server is crashing!');
|
throw new Error('Server is crashing!');
|
||||||
};
|
};
|
||||||
const handler = new CompositeAsyncHandler([ handlerTrue, handlerFalse ]);
|
const handler = new FirstCompositeHandler([ handlerTrue, handlerFalse ]);
|
||||||
|
|
||||||
await expect(handler.canHandle(null)).rejects.toMatchObject({
|
await expect(handler.canHandle(null)).rejects.toMatchObject({
|
||||||
statusCode: 500,
|
statusCode: 500,
|
||||||
@ -118,7 +118,7 @@ describe('A CompositeAsyncHandler', (): void => {
|
|||||||
handlerFalse.canHandle = async(): Promise<void> => {
|
handlerFalse.canHandle = async(): Promise<void> => {
|
||||||
throw new HttpError(415, 'UnsupportedMediaTypeHttpError');
|
throw new HttpError(415, 'UnsupportedMediaTypeHttpError');
|
||||||
};
|
};
|
||||||
const handler = new CompositeAsyncHandler([ handlerTrue, handlerFalse ]);
|
const handler = new FirstCompositeHandler([ handlerTrue, handlerFalse ]);
|
||||||
|
|
||||||
await expect(handler.canHandle(null)).rejects.toThrow(UnsupportedHttpError);
|
await expect(handler.canHandle(null)).rejects.toThrow(UnsupportedHttpError);
|
||||||
});
|
});
|
Loading…
x
Reference in New Issue
Block a user