diff --git a/packages/lib/src/components/Klarna/components/KlarnaWidget/KlarnaWidget.test.tsx b/packages/lib/src/components/Klarna/components/KlarnaWidget/KlarnaWidget.test.tsx new file mode 100644 index 0000000000..e0f186a0ed --- /dev/null +++ b/packages/lib/src/components/Klarna/components/KlarnaWidget/KlarnaWidget.test.tsx @@ -0,0 +1,141 @@ +import { h } from 'preact'; +import { fireEvent, render, screen } from '@testing-library/preact'; +import { KlarnaWidget } from './KlarnaWidget'; +import Script from '../../../../utils/Script'; +import { KLARNA_WIDGET_URL } from '../../constants'; +import { KlarnaWidgetAuthorizeResponse } from '../../types'; + +jest.mock('../../../../utils/Script', () => { + return jest.fn().mockImplementation(() => { + return { load: mockScriptLoaded, remove: jest.fn() }; + }); +}); +const mockScriptLoaded = jest.fn().mockImplementation(() => { + window.klarnaAsyncCallback(); +}); + +let klarnaObj; +const originalLocation = window; +const klarnaInit = jest.fn(); +const getKlarnaActionImp = (res: Partial = {}) => + jest.fn().mockImplementation((_, onAction) => { + onAction(res); + }); + +describe('KlarnaWidget', () => { + const onLoaded = jest.fn(); + const onComplete = jest.fn(); + const onError = jest.fn(); + const paymentData = 'test'; + const paymentMethodType = 'klarna'; + const sdkData = { client_token: '123', payment_method_category: 'paynow' }; + const payButton = props => ( + + ); + const props = { + onLoaded, + onComplete, + onError, + paymentData, + paymentMethodType, + sdkData, + payButton + }; + + beforeAll(() => { + klarnaObj = { + Payments: { + init: klarnaInit, + load: jest.fn(), + authorize: jest.fn() + } + }; + Object.defineProperty(window, 'Klarna', { + value: klarnaObj + }); + }); + + afterAll(() => { + jest.restoreAllMocks(); + Object.defineProperty(globalThis, 'window', { + value: originalLocation + }); + }); + + describe('Klarna widget initialization', () => { + test('should download Klarna widget script on init', () => { + render(); + expect(Script).toHaveBeenCalledWith(KLARNA_WIDGET_URL); + expect(mockScriptLoaded).toHaveBeenCalledTimes(1); + }); + + test('should show pay button on init', async () => { + render(); + expect(await screen.findByTestId('pay-with-klarna')).toBeTruthy(); + }); + + test('should call Klarna init with client_token', () => { + render(); + expect(klarnaInit).toHaveBeenCalledWith({ client_token: sdkData.client_token }); + }); + + test('should call props onLoaded if Klarna pre-authorization passed', () => { + klarnaObj.Payments.load = getKlarnaActionImp({ show_form: true }); + render(); + expect(onLoaded).toHaveBeenCalled(); + }); + + test('should call props onComplete if Klarna pre-authorization failed', () => { + klarnaObj.Payments.load = getKlarnaActionImp({ show_form: false }); + render(); + expect(onComplete).toHaveBeenCalledWith({ + data: { + paymentData, + details: {} + } + }); + }); + }); + + describe('Pay with Klarna widget', () => { + test('should call the onComplete if the payment is authorized', async () => { + const authRes = { approved: true, show_form: true, authorization_token: 'abc' }; + klarnaObj.Payments.load = getKlarnaActionImp({ show_form: true }); + klarnaObj.Payments.authorize = getKlarnaActionImp(authRes); + render(); + fireEvent.click(await screen.findByTestId(/pay-with-klarna/i)); + expect(onComplete).toHaveBeenCalledWith({ + data: { + paymentData, + details: { + token: authRes.authorization_token, + authorization_token: authRes.authorization_token + } + } + }); + }); + test('should call the onError if the payment is not authorized temporarily', async () => { + klarnaObj.Payments.load = getKlarnaActionImp({ show_form: true }); + const authRes = { approved: false, show_form: true }; + klarnaObj.Payments.authorize = getKlarnaActionImp(authRes); + render(); + fireEvent.click(await screen.findByTestId(/pay-with-klarna/i)); + expect(onError).toHaveBeenCalledWith(authRes); + }); + + test('should call the onComplete if the payment is not authorized permanently', async () => { + klarnaObj.Payments.load = getKlarnaActionImp({ show_form: true }); + klarnaObj.Payments.authorize = getKlarnaActionImp({ show_form: false }); + render(); + fireEvent.click(await screen.findByTestId(/pay-with-klarna/i)); + expect(onComplete).toHaveBeenCalledWith({ + data: { + paymentData, + details: {} + } + }); + }); + }); +});