import type { EnvironmentId, T3ProjectFileScript, ThreadId } from "@t3tools/contracts";import { renderToStaticMarkup } from "react-dom/server";import { beforeEach, describe, expect, it, vi } from "vite-plus/test"; const testState = vi.hoisted(() => ({ useT3ProjectFileScripts: vi.fn(), projectScriptsControl: vi.fn(),})); vi.mock("../../hooks/useT3ProjectFileScripts", () => ({ useT3ProjectFileScripts: (...args: ReadonlyArray<unknown>) => testState.useT3ProjectFileScripts(...args),}));vi.mock("../BranchToolbar", () => ({ BranchToolbar: () => null,}));vi.mock("../ProjectScriptsControl", () => ({ default: (props: unknown) => { testState.projectScriptsControl(props); return null; },}));vi.mock("./ThreadAutomationsPanel", () => ({ ThreadAutomationsPanel: () => null,}));vi.mock("./ThreadRelationshipsControl", () => ({ ThreadRelationshipsPanel: () => null,})); import { ThreadDetailsPanel, type ThreadDetailsPanelProps } from "./ThreadDetailsPanel"; describe("ThreadDetailsPanel", () => { beforeEach(() => { testState.useT3ProjectFileScripts.mockReset(); testState.projectScriptsControl.mockReset(); }); it("passes checked-in t3.json scripts to the project scripts control", () => { const environmentId = "environment:thread-details" as EnvironmentId; const gitCwd = "/tmp/thread-details-project"; const fileScripts = [ { name: "Check project", command: "vp check", icon: "test", }, ] satisfies ReadonlyArray<T3ProjectFileScript>; testState.useT3ProjectFileScripts.mockReturnValue(fileScripts); const props: ThreadDetailsPanelProps = { mode: "popover", environmentId, environmentConnection: null, threadId: "thread:thread-details" as ThreadId, activeProjectName: undefined, activeProjectScripts: [], preferredScriptId: null, keybindings: [], availableEditors: [], showOpenInPicker: false, gitCwd, isGitRepo: false, envLocked: false, availableEnvironments: [], onEnvironmentChange: vi.fn(), onEnvModeChange: vi.fn(), startFromOrigin: false, onStartFromOriginChange: vi.fn(), onComposerFocusRequest: vi.fn(), onReconnectEnvironment: vi.fn(), onOpenConnectionSettings: vi.fn(), versionMismatch: null, onDismissVersionMismatch: vi.fn(), onRunProjectScript: vi.fn(), onAddProjectScript: vi.fn() as ThreadDetailsPanelProps["onAddProjectScript"], onUpdateProjectScript: vi.fn() as ThreadDetailsPanelProps["onUpdateProjectScript"], onDeleteProjectScript: vi.fn() as ThreadDetailsPanelProps["onDeleteProjectScript"], }; renderToStaticMarkup(<ThreadDetailsPanel {...props} />); expect(testState.useT3ProjectFileScripts).toHaveBeenCalledWith(environmentId, gitCwd); expect(testState.projectScriptsControl).toHaveBeenCalledWith( expect.objectContaining({ displayMode: "panel", scripts: [], fileScripts, }), ); });});
import type { EnvironmentId, T3ProjectFileScript, ThreadId } from "@t3tools/contracts";
import { renderToStaticMarkup } from "react-dom/server";
import { beforeEach, describe, expect, it, vi } from "vite-plus/test";
const testState = vi.hoisted(() => ({
useT3ProjectFileScripts: vi.fn(),
projectScriptsControl: vi.fn(),
}));
vi.mock("../../hooks/useT3ProjectFileScripts", () => ({
useT3ProjectFileScripts: (...args: ReadonlyArray<unknown>) =>
testState.useT3ProjectFileScripts(...args),
}));
vi.mock("../BranchToolbar", () => ({
BranchToolbar: () => null,
}));
vi.mock("../ProjectScriptsControl", () => ({
default: (props: unknown) => {
testState.projectScriptsControl(props);
return null;
},
}));
vi.mock("./ThreadAutomationsPanel", () => ({
ThreadAutomationsPanel: () => null,
}));
vi.mock("./ThreadRelationshipsControl", () => ({
ThreadRelationshipsPanel: () => null,
}));
import { ThreadDetailsPanel, type ThreadDetailsPanelProps } from "./ThreadDetailsPanel";
describe("ThreadDetailsPanel", () => {
beforeEach(() => {
testState.useT3ProjectFileScripts.mockReset();
testState.projectScriptsControl.mockReset();
});
it("passes checked-in t3.json scripts to the project scripts control", () => {
const environmentId = "environment:thread-details" as EnvironmentId;
const gitCwd = "/tmp/thread-details-project";
const fileScripts = [
{
name: "Check project",
command: "vp check",
icon: "test",
},
] satisfies ReadonlyArray<T3ProjectFileScript>;
testState.useT3ProjectFileScripts.mockReturnValue(fileScripts);
const props: ThreadDetailsPanelProps = {
mode: "popover",
environmentId,
environmentConnection: null,
threadId: "thread:thread-details" as ThreadId,
activeProjectName: undefined,
activeProjectScripts: [],
preferredScriptId: null,
keybindings: [],
availableEditors: [],
showOpenInPicker: false,
gitCwd,
isGitRepo: false,
envLocked: false,
availableEnvironments: [],
onEnvironmentChange: vi.fn(),
onEnvModeChange: vi.fn(),
startFromOrigin: false,
onStartFromOriginChange: vi.fn(),
onComposerFocusRequest: vi.fn(),
onReconnectEnvironment: vi.fn(),
onOpenConnectionSettings: vi.fn(),
versionMismatch: null,
onDismissVersionMismatch: vi.fn(),
onRunProjectScript: vi.fn(),
onAddProjectScript: vi.fn() as ThreadDetailsPanelProps["onAddProjectScript"],
onUpdateProjectScript: vi.fn() as ThreadDetailsPanelProps["onUpdateProjectScript"],
onDeleteProjectScript: vi.fn() as ThreadDetailsPanelProps["onDeleteProjectScript"],
};
renderToStaticMarkup(<ThreadDetailsPanel {...props} />);
expect(testState.useT3ProjectFileScripts).toHaveBeenCalledWith(environmentId, gitCwd);
expect(testState.projectScriptsControl).toHaveBeenCalledWith(
expect.objectContaining({
displayMode: "panel",
scripts: [],
fileScripts,
}),
);
});
});