import { describe, it, expect, vi, beforeEach } from "vitest"; vi.mock("@/src/lib/stripe", () => ({ stripe: { refunds: { create: vi.fn() } }, })); import { refundStripePayment } from "@/src/lib/stripe-refund"; import { stripe } from "@/src/lib/stripe"; beforeEach(() => { vi.clearAllMocks(); vi.mocked(stripe.refunds.create).mockResolvedValue({ id: "re_1", amount: 2900 } as never); }); describe("refundStripePayment", () => { it("erstattet eine Direct Charge auf dem Studio-Account, ohne reverse_transfer", async () => { const result = await refundStripePayment({ paymentIntentId: "pi_1", stripeAccountId: "acct_studio", amountCents: 2900, idempotencyKey: "refund-b1", refundApplicationFee: false, }); expect(result).toEqual({ success: true, stripeRefundId: "re_1", amountRefundedCents: 2900 }); expect(stripe.refunds.create).toHaveBeenCalledWith( { payment_intent: "pi_1", amount: 2900, refund_application_fee: false }, { stripeAccount: "acct_studio", idempotencyKey: "refund-b1" } ); }); it("holt das Geld bei Altbuchungen per reverse_transfer vom Studio zurück", async () => { await refundStripePayment({ paymentIntentId: "pi_1", stripeAccountId: null, refundApplicationFee: true, }); expect(stripe.refunds.create).toHaveBeenCalledWith( { payment_intent: "pi_1", refund_application_fee: true, reverse_transfer: true }, {} ); }); it("meldet einen Stripe-Fehler als Ergebnis statt zu werfen", async () => { vi.mocked(stripe.refunds.create).mockRejectedValue(new Error("insufficient balance")); const result = await refundStripePayment({ paymentIntentId: "pi_1", stripeAccountId: "acct_studio", refundApplicationFee: false, }); expect(result).toEqual({ success: false, error: "insufficient balance", definitive: false }); }); it("unterscheidet eine sichere Ablehnung von einem offenen Ausgang", async () => { const rejected = Object.assign(new Error("Charge already refunded"), { type: "StripeInvalidRequestError", code: "charge_already_refunded", }); vi.mocked(stripe.refunds.create).mockRejectedValueOnce(rejected); const timeout = Object.assign(new Error("timeout"), { type: "StripeConnectionError" }); vi.mocked(stripe.refunds.create).mockRejectedValueOnce(timeout); const params = { paymentIntentId: "pi_1", stripeAccountId: "acct", refundApplicationFee: false, }; expect(await refundStripePayment(params)).toMatchObject({ success: false, definitive: true, code: "charge_already_refunded", }); expect(await refundStripePayment(params)).toMatchObject({ success: false, definitive: false }); }); });