Files
gerbeur/src/test/pages/UserDumps.test.tsx

91 lines
3.4 KiB
TypeScript

import { describe, expect, test } from "vitest";
import { screen } from "@testing-library/react";
import { userEvent } from "@testing-library/user-event";
import { UserDumps } from "../../pages/UserDumps.tsx";
import { fail, route } from "../fetch.ts";
import { makeDump, makeSession, makeUser, page, wire } from "../fixtures.ts";
import { renderApp } from "../render.tsx";
import { FakeWebSocket } from "../ws.ts";
const ann = makeUser({ id: "ann", username: "ann" });
const annSession = makeSession({ id: "ann", username: "ann" });
function openDumps(session: ReturnType<typeof makeSession> | null = null) {
const user = userEvent.setup();
renderApp(<UserDumps />, {
route: "/users/ann/dumps",
path: "/users/:username/dumps",
session,
});
return { user, socket: FakeWebSocket.last };
}
describe("UserDumps", () => {
test("lists a user's dumps under a header back to the profile", async () => {
route("GET /api/users/:u", () => wire(ann));
route(
"GET /api/users/:u/dumps",
() => page([makeDump({ title: "Hers", userId: "ann" })]),
);
openDumps();
expect(await screen.findByText("Hers")).toBeInTheDocument();
expect(screen.getByRole("heading", { name: "Dumps" })).toBeInTheDocument();
expect(screen.getByRole("link", { name: "← ann" })).toHaveAttribute(
"href",
"/users/ann",
);
expect(screen.queryByRole("button", { name: /New dump/ })).not
.toBeInTheDocument();
});
test("an unknown user", async () => {
route("GET /api/users/:u", () => fail("User not found", 404));
route("GET /api/users/:u/dumps", () => page([]));
openDumps();
expect(await screen.findByRole("alert")).toBeInTheDocument();
expect(screen.getByRole("link", { name: "← Back to profile" }))
.toBeInTheDocument();
});
test("on your own page: a new-dump button, and your dumps going private stay", async () => {
route("GET /api/users/:u", () => wire(ann));
const mine = makeDump({ id: "m", title: "Mine", userId: "ann" });
route("GET /api/users/:u/dumps", () => page([mine]));
const { user, socket } = openDumps(annSession);
await screen.findByText("Mine");
socket.welcome();
socket.receive({
type: "dump_updated",
dump: wire({ ...mine, isPrivate: true }),
});
expect(screen.getByText("Mine")).toBeInTheDocument();
route("GET /api/preview", () => ({ reached: false, richContent: null }));
await user.click(screen.getByRole("button", { name: /New dump/ }));
expect(screen.getByRole("dialog", { name: "New dump" }))
.toBeInTheDocument();
});
test("a visitor loses a dump that goes private, and gets it back where it was", async () => {
route("GET /api/users/:u", () => wire(ann));
const list = ["x", "y", "z"].map((id) =>
makeDump({ id, title: `T-${id}`, userId: "ann" })
);
route("GET /api/users/:u/dumps", () => page(list));
const { socket } = openDumps();
await screen.findByText("T-z");
socket.welcome();
socket.receive({
type: "dump_updated",
dump: wire({ ...list[1], isPrivate: true }),
});
expect(screen.queryByText("T-y")).not.toBeInTheDocument();
socket.receive({
type: "dump_updated",
dump: wire({ ...list[1], isPrivate: false }),
});
const titles = Array.from(document.querySelectorAll(".dump-card-title"))
.map((a) => a.textContent);
expect(titles).toEqual(["T-x", "T-y", "T-z"]);
});
});