121 lines
3.0 KiB
TypeScript
121 lines
3.0 KiB
TypeScript
import { act } from "react";
|
|
import { createRoot, type Root } from "react-dom/client";
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
|
import type { PayChannel } from "@/data/schemas/payment";
|
|
import type { PaymentMethodConfig } from "@/lib/payment/payment_method";
|
|
|
|
import { usePaymentMethodSelection } from "../use-payment-method-selection";
|
|
|
|
describe("usePaymentMethodSelection", () => {
|
|
let container: HTMLDivElement;
|
|
let root: Root;
|
|
|
|
beforeEach(() => {
|
|
(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean })
|
|
.IS_REACT_ACT_ENVIRONMENT = true;
|
|
container = document.createElement("div");
|
|
document.body.appendChild(container);
|
|
root = createRoot(container);
|
|
});
|
|
|
|
afterEach(() => {
|
|
act(() => root.unmount());
|
|
container.remove();
|
|
});
|
|
|
|
it("forces Stripe when payment method selection is unavailable", () => {
|
|
const onChange = vi.fn();
|
|
renderHarness(root, {
|
|
config: {
|
|
canChoosePaymentMethod: false,
|
|
initialPayChannel: "stripe",
|
|
showPaymentMethodSelector: false,
|
|
},
|
|
currentPayChannel: "ezpay",
|
|
onChange,
|
|
});
|
|
|
|
expect(onChange).toHaveBeenCalledWith("stripe");
|
|
});
|
|
|
|
it("applies the default channel once when no return channel was requested", () => {
|
|
const onChange = vi.fn();
|
|
const config = {
|
|
canChoosePaymentMethod: true,
|
|
initialPayChannel: "ezpay",
|
|
showPaymentMethodSelector: true,
|
|
} as const;
|
|
renderHarness(root, {
|
|
config,
|
|
currentPayChannel: "stripe",
|
|
onChange,
|
|
});
|
|
renderHarness(root, {
|
|
config,
|
|
currentPayChannel: "ezpay",
|
|
onChange,
|
|
});
|
|
|
|
expect(onChange).toHaveBeenCalledTimes(1);
|
|
expect(onChange).toHaveBeenCalledWith("ezpay");
|
|
});
|
|
|
|
it("preserves an explicit return channel and pauses while payment is busy", () => {
|
|
const onChange = vi.fn();
|
|
renderHarness(root, {
|
|
config: {
|
|
canChoosePaymentMethod: true,
|
|
initialPayChannel: "ezpay",
|
|
showPaymentMethodSelector: true,
|
|
},
|
|
currentPayChannel: "stripe",
|
|
requestedPayChannel: "stripe",
|
|
onChange,
|
|
});
|
|
renderHarness(root, {
|
|
config: {
|
|
canChoosePaymentMethod: false,
|
|
initialPayChannel: "stripe",
|
|
showPaymentMethodSelector: false,
|
|
},
|
|
currentPayChannel: "ezpay",
|
|
isPaymentBusy: true,
|
|
onChange,
|
|
});
|
|
|
|
expect(onChange).not.toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
interface HarnessProps {
|
|
config: PaymentMethodConfig;
|
|
currentPayChannel: PayChannel;
|
|
requestedPayChannel?: PayChannel | null;
|
|
isPaymentBusy?: boolean;
|
|
onChange: (payChannel: PayChannel) => void;
|
|
}
|
|
|
|
function renderHarness(root: Root, props: HarnessProps): void {
|
|
act(() => {
|
|
root.render(<Harness {...props} />);
|
|
});
|
|
}
|
|
|
|
function Harness({
|
|
config,
|
|
currentPayChannel,
|
|
requestedPayChannel = null,
|
|
isPaymentBusy = false,
|
|
onChange,
|
|
}: HarnessProps) {
|
|
usePaymentMethodSelection({
|
|
config,
|
|
currentPayChannel,
|
|
requestedPayChannel,
|
|
isPaymentBusy,
|
|
onChange,
|
|
});
|
|
return null;
|
|
}
|