Skip to content

Commit

Permalink
Revert "Only call element.on when the merchant passes in a callback (
Browse files Browse the repository at this point in the history
…#360)" (#369)

This reverts commit 00f3e00.
  • Loading branch information
awalker-stripe authored Jan 4, 2023
1 parent 5a15b91 commit a9fe259
Show file tree
Hide file tree
Showing 4 changed files with 239 additions and 237 deletions.
225 changes: 83 additions & 142 deletions src/components/createElementComponent.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,21 @@ describe('createElementComponent', () => {
let mockElements: any;
let mockElement: any;
let mockCartElementContext: any;

let simulateElementsEvents: Record<string, any[]>;
let simulateOn: any;
let simulateOff: any;
const simulateEvent = (event: string, ...args: any[]) => {
simulateElementsEvents[event].forEach((fn) => fn(...args));
};
let simulateChange: any;
let simulateBlur: any;
let simulateFocus: any;
let simulateEscape: any;
let simulateReady: any;
let simulateClick: any;
let simulateLoadError: any;
let simulateLoaderStart: any;
let simulateNetworksChange: any;
let simulateCheckout: any;
let simulateLineItemClick: any;
let simulateConfirm: any;
let simulateCancel: any;
let simulateShippingAddressChange: any;
let simulateShippingRateChange: any;

beforeEach(() => {
mockStripe = mocks.mockStripe();
Expand All @@ -34,23 +42,57 @@ describe('createElementComponent', () => {
mockStripe.elements.mockReturnValue(mockElements);
mockElements.create.mockReturnValue(mockElement);
jest.spyOn(React, 'useLayoutEffect');

simulateElementsEvents = {};
simulateOn = jest.fn((event, fn) => {
simulateElementsEvents[event] = [
...(simulateElementsEvents[event] || []),
fn,
];
mockElement.on = jest.fn((event, fn) => {
switch (event) {
case 'change':
simulateChange = fn;
break;
case 'blur':
simulateBlur = fn;
break;
case 'focus':
simulateFocus = fn;
break;
case 'escape':
simulateEscape = fn;
break;
case 'ready':
simulateReady = fn;
break;
case 'click':
simulateClick = fn;
break;
case 'loaderror':
simulateLoadError = fn;
break;
case 'loaderstart':
simulateLoaderStart = fn;
break;
case 'networkschange':
simulateNetworksChange = fn;
break;
case 'checkout':
simulateCheckout = fn;
break;
case 'lineitemclick':
simulateLineItemClick = fn;
break;
case 'confirm':
simulateConfirm = fn;
break;
case 'cancel':
simulateCancel = fn;
break;
case 'shippingaddresschange':
simulateShippingAddressChange = fn;
break;
case 'shippingratechange':
simulateShippingRateChange = fn;
break;
default:
throw new Error('TestSetupError: Unexpected event registration.');
}
});
simulateOff = jest.fn((event, fn) => {
simulateElementsEvents[event] = simulateElementsEvents[event].filter(
(previouslyAddedFn) => previouslyAddedFn !== fn
);
});

mockElement.on = simulateOn;
mockElement.off = simulateOff;

mockCartElementContext = mocks.mockCartElementContext();
jest
.spyOn(ElementsModule, 'useCartElementContextWithUseCase')
Expand Down Expand Up @@ -204,9 +246,6 @@ describe('createElementComponent', () => {
);

expect(mockElements.create).toHaveBeenCalledWith('card', options);

expect(simulateOn).not.toBeCalled();
expect(simulateOff).not.toBeCalled();
});

it('mounts the element', () => {
Expand All @@ -218,9 +257,6 @@ describe('createElementComponent', () => {

expect(mockElement.mount).toHaveBeenCalledWith(container.firstChild);
expect(React.useLayoutEffect).toHaveBeenCalled();

expect(simulateOn).not.toBeCalled();
expect(simulateOff).not.toBeCalled();
});

it('does not create and mount until Elements has been instantiated', () => {
Expand Down Expand Up @@ -253,28 +289,6 @@ describe('createElementComponent', () => {
);
});

it('removes old event handlers when an event handler changes', () => {
const mockHandler = jest.fn();
const mockHandler2 = jest.fn();
const {rerender} = render(
<Elements stripe={mockStripe}>
<CardElement onChange={mockHandler} />
</Elements>
);

expect(simulateOn).toBeCalledWith('change', mockHandler);
expect(simulateOff).not.toBeCalled();

rerender(
<Elements stripe={mockStripe}>
<CardElement onChange={mockHandler2} />
</Elements>
);

expect(simulateOff).toBeCalledWith('change', mockHandler);
expect(simulateOn).toHaveBeenLastCalledWith('change', mockHandler2);
});

it('propagates the Element`s ready event to the current onReady prop', () => {
const mockHandler = jest.fn();
const mockHandler2 = jest.fn();
Expand All @@ -289,32 +303,11 @@ describe('createElementComponent', () => {
</Elements>
);

const mockEvent = Symbol('ready');
simulateEvent('ready', mockEvent);
simulateReady();
expect(mockHandler2).toHaveBeenCalledWith(mockElement);
expect(mockHandler).not.toHaveBeenCalled();
});

it('propagates the Pay Button Element`s ready event to the current onReady prop', () => {
const mockHandler = jest.fn();
const mockHandler2 = jest.fn();
const {rerender} = render(
<Elements stripe={mockStripe}>
<PayButtonElement onReady={mockHandler} onConfirm={() => {}} />
</Elements>
);
rerender(
<Elements stripe={mockStripe}>
<PayButtonElement onReady={mockHandler2} onConfirm={() => {}} />
</Elements>
);

const mockEvent = Symbol('ready');
simulateEvent('ready', mockEvent);
expect(mockHandler2).toHaveBeenCalledWith(mockEvent);
expect(mockHandler).not.toHaveBeenCalled();
});

it('sets cart in the CartElementContext', () => {
expect(mockCartElementContext.cart).toBe(null);

Expand Down Expand Up @@ -344,58 +337,8 @@ describe('createElementComponent', () => {
},
};

simulateEvent('ready', readyEvent);
expect(mockCartElementContext.cartState).toBe(readyEvent);

const changeEvent = {
elementType: 'cart',
id: 'cart_session_id_change',
lineItems: {
count: 1,
},
};
simulateEvent('change', changeEvent);
expect(mockCartElementContext.cartState).toBe(changeEvent);

const checkoutEvent = {
elementType: 'cart',
id: 'cart_session_id_checkout',
lineItems: {
count: 2,
},
};
simulateEvent('checkout', checkoutEvent);
expect(mockCartElementContext.cartState).toBe(checkoutEvent);
});

it('sets cartState in the CartElementContext when passing in callbacks', () => {
const onReady = jest.fn();
const onChange = jest.fn();
const onCheckout = jest.fn();

render(
<Elements stripe={mockStripe}>
<CartElement
onReady={onReady}
onChange={onChange}
onCheckout={onCheckout}
/>
</Elements>
);

expect(mockCartElementContext.cartState).toBe(null);

const readyEvent = {
elementType: 'cart',
id: 'cart_session_id_ready',
lineItems: {
count: 0,
},
};

simulateEvent('ready', readyEvent);
simulateReady(readyEvent);
expect(mockCartElementContext.cartState).toBe(readyEvent);
expect(onReady).toBeCalledWith(readyEvent);

const changeEvent = {
elementType: 'cart',
Expand All @@ -404,9 +347,8 @@ describe('createElementComponent', () => {
count: 1,
},
};
simulateEvent('change', changeEvent);
simulateChange(changeEvent);
expect(mockCartElementContext.cartState).toBe(changeEvent);
expect(onChange).toBeCalledWith(changeEvent);

const checkoutEvent = {
elementType: 'cart',
Expand All @@ -415,9 +357,8 @@ describe('createElementComponent', () => {
count: 2,
},
};
simulateEvent('checkout', checkoutEvent);
simulateCheckout(checkoutEvent);
expect(mockCartElementContext.cartState).toBe(checkoutEvent);
expect(onCheckout).toBeCalledWith(checkoutEvent);
});

it('propagates the Element`s change event to the current onChange prop', () => {
Expand All @@ -435,7 +376,7 @@ describe('createElementComponent', () => {
);

const changeEventMock = Symbol('change');
simulateEvent('change', changeEventMock);
simulateChange(changeEventMock);
expect(mockHandler2).toHaveBeenCalledWith(changeEventMock);
expect(mockHandler).not.toHaveBeenCalled();
});
Expand All @@ -454,7 +395,7 @@ describe('createElementComponent', () => {
</Elements>
);

simulateEvent('blur');
simulateBlur();
expect(mockHandler2).toHaveBeenCalledWith();
expect(mockHandler).not.toHaveBeenCalled();
});
Expand All @@ -473,7 +414,7 @@ describe('createElementComponent', () => {
</Elements>
);

simulateEvent('focus');
simulateFocus();
expect(mockHandler2).toHaveBeenCalledWith();
expect(mockHandler).not.toHaveBeenCalled();
});
Expand All @@ -492,7 +433,7 @@ describe('createElementComponent', () => {
</Elements>
);

simulateEvent('escape');
simulateEscape();
expect(mockHandler2).toHaveBeenCalledWith();
expect(mockHandler).not.toHaveBeenCalled();
});
Expand All @@ -512,7 +453,7 @@ describe('createElementComponent', () => {
);

const clickEventMock = Symbol('click');
simulateEvent('click', clickEventMock);
simulateClick(clickEventMock);
expect(mockHandler2).toHaveBeenCalledWith(clickEventMock);
expect(mockHandler).not.toHaveBeenCalled();
});
Expand All @@ -532,7 +473,7 @@ describe('createElementComponent', () => {
);

const loadErrorEventMock = Symbol('loaderror');
simulateEvent('loaderror', loadErrorEventMock);
simulateLoadError(loadErrorEventMock);
expect(mockHandler2).toHaveBeenCalledWith(loadErrorEventMock);
expect(mockHandler).not.toHaveBeenCalled();
});
Expand All @@ -551,7 +492,7 @@ describe('createElementComponent', () => {
</Elements>
);

simulateEvent('loaderstart');
simulateLoaderStart();
expect(mockHandler2).toHaveBeenCalledWith();
expect(mockHandler).not.toHaveBeenCalled();
});
Expand All @@ -570,7 +511,7 @@ describe('createElementComponent', () => {
</Elements>
);

simulateEvent('networkschange');
simulateNetworksChange();
expect(mockHandler2).toHaveBeenCalledWith();
expect(mockHandler).not.toHaveBeenCalled();
});
Expand All @@ -590,7 +531,7 @@ describe('createElementComponent', () => {
);

const checkoutEventMock = Symbol('checkout');
simulateEvent('checkout', checkoutEventMock);
simulateCheckout(checkoutEventMock);
expect(mockHandler2).toHaveBeenCalledWith(checkoutEventMock);
expect(mockHandler).not.toHaveBeenCalled();
});
Expand All @@ -610,7 +551,7 @@ describe('createElementComponent', () => {
);

const lineItemClickEventMock = Symbol('lineitemclick');
simulateEvent('lineitemclick', lineItemClickEventMock);
simulateLineItemClick(lineItemClickEventMock);
expect(mockHandler2).toHaveBeenCalledWith(lineItemClickEventMock);
expect(mockHandler).not.toHaveBeenCalled();
});
Expand All @@ -630,7 +571,7 @@ describe('createElementComponent', () => {
);

const confirmEventMock = Symbol('confirm');
simulateEvent('confirm', confirmEventMock);
simulateConfirm(confirmEventMock);
expect(mockHandler2).toHaveBeenCalledWith(confirmEventMock);
expect(mockHandler).not.toHaveBeenCalled();
});
Expand All @@ -650,7 +591,7 @@ describe('createElementComponent', () => {
);

const cancelEventMock = Symbol('cancel');
simulateEvent('cancel', cancelEventMock);
simulateCancel(cancelEventMock);
expect(mockHandler2).toHaveBeenCalledWith(cancelEventMock);
expect(mockHandler).not.toHaveBeenCalled();
});
Expand All @@ -676,7 +617,7 @@ describe('createElementComponent', () => {
);

const shippingAddressChangeEventMock = Symbol('shippingaddresschange');
simulateEvent('shippingaddresschange', shippingAddressChangeEventMock);
simulateShippingAddressChange(shippingAddressChangeEventMock);
expect(mockHandler2).toHaveBeenCalledWith(shippingAddressChangeEventMock);
expect(mockHandler).not.toHaveBeenCalled();
});
Expand All @@ -702,7 +643,7 @@ describe('createElementComponent', () => {
);

const shippingRateChangeEventMock = Symbol('shippingratechange');
simulateEvent('shippingratechange', shippingRateChangeEventMock);
simulateShippingRateChange(shippingRateChangeEventMock);
expect(mockHandler2).toHaveBeenCalledWith(shippingRateChangeEventMock);
expect(mockHandler).not.toHaveBeenCalled();
});
Expand Down
Loading

0 comments on commit a9fe259

Please sign in to comment.