test(FN-4353): complete Step 1 — core default-on regression coverage

Fusion-Task-Id: FN-4353
Fusion-Task-Lineage: 2384df03-5eb9-4327-bb8a-1ee0f97ac0fd
This commit is contained in:
Fusion
2026-05-13 10:53:38 -07:00
committed by gsxdsm
parent e4ec867f8d
commit 8078c48c21
2 changed files with 49 additions and 2 deletions

View File

@@ -1598,6 +1598,44 @@ describe("TaskStore", () => {
});
describe("getSettingsFast()", () => {
it("defaults ephemeralAgentsEnabled to true for new projects", async () => {
const fast = await harness.store().getSettingsFast();
const regular = await harness.store().getSettings();
const scopedFast = await harness.store().getSettingsByScopeFast();
expect(fast.ephemeralAgentsEnabled).toBe(true);
expect(regular.ephemeralAgentsEnabled).toBe(true);
expect(scopedFast.project.ephemeralAgentsEnabled).toBe(true);
});
it("falls back to ephemeralAgentsEnabled=true when upgrading settings omit the key", async () => {
const db = (harness.store() as any).db;
const row = db.prepare("SELECT settings FROM config WHERE id = 1").get() as { settings?: string } | undefined;
const existingSettings = row?.settings ? JSON.parse(row.settings) : {};
delete existingSettings.ephemeralAgentsEnabled;
db.prepare("UPDATE config SET settings = ? WHERE id = 1").run(JSON.stringify(existingSettings));
const fast = await harness.store().getSettingsFast();
const regular = await harness.store().getSettings();
const scopedFast = await harness.store().getSettingsByScopeFast();
expect(fast.ephemeralAgentsEnabled).toBe(true);
expect(regular.ephemeralAgentsEnabled).toBe(true);
expect(scopedFast.project.ephemeralAgentsEnabled).toBe(true);
});
it("preserves explicit ephemeralAgentsEnabled=false", async () => {
await harness.store().updateSettings({ ephemeralAgentsEnabled: false });
const fast = await harness.store().getSettingsFast();
const regular = await harness.store().getSettings();
const scopedFast = await harness.store().getSettingsByScopeFast();
expect(fast.ephemeralAgentsEnabled).toBe(false);
expect(regular.ephemeralAgentsEnabled).toBe(false);
expect(scopedFast.project.ephemeralAgentsEnabled).toBe(false);
});
it("returns the same merged result as getSettings()", async () => {
await harness.store().updateGlobalSettings({ themeMode: "light", ntfyEnabled: true });
await harness.store().updateSettings({ maxConcurrent: 5, autoMerge: false });

View File

@@ -6,6 +6,7 @@ import { existsSync, watch, type FSWatcher } from "node:fs";
import type { Task, TaskDetail, TaskCreateInput, TaskAttachment, AgentLogEntry, BoardConfig, Column, MergeResult, Settings, GlobalSettings, ProjectSettings, ActivityLogEntry, ActivityEventType, TaskDocument, TaskDocumentRevision, TaskDocumentCreateInput, TaskDocumentWithTask, InboxTask, TaskLogEntry, RunMutationContext, RunAuditEvent, RunAuditEventInput, RunAuditEventFilter, ArchivedTaskEntry, ArchiveAgentLogMode, TaskPriority, SourceType, WorkflowStepTemplate, Agent, AutostashOrphanRecord, TaskCommitAssociation, TaskCommitAssociationMatchSource, TaskCommitAssociationConfidence } from "./types.js";
import { createActivityLogSnapshot, createRunAuditSnapshot, createTaskMetadataSnapshot, toTaskMetadataRecord, validateSnapshotEnvelope, type ActivityLogSnapshot, type RunAuditSnapshot, type TaskMetadataSnapshot } from "./shared-mesh-state.js";
import { VALID_TRANSITIONS, DEFAULT_SETTINGS, isGlobalOnlySettingsKey, WORKFLOW_STEP_TEMPLATES, validateDocumentKey } from "./types.js";
import { DEFAULT_PROJECT_SETTINGS } from "./settings-schema.js";
import { normalizeTaskPriority } from "./task-priority.js";
import { canAgentTakeImplementationTaskForExplicitRouting } from "./agent-role-policy.js";
import { GlobalSettingsStore } from "./global-settings.js";
@@ -2089,8 +2090,12 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
}
}
// Apply canonicalization to both the project settings and the merged result
// Apply canonicalization to project settings and keep upgrade-safe
// default fallback behavior for legacy rows that omit this key.
const canonicalizedProject = canonicalizeSettings(projectSettings as Settings);
if (canonicalizedProject.ephemeralAgentsEnabled === undefined) {
canonicalizedProject.ephemeralAgentsEnabled = DEFAULT_PROJECT_SETTINGS.ephemeralAgentsEnabled;
}
return { global: globalSettings, project: canonicalizedProject };
}
@@ -2124,8 +2129,12 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
}
}
// Apply canonicalization to the project settings
// Apply canonicalization and keep upgrade-safe default fallback behavior
// for legacy rows that omit this key.
const canonicalizedProject = canonicalizeSettings(projectScoped as Settings);
if (canonicalizedProject.ephemeralAgentsEnabled === undefined) {
canonicalizedProject.ephemeralAgentsEnabled = DEFAULT_PROJECT_SETTINGS.ephemeralAgentsEnabled;
}
return { global: globalSettings, project: canonicalizedProject };
}