Skip to content

Commit

Permalink
test(ramp): add useApplePay tests (#9589)
Browse files Browse the repository at this point in the history
  • Loading branch information
wachunei authored Jul 25, 2024
1 parent f179355 commit 340f3f3
Show file tree
Hide file tree
Showing 2 changed files with 220 additions and 1 deletion.
219 changes: 219 additions & 0 deletions app/components/UI/Ramp/hooks/useApplePay.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
import { QuoteResponse } from '@consensys/on-ramp-sdk';
import { ApplePayPurchaseStatus } from '@consensys/on-ramp-sdk/dist/ApplePay';
// @ts-expect-error ts(7016) react-native-payments is not typed
import { PaymentRequest } from '@metamask/react-native-payments';
import useApplePay from './useApplePay';
import { renderHookWithProvider } from '../../../../util/test/renderWithProvider';

jest.mock('@metamask/react-native-payments', () => ({
PaymentRequest: jest.fn(),
}));

describe('useApplePay', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('throws an error if quote does not support Apple Pay', async () => {
const quote = {
getApplePayRequestInfo: undefined,
purchaseWithApplePay: undefined,
} as QuoteResponse;
const { result } = renderHookWithProvider(() => useApplePay(quote));
const [showRequest] = result.current;
await expect(showRequest()).rejects.toThrow(
'Quote does not support Apple Pay',
);
});

it('creates a PaymentRequest with applePayInfo and returns result if successful', async () => {
const quote = {
getApplePayRequestInfo: jest.fn().mockReturnValue({
methodData: 'test-method-data',
paymentDetails: 'test-payment-details',
paymentOptions: 'test-payment-options',
}),
purchaseWithApplePay: jest.fn().mockResolvedValue({
status: ApplePayPurchaseStatus.SUCCESS,
order: 'test-order',
authenticationUrl: 'test-auth-url',
}),
provider: {
name: 'test-provider',
},
} as unknown as QuoteResponse;

const mockPaymentRequestComplete = jest.fn();
const mockPaymentRequestShow = jest.fn().mockResolvedValue({
details: 'test-details',
complete: mockPaymentRequestComplete,
});
const mockAbort = jest.fn();

PaymentRequest.mockImplementation(() => ({
show: mockPaymentRequestShow,
abort: mockAbort,
}));

const { result } = renderHookWithProvider(() => useApplePay(quote));
const [showRequest] = result.current;
const paymentResult = await showRequest();

expect(quote.getApplePayRequestInfo).toHaveBeenCalledWith({
getPurchaseFiatAmountWithoutFeeLabel: expect.any(Function),
getPurchaseFiatFeeLabel: expect.any(Function),
getPurchaseFiatTotalAmountLabel: expect.any(Function),
});

expect(
(
quote.getApplePayRequestInfo as jest.Mock
).mock.calls[0][0].getPurchaseFiatAmountWithoutFeeLabel({
symbol: 'TEST_SYMBOL',
}),
).toBe('TEST_SYMBOL Purchase');
expect(
(
quote.getApplePayRequestInfo as jest.Mock
).mock.calls[0][0].getPurchaseFiatFeeLabel(),
).toBe('Fee');
expect(
(
quote.getApplePayRequestInfo as jest.Mock
).mock.calls[0][0].getPurchaseFiatTotalAmountLabel(),
).toBe('test-provider (via MetaMask)');

expect(PaymentRequest).toHaveBeenCalledWith(
'test-method-data',
'test-payment-details',
'test-payment-options',
);

expect(quote.purchaseWithApplePay).toHaveBeenCalledWith('test-details');
expect(mockPaymentRequestShow).toHaveBeenCalled();
expect(mockPaymentRequestComplete).toHaveBeenCalledWith('success');
expect(mockAbort).not.toHaveBeenCalled();

expect(paymentResult).toEqual({
order: 'test-order',
authenticationUrl: 'test-auth-url',
});
});

it('throws if the paymentResponse is falsy', async () => {
const quote = {
getApplePayRequestInfo: jest.fn().mockReturnValue({
methodData: 'test-method-data',
paymentDetails: 'test-payment-details',
paymentOptions: 'test-payment-options',
}),
purchaseWithApplePay: jest.fn().mockResolvedValue({
status: ApplePayPurchaseStatus.SUCCESS,
order: 'test-order',
authenticationUrl: 'test-auth-url',
}),
} as unknown as QuoteResponse;

const mockPaymentRequestShow = jest.fn().mockResolvedValue(null);
const mockAbort = jest.fn();

PaymentRequest.mockImplementation(() => ({
show: mockPaymentRequestShow,
abort: mockAbort,
}));

const { result } = renderHookWithProvider(() => useApplePay(quote));
const [showRequest] = result.current;

await expect(showRequest()).rejects.toThrow(
'Payment Request Failed: empty apple pay response',
);

expect(mockAbort).toHaveBeenCalled();
});

it('throws if purchaseWithApplePay status is FAILURE with error', async () => {
const quote = {
getApplePayRequestInfo: jest.fn().mockReturnValue({
methodData: 'test-method-data',
paymentDetails: 'test-payment-details',
paymentOptions: 'test-payment-options',
}),
purchaseWithApplePay: jest.fn().mockResolvedValue({
status: ApplePayPurchaseStatus.FAILURE,
error: 'test-error',
}),
} as unknown as QuoteResponse;

const mockPaymentRequestComplete = jest.fn();
const mockPaymentRequestShow = jest.fn().mockResolvedValue({
details: 'test-details',
complete: mockPaymentRequestComplete,
});
const mockAbort = jest.fn();

PaymentRequest.mockImplementation(() => ({
show: mockPaymentRequestShow,
abort: mockAbort,
}));

const { result } = renderHookWithProvider(() => useApplePay(quote));
const [showRequest] = result.current;
await expect(showRequest()).rejects.toThrow('test-error');
expect(mockPaymentRequestComplete).toHaveBeenCalledWith('fail');
expect(mockAbort).toHaveBeenCalled();
});

it('throws if purchaseWithApplePay status is FAILURE with error object', async () => {
const quote = {
getApplePayRequestInfo: jest.fn().mockReturnValue({
methodData: 'test-method-data',
paymentDetails: 'test-payment-details',
paymentOptions: 'test-payment-options',
}),
purchaseWithApplePay: jest.fn().mockResolvedValue({
status: ApplePayPurchaseStatus.FAILURE,
error: new Error('test-error-message'),
}),
} as unknown as QuoteResponse;

const mockPaymentRequestComplete = jest.fn();
const mockPaymentRequestShow = jest.fn().mockResolvedValue({
details: 'test-details',
complete: mockPaymentRequestComplete,
});

PaymentRequest.mockImplementation(() => ({
show: mockPaymentRequestShow,
}));

const { result } = renderHookWithProvider(() => useApplePay(quote));
const [showRequest] = result.current;
await expect(showRequest()).rejects.toThrow('test-error-message');
expect(mockPaymentRequestComplete).toHaveBeenCalledWith('fail');
});

it('returns ABORTED if error message includes AbortError', async () => {
const quote = {
getApplePayRequestInfo: jest.fn().mockReturnValue({
methodData: 'test-method-data',
paymentDetails: 'test-payment-details',
paymentOptions: 'test-payment-options',
}),
purchaseWithApplePay: jest.fn(),
} as unknown as QuoteResponse;

const mockPaymentRequestShow = jest.fn().mockRejectedValue({
message: 'AbortError',
});

PaymentRequest.mockImplementation(() => ({
show: mockPaymentRequestShow,
}));

const { result } = renderHookWithProvider(() => useApplePay(quote));
const [showRequest] = result.current;
const paymentResult = await showRequest();
expect(paymentResult).toEqual('ABORTED');
});
});
2 changes: 1 addition & 1 deletion app/components/UI/Ramp/hooks/useApplePay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ function useApplePay(quote: QuoteResponse) {
}
}, [quote]);

return [showRequest];
return [showRequest] as const;
}

export default useApplePay;

0 comments on commit 340f3f3

Please sign in to comment.