import { describe, expect, it, vi } from "vitest"; import { getPaymentUrl, getPaymentUrlHostname, getStripeClientSecret, isEzpayPayment, launchEzpayRedirect, resolveEzpayLaunchTarget, } from "../payment_launch"; describe("payment launch helpers", () => { it("extracts supported redirect urls from payment params", () => { expect(getPaymentUrl({ cashier_url: "https://pay.example/cashier" })).toBe( "https://pay.example/cashier", ); expect(getPaymentUrl({ checkoutUrl: "https://pay.example/checkout" })).toBe( "https://pay.example/checkout", ); expect(getPaymentUrl({ url: "" })).toBeNull(); }); it("detects ezpay provider case-insensitively", () => { expect(isEzpayPayment({ provider: "ezpay" })).toBe(true); expect(isEzpayPayment({ provider: "EZPAY" })).toBe(true); expect(isEzpayPayment({ provider: "stripe" })).toBe(false); }); it("extracts stripe client secrets only for stripe-like providers", () => { expect( getStripeClientSecret({ provider: "stripe", clientSecret: "pi_secret", }), ).toBe("pi_secret"); expect(getStripeClientSecret({ client_secret: "pi_secret_snake" })).toBe( "pi_secret_snake", ); expect( getStripeClientSecret({ provider: "ezpay", clientSecret: "pi_secret", }), ).toBeNull(); }); it("prioritizes a hosted GCash URL for Philippine checkout", () => { expect( resolveEzpayLaunchTarget({ provider: "ezpay", channelType: "URL", payData: "https://pay.example/gcash", }, { countryCode: "PH", currency: "PHP" }), ).toEqual({ kind: "url", paymentUrl: "https://pay.example/gcash" }); expect( resolveEzpayLaunchTarget({ provider: "ezpay", channelType: "QR", payData: "000201010212ph-qr-payload", cashierUrl: "https://pay.example/gcash-hosted", }, { countryCode: "PH" }), ).toEqual({ kind: "url", paymentUrl: "https://pay.example/gcash-hosted", }); }); it("keeps a usable QR Ph fallback without calling it QRIS", () => { expect( resolveEzpayLaunchTarget( { provider: "ezpay", channelType: "QR", payData: "000201010212ph-qr-payload", }, { currency: "PHP" }, ), ).toEqual({ kind: "qr", experience: "gcashQrPh", qrData: "000201010212ph-qr-payload", }); expect( resolveEzpayLaunchTarget( { provider: "ezpay", payData: "000201010212ph-qr-payload", }, { countryCode: "PH" }, ), ).toEqual({ kind: "qr", experience: "gcashQrPh", qrData: "000201010212ph-qr-payload", }); }); it("keeps Indonesian QRIS ahead of an optional hosted URL", () => { expect( resolveEzpayLaunchTarget( { provider: "ezpay", channelType: "QR", payData: "00020101021226670016COM.NOBUBANK.WWW", cashierUrl: "https://pay.example/indonesia", }, { countryCode: "ID", currency: "IDR" }, ), ).toEqual({ kind: "qr", experience: "qris", qrData: "00020101021226670016COM.NOBUBANK.WWW", }); }); it("reports a regional error only when both URL and QR data are absent", () => { expect( resolveEzpayLaunchTarget( { provider: "ezpay", channelType: "QR", payData: "", }, { countryCode: "PH" }, ), ).toEqual({ kind: "error", errorMessage: "GCash / QR Ph payment data is missing. Please try again.", }); }); it("keeps diagnostics to the payment URL hostname", () => { expect( getPaymentUrlHostname( "https://pay.example/gcash?token=must-not-appear-in-logs", ), ).toBe("pay.example"); expect(getPaymentUrlHostname("not-a-url")).toBeNull(); }); it("rejects VA and unknown Ezpay channel types with explicit errors", () => { expect( resolveEzpayLaunchTarget({ provider: "ezpay", channelType: "VA" }), ).toEqual({ kind: "error", errorMessage: "Virtual account payments are not supported in this app.", }); expect( resolveEzpayLaunchTarget({ provider: "ezpay", channelType: "OTHER" }), ).toEqual({ kind: "error", errorMessage: "Unsupported Ezpay payment channel: OTHER.", }); }); it("reports a launch failure before redirecting without an order id", async () => { const onOpened = vi.fn(); const onFailed = vi.fn(); await launchEzpayRedirect({ orderId: null, paymentUrl: "https://pay.example/checkout?token=secret", subscriptionType: "topup", onOpened, onFailed, }); expect(onOpened).not.toHaveBeenCalled(); expect(onFailed).toHaveBeenCalledWith( "Missing order id before opening Ezpay.", ); }); });