mirror of
https://github.com/Since-3/Kuma.git
synced 2026-10-12 20:51:18 +00:00
see comments
This commit is contained in:
parent
55d8838c0e
commit
85c2bd95eb
7 changed files with 153 additions and 47 deletions
|
|
@ -177,6 +177,25 @@ describe("Stripe-Webhook – Buchung", () => {
|
|||
expect(recordStripeFee).toHaveBeenCalledWith("pi_1", "acct_studio");
|
||||
});
|
||||
|
||||
it("bucht nicht mit Gebühr 0, wenn der PaymentIntent nicht abrufbar ist", async () => {
|
||||
// Mit 0 als Ersatz wäre die Gebühr dauerhaft falsch verbucht - eine erneute
|
||||
// Zustellung ändert eine bezahlte Buchung nicht mehr. Stattdessen 500,
|
||||
// damit Stripe das Event erneut zustellt.
|
||||
vi.mocked(stripe.paymentIntents.retrieve).mockRejectedValue(
|
||||
new Error("Stripe nicht erreichbar")
|
||||
);
|
||||
const consoleError = vi.spyOn(console, "error").mockImplementation(() => {});
|
||||
|
||||
const res = await deliver(
|
||||
sessionEvent("checkout.session.completed", { account: "acct_studio" }),
|
||||
"whsec_connect"
|
||||
);
|
||||
|
||||
expect(res.status).toBe(500);
|
||||
expect(tx.courseBooking.upsert).not.toHaveBeenCalled();
|
||||
consoleError.mockRestore();
|
||||
});
|
||||
|
||||
it("speichert die Rechnungsadresse aus dem Checkout an der Buchung", async () => {
|
||||
const event = sessionEvent("checkout.session.completed", { account: "acct_studio" });
|
||||
(event.data.object as Record<string, unknown>).customer_details = {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
||||
import { render, screen, fireEvent } from "@testing-library/react";
|
||||
|
||||
vi.mock("next/navigation", () => ({ useSearchParams: () => new URLSearchParams() }));
|
||||
const nav = vi.hoisted(() => ({ params: new URLSearchParams() }));
|
||||
vi.mock("next/navigation", () => ({ useSearchParams: () => nav.params }));
|
||||
vi.mock("next/image", () => ({ default: () => null }));
|
||||
// Block (Desktop) und Zeitleiste (Handy) sind eigene Bausteine - hier zählt,
|
||||
// welche Kurse in welcher Woche bzw. an welchem Tag erscheinen.
|
||||
|
|
@ -20,7 +21,8 @@ vi.mock("@/src/modules/courses/ui/components/DayTimeline", () => ({
|
|||
),
|
||||
}));
|
||||
vi.mock("@/src/modules/courses/ui/components/BookingDialog", () => ({
|
||||
BookingDialog: () => null,
|
||||
BookingDialog: ({ open, course }: { open: boolean; course: { name: string } }) =>
|
||||
open ? <div role="dialog">{course.name}</div> : null,
|
||||
}));
|
||||
vi.mock("@/src/modules/courses/actions/booking-actions", () => ({
|
||||
getPublishedCoursesForBusiness: vi.fn(),
|
||||
|
|
@ -96,6 +98,7 @@ beforeEach(() => {
|
|||
vi.useFakeTimers({ toFake: ["Date"] });
|
||||
vi.setSystemTime(new Date("2026-10-01T08:00:00Z"));
|
||||
vi.mocked(getPublishedCoursesForBusiness).mockReset();
|
||||
nav.params = new URLSearchParams();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
|
@ -173,6 +176,27 @@ describe("Öffentliche Studio-Seite – Wochenkalender", () => {
|
|||
});
|
||||
});
|
||||
|
||||
it("öffnet einen geteilten Link auf einen Kurs in einer späteren Woche", () => {
|
||||
nav.params = new URLSearchParams({ course: "pilates" });
|
||||
renderView();
|
||||
|
||||
expect(screen.getByRole("dialog").textContent).toBe("Reformer Pilates");
|
||||
// Der Kalender steht dahinter in der Woche des Kurses.
|
||||
expect(cards()).toEqual(["18:00 Reformer Pilates"]);
|
||||
});
|
||||
|
||||
it("öffnet keinen Buchungsdialog für einen bereits begonnenen Kurs", () => {
|
||||
// "Frueh" lief heute um 07:30 - jetzt ist es 10:00.
|
||||
nav.params = new URLSearchParams({ course: "started" });
|
||||
renderView();
|
||||
|
||||
expect(screen.queryByRole("dialog")).toBeNull();
|
||||
expect(screen.getByRole("status").textContent).toMatch(
|
||||
/„Frueh“ hat bereits begonnen und kann nicht mehr gebucht werden/
|
||||
);
|
||||
expect(cards()).toEqual(["18:00 Yoga Flow", "07:30 Spinning"]);
|
||||
});
|
||||
|
||||
it("nennt Stornoregel und Servicegebühr in einer Zeile", () => {
|
||||
renderView();
|
||||
expect(
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import "@testing-library/jest-dom/vitest";
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
||||
import { render, screen, cleanup } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
|
|
@ -44,7 +45,7 @@ const defaultProps = {
|
|||
primaryColor: "#1d3557",
|
||||
accentColor: "#c9a84c",
|
||||
},
|
||||
policy: { tiers: [] },
|
||||
policy: { enabled: true, mode: "tiered" as const, fixedRefundPercent: 100, tiers: [] },
|
||||
isPublic: false,
|
||||
slug: null,
|
||||
stripeAccountStatus: null,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue