129 lines
4.4 KiB
TypeScript
129 lines
4.4 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from "vitest";
|
||
import { useEffect } from "react";
|
||
import userEvent from "@testing-library/user-event";
|
||
import { renderWithProviders as render, screen } from "../utils/test-utils";
|
||
import "@testing-library/jest-dom/vitest";
|
||
import { ConfirmStakeholdersScreen } from "../../app/(app)/create/screens/select/ConfirmStakeholdersScreen";
|
||
import { useCreateFlow } from "../../app/(app)/create/context/CreateFlowContext";
|
||
import type { CreateFlowState } from "../../app/(app)/create/types";
|
||
|
||
vi.mock("../../lib/create/api", async (importOriginal) => {
|
||
const actual = await importOriginal<typeof import("../../lib/create/api")>();
|
||
return {
|
||
...actual,
|
||
fetchAuthSession: vi.fn(async () => ({
|
||
user: { id: "u1", email: "maya@example.org" },
|
||
})),
|
||
};
|
||
});
|
||
|
||
function SeedCreateFlow({ patch }: { patch: Partial<CreateFlowState> }) {
|
||
const { updateState } = useCreateFlow();
|
||
useEffect(() => {
|
||
updateState(patch);
|
||
}, [patch, updateState]);
|
||
return null;
|
||
}
|
||
|
||
describe("ConfirmStakeholdersScreen", () => {
|
||
beforeEach(() => {
|
||
vi.clearAllMocks();
|
||
});
|
||
|
||
it("renders the invite heading and email field", () => {
|
||
render(<ConfirmStakeholdersScreen />);
|
||
expect(
|
||
screen.getByRole("heading", {
|
||
name: "Invite people to read your Rule",
|
||
}),
|
||
).toBeInTheDocument();
|
||
expect(
|
||
screen.getByText("Everyone you add gets a private link to read the Rule."),
|
||
).toBeInTheDocument();
|
||
expect(
|
||
screen.getByRole("button", { name: "Add" }),
|
||
).toBeInTheDocument();
|
||
expect(
|
||
screen.getByText(
|
||
/Every Rule starts private\. Only the people you invite can read it/,
|
||
),
|
||
).toBeInTheDocument();
|
||
});
|
||
|
||
it("does not show the old draft toast", () => {
|
||
render(<ConfirmStakeholdersScreen />);
|
||
expect(
|
||
screen.queryByText(/Congratulations! You've drafted your CommunityRule!/i),
|
||
).not.toBeInTheDocument();
|
||
});
|
||
|
||
it("adds an email and shows the owner as You", async () => {
|
||
const user = userEvent.setup();
|
||
render(<ConfirmStakeholdersScreen />);
|
||
expect(await screen.findByText("maya@example.org")).toBeInTheDocument();
|
||
expect(screen.getByText("You")).toBeInTheDocument();
|
||
|
||
await user.type(
|
||
screen.getByRole("textbox", { name: /Add someone by email/i }),
|
||
"rosa@example.org",
|
||
);
|
||
await user.click(screen.getByRole("button", { name: "Add" }));
|
||
expect(screen.getByText("rosa@example.org")).toBeInTheDocument();
|
||
expect(
|
||
screen.getByText("2 people get a private link to read the Rule."),
|
||
).toBeInTheDocument();
|
||
expect(
|
||
screen.queryByRole("button", { name: /Remove maya@example.org/i }),
|
||
).not.toBeInTheDocument();
|
||
expect(
|
||
screen.getByRole("button", { name: /Remove rosa@example.org/i }),
|
||
).toBeInTheDocument();
|
||
});
|
||
|
||
it("keeps a pasted invalid address in the field and reports what was added", async () => {
|
||
const user = userEvent.setup();
|
||
render(<ConfirmStakeholdersScreen />);
|
||
const field = await screen.findByRole("textbox", {
|
||
name: /Add someone by email/i,
|
||
});
|
||
field.focus();
|
||
await user.paste("rosa@example.org, jo@example, sam@example.org");
|
||
expect(await screen.findByText("rosa@example.org")).toBeInTheDocument();
|
||
expect(screen.getByText("sam@example.org")).toBeInTheDocument();
|
||
expect(field).toHaveValue("jo@example");
|
||
expect(
|
||
screen.getByText(
|
||
/Added two people from your list\. One is not an email address\./,
|
||
),
|
||
).toBeInTheDocument();
|
||
expect(
|
||
screen.getByText("Not an email address. Fix it and select Add, or clear it."),
|
||
).toBeInTheDocument();
|
||
});
|
||
|
||
it("shows the membership card from the selected method", async () => {
|
||
render(
|
||
<>
|
||
<SeedCreateFlow
|
||
patch={{
|
||
selectedMembershipMethodIds: ["open-admission"],
|
||
membershipMethodDetailsById: {
|
||
"open-admission": {
|
||
eligibility: "Anyone who shares the work belongs.",
|
||
joiningProcess: "Work two Sunday shares, then ask to join.",
|
||
expectations: "",
|
||
},
|
||
},
|
||
}}
|
||
/>
|
||
<ConfirmStakeholdersScreen />
|
||
</>,
|
||
);
|
||
expect(await screen.findByText("Open admission")).toBeInTheDocument();
|
||
expect(screen.getByText("Who belongs, in your Rule’s words")).toBeInTheDocument();
|
||
expect(
|
||
screen.getByText(/Anyone who shares the work belongs/),
|
||
).toBeInTheDocument();
|
||
});
|
||
});
|