fix(events): allow multiple event handlers to execute (#4612)

This commit is contained in:
Pearce 2020-11-26 06:20:25 -08:00 committed by GitHub
parent 562a8e06b4
commit 70cd0eef8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 85 additions and 2 deletions

View File

@ -1,3 +1,5 @@
import { fromJS } from 'immutable';
jest.spyOn(console, 'error').mockImplementation(() => {});
describe('registry', () => {
@ -145,12 +147,86 @@ describe('registry', () => {
registerEventListener({ name, handler }, options);
const data = { entry: {} };
const data = { entry: fromJS({ data: {} }) };
await invokeEvent({ name, data });
expect(handler).toHaveBeenCalledTimes(1);
expect(handler).toHaveBeenCalledWith(data, options);
});
it(`should invoke multiple handlers on '${name}`, async () => {
const { registerEventListener, invokeEvent } = require('../registry');
const options1 = { hello: 'test1' };
const options2 = { hello: 'test2' };
const handler = jest.fn(({ entry }) => entry.get('data'));
registerEventListener({ name, handler }, options1);
registerEventListener({ name, handler }, options2);
const data = { entry: fromJS({ data: {} }) };
await invokeEvent({ name, data });
expect(handler).toHaveBeenCalledTimes(2);
expect(handler).toHaveBeenLastCalledWith(data, options2);
});
});
it(`should return an updated entry's DataMap`, async () => {
const { registerEventListener, invokeEvent } = require('../registry');
const event = 'preSave';
const options = { hello: 'world' };
const handler1 = jest.fn(({ entry }) => {
const data = entry.get('data');
return data.set('a', 'test1');
});
const handler2 = jest.fn(({ entry }) => {
const data = entry.get('data');
return data.set('c', 'test2');
});
registerEventListener({ name: event, handler: handler1 }, options);
registerEventListener({ name: event, handler: handler2 }, options);
const data = {
entry: fromJS({ data: { a: 'foo', b: 'bar' } }),
};
const dataAfterFirstHandlerExecution = {
entry: fromJS({ data: { a: 'test1', b: 'bar' } }),
};
const dataAfterSecondHandlerExecution = {
entry: fromJS({ data: { a: 'test1', b: 'bar', c: 'test2' } }),
};
const result = await invokeEvent({ name: event, data });
expect(handler1).toHaveBeenCalledWith(data, options);
expect(handler2).toHaveBeenCalledWith(dataAfterFirstHandlerExecution, options);
expect(result).toEqual(dataAfterSecondHandlerExecution.entry.get('data'));
});
it('should allow multiple events to not return a value', async () => {
const { registerEventListener, invokeEvent } = require('../registry');
const event = 'prePublish';
const options = { hello: 'world' };
const handler1 = jest.fn();
const handler2 = jest.fn();
registerEventListener({ name: event, handler: handler1 }, options);
registerEventListener({ name: event, handler: handler2 }, options);
const data = {
entry: fromJS({ data: { a: 'foo', b: 'bar' } }),
};
const result = await invokeEvent({ name: event, data });
expect(handler1).toHaveBeenCalledWith(data, options);
expect(handler2).toHaveBeenCalledWith(data, options);
expect(result).toEqual(data.entry.get('data'));
});
});
});

View File

@ -226,13 +226,20 @@ export function registerEventListener({ name, handler }, options = {}) {
export async function invokeEvent({ name, data }) {
validateEventName(name);
const handlers = registry.eventHandlers[name];
let _data = { ...data };
for (const { handler, options } of handlers) {
try {
return await handler(data, options);
const result = await handler(_data, options);
if (result !== undefined) {
const entry = _data.entry.set('data', result);
_data = { ...data, entry };
}
} catch (e) {
console.warn(`Failed running handler for event ${name} with message: ${e.message}`);
}
}
return _data.entry.get('data');
}
export function removeEventListener({ name, handler }) {