import { EnvironmentId, ProjectId, ProviderInstanceId } from "@t3tools/contracts"; import { describe, expect, it } from "vite-plus/test"; import { deriveLogicalProjectKey, deriveLogicalProjectKeyFromSettings, derivePhysicalProjectKey, resolveProjectGroupingMode, } from "./logicalProject"; import type { Project } from "./types"; const primaryEnvironmentId = EnvironmentId.make("env-primary"); const remoteEnvironmentId = EnvironmentId.make("env-remote"); const repositoryIdentity = { canonicalKey: "github.com/example/shared-repo", locator: { source: "git-remote" as const, remoteName: "origin", remoteUrl: "https://github.com/example/shared-repo.git", }, }; const defaultGroupingSettings = { sidebarProjectGroupingMode: "repository" as const, sidebarProjectGroupingOverrides: {}, }; function makeProject(overrides: Partial = {}): Project { return { id: ProjectId.make("project-1"), environmentId: primaryEnvironmentId, title: "shared-repo", workspaceRoot: "/tmp/shared-repo", repositoryIdentity: null, defaultModelSelection: { instanceId: ProviderInstanceId.make("codex"), model: "gpt-5-codex", }, createdAt: "2026-01-01T00:00:00.000Z", updatedAt: "2026-01-01T00:00:00.000Z", scripts: [], ...overrides, }; } describe("environment grouping", () => { it("groups matching repository identities across environments", () => { const primary = makeProject({ repositoryIdentity }); const remote = makeProject({ id: ProjectId.make("project-remote"), environmentId: remoteEnvironmentId, repositoryIdentity, }); expect(deriveLogicalProjectKey(primary)).toBe(repositoryIdentity.canonicalKey); expect(deriveLogicalProjectKey(remote)).toBe(repositoryIdentity.canonicalKey); }); it("keeps projects without repository identity physically scoped", () => { const primary = makeProject(); const remote = makeProject({ id: ProjectId.make("project-remote"), environmentId: remoteEnvironmentId, }); expect(deriveLogicalProjectKey(primary)).toBe(derivePhysicalProjectKey(primary)); expect(deriveLogicalProjectKey(remote)).toBe(derivePhysicalProjectKey(remote)); expect(deriveLogicalProjectKey(primary)).not.toBe(deriveLogicalProjectKey(remote)); }); it("uses the physical key when repository grouping is disabled", () => { const project = makeProject({ repositoryIdentity }); expect( deriveLogicalProjectKeyFromSettings(project, { sidebarProjectGroupingMode: "separate", sidebarProjectGroupingOverrides: {}, }), ).toBe(derivePhysicalProjectKey(project)); }); it("allows a per-project override to separate an otherwise grouped repository", () => { const project = makeProject({ repositoryIdentity }); const physicalKey = derivePhysicalProjectKey(project); expect( deriveLogicalProjectKeyFromSettings(project, { ...defaultGroupingSettings, sidebarProjectGroupingOverrides: { [physicalKey]: "separate", }, }), ).toBe(physicalKey); }); it("allows a per-project override to group a repository while the global mode is separate", () => { const project = makeProject({ repositoryIdentity }); expect( deriveLogicalProjectKeyFromSettings(project, { sidebarProjectGroupingMode: "separate", sidebarProjectGroupingOverrides: { [derivePhysicalProjectKey(project)]: "repository", }, }), ).toBe(repositoryIdentity.canonicalKey); }); it("reports the effective grouping mode after applying an override", () => { const project = makeProject({ repositoryIdentity }); const physicalKey = derivePhysicalProjectKey(project); expect(resolveProjectGroupingMode(project, defaultGroupingSettings)).toBe("repository"); expect( resolveProjectGroupingMode(project, { ...defaultGroupingSettings, sidebarProjectGroupingOverrides: { [physicalKey]: "separate", }, }), ).toBe("separate"); }); });