fix(events): allow multiple event handlers to execute (#4612)
This commit is contained in:
parent
562a8e06b4
commit
70cd0eef8c
@ -1,3 +1,5 @@
|
|||||||
|
import { fromJS } from 'immutable';
|
||||||
|
|
||||||
jest.spyOn(console, 'error').mockImplementation(() => {});
|
jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
|
||||||
describe('registry', () => {
|
describe('registry', () => {
|
||||||
@ -145,12 +147,86 @@ describe('registry', () => {
|
|||||||
|
|
||||||
registerEventListener({ name, handler }, options);
|
registerEventListener({ name, handler }, options);
|
||||||
|
|
||||||
const data = { entry: {} };
|
const data = { entry: fromJS({ data: {} }) };
|
||||||
await invokeEvent({ name, data });
|
await invokeEvent({ name, data });
|
||||||
|
|
||||||
expect(handler).toHaveBeenCalledTimes(1);
|
expect(handler).toHaveBeenCalledTimes(1);
|
||||||
expect(handler).toHaveBeenCalledWith(data, options);
|
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'));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -226,13 +226,20 @@ export function registerEventListener({ name, handler }, options = {}) {
|
|||||||
export async function invokeEvent({ name, data }) {
|
export async function invokeEvent({ name, data }) {
|
||||||
validateEventName(name);
|
validateEventName(name);
|
||||||
const handlers = registry.eventHandlers[name];
|
const handlers = registry.eventHandlers[name];
|
||||||
|
|
||||||
|
let _data = { ...data };
|
||||||
for (const { handler, options } of handlers) {
|
for (const { handler, options } of handlers) {
|
||||||
try {
|
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) {
|
} catch (e) {
|
||||||
console.warn(`Failed running handler for event ${name} with message: ${e.message}`);
|
console.warn(`Failed running handler for event ${name} with message: ${e.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return _data.entry.get('data');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function removeEventListener({ name, handler }) {
|
export function removeEventListener({ name, handler }) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user