Files
buzz-sheet/lib/commission/payment.test.ts
T
gunshiz bb5c571837
CI / Verify (push) Successful in 2m25s
CI / Build immutable images and deploy (push) Successful in 2m24s
fix : dupe slip issue
2026-10-02 11:25:28 +07:00

70 lines
3.6 KiB
TypeScript

import { afterEach, describe, expect, it, vi } from "vitest";
vi.mock("server-only", () => ({}));
import { promptPayConfig, verifyCommissionSlip } from "./payment";
const names = ["SLIP2GO_VERIFY_URL", "SLIP2GO_API_SECRET", "COMMISSION_PROMPTPAY_TYPE",
"COMMISSION_PROMPTPAY_VALUE", "COMMISSION_RECEIVER_ACCOUNT_NUMBER"] as const;
const original = names.map((name) => process.env[name]);
const checkoutDate = new Date("2026-09-01T12:00:00.000Z");
const validData = { code: "200200", data: { referenceId: "provider-ref", transRef: "bank-ref",
amount: 100, dateTime: "2026-09-01T12:01:00.000Z" } };
afterEach(() => {
names.forEach((name, index) => {
if (original[index] === undefined) delete process.env[name];
else process.env[name] = original[index];
});
vi.unstubAllGlobals();
});
describe("commission slip verification", () => {
it("rejects a non-mobile PromptPay value before checkout", () => {
process.env.COMMISSION_PROMPTPAY_TYPE = "mobile";
process.env.COMMISSION_PROMPTPAY_VALUE = "123456789012345";
process.env.COMMISSION_RECEIVER_ACCOUNT_NUMBER = "0812345678";
expect(() => promptPayConfig()).toThrow("invalid-promptpay-value");
process.env.COMMISSION_PROMPTPAY_VALUE = "0812345678";
expect(promptPayConfig().identifier).toEqual({ type: "mobile", value: "0066812345678" });
});
async function check(response: unknown) {
process.env.SLIP2GO_VERIFY_URL = "https://example.test/api/verify-slip/qr-image/info";
process.env.SLIP2GO_API_SECRET = "secret";
process.env.COMMISSION_PROMPTPAY_TYPE = "mobile";
process.env.COMMISSION_PROMPTPAY_VALUE = "0812345678";
process.env.COMMISSION_RECEIVER_ACCOUNT_NUMBER = "0812345678";
const fetch = vi.fn(async (_url: URL, init: RequestInit) => {
expect(init.headers).toEqual({ Authorization: "Bearer secret" });
const payload = JSON.parse((init.body as FormData).get("payload") as string);
expect(payload).toMatchObject({
checkReceiver: [{ accountType: "02001", accountNumber: "0812345678" }],
checkAmount: { type: "eq", amount: "100.00" } });
expect(payload).not.toHaveProperty("checkDuplicate");
return Response.json(response);
});
vi.stubGlobal("fetch", fetch);
return verifyCommissionSlip(new File(["image"], "slip.png", { type: "image/png" }), 100, checkoutDate);
}
it("accepts a matching verified transfer", async () => {
await expect(check(validData)).resolves.toMatchObject({ referenceId: "provider-ref",
transRef: "bank-ref", amountBaht: 100 });
});
it("rejects duplicate and amount mismatch results", async () => {
await expect(check({ code: "200501" })).rejects.toMatchObject({ status: 422 });
await expect(check({ code: "200401", data: { referenceId: "provider-ref" } }))
.rejects.toMatchObject({ status: 422, message: "slip-rejected:200401" });
await expect(check({ ...validData, code: "200000" })).rejects.toMatchObject({ status: 422 });
await expect(check({ ...validData, data: { ...validData.data, amount: 80 } }))
.rejects.toMatchObject({ status: 422 });
});
it("treats a rejected API secret as a service error, not an invalid slip", async () => {
await expect(check({ code: "401001", message: "Authentication Token Mismatch",
data: { referenceId: "provider-ref" } }))
.rejects.toMatchObject({ status: 503, message: "slip2go-service:401001" });
});
it("reports which required field is missing from a successful provider response", async () => {
await expect(check({ code: "200200", data: { referenceId: "provider-ref" } }))
.rejects.toMatchObject({ status: 503, message: "invalid-slip-verification-response:transRef" });
});
});