import { EnvironmentId, ProjectId } from "@t3tools/contracts";
import { scopeProjectRef } from "@t3tools/client-runtime/environment";
import { describe, expect, it, vi } from "vite-plus/test";
import { act, render } from "../../test/render";
const project = vi.hoisted(() => {
let value: unknown = null;
const listeners = new Set<() => void>();
return {
// Each test starts from no project and no listeners left by an earlier test.
setup: (initial: unknown) => {
value = initial;
listeners.clear();
},
get: () => value,
set: (next: unknown) => {
value = next;
for (const listener of listeners) listener();
},
subscribe: (listener: () => void) => {
listeners.add(listener);
return () => listeners.delete(listener);
},
};
});
vi.mock(import("../state/entities"), async (original) => {
const { useSyncExternalStore } = await import("react");
return {
...(await original()),
readProject: (() => project.get()) as never,
subscribeProject: ((_ref: unknown, listener: (value: unknown) => void) =>
project.subscribe(() => listener(project.get()))) as never,
useProject: (() => useSyncExternalStore(project.subscribe, project.get)) as never,
};
});
vi.mock(import("../state/environments"), async (original) => ({
...(await original()),
useEnvironments: (() => ({ environments: [] })) as never,
}));
vi.mock(import("../hooks/useHandleNewThread"), async (original) => ({
...(await original()),
useNewThreadHandler: (() => () => undefined) as never,
}));
vi.mock(import("../hooks/useAddProjectTargets"), async (original) => ({
...(await original()),
useAddProjectTargets: (() => []) as never,
}));
vi.mock(import("../hooks/useLogicalProjectEnvironments"), async (original) => ({
...(await original()),
useLogicalProjectEnvironments: (() => []) as never,
}));
import {
AddProjectToMachineDialogHost,
openAddProjectToMachine,
} from "./AddProjectToMachineDialog";
const environmentId = EnvironmentId.make("environment-1");
const projectRef = scopeProjectRef(environmentId, ProjectId.make("project-1"));
const PROJECT = {
environmentId,
id: projectRef.projectId,
title: "Repo",
workspaceRoot: "/repo",
repositoryIdentity: null,
};
describe("AddProjectToMachineDialog", () => {
it("closes when its project goes away", async () => {
project.setup(PROJECT);
await using screen = await render();
await act(() => openAddProjectToMachine({ projectRef, targetEnvironmentId: null }));
await expect.element(screen.getByText("Add to another machine")).toBeInTheDocument();
await act(() => project.set(null));
await act(() => project.set(PROJECT));
await expect.element(screen.getByText("Add to another machine")).not.toBeInTheDocument();
});
it("does not reopen for a project that vanished before the dialog showed", async () => {
project.setup(PROJECT);
await using screen = await render();
await act(() => {
openAddProjectToMachine({ projectRef, targetEnvironmentId: null });
project.set(null);
});
await act(() => project.set(PROJECT));
await expect.element(screen.getByText("Add to another machine")).not.toBeInTheDocument();
});
});