woocommerce/plugins/woocommerce-blocks/assets/js/base/context/event-emit/test/emitters.js

114 lines
3.7 KiB
JavaScript

/**
* Internal dependencies
*/
import { emitEvent, emitEventWithAbort } from '../emitters';
describe( 'Testing emitters', () => {
let observerMocks = {};
let observerA;
let observerB;
let observerPromiseWithResolvedValue;
beforeEach( () => {
observerA = jest.fn().mockReturnValue( true );
observerB = jest.fn().mockReturnValue( true );
observerPromiseWithResolvedValue = jest.fn().mockResolvedValue( 10 );
observerMocks = new Map( [
[ 'observerA', { priority: 10, callback: observerA } ],
[ 'observerB', { priority: 10, callback: observerB } ],
[
'observerReturnValue',
{ priority: 10, callback: jest.fn().mockReturnValue( 10 ) },
],
[
'observerPromiseWithReject',
{
priority: 10,
callback: jest.fn().mockRejectedValue( 'an error' ),
},
],
[
'observerPromiseWithResolvedValue',
{ priority: 10, callback: observerPromiseWithResolvedValue },
],
] );
} );
describe( 'Testing emitEvent()', () => {
it( 'invokes all observers', async () => {
const observers = { test: observerMocks };
const response = await emitEvent( observers, 'test', 'foo' );
expect( console ).toHaveErroredWith( 'an error' );
expect( observerA ).toHaveBeenCalledTimes( 1 );
expect( observerB ).toHaveBeenCalledWith( 'foo' );
expect( response ).toBe( true );
} );
} );
describe( 'Testing emitEventWithAbort()', () => {
it( 'does not abort on any return value other than an object with a type property', async () => {
observerMocks.delete( 'observerPromiseWithReject' );
const observers = { test: observerMocks };
const response = await emitEventWithAbort(
observers,
'test',
'foo'
);
expect( console ).not.toHaveErrored();
expect( observerB ).toHaveBeenCalledTimes( 1 );
expect( observerPromiseWithResolvedValue ).toHaveBeenCalled();
expect( response ).toBe( true );
} );
it( 'Aborts on a return value with an object that has a type property', async () => {
const validObjectResponse = jest
.fn()
.mockReturnValue( { type: 'success' } );
observerMocks.set( 'observerValidObject', {
priority: 5,
callback: validObjectResponse,
} );
observerMocks.delete( 'observerPromiseWithReject' );
const observers = { test: observerMocks };
const response = await emitEventWithAbort(
observers,
'test',
'foo'
);
expect( console ).not.toHaveErrored();
expect( validObjectResponse ).toHaveBeenCalledTimes( 1 );
expect( observerPromiseWithResolvedValue ).not.toHaveBeenCalled();
expect( response ).toEqual( { type: 'success' } );
} );
it( 'throws an error on an object returned from observer without a type property', async () => {
const failingObjectResponse = jest.fn().mockReturnValue( {} );
observerMocks.set( 'observerInvalidObject', {
priority: 5,
callback: failingObjectResponse,
} );
const observers = { test: observerMocks };
const response = await emitEventWithAbort(
observers,
'test',
'foo'
);
expect( console ).toHaveErrored();
expect( failingObjectResponse ).toHaveBeenCalledTimes( 1 );
expect( observerPromiseWithResolvedValue ).not.toHaveBeenCalled();
expect( response ).toEqual( { type: 'error' } );
} );
} );
describe( 'Test Priority', () => {
it( 'executes observers in expected order by priority', async () => {
const a = jest.fn();
const b = jest.fn().mockReturnValue( { type: 'error' } );
const observers = {
test: new Map( [
[ 'observerA', { priority: 200, callback: a } ],
[ 'observerB', { priority: 10, callback: b } ],
] ),
};
await emitEventWithAbort( observers, 'test', 'foo' );
expect( console ).not.toHaveErrored();
expect( b ).toHaveBeenCalledTimes( 1 );
expect( a ).not.toHaveBeenCalled();
} );
} );
} );