Files
kandev/apps/web/src/app-shell.test.tsx
T

73 lines
3.1 KiB
TypeScript

import { cleanup, render, screen } from "@testing-library/react";
import { afterEach, describe, expect, it, vi } from "vitest";
import { TaskChangeRequestLinkForm } from "@/components/integrations/task-change-request-link-form";
import { pluginModalManager } from "@/lib/plugins/modal-manager";
import { AppShell } from "./app-shell";
const mocks = vi.hoisted(() => ({
passthrough: ({ children }: { children: React.ReactNode }) => children,
}));
vi.mock("@/components/app-sidebar/app-sidebar", () => ({ AppSidebar: () => null }));
vi.mock("@/components/app-status-bar/app-status-surface-provider", () => ({
AppStatusSurfaceProvider: mocks.passthrough,
}));
vi.mock("@/components/command-panel", () => ({ CommandPanel: () => null }));
vi.mock("@/components/config-chat/config-chat-provider", () => ({
ConfigChatProvider: mocks.passthrough,
}));
vi.mock("@/components/diff-worker-pool-provider", () => ({
DiffWorkerPoolProvider: mocks.passthrough,
}));
vi.mock("@/components/desktop-command-host", () => ({ DesktopCommandHost: () => null }));
vi.mock("@/components/global-commands", () => ({ GlobalCommands: () => null }));
vi.mock("@/components/log-buffer-bridge", () => ({ LogBufferBridge: () => null }));
vi.mock("@/components/quick-chat/quick-chat-provider", () => ({
QuickChatProvider: mocks.passthrough,
}));
vi.mock("@/components/task/recent-task-switcher", () => ({ RecentTaskSwitcher: () => null }));
vi.mock("@/components/session-failure-toast-bridge", () => ({
SessionFailureToastBridge: () => null,
}));
vi.mock("@/components/task-deleted-toast-bridge", () => ({ TaskDeletedToastBridge: () => null }));
vi.mock("@/components/update-available-toast-bridge", () => ({
UpdateAvailableToastBridge: () => null,
}));
vi.mock("@/components/sidebar-views-sync-bridge", () => ({ SidebarViewsSyncBridge: () => null }));
vi.mock("@/components/theme-provider", () => ({ ThemeProvider: mocks.passthrough }));
vi.mock("@/components/ws-connector", () => ({ WebSocketConnector: () => null }));
vi.mock("@/lib/commands/command-registry", () => ({
CommandRegistryProvider: mocks.passthrough,
}));
vi.mock("@kandev/ui/sonner", () => ({ Toaster: () => null }));
vi.mock("@kandev/ui/tooltip", () => ({ TooltipProvider: mocks.passthrough }));
describe("AppShell plugin modal topology", () => {
afterEach(() => {
cleanup();
pluginModalManager.closeAllForPlugin("bitbucket");
});
it("renders host task-link forms inside the shared toast provider", () => {
pluginModalManager.openTaskLinkDialog("bitbucket", {
title: "Link Bitbucket pull request",
content: () => (
<TaskChangeRequestLinkForm
inputLabel="Pull request"
emptyError="Enter a Bitbucket pull request URL or key."
failureMessage="Failed to link Bitbucket pull request."
successMessage="Bitbucket pull request linked"
onSubmit={vi.fn().mockResolvedValue(undefined)}
onCancel={() => undefined}
onSuccess={() => undefined}
/>
),
});
render(<AppShell>App content</AppShell>);
expect(screen.getByLabelText("Pull request")).not.toBeNull();
expect(screen.getByRole("button", { name: "Save" })).not.toBeNull();
});
});