feat(webui): add MCP management dialog
This commit is contained in:
@@ -128,8 +128,8 @@ describe("SettingsView Apps catalog", () => {
|
||||
);
|
||||
expect(screen.getByRole("button", { name: "Cancel" })).toBeInTheDocument();
|
||||
|
||||
expect(await screen.findByRole("button", { name: "Xmind: Configured" }, { timeout: 2500 }))
|
||||
.toHaveTextContent("Configured");
|
||||
expect(await screen.findByRole("button", { name: "Manage Xmind" }, { timeout: 2500 }))
|
||||
.toHaveTextContent("Manage");
|
||||
expect(screen.queryByRole("button", { name: "Cancel" })).not.toBeInTheDocument();
|
||||
expect(screen.queryByText("Xmind connected.")).not.toBeInTheDocument();
|
||||
expect(screen.queryByText(/some servers did not connect: notion/i)).not.toBeInTheDocument();
|
||||
@@ -182,22 +182,21 @@ describe("SettingsView Apps catalog", () => {
|
||||
expect(failed.closest("button")).toBeNull();
|
||||
expect(failed.closest("p")?.querySelector(".lucide-triangle-alert")).not.toBeNull();
|
||||
expect(row?.querySelector(".lucide-check")).toBeNull();
|
||||
expect(within(row as HTMLElement).getByRole("button", { name: "Reconnect Xmind" })).toHaveTextContent(
|
||||
"Reconnect",
|
||||
expect(within(row as HTMLElement).getByRole("button", { name: "Manage Xmind" })).toHaveTextContent(
|
||||
"Fix connection",
|
||||
);
|
||||
const actions = within(row as HTMLElement).getByRole("button", { name: "Actions for Xmind" });
|
||||
expect(actions).toHaveAttribute("aria-haspopup", "menu");
|
||||
fireEvent.pointerDown(actions, { button: 0, ctrlKey: false });
|
||||
expect(await screen.findByRole("menuitem", { name: "Test" })).toBeInTheDocument();
|
||||
expect(screen.getByRole("menuitem", { name: "Remove" })).toBeInTheDocument();
|
||||
fireEvent.keyDown(document, { key: "Escape" });
|
||||
|
||||
await act(() => i18n.changeLanguage("zh-CN"));
|
||||
expect(within(row as HTMLElement).getByText("连接失败。")).toBeInTheDocument();
|
||||
expect(within(row as HTMLElement).getByRole("button", { name: "Xmind 操作" }))
|
||||
.toBeInTheDocument();
|
||||
const reconnect = screen.getByRole("button", { name: "重新连接 Xmind" });
|
||||
expect(reconnect).toHaveTextContent("重新连接");
|
||||
const manage = within(row as HTMLElement).getByRole("button", { name: "管理 Xmind" });
|
||||
expect(manage).toHaveTextContent("修复连接");
|
||||
fireEvent.click(manage);
|
||||
const dialog = screen.getByRole("dialog", { name: "Xmind" });
|
||||
expect(within(dialog).getByRole("tab", { name: "连接" })).toHaveAttribute("aria-selected", "true");
|
||||
expect(within(dialog).getByText("创建、读取和编辑 Xmind 云端思维导图。")).toHaveClass("sr-only");
|
||||
expect(within(dialog).getByText("连接失败", { exact: true })).toBeInTheDocument();
|
||||
expect(within(dialog).getByRole("button", { name: "移除连接" })).toBeInTheDocument();
|
||||
const reconnect = within(dialog).getByRole("button", { name: "重新连接" });
|
||||
fireEvent.click(reconnect);
|
||||
|
||||
await waitFor(() => expect(requestMutationMock).toHaveBeenCalledWith(
|
||||
@@ -246,9 +245,9 @@ describe("SettingsView Apps catalog", () => {
|
||||
.toHaveTextContent("Connecting…");
|
||||
expect(await screen.findByRole(
|
||||
"button",
|
||||
{ name: "Xmind: Connected." },
|
||||
{ name: "Manage Xmind" },
|
||||
{ timeout: 2_500 },
|
||||
)).toHaveTextContent("Connected.");
|
||||
)).toHaveTextContent("Manage");
|
||||
expect(mcpPresetRequests).toBe(2);
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: "Ready" }));
|
||||
@@ -299,15 +298,17 @@ describe("SettingsView Apps catalog", () => {
|
||||
fireEvent.click(await screen.findByRole("button", { name: "MCP" }));
|
||||
expect(await screen.findByText("Connection failed.")).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: "Reconnect team-docs" }));
|
||||
fireEvent.click(screen.getByRole("button", { name: "Manage team-docs" }));
|
||||
fireEvent.click(within(screen.getByRole("dialog", { name: "team-docs" }))
|
||||
.getByRole("button", { name: "Reconnect" }));
|
||||
|
||||
await waitFor(() => expect(requestMutationMock).toHaveBeenCalledWith(
|
||||
"settings.mcp.reconnect",
|
||||
{ name: "team-docs" },
|
||||
20_000,
|
||||
));
|
||||
const connected = await screen.findByRole("button", { name: "team-docs: Connected." });
|
||||
expect(connected).toHaveTextContent("Connected.");
|
||||
const connected = await screen.findByRole("button", { name: "Manage team-docs" });
|
||||
expect(connected).toHaveTextContent("Manage");
|
||||
expect(connected.querySelector(".lucide-check")).not.toBeNull();
|
||||
fireEvent.click(screen.getByRole("button", { name: "Ready" }));
|
||||
const readyHeading = await screen.findByRole("heading", { name: "team-docs" });
|
||||
@@ -500,8 +501,8 @@ describe("SettingsView Apps catalog", () => {
|
||||
{ flow_id: "flow-manual", callback_url: callbackUrl },
|
||||
20_000,
|
||||
));
|
||||
expect(await screen.findByRole("button", { name: "Xmind: Configured" }, { timeout: 2500 }))
|
||||
.toHaveTextContent("Configured");
|
||||
expect(await screen.findByRole("button", { name: "Manage Xmind" }, { timeout: 2500 }))
|
||||
.toHaveTextContent("Manage");
|
||||
expect(screen.queryByRole("textbox", { name: "Full callback URL" })).not.toBeInTheDocument();
|
||||
expect(popup.close).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
@@ -610,7 +611,10 @@ describe("SettingsView Apps catalog", () => {
|
||||
|
||||
renderSettingsView({ initialSection: "apps" });
|
||||
fireEvent.click(await screen.findByRole("button", { name: "MCP" }));
|
||||
fireEvent.click(await screen.findByRole("button", { name: "Remove" }));
|
||||
fireEvent.click(await screen.findByRole("button", { name: "Manage Xmind" }));
|
||||
const dialog = screen.getByRole("dialog", { name: "Xmind" });
|
||||
fireEvent.click(within(dialog).getByRole("tab", { name: "Connection" }));
|
||||
fireEvent.click(within(dialog).getByRole("button", { name: "Remove connection" }));
|
||||
|
||||
await waitFor(() => expect(requestMutationMock).toHaveBeenCalledWith(
|
||||
"settings.mcp.remove",
|
||||
|
||||
Reference in New Issue
Block a user