Rollen Chunk 7: Benutzerverwaltung und Sicherung strikt Admin-only
This commit is contained in:
1 parent
b523982cd0
commit
03dbf30acf
1 file changed
+81
@@ -0,0 +1,81 @@
|
||||
import { fireEvent, render, screen, within } from "@testing-library/react";
|
||||
import { describe, expect, test, vi } from "vitest";
|
||||
import { createUser, deleteUser, listUsers, setUserRole } from "@/lib/api-client";
|
||||
import { UsersTab } from "./UsersTab";
|
||||
|
||||
vi.mock("@/lib/api-client", async (importOriginal) => ({
|
||||
...(await importOriginal<typeof import("@/lib/api-client")>()),
|
||||
listUsers: vi.fn(),
|
||||
createUser: vi.fn(),
|
||||
setUserRole: vi.fn(),
|
||||
deleteUser: vi.fn(),
|
||||
}));
|
||||
|
||||
const users = [
|
||||
{ id: "u-1", name: "Admina", email: "admina@example.org", role: "admin" as const },
|
||||
{ id: "u-2", name: "Ben", email: "ben@example.org", role: "benutzer" as const },
|
||||
];
|
||||
|
||||
function open(selfId = "u-1") {
|
||||
vi.mocked(listUsers).mockResolvedValue({ users });
|
||||
return render(<UsersTab selfId={selfId} />);
|
||||
}
|
||||
|
||||
describe("UsersTab", () => {
|
||||
test("listet Benutzer mit Rollen", async () => {
|
||||
open();
|
||||
expect(await screen.findByRole("heading", { name: "Benutzer" })).toBeInTheDocument();
|
||||
const row = screen.getByRole("row", { name: /Ben/ });
|
||||
expect(within(row).getByText("ben@example.org")).toBeInTheDocument();
|
||||
expect(within(row).getByDisplayValue("benutzer")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("legt Benutzer mit deutschem Fehler bei belegter Mail an", async () => {
|
||||
const { ApiError } = await import("@/lib/api-client");
|
||||
vi.mocked(createUser).mockRejectedValue(
|
||||
new ApiError("Diese E-Mail ist bereits vergeben.", "emailTaken", 409),
|
||||
);
|
||||
open();
|
||||
await screen.findByRole("heading", { name: "Benutzer" });
|
||||
fireEvent.change(screen.getByLabelText(/Name/), {
|
||||
target: { value: "Neu" },
|
||||
});
|
||||
fireEvent.change(screen.getByLabelText(/E-Mail/), {
|
||||
target: { value: "ben@example.org" },
|
||||
});
|
||||
fireEvent.change(screen.getByLabelText(/Passwort/), {
|
||||
target: { value: "geheim-geheim!" },
|
||||
});
|
||||
fireEvent.click(screen.getByRole("button", { name: "Benutzer anlegen" }));
|
||||
await vi.waitFor(() => expect(createUser).toHaveBeenCalled());
|
||||
expect(await screen.findByRole("alert")).toHaveTextContent(
|
||||
"Diese E-Mail ist bereits vergeben.",
|
||||
);
|
||||
});
|
||||
|
||||
test("löscht nach zweistufiger Bestätigung", async () => {
|
||||
vi.mocked(deleteUser).mockResolvedValue({ deleted: true });
|
||||
open();
|
||||
await screen.findByRole("heading", { name: "Benutzer" });
|
||||
const row = screen.getByRole("row", { name: /Ben/ });
|
||||
fireEvent.click(within(row).getByRole("button", { name: "Ben löschen" }));
|
||||
fireEvent.click(screen.getByRole("button", { name: "Ja, löschen" }));
|
||||
await vi.waitFor(() => expect(deleteUser).toHaveBeenCalledWith("u-2"));
|
||||
});
|
||||
|
||||
test("eigene Zeile ohne Löschen, Rollenwechsel ruft API", async () => {
|
||||
vi.mocked(setUserRole).mockResolvedValue({ user: { id: "u-2", role: "teamleiter" } });
|
||||
open();
|
||||
await screen.findByRole("heading", { name: "Benutzer" });
|
||||
expect(
|
||||
within(screen.getByRole("row", { name: /Admina/ })).queryByRole("button", {
|
||||
name: /löschen/,
|
||||
}),
|
||||
).toBeNull();
|
||||
const row = screen.getByRole("row", { name: /Ben/ });
|
||||
fireEvent.change(within(row).getByLabelText("Rolle"), {
|
||||
target: { value: "teamleiter" },
|
||||
});
|
||||
await vi.waitFor(() => expect(setUserRole).toHaveBeenCalledWith("u-2", "teamleiter"));
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user