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> = {}): 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"); });});
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> = {}): 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");
});
});