mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
feat: add CompositeAsyncHandler to support multiple handlers
This commit is contained in:
30
test/unit/util/AsyncHandler.test.ts
Normal file
30
test/unit/util/AsyncHandler.test.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { AsyncHandler } from '../../../src/util/AsyncHandler';
|
||||
import { StaticAsyncHandler } from '../../util/StaticAsyncHandler';
|
||||
|
||||
describe('An AsyncHandler', (): void => {
|
||||
it('calls canHandle and handle when handleSafe is called.', async (): Promise<void> => {
|
||||
const handlerTrue: AsyncHandler<any, any> = new StaticAsyncHandler(true, null);
|
||||
const canHandleFn = jest.fn(async (input: any): Promise<void> => input);
|
||||
const handleFn = jest.fn(async (input: any): Promise<any> => input);
|
||||
|
||||
handlerTrue.canHandle = canHandleFn;
|
||||
handlerTrue.handle = handleFn;
|
||||
await expect(handlerTrue.handleSafe('test')).resolves.toBe('test');
|
||||
expect(canHandleFn).toHaveBeenCalledTimes(1);
|
||||
expect(handleFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('does not call handle when canHandle errors during a handleSafe call.', async (): Promise<void> => {
|
||||
const handlerFalse: AsyncHandler<any, any> = new StaticAsyncHandler(false, null);
|
||||
const canHandleFn = jest.fn(async (): Promise<void> => {
|
||||
throw new Error('test');
|
||||
});
|
||||
const handleFn = jest.fn(async (input: any): Promise<any> => input);
|
||||
|
||||
handlerFalse.canHandle = canHandleFn;
|
||||
handlerFalse.handle = handleFn;
|
||||
await expect(handlerFalse.handleSafe('test')).rejects.toThrow(Error);
|
||||
expect(canHandleFn).toHaveBeenCalledTimes(1);
|
||||
expect(handleFn).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
});
|
||||
76
test/unit/util/CompositeAsyncHandler.test.ts
Normal file
76
test/unit/util/CompositeAsyncHandler.test.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import { AsyncHandler } from '../../../src/util/AsyncHandler';
|
||||
import { CompositeAsyncHandler } from '../../../src/util/CompositeAsyncHandler';
|
||||
import { StaticAsyncHandler } from '../../util/StaticAsyncHandler';
|
||||
|
||||
describe('A CompositeAsyncHandler', (): void => {
|
||||
describe('with no handlers', (): void => {
|
||||
it('can never handle data.', async (): Promise<void> => {
|
||||
const handler = new CompositeAsyncHandler([]);
|
||||
|
||||
await expect(handler.canHandle(null)).rejects.toThrow(Error);
|
||||
});
|
||||
|
||||
it('errors if its handle function is called.', async (): Promise<void> => {
|
||||
const handler = new CompositeAsyncHandler([]);
|
||||
|
||||
await expect(handler.handle(null)).rejects.toThrow(Error);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with multiple handlers', (): void => {
|
||||
let handlerTrue: AsyncHandler<any, any>;
|
||||
let handlerFalse: AsyncHandler<any, any>;
|
||||
let canHandleFn: jest.Mock<Promise<void>, [any]>;
|
||||
let handleFn: jest.Mock<Promise<void>, [any]>;
|
||||
|
||||
beforeEach(async (): Promise<void> => {
|
||||
handlerTrue = new StaticAsyncHandler(true, null);
|
||||
handlerFalse = new StaticAsyncHandler(false, null);
|
||||
|
||||
canHandleFn = jest.fn(async (input: any): Promise<any> => input);
|
||||
handleFn = jest.fn(async (input: any): Promise<any> => input);
|
||||
handlerTrue.canHandle = canHandleFn;
|
||||
handlerTrue.handle = handleFn;
|
||||
});
|
||||
|
||||
it('can handle data if a handler supports it.', async (): Promise<void> => {
|
||||
const handler = new CompositeAsyncHandler([ handlerFalse, handlerTrue ]);
|
||||
|
||||
await expect(handler.canHandle(null)).resolves.toBeUndefined();
|
||||
});
|
||||
|
||||
it('can not handle data if no handler supports it.', async (): Promise<void> => {
|
||||
const handler = new CompositeAsyncHandler([ handlerFalse, handlerFalse ]);
|
||||
|
||||
await expect(handler.canHandle(null)).rejects.toThrow('[Not supported., Not supported.]');
|
||||
});
|
||||
|
||||
it('handles data if a handler supports it.', async (): Promise<void> => {
|
||||
const handler = new CompositeAsyncHandler([ handlerFalse, handlerTrue ]);
|
||||
|
||||
await expect(handler.handle('test')).resolves.toEqual('test');
|
||||
expect(canHandleFn).toHaveBeenCalledTimes(1);
|
||||
expect(handleFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('errors if the handle function is called but no handler supports the data.', async (): Promise<void> => {
|
||||
const handler = new CompositeAsyncHandler([ handlerFalse, handlerFalse ]);
|
||||
|
||||
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> => {
|
||||
const handler = new CompositeAsyncHandler([ handlerFalse, handlerTrue ]);
|
||||
|
||||
await expect(handler.handleSafe('test')).resolves.toEqual('test');
|
||||
expect(canHandleFn).toHaveBeenCalledTimes(1);
|
||||
expect(handleFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('throws the same error as canHandle when calling handleSafe if no handler supports the data.', async (): Promise<void> => {
|
||||
const handler = new CompositeAsyncHandler([ handlerFalse, handlerFalse ]);
|
||||
|
||||
await expect(handler.handleSafe(null)).rejects.toThrow('[Not supported., Not supported.]');
|
||||
});
|
||||
});
|
||||
});
|
||||
24
test/util/StaticAsyncHandler.ts
Normal file
24
test/util/StaticAsyncHandler.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { AsyncHandler } from '../../src/util/AsyncHandler';
|
||||
|
||||
export class StaticAsyncHandler<TOut> extends AsyncHandler<any, TOut> {
|
||||
private readonly canHandleStatic: boolean;
|
||||
|
||||
private readonly handleStatic: TOut;
|
||||
|
||||
public constructor (canHandleStatic: boolean, handleStatic: TOut) {
|
||||
super();
|
||||
this.canHandleStatic = canHandleStatic;
|
||||
this.handleStatic = handleStatic;
|
||||
}
|
||||
|
||||
public async canHandle (): Promise<void> {
|
||||
if (this.canHandleStatic) {
|
||||
return;
|
||||
}
|
||||
throw new Error('Not supported.');
|
||||
}
|
||||
|
||||
public async handle (): Promise<TOut> {
|
||||
return this.handleStatic;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user