feat: consolidate database management work
Add catalog-owned logical relationships and runtime snapshots, extend the database-management UI and validation coverage, and document the updated operational workflow. Keep active sensitive-generation status in a tooltip and indicator, and update the layout E2E to follow the history action in its new database-scoped location.
This commit is contained in:
@@ -16,7 +16,7 @@ const regularUser: AuthenticatedUser = {
|
||||
};
|
||||
const adminUser: AuthenticatedUser = {
|
||||
...regularUser, subject: "alice-id", roles: ["admin"] as const,
|
||||
permissions: ["session.use", "session.read_all", "pi.manage"] as const, isAdmin: true,
|
||||
permissions: ["session.use", "session.read_all", "workspace.manage", "workspace.secrets.manage", "database.manage", "pi.manage"] as const, isAdmin: true,
|
||||
};
|
||||
|
||||
function wrap(user: AuthenticatedUser = regularUser) {
|
||||
@@ -95,7 +95,8 @@ test("regular users load only their sessions and never see administrator control
|
||||
wrap();
|
||||
await screen.findByText("Attiva uno");
|
||||
expect(scope).toBe("mine");
|
||||
expect(screen.queryByRole("button", { name: "All sessions" })).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole("button", { name: "Administration" })).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole("tab", { name: "All sessions" })).not.toBeInTheDocument();
|
||||
expect(screen.queryByText(/administrator view/i)).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -115,17 +116,25 @@ test("Pi management preserves the open session summary and the model activity ti
|
||||
http.post("/api/sessions/:id/resume", () => resumeResult("s1")),
|
||||
http.get("/api/sessions/:id", () => HttpResponse.json({ phase: 4 })),
|
||||
);
|
||||
wrap();
|
||||
wrap(adminUser);
|
||||
|
||||
await user.click(await screen.findByText("Attiva uno"));
|
||||
expect(await screen.findByRole("complementary", { name: "Session summary" })).toHaveTextContent("Domanda originale");
|
||||
await user.click(screen.getByRole("button", { name: "Administration" }));
|
||||
await user.click(screen.getByRole("button", { name: "Pi management" }));
|
||||
expect(await screen.findByRole("heading", { name: "Pi management" })).toBeVisible();
|
||||
const dialog = screen.getByRole("dialog", { name: "Pi management" });
|
||||
const workArea = screen.getByTestId("conversation-column");
|
||||
const sessionNavigation = screen.getByRole("complementary", { name: "Session navigation" });
|
||||
const piManagement = within(sessionNavigation).getByRole("button", { name: "Pi management" });
|
||||
const newSession = within(sessionNavigation).getByRole("button", { name: "New session" });
|
||||
expect(workArea).toContainElement(dialog);
|
||||
expect(sessionNavigation).not.toContainElement(dialog);
|
||||
expect(piManagement).toHaveAttribute("aria-current", "page");
|
||||
expect(piManagement).toHaveAttribute("aria-expanded", "true");
|
||||
expect(piManagement).toHaveAttribute("data-navigation-state", "current");
|
||||
expect(newSession).toHaveAttribute("data-navigation-state", "available");
|
||||
expect(newSession).not.toHaveAttribute("aria-current");
|
||||
const preservedSummary = screen.getByRole("complementary", { name: "Session summary" });
|
||||
expect(preservedSummary).not.toHaveAttribute("aria-hidden", "true");
|
||||
expect(preservedSummary).toHaveTextContent("Attiva uno");
|
||||
@@ -133,6 +142,10 @@ test("Pi management preserves the open session summary and the model activity ti
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole("complementary", { name: "Session summary" })).toHaveTextContent("Domanda originale");
|
||||
});
|
||||
expect(newSession).toHaveAttribute("aria-current", "page");
|
||||
expect(newSession).toHaveAttribute("data-navigation-state", "current");
|
||||
expect(piManagement).toHaveAttribute("aria-expanded", "false");
|
||||
expect(piManagement).toHaveAttribute("data-navigation-state", "available");
|
||||
|
||||
await user.click(screen.getByRole("button", { name: "Resume" }));
|
||||
await screen.findByRole("button", { name: "Show model activity" });
|
||||
@@ -160,17 +173,66 @@ test("administrators can explicitly switch to all sessions and see owners", asyn
|
||||
}),
|
||||
);
|
||||
wrap(adminUser);
|
||||
await screen.findByRole("button", { name: "All sessions" });
|
||||
expect(screen.getByRole("button", { name: "My sessions" })).toHaveAttribute("aria-pressed", "true");
|
||||
expect(screen.getByRole("button", { name: "All sessions" })).toHaveAttribute("aria-pressed", "false");
|
||||
await userEvent.click(screen.getByRole("button", { name: "All sessions" }));
|
||||
const tablist = await screen.findByRole("tablist", { name: "Session scope" });
|
||||
const mySessions = within(tablist).getByRole("tab", { name: "My sessions" });
|
||||
const allSessions = within(tablist).getByRole("tab", { name: "All sessions" });
|
||||
expect(mySessions).toHaveAttribute("aria-selected", "true");
|
||||
expect(mySessions).toHaveAttribute("aria-controls", "session-scope-panel");
|
||||
expect(mySessions).toHaveAttribute("tabindex", "0");
|
||||
expect(mySessions).toHaveAttribute("data-tab-state", "active");
|
||||
expect(mySessions).toHaveClass("bg-[oklch(var(--nav-active))]");
|
||||
expect(allSessions).toHaveAttribute("aria-selected", "false");
|
||||
expect(allSessions).toHaveAttribute("aria-controls", "session-scope-panel");
|
||||
expect(allSessions).toHaveAttribute("tabindex", "-1");
|
||||
expect(allSessions).toHaveAttribute("data-tab-state", "inactive");
|
||||
expect(allSessions).toHaveClass("border-border", "bg-card");
|
||||
expect(allSessions).not.toHaveClass("border-transparent", "bg-transparent");
|
||||
expect(screen.getByRole("tabpanel")).toHaveAttribute("aria-labelledby", "session-scope-mine-tab");
|
||||
await userEvent.click(allSessions);
|
||||
await waitFor(() => expect(scope).toBe("all"));
|
||||
expect(screen.getByRole("button", { name: "My sessions" })).toHaveAttribute("aria-pressed", "false");
|
||||
expect(screen.getByRole("button", { name: "All sessions" })).toHaveAttribute("aria-pressed", "true");
|
||||
expect(mySessions).toHaveAttribute("aria-selected", "false");
|
||||
expect(mySessions).toHaveAttribute("data-tab-state", "inactive");
|
||||
expect(allSessions).toHaveAttribute("aria-selected", "true");
|
||||
expect(allSessions).toHaveAttribute("data-tab-state", "active");
|
||||
expect(allSessions).toHaveClass("bg-[oklch(var(--nav-active))]");
|
||||
expect(screen.getByRole("tabpanel")).toHaveAttribute("aria-labelledby", "session-scope-all-tab");
|
||||
expect(await screen.findByText("Administrator view: all sessions")).toBeInTheDocument();
|
||||
expect(screen.getByText("Owner: Bob")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("session scope tabs support roving keyboard navigation", async () => {
|
||||
let scope = "";
|
||||
server.use(http.get("/api/sessions", ({ request }) => {
|
||||
scope = new URL(request.url).searchParams.get("scope") ?? "";
|
||||
return HttpResponse.json(LIST);
|
||||
}));
|
||||
wrap(adminUser);
|
||||
|
||||
const user = userEvent.setup();
|
||||
const tablist = await screen.findByRole("tablist", { name: "Session scope" });
|
||||
const mySessions = within(tablist).getByRole("tab", { name: "My sessions" });
|
||||
const allSessions = within(tablist).getByRole("tab", { name: "All sessions" });
|
||||
mySessions.focus();
|
||||
|
||||
await user.keyboard("{ArrowRight}");
|
||||
await waitFor(() => expect(scope).toBe("all"));
|
||||
expect(allSessions).toHaveFocus();
|
||||
expect(allSessions).toHaveAttribute("aria-selected", "true");
|
||||
expect(mySessions).toHaveAttribute("tabindex", "-1");
|
||||
|
||||
await user.keyboard("{ArrowLeft}");
|
||||
await waitFor(() => expect(scope).toBe("mine"));
|
||||
expect(mySessions).toHaveFocus();
|
||||
expect(mySessions).toHaveAttribute("aria-selected", "true");
|
||||
|
||||
await user.keyboard("{End}");
|
||||
expect(allSessions).toHaveFocus();
|
||||
expect(allSessions).toHaveAttribute("aria-selected", "true");
|
||||
await user.keyboard("{Home}");
|
||||
expect(mySessions).toHaveFocus();
|
||||
expect(mySessions).toHaveAttribute("aria-selected", "true");
|
||||
});
|
||||
|
||||
test("administrator confirms before deleting a same-named user's session", async () => {
|
||||
let deletes = 0;
|
||||
server.use(
|
||||
@@ -187,7 +249,7 @@ test("administrator confirms before deleting a same-named user's session", async
|
||||
}),
|
||||
);
|
||||
wrap(adminUser);
|
||||
await userEvent.click(await screen.findByRole("button", { name: "All sessions" }));
|
||||
await userEvent.click(await screen.findByRole("tab", { name: "All sessions" }));
|
||||
await screen.findByText("Owner: Alice");
|
||||
await userEvent.click(screen.getByRole("checkbox", { name: "Select Attiva uno" }));
|
||||
await userEvent.click(screen.getByRole("button", { name: "Delete 1 selected sessions" }));
|
||||
@@ -213,7 +275,7 @@ test("administrator confirms before archiving a same-named user's session", asyn
|
||||
}),
|
||||
);
|
||||
wrap(adminUser);
|
||||
await userEvent.click(await screen.findByRole("button", { name: "All sessions" }));
|
||||
await userEvent.click(await screen.findByRole("tab", { name: "All sessions" }));
|
||||
await screen.findByText("Owner: Alice");
|
||||
await userEvent.click(screen.getByRole("button", { name: "Session actions" }));
|
||||
await userEvent.click(await screen.findByText("Archive"));
|
||||
|
||||
Reference in New Issue
Block a user