import { DEFAULT_SERVER_SETTINGS, DEFAULT_UNIFIED_SETTINGS, ProviderDriverKind, ProviderInstanceId, type ProviderInstanceConfig,} from "@t3tools/contracts";import { getBackgroundActivityPresetSettings } from "@t3tools/shared/backgroundActivitySettings";import * as Duration from "effect/Duration";import { describe, expect, it } from "vite-plus/test";import { backgroundActivitySharedPolicySettings, buildProviderInstanceUpdatePatch, formatDiagnosticsDescription, getChangedBrowserSettingLabels, getChangedTypographySettingLabels, isSamePreviewViewport, hasChangedBackgroundActivitySettings, isProjectGroupingEnabled, projectGroupingModeFromToggle, resolveBackgroundActivityProfileOption,} from "./SettingsPanels.logic"; describe("typography settings restore", () => { it("detects family and size changes by font row", () => { expect(getChangedTypographySettingLabels(DEFAULT_UNIFIED_SETTINGS)).toEqual([]); expect( getChangedTypographySettingLabels({ ...DEFAULT_UNIFIED_SETTINGS, fontSizeInterface: 18, fontFamilyCode: "Fira Code", }), ).toEqual(["Interface font", "Code font"]); });}); describe("background activity settings restore", () => { it("detects legacy interval values even when the structured setting is at its default", () => { expect( hasChangedBackgroundActivitySettings({ backgroundActivity: DEFAULT_UNIFIED_SETTINGS.backgroundActivity, backgroundActivityProfile: DEFAULT_UNIFIED_SETTINGS.backgroundActivityProfile, automaticGitFetchInterval: Duration.seconds(45), providerHealthRefreshInterval: DEFAULT_UNIFIED_SETTINGS.providerHealthRefreshInterval, }), ).toBe(true); expect( hasChangedBackgroundActivitySettings({ backgroundActivity: DEFAULT_UNIFIED_SETTINGS.backgroundActivity, backgroundActivityProfile: DEFAULT_UNIFIED_SETTINGS.backgroundActivityProfile, automaticGitFetchInterval: DEFAULT_UNIFIED_SETTINGS.automaticGitFetchInterval, providerHealthRefreshInterval: Duration.minutes(7), }), ).toBe(true); expect(hasChangedBackgroundActivitySettings(DEFAULT_UNIFIED_SETTINGS)).toBe(false); }); it("detects a legacy profile override so restoring defaults clears it", () => { expect( hasChangedBackgroundActivitySettings({ ...DEFAULT_UNIFIED_SETTINGS, backgroundActivityProfile: "performance", }), ).toBe(true); }); it("shows the effective legacy preset and marks custom legacy intervals as advanced", () => { const performance = getBackgroundActivityPresetSettings("performance"); expect( resolveBackgroundActivityProfileOption({ ...DEFAULT_UNIFIED_SETTINGS, backgroundActivity: DEFAULT_UNIFIED_SETTINGS.backgroundActivity, backgroundActivityProfile: "performance", automaticGitFetchInterval: performance.automaticGitFetchInterval, providerHealthRefreshInterval: performance.providerHealthRefreshInterval, }), ).toBe("performance"); expect( resolveBackgroundActivityProfileOption({ ...DEFAULT_UNIFIED_SETTINGS, backgroundActivity: DEFAULT_UNIFIED_SETTINGS.backgroundActivity, backgroundActivityProfile: "performance", automaticGitFetchInterval: Duration.seconds(45), providerHealthRefreshInterval: Duration.minutes(7), }), ).toBe("advanced"); }); it("preserves advanced overrides when the shared policy changes", () => { const automaticGitFetchInterval = Duration.seconds(42); expect( backgroundActivitySharedPolicySettings( { ...DEFAULT_UNIFIED_SETTINGS, backgroundActivity: { schemaVersion: 1, profile: "custom", baseProfile: "balanced", overrides: { automaticGitFetchInterval, pauseWhenOnBattery: true, }, }, }, "performance", ), ).toEqual({ schemaVersion: 1, profile: "custom", baseProfile: "performance", overrides: { automaticGitFetchInterval, pauseWhenOnBattery: true, }, }); }); it("materializes legacy advanced overrides before changing the shared policy", () => { const automaticGitFetchInterval = Duration.seconds(42); expect( backgroundActivitySharedPolicySettings( { ...DEFAULT_UNIFIED_SETTINGS, automaticGitFetchInterval, }, "battery-saver", ), ).toEqual({ schemaVersion: 1, profile: "custom", baseProfile: "battery-saver", overrides: { automaticGitFetchInterval, }, }); });}); describe("project grouping toggle", () => { it("enables repository grouping and disables into separate projects", () => { expect(isProjectGroupingEnabled("repository")).toBe(true); expect(isProjectGroupingEnabled("repository_path")).toBe(true); expect(isProjectGroupingEnabled("separate")).toBe(false); expect(projectGroupingModeFromToggle(true)).toBe("repository"); expect(projectGroupingModeFromToggle(false)).toBe("separate"); }); it("restores repository path grouping when the toggle is cycled", () => { expect(projectGroupingModeFromToggle(false, "repository_path")).toBe("separate"); expect(projectGroupingModeFromToggle(true, "repository_path")).toBe("repository_path"); });}); describe("formatDiagnosticsDescription", () => { it("collapses trace and metric URLs that share the same OTEL base path", () => { expect( formatDiagnosticsDescription({ localTracingEnabled: true, otlpTracesEnabled: true, otlpTracesUrl: "http://localhost:4318/v1/traces", otlpMetricsEnabled: true, otlpMetricsUrl: "http://localhost:4318/v1/metrics", }), ).toBe("Local trace file. Exporting OTEL to http://localhost:4318/v1/{traces,metrics}."); }); it("keeps separate trace and metric URLs when their base paths differ", () => { expect( formatDiagnosticsDescription({ localTracingEnabled: true, otlpTracesEnabled: true, otlpTracesUrl: "http://localhost:4318/v1/traces", otlpMetricsEnabled: true, otlpMetricsUrl: "http://localhost:9000/v1/metrics", }), ).toBe( "Local trace file. Exporting OTEL traces to http://localhost:4318/v1/traces and metrics to http://localhost:9000/v1/metrics.", ); }); it("omits OTEL text when no exporter is enabled", () => { expect( formatDiagnosticsDescription({ localTracingEnabled: true, otlpTracesEnabled: false, otlpMetricsEnabled: false, }), ).toBe("Local trace file."); });}); describe("buildProviderInstanceUpdatePatch", () => { it("promotes an edited default provider into providerInstances and resets the legacy provider", () => { const instanceId = ProviderInstanceId.make("codex"); const nextInstance = { driver: ProviderDriverKind.make("codex"), enabled: true, config: { binaryPath: "/opt/t3/codex", }, } satisfies ProviderInstanceConfig; const patch = buildProviderInstanceUpdatePatch({ settings: { ...DEFAULT_SERVER_SETTINGS, providers: { ...DEFAULT_SERVER_SETTINGS.providers, codex: { ...DEFAULT_SERVER_SETTINGS.providers.codex, binaryPath: "/legacy/codex", }, }, }, instanceId, instance: nextInstance, driver: ProviderDriverKind.make("codex"), isDefault: true, }); expect(patch.providerInstances?.[instanceId]).toEqual(nextInstance); expect(patch.providers?.codex).toEqual(DEFAULT_SERVER_SETTINGS.providers.codex); }); it("updates custom instances without touching legacy provider settings", () => { const instanceId = ProviderInstanceId.make("codex_personal"); const nextInstance = { driver: ProviderDriverKind.make("codex"), enabled: true, config: { homePath: "/Users/example/.codex-personal", }, } satisfies ProviderInstanceConfig; const patch = buildProviderInstanceUpdatePatch({ settings: DEFAULT_SERVER_SETTINGS, instanceId, instance: nextInstance, driver: ProviderDriverKind.make("codex"), isDefault: false, }); expect(patch.providerInstances?.[instanceId]).toEqual(nextInstance); expect(patch.providers).toBeUndefined(); });}); describe("getChangedBrowserSettingLabels", () => { it("reports nothing for the defaults", () => { expect(getChangedBrowserSettingLabels(DEFAULT_UNIFIED_SETTINGS)).toEqual([]); }); it("treats a structurally equal viewport as unchanged", () => { // The viewport is a tagged union, so identity comparison would report a // freshly decoded copy of the default as dirty and offer to "restore" it. expect( getChangedBrowserSettingLabels({ ...DEFAULT_UNIFIED_SETTINGS, browserDefaultViewport: { ...DEFAULT_UNIFIED_SETTINGS.browserDefaultViewport }, }), ).toEqual([]); }); it("labels each browser default that differs", () => { expect( getChangedBrowserSettingLabels({ ...DEFAULT_UNIFIED_SETTINGS, browserDefaultViewport: { _tag: "freeform", width: 900, height: 600 }, browserDefaultZoomFactor: 1.5, browserDefaultAppearance: "dark", browserRecordingFrameRate: 60, browserAutoShowFloatingPreview: !DEFAULT_UNIFIED_SETTINGS.browserAutoShowFloatingPreview, }), ).toEqual([ "Browser viewport", "Browser zoom", "Browser appearance", "Recording frame rate", "Floating preview", ]); });}); describe("isSamePreviewViewport", () => { it("separates presets that share a size", () => { // Two presets can agree on width and height and still be different // entries in the picker, so the id has to take part in the comparison. expect( isSamePreviewViewport( { _tag: "preset", width: 390, height: 844, presetId: "iphone-12-pro" }, { _tag: "preset", width: 390, height: 844, presetId: "ipad-mini" }, ), ).toBe(false); }); it("separates a freeform viewport from a preset of the same size", () => { expect( isSamePreviewViewport( { _tag: "freeform", width: 390, height: 844 }, { _tag: "preset", width: 390, height: 844, presetId: "iphone-12-pro" }, ), ).toBe(false); });});
import {
DEFAULT_SERVER_SETTINGS,
DEFAULT_UNIFIED_SETTINGS,
ProviderDriverKind,
ProviderInstanceId,
type ProviderInstanceConfig,
} from "@t3tools/contracts";
import { getBackgroundActivityPresetSettings } from "@t3tools/shared/backgroundActivitySettings";
import * as Duration from "effect/Duration";
import { describe, expect, it } from "vite-plus/test";
import {
backgroundActivitySharedPolicySettings,
buildProviderInstanceUpdatePatch,
formatDiagnosticsDescription,
getChangedBrowserSettingLabels,
getChangedTypographySettingLabels,
isSamePreviewViewport,
hasChangedBackgroundActivitySettings,
isProjectGroupingEnabled,
projectGroupingModeFromToggle,
resolveBackgroundActivityProfileOption,
} from "./SettingsPanels.logic";
describe("typography settings restore", () => {
it("detects family and size changes by font row", () => {
expect(getChangedTypographySettingLabels(DEFAULT_UNIFIED_SETTINGS)).toEqual([]);
expect(
getChangedTypographySettingLabels({
...DEFAULT_UNIFIED_SETTINGS,
fontSizeInterface: 18,
fontFamilyCode: "Fira Code",
}),
).toEqual(["Interface font", "Code font"]);
});
});
describe("background activity settings restore", () => {
it("detects legacy interval values even when the structured setting is at its default", () => {
expect(
hasChangedBackgroundActivitySettings({
backgroundActivity: DEFAULT_UNIFIED_SETTINGS.backgroundActivity,
backgroundActivityProfile: DEFAULT_UNIFIED_SETTINGS.backgroundActivityProfile,
automaticGitFetchInterval: Duration.seconds(45),
providerHealthRefreshInterval: DEFAULT_UNIFIED_SETTINGS.providerHealthRefreshInterval,
}),
).toBe(true);
expect(
hasChangedBackgroundActivitySettings({
backgroundActivity: DEFAULT_UNIFIED_SETTINGS.backgroundActivity,
backgroundActivityProfile: DEFAULT_UNIFIED_SETTINGS.backgroundActivityProfile,
automaticGitFetchInterval: DEFAULT_UNIFIED_SETTINGS.automaticGitFetchInterval,
providerHealthRefreshInterval: Duration.minutes(7),
}),
).toBe(true);
expect(hasChangedBackgroundActivitySettings(DEFAULT_UNIFIED_SETTINGS)).toBe(false);
});
it("detects a legacy profile override so restoring defaults clears it", () => {
expect(
hasChangedBackgroundActivitySettings({
...DEFAULT_UNIFIED_SETTINGS,
backgroundActivityProfile: "performance",
}),
).toBe(true);
});
it("shows the effective legacy preset and marks custom legacy intervals as advanced", () => {
const performance = getBackgroundActivityPresetSettings("performance");
expect(
resolveBackgroundActivityProfileOption({
...DEFAULT_UNIFIED_SETTINGS,
backgroundActivity: DEFAULT_UNIFIED_SETTINGS.backgroundActivity,
backgroundActivityProfile: "performance",
automaticGitFetchInterval: performance.automaticGitFetchInterval,
providerHealthRefreshInterval: performance.providerHealthRefreshInterval,
}),
).toBe("performance");
expect(
resolveBackgroundActivityProfileOption({
...DEFAULT_UNIFIED_SETTINGS,
backgroundActivity: DEFAULT_UNIFIED_SETTINGS.backgroundActivity,
backgroundActivityProfile: "performance",
automaticGitFetchInterval: Duration.seconds(45),
providerHealthRefreshInterval: Duration.minutes(7),
}),
).toBe("advanced");
});
it("preserves advanced overrides when the shared policy changes", () => {
const automaticGitFetchInterval = Duration.seconds(42);
expect(
backgroundActivitySharedPolicySettings(
{
...DEFAULT_UNIFIED_SETTINGS,
backgroundActivity: {
schemaVersion: 1,
profile: "custom",
baseProfile: "balanced",
overrides: {
automaticGitFetchInterval,
pauseWhenOnBattery: true,
},
},
},
"performance",
),
).toEqual({
schemaVersion: 1,
profile: "custom",
baseProfile: "performance",
overrides: {
automaticGitFetchInterval,
pauseWhenOnBattery: true,
},
});
});
it("materializes legacy advanced overrides before changing the shared policy", () => {
const automaticGitFetchInterval = Duration.seconds(42);
expect(
backgroundActivitySharedPolicySettings(
{
...DEFAULT_UNIFIED_SETTINGS,
automaticGitFetchInterval,
},
"battery-saver",
),
).toEqual({
schemaVersion: 1,
profile: "custom",
baseProfile: "battery-saver",
overrides: {
automaticGitFetchInterval,
},
});
});
});
describe("project grouping toggle", () => {
it("enables repository grouping and disables into separate projects", () => {
expect(isProjectGroupingEnabled("repository")).toBe(true);
expect(isProjectGroupingEnabled("repository_path")).toBe(true);
expect(isProjectGroupingEnabled("separate")).toBe(false);
expect(projectGroupingModeFromToggle(true)).toBe("repository");
expect(projectGroupingModeFromToggle(false)).toBe("separate");
});
it("restores repository path grouping when the toggle is cycled", () => {
expect(projectGroupingModeFromToggle(false, "repository_path")).toBe("separate");
expect(projectGroupingModeFromToggle(true, "repository_path")).toBe("repository_path");
});
});
describe("formatDiagnosticsDescription", () => {
it("collapses trace and metric URLs that share the same OTEL base path", () => {
expect(
formatDiagnosticsDescription({
localTracingEnabled: true,
otlpTracesEnabled: true,
otlpTracesUrl: "http://localhost:4318/v1/traces",
otlpMetricsEnabled: true,
otlpMetricsUrl: "http://localhost:4318/v1/metrics",
}),
).toBe("Local trace file. Exporting OTEL to http://localhost:4318/v1/{traces,metrics}.");
});
it("keeps separate trace and metric URLs when their base paths differ", () => {
expect(
formatDiagnosticsDescription({
localTracingEnabled: true,
otlpTracesEnabled: true,
otlpTracesUrl: "http://localhost:4318/v1/traces",
otlpMetricsEnabled: true,
otlpMetricsUrl: "http://localhost:9000/v1/metrics",
}),
).toBe(
"Local trace file. Exporting OTEL traces to http://localhost:4318/v1/traces and metrics to http://localhost:9000/v1/metrics.",
);
});
it("omits OTEL text when no exporter is enabled", () => {
expect(
formatDiagnosticsDescription({
localTracingEnabled: true,
otlpTracesEnabled: false,
otlpMetricsEnabled: false,
}),
).toBe("Local trace file.");
});
});
describe("buildProviderInstanceUpdatePatch", () => {
it("promotes an edited default provider into providerInstances and resets the legacy provider", () => {
const instanceId = ProviderInstanceId.make("codex");
const nextInstance = {
driver: ProviderDriverKind.make("codex"),
enabled: true,
config: {
binaryPath: "/opt/t3/codex",
},
} satisfies ProviderInstanceConfig;
const patch = buildProviderInstanceUpdatePatch({
settings: {
...DEFAULT_SERVER_SETTINGS,
providers: {
...DEFAULT_SERVER_SETTINGS.providers,
codex: {
...DEFAULT_SERVER_SETTINGS.providers.codex,
binaryPath: "/legacy/codex",
},
},
},
instanceId,
instance: nextInstance,
driver: ProviderDriverKind.make("codex"),
isDefault: true,
});
expect(patch.providerInstances?.[instanceId]).toEqual(nextInstance);
expect(patch.providers?.codex).toEqual(DEFAULT_SERVER_SETTINGS.providers.codex);
});
it("updates custom instances without touching legacy provider settings", () => {
const instanceId = ProviderInstanceId.make("codex_personal");
const nextInstance = {
driver: ProviderDriverKind.make("codex"),
enabled: true,
config: {
homePath: "/Users/example/.codex-personal",
},
} satisfies ProviderInstanceConfig;
const patch = buildProviderInstanceUpdatePatch({
settings: DEFAULT_SERVER_SETTINGS,
instanceId,
instance: nextInstance,
driver: ProviderDriverKind.make("codex"),
isDefault: false,
});
expect(patch.providerInstances?.[instanceId]).toEqual(nextInstance);
expect(patch.providers).toBeUndefined();
});
});
describe("getChangedBrowserSettingLabels", () => {
it("reports nothing for the defaults", () => {
expect(getChangedBrowserSettingLabels(DEFAULT_UNIFIED_SETTINGS)).toEqual([]);
});
it("treats a structurally equal viewport as unchanged", () => {
// The viewport is a tagged union, so identity comparison would report a
// freshly decoded copy of the default as dirty and offer to "restore" it.
expect(
getChangedBrowserSettingLabels({
...DEFAULT_UNIFIED_SETTINGS,
browserDefaultViewport: { ...DEFAULT_UNIFIED_SETTINGS.browserDefaultViewport },
}),
).toEqual([]);
});
it("labels each browser default that differs", () => {
expect(
getChangedBrowserSettingLabels({
...DEFAULT_UNIFIED_SETTINGS,
browserDefaultViewport: { _tag: "freeform", width: 900, height: 600 },
browserDefaultZoomFactor: 1.5,
browserDefaultAppearance: "dark",
browserRecordingFrameRate: 60,
browserAutoShowFloatingPreview: !DEFAULT_UNIFIED_SETTINGS.browserAutoShowFloatingPreview,
}),
).toEqual([
"Browser viewport",
"Browser zoom",
"Browser appearance",
"Recording frame rate",
"Floating preview",
]);
});
});
describe("isSamePreviewViewport", () => {
it("separates presets that share a size", () => {
// Two presets can agree on width and height and still be different
// entries in the picker, so the id has to take part in the comparison.
expect(
isSamePreviewViewport(
{ _tag: "preset", width: 390, height: 844, presetId: "iphone-12-pro" },
{ _tag: "preset", width: 390, height: 844, presetId: "ipad-mini" },
),
).toBe(false);
});
it("separates a freeform viewport from a preset of the same size", () => {
expect(
isSamePreviewViewport(
{ _tag: "freeform", width: 390, height: 844 },
{ _tag: "preset", width: 390, height: 844, presetId: "iphone-12-pro" },
),
).toBe(false);
});
});