feat: complete catalog fleet management workflow
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { render, screen, waitFor } from "@testing-library/react";
|
||||
import { render, screen, waitFor, within } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { http, HttpResponse } from "msw";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
@@ -6,7 +6,7 @@ import { server } from "../test/msw";
|
||||
import { FakeEventSource } from "../test/fakeEventSource";
|
||||
import { useSessionStore } from "../store/sessionStore";
|
||||
import { clearAuthState, setAuthState } from "../auth/authState";
|
||||
import { AppShell } from "./AppShell";
|
||||
import { AppShell, resolveDatabaseManagementPresentation } from "./AppShell";
|
||||
|
||||
function renderShell() {
|
||||
const client = new QueryClient({ defaultOptions: { queries: { retry: false } } });
|
||||
@@ -29,6 +29,7 @@ beforeEach(() => {
|
||||
session: null,
|
||||
});
|
||||
localStorage.clear();
|
||||
window.history.replaceState(null, "", "/");
|
||||
FakeEventSource.instances = [];
|
||||
(globalThis as any).EventSource = FakeEventSource;
|
||||
useSessionStore.getState().resetSession();
|
||||
@@ -49,33 +50,66 @@ beforeEach(() => {
|
||||
http.get("/api/workspaces", () => HttpResponse.json([])),
|
||||
http.get("/api/models", () => HttpResponse.json({ models: [] })),
|
||||
http.post("/api/runtime/prewarm", () => new HttpResponse(null, { status: 202 })),
|
||||
http.get("/api/catalog/metrics", () => HttpResponse.json({
|
||||
scope: "global",
|
||||
databaseId: null,
|
||||
tables: 0,
|
||||
columns: 0,
|
||||
sensitiveColumns: 0,
|
||||
relationships: 0,
|
||||
descriptionTargets: 0,
|
||||
describedTargets: 0,
|
||||
descriptionCoverage: 0,
|
||||
updatedAt: null,
|
||||
})),
|
||||
);
|
||||
});
|
||||
|
||||
test("opens the database management surface and returns to the core", async () => {
|
||||
renderShell();
|
||||
|
||||
const composer = screen.getByRole("textbox", { name: /new question/i });
|
||||
await userEvent.type(composer, "Unsent draft");
|
||||
|
||||
const databaseManagement = screen.getByRole("button", { name: "Database management" });
|
||||
await userEvent.click(databaseManagement);
|
||||
|
||||
expect(screen.getByRole("main", { name: "Database management" })).toBeVisible();
|
||||
expect(databaseManagement).toHaveAttribute("aria-current", "page");
|
||||
expect(databaseManagement).toHaveClass("w-full");
|
||||
expect(databaseManagement).not.toHaveClass("bg-sidebar-accent");
|
||||
expect(screen.queryByRole("textbox", { name: /new question/i })).not.toBeInTheDocument();
|
||||
|
||||
await userEvent.click(screen.getByRole("button", { name: "New session" }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByRole("main", { name: "Database management" })).not.toBeInTheDocument();
|
||||
});
|
||||
expect(screen.getByRole("textbox", { name: /new question/i })).toHaveValue("Unsent draft");
|
||||
test("uses Fleet Ledger by default and gates the legacy fallback to non-production environments", () => {
|
||||
expect(resolveDatabaseManagementPresentation({
|
||||
isDevelopment: true,
|
||||
mode: "development",
|
||||
search: "",
|
||||
})).toBe("fleet");
|
||||
expect(resolveDatabaseManagementPresentation({
|
||||
isDevelopment: true,
|
||||
mode: "development",
|
||||
search: "?db-ui=legacy",
|
||||
})).toBe("legacy");
|
||||
expect(resolveDatabaseManagementPresentation({
|
||||
isDevelopment: false,
|
||||
mode: "staging",
|
||||
legacyFlag: "true",
|
||||
search: "",
|
||||
})).toBe("legacy");
|
||||
expect(resolveDatabaseManagementPresentation({
|
||||
isDevelopment: false,
|
||||
mode: "production",
|
||||
legacyFlag: "true",
|
||||
search: "?db-ui=legacy",
|
||||
})).toBe("fleet");
|
||||
});
|
||||
|
||||
test("keeps a live core session connected and returns when that session is opened", async () => {
|
||||
test("replaces the core conversation while keeping the session navigation", async () => {
|
||||
renderShell();
|
||||
|
||||
const conversationColumn = screen.getByTestId("conversation-column");
|
||||
const sessionNavigation = screen.getByRole("complementary", { name: "Session navigation" });
|
||||
const databaseManagement = within(sessionNavigation).getByRole("button", { name: "Database management" });
|
||||
await userEvent.click(databaseManagement);
|
||||
|
||||
const manager = screen.getByRole("main", { name: "Database management" });
|
||||
expect(manager).toBeVisible();
|
||||
expect(conversationColumn).toContainElement(manager);
|
||||
expect(screen.getByRole("complementary", { name: "Session navigation" })).toBe(sessionNavigation);
|
||||
expect(sessionNavigation).toBeVisible();
|
||||
expect(within(sessionNavigation).getByRole("button", { name: "New session" })).toBeVisible();
|
||||
expect(databaseManagement).toHaveAttribute("aria-current", "page");
|
||||
expect(screen.queryByRole("button", { name: "Back to workspace" })).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole("textbox", { name: /new question/i })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("keeps a live core session connected while returning from database management", async () => {
|
||||
server.use(
|
||||
http.get("/api/sessions", () => HttpResponse.json([{
|
||||
id: "s1",
|
||||
@@ -113,6 +147,7 @@ test("keeps a live core session connected and returns when that session is opene
|
||||
expect(source.closed).toBe(false);
|
||||
expect(FakeEventSource.instances).toHaveLength(1);
|
||||
|
||||
expect(session).toBeVisible();
|
||||
await userEvent.click(session);
|
||||
|
||||
await waitFor(() => {
|
||||
@@ -174,14 +209,15 @@ test("does not leave database management without confirming a dirty form", async
|
||||
await userEvent.clear(schema);
|
||||
await userEvent.type(schema, "reporting");
|
||||
|
||||
await userEvent.click(screen.getByRole("button", { name: "New session" }));
|
||||
const newSession = screen.getByRole("button", { name: "New session" });
|
||||
await userEvent.click(newSession);
|
||||
|
||||
expect(confirm).toHaveBeenCalledWith("Discard unsaved database changes and leave database management?");
|
||||
expect(screen.getByRole("main", { name: "Database management" })).toBeVisible();
|
||||
expect(schema).toHaveValue("reporting");
|
||||
|
||||
confirm.mockReturnValue(true);
|
||||
await userEvent.click(screen.getByRole("button", { name: "New session" }));
|
||||
await userEvent.click(newSession);
|
||||
await waitFor(() => expect(screen.queryByRole("main", { name: "Database management" })).not.toBeInTheDocument());
|
||||
confirm.mockRestore();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user