mirror of
https://github.com/Since-3/Kuma.git
synced 2026-10-12 19:51:17 +00:00
122 lines
4 KiB
TypeScript
122 lines
4 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
import { act, fireEvent, render, screen } from "@testing-library/react";
|
|
import type { ReactNode } from "react";
|
|
|
|
vi.mock("@/src/hooks/use-mobile", () => ({ useIsMobile: () => true }));
|
|
vi.mock("sonner", () => ({ toast: { error: vi.fn(), success: vi.fn() } }));
|
|
vi.mock("@/src/modules/marketing/actions/editor-actions", () => ({
|
|
getMarketingEditor: vi.fn(),
|
|
setTriggerActive: vi.fn(),
|
|
getSendHistory: vi.fn(),
|
|
getChangeHistory: vi.fn(),
|
|
}));
|
|
// Radix-Select lässt sich in jsdom kaum bedienen - ein natives <select> reicht hier.
|
|
vi.mock("@/src/components/ui/select", () => ({
|
|
Select: ({
|
|
value,
|
|
onValueChange,
|
|
children,
|
|
}: {
|
|
value: string;
|
|
onValueChange: (v: string) => void;
|
|
children: ReactNode;
|
|
}) => (
|
|
<select aria-label="Business" value={value} onChange={(e) => onValueChange(e.target.value)}>
|
|
{children}
|
|
</select>
|
|
),
|
|
SelectTrigger: () => null,
|
|
SelectValue: () => null,
|
|
SelectContent: ({ children }: { children: ReactNode }) => <>{children}</>,
|
|
SelectItem: ({ value, children }: { value: string; children: ReactNode }) => (
|
|
<option value={value}>{children}</option>
|
|
),
|
|
}));
|
|
|
|
import { toast } from "sonner";
|
|
import MarketingView from "@/src/modules/marketing/ui/views/marketing-view";
|
|
import {
|
|
getMarketingEditor,
|
|
setTriggerActive,
|
|
type EditorData,
|
|
} from "@/src/modules/marketing/actions/editor-actions";
|
|
import { EMAIL_TEMPLATES } from "@/src/modules/marketing/lib/node-config";
|
|
|
|
function editorData(prefix: string): EditorData {
|
|
return {
|
|
consentingCustomers: 3,
|
|
nodes: [
|
|
{
|
|
id: `${prefix}-trigger`,
|
|
kind: "birthday",
|
|
config: {},
|
|
position: { x: 0, y: 0 },
|
|
emailNodeId: `${prefix}-mail`,
|
|
isActive: false,
|
|
sent: 0,
|
|
redeemed: 0,
|
|
activatedAt: null,
|
|
},
|
|
{
|
|
id: `${prefix}-mail`,
|
|
kind: "email",
|
|
config: { ...EMAIL_TEMPLATES.birthday, name: `Mail ${prefix}` },
|
|
position: { x: 300, y: 0 },
|
|
emailNodeId: null,
|
|
isActive: false,
|
|
sent: 0,
|
|
redeemed: 0,
|
|
activatedAt: null,
|
|
},
|
|
],
|
|
};
|
|
}
|
|
|
|
const businesses = [
|
|
{ id: "biz-a", name: "Studio A" },
|
|
{ id: "biz-b", name: "Studio B" },
|
|
];
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
describe("MarketingView - Studio wechseln", () => {
|
|
it("wechselt Studio und Daten erst zusammen, wenn das neue Studio geladen ist", async () => {
|
|
let resolve!: (value: Awaited<ReturnType<typeof getMarketingEditor>>) => void;
|
|
vi.mocked(getMarketingEditor).mockReturnValue(new Promise((r) => (resolve = r)));
|
|
vi.mocked(setTriggerActive).mockResolvedValue({ success: true, data: editorData("b") });
|
|
|
|
render(<MarketingView businesses={businesses} initialData={editorData("a")} />);
|
|
expect(screen.getByText(/Mail a/)).toBeInTheDocument();
|
|
|
|
fireEvent.change(screen.getByLabelText("Business"), { target: { value: "biz-b" } });
|
|
|
|
// Solange B lädt, bleibt alles bei A - auch die Auswahl.
|
|
expect(screen.getByText(/Mail a/)).toBeInTheDocument();
|
|
expect(screen.getByLabelText("Business")).toHaveValue("biz-a");
|
|
|
|
await act(async () => resolve({ success: true, data: editorData("b") }));
|
|
|
|
expect(screen.getByText(/Mail b/)).toBeInTheDocument();
|
|
expect(screen.getByLabelText("Business")).toHaveValue("biz-b");
|
|
|
|
await act(async () => {
|
|
fireEvent.click(screen.getByRole("switch"));
|
|
});
|
|
expect(setTriggerActive).toHaveBeenCalledWith("biz-b", "b-trigger", true);
|
|
});
|
|
|
|
it("bleibt beim alten Studio, wenn das neue nicht lädt", async () => {
|
|
vi.mocked(getMarketingEditor).mockResolvedValue({ success: false, error: "Kaputt" });
|
|
|
|
render(<MarketingView businesses={businesses} initialData={editorData("a")} />);
|
|
await act(async () => {
|
|
fireEvent.change(screen.getByLabelText("Business"), { target: { value: "biz-b" } });
|
|
});
|
|
|
|
expect(toast.error).toHaveBeenCalledWith("Kaputt");
|
|
expect(screen.getByLabelText("Business")).toHaveValue("biz-a");
|
|
expect(screen.getByText(/Mail a/)).toBeInTheDocument();
|
|
});
|
|
});
|