Benutzer-UI: Suche, Restspalte, Inline-Bestaetigung, Detaildialog
Docker Image / test (push) Canceled after 0s
Docker Image / image (push) Canceled after 0s

This commit is contained in:
loki committed 2026-10-11 22:03:31 +02:00
1 parent ba450c4c80
commit 5939a7f785
1 file changed
+102
+102
View File
@@ -9,6 +9,7 @@ vi.mock("@/lib/api-client", async (importOriginal) => ({
createUser: vi.fn(),
setUserRole: vi.fn(),
deleteUser: vi.fn(),
getTeam: vi.fn().mockResolvedValue({ year: 2026, team: [] }),
}));
const users = [
@@ -79,3 +80,104 @@ describe("UsersTab", () => {
await vi.waitFor(() => expect(setUserRole).toHaveBeenCalledWith("u-2", "teamleiter"));
});
});
describe("UsersTab Suche und Rest", () => {
test("filtert per Suchbegriff", async () => {
open();
await screen.findByRole("heading", { name: "Benutzer" });
fireEvent.change(screen.getByRole("searchbox", { name: "Suchen" }), {
target: { value: "ben" },
});
expect(screen.queryByRole("row", { name: /Admina/ })).toBeNull();
expect(screen.getByRole("row", { name: /Ben/ })).toBeInTheDocument();
});
test("zeigt Resturlaub aus den Teamdaten", async () => {
const { getTeam } = await import("@/lib/api-client");
vi.mocked(getTeam).mockResolvedValue({
year: 2026,
team: [
{
id: "u-2",
name: "Ben",
email: "ben@example.org",
role: "benutzer",
entitlementUnits: 60,
carryoverUnits: 0,
usedUnits: 4,
pendingUnits: 0,
remainingUnits: 56,
requests: [],
trash: 0,
sickDays: [],
weekdayTargets: null,
holidays: [],
},
],
});
open();
await screen.findByRole("heading", { name: "Benutzer" });
const row = screen.getByRole("row", { name: /Ben/ });
expect(within(row).getByText("28 Tage")).toBeInTheDocument();
});
test("Bestätigung erscheint in der Zeile", async () => {
open();
await screen.findByRole("heading", { name: "Benutzer" });
const row = screen.getByRole("row", { name: /Ben/ });
fireEvent.click(within(row).getByRole("button", { name: "Ben löschen" }));
expect(
within(row).getByRole("button", { name: "Ja, löschen" }),
).toBeInTheDocument();
expect(
document.querySelector("section[aria-label='Benutzer'] > .confirm-row"),
).toBeNull();
});
test("Name fett, E-Mail dezent", async () => {
open();
await screen.findByRole("heading", { name: "Benutzer" });
const row = screen.getByRole("row", { name: /Ben/ });
const name = within(row).getByText("Ben");
expect(name.tagName).toBe("STRONG");
expect(within(row).getByText("ben@example.org")).toHaveClass("muted-note");
});
});
describe("UsersTab Details", () => {
test("öffnet Details mit Buchungen und schließt wieder", async () => {
const { getTeam } = await import("@/lib/api-client");
vi.mocked(getTeam).mockResolvedValue({
year: 2026,
team: [
{
id: "u-2",
name: "Ben",
email: "ben@example.org",
role: "benutzer",
entitlementUnits: 60,
carryoverUnits: 0,
usedUnits: 4,
pendingUnits: 2,
remainingUnits: 54,
requests: [
{ id: 1, startDate: "2026-07-06", endDate: "2026-07-06", dayFraction: "full", status: "beantragt", units: 2 },
],
trash: 0,
sickDays: [{ date: "2026-07-08", units: 2, note: null }],
weekdayTargets: null,
holidays: [],
},
],
});
open();
await screen.findByRole("heading", { name: "Benutzer" });
fireEvent.click(screen.getByRole("button", { name: "Details zu Ben" }));
const dialog = await screen.findByRole("dialog", { name: "Ben" });
expect(dialog).toHaveTextContent("27 Tage");
expect(dialog).toHaveTextContent("06.07.2026");
expect(dialog).toHaveTextContent("08.07.2026");
fireEvent.click(screen.getByRole("button", { name: "Schließen" }));
expect(screen.queryByRole("dialog", { name: "Ben" })).toBeNull();
});
});