From 16238276fb94efd59a3e04beb330ac075a85fab1 Mon Sep 17 00:00:00 2001 From: iliya Date: Sun, 29 Mar 2026 02:01:07 +0200 Subject: [PATCH] refactor(team): update tracking logic and enhance test coverage - Replaced `ensureTracking` and `stopTracking` with a single `setTracking` function in `TeamDataService` to streamline task change presence tracking. - Updated related tests to reflect the new tracking logic and ensure proper function calls. - Added `activeToolCalls` property to various service interfaces to improve state management during provisioning operations. --- test/main/services/team/TeamDataService.test.ts | 13 ++++--------- .../TeamProvisioningServiceLiveMessages.test.ts | 2 ++ .../TeamProvisioningServicePostCompact.test.ts | 3 +++ .../team/TeamProvisioningServicePrepare.test.ts | 2 ++ .../team/TeamProvisioningServicePrompts.test.ts | 3 +++ .../team/TeamProvisioningServiceRelay.test.ts | 14 ++++++++++++++ 6 files changed, 28 insertions(+), 9 deletions(-) diff --git a/test/main/services/team/TeamDataService.test.ts b/test/main/services/team/TeamDataService.test.ts index 53b7cc36..dd62008f 100644 --- a/test/main/services/team/TeamDataService.test.ts +++ b/test/main/services/team/TeamDataService.test.ts @@ -147,11 +147,7 @@ describe('TeamDataService', () => { }); it('starts and stops task change presence tracking outside getTeamData', async () => { - const ensureTracking = vi.fn(async () => ({ - projectFingerprint: 'project-fingerprint', - logSourceGeneration: 'generation-1', - })); - const stopTracking = vi.fn(async () => undefined); + const setTracking = vi.fn(async () => undefined); const service = new TeamDataService( { @@ -178,8 +174,7 @@ describe('TeamDataService', () => { deleteTasks: vi.fn(async () => undefined), } as never, { - ensureTracking, - stopTracking, + setTracking, } as never ); @@ -187,8 +182,8 @@ describe('TeamDataService', () => { service.setTaskChangePresenceTracking('my-team', false); await Promise.resolve(); - expect(ensureTracking).toHaveBeenCalledWith('my-team'); - expect(stopTracking).toHaveBeenCalledWith('my-team'); + expect(setTracking).toHaveBeenNthCalledWith(1, 'my-team', 'change_presence', true); + expect(setTracking).toHaveBeenNthCalledWith(2, 'my-team', 'change_presence', false); }); it('surfaces controller reconcile failures', async () => { diff --git a/test/main/services/team/TeamProvisioningServiceLiveMessages.test.ts b/test/main/services/team/TeamProvisioningServiceLiveMessages.test.ts index d9e68057..8a5f930e 100644 --- a/test/main/services/team/TeamProvisioningServiceLiveMessages.test.ts +++ b/test/main/services/team/TeamProvisioningServiceLiveMessages.test.ts @@ -134,6 +134,7 @@ interface RunLike { provisioningComplete: boolean; leadMsgSeq: number; pendingToolCalls: { name: string; preview: string }[]; + activeToolCalls: Map; pendingDirectCrossTeamSendRefresh: boolean; lastLeadTextEmitMs: number; leadRelayCapture: null; @@ -166,6 +167,7 @@ function attachRun( provisioningComplete: opts?.provisioningComplete ?? false, leadMsgSeq: 0, pendingToolCalls: [], + activeToolCalls: new Map(), pendingDirectCrossTeamSendRefresh: false, lastLeadTextEmitMs: 0, leadRelayCapture: null, diff --git a/test/main/services/team/TeamProvisioningServicePostCompact.test.ts b/test/main/services/team/TeamProvisioningServicePostCompact.test.ts index 3f7decf8..14ca34dc 100644 --- a/test/main/services/team/TeamProvisioningServicePostCompact.test.ts +++ b/test/main/services/team/TeamProvisioningServicePostCompact.test.ts @@ -32,6 +32,7 @@ vi.mock('@main/utils/pathDecoder', async (importOriginal) => { import { TeamProvisioningService } from '@main/services/team/TeamProvisioningService'; import { ClaudeBinaryResolver } from '@main/services/team/ClaudeBinaryResolver'; import { spawnCli } from '@main/utils/childProcess'; +import { setAppDataBasePath } from '@main/utils/pathDecoder'; function createFakeChild() { const writeSpy = vi.fn((_data: unknown, cb?: (err?: Error | null) => void) => { @@ -109,11 +110,13 @@ describe('TeamProvisioningService post-compact lifecycle', () => { tempClaudeRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'claude-team-compact-')); tempTeamsBase = path.join(tempClaudeRoot, 'teams'); tempTasksBase = path.join(tempClaudeRoot, 'tasks'); + setAppDataBasePath(tempClaudeRoot); fs.mkdirSync(tempTeamsBase, { recursive: true }); fs.mkdirSync(tempTasksBase, { recursive: true }); }); afterEach(() => { + setAppDataBasePath(null); try { fs.rmSync(tempClaudeRoot, { recursive: true, force: true }); } catch { diff --git a/test/main/services/team/TeamProvisioningServicePrepare.test.ts b/test/main/services/team/TeamProvisioningServicePrepare.test.ts index 6b30db2d..c8bbfa26 100644 --- a/test/main/services/team/TeamProvisioningServicePrepare.test.ts +++ b/test/main/services/team/TeamProvisioningServicePrepare.test.ts @@ -149,6 +149,7 @@ describe('TeamProvisioningService prepare/auth behavior', () => { timeoutHandle: null, fsMonitorHandle: null, claudeLogLines: [], + activeToolCalls: new Map(), leadActivityState: 'active', leadContextUsage: null, }; @@ -205,6 +206,7 @@ describe('TeamProvisioningService prepare/auth behavior', () => { timeoutHandle: null, fsMonitorHandle: null, claudeLogLines: [], + activeToolCalls: new Map(), leadActivityState: 'active', leadContextUsage: null, }; diff --git a/test/main/services/team/TeamProvisioningServicePrompts.test.ts b/test/main/services/team/TeamProvisioningServicePrompts.test.ts index d66df320..1be584ae 100644 --- a/test/main/services/team/TeamProvisioningServicePrompts.test.ts +++ b/test/main/services/team/TeamProvisioningServicePrompts.test.ts @@ -36,6 +36,7 @@ import { } from '@main/services/team/TeamProvisioningService'; import { ClaudeBinaryResolver } from '@main/services/team/ClaudeBinaryResolver'; import { spawnCli } from '@main/utils/childProcess'; +import { setAppDataBasePath } from '@main/utils/pathDecoder'; function createFakeChild() { const writeSpy = vi.fn((_data: unknown, cb?: (err?: Error | null) => void) => { @@ -72,11 +73,13 @@ describe('TeamProvisioningService prompt content (solo mode discipline)', () => tempClaudeRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'claude-team-prompts-')); tempTeamsBase = path.join(tempClaudeRoot, 'teams'); tempTasksBase = path.join(tempClaudeRoot, 'tasks'); + setAppDataBasePath(tempClaudeRoot); fs.mkdirSync(tempTeamsBase, { recursive: true }); fs.mkdirSync(tempTasksBase, { recursive: true }); }); afterEach(() => { + setAppDataBasePath(null); // Best-effort cleanup of temp dir (per-test) try { fs.rmSync(tempClaudeRoot, { recursive: true, force: true }); diff --git a/test/main/services/team/TeamProvisioningServiceRelay.test.ts b/test/main/services/team/TeamProvisioningServiceRelay.test.ts index ac8f5623..73e4318a 100644 --- a/test/main/services/team/TeamProvisioningServiceRelay.test.ts +++ b/test/main/services/team/TeamProvisioningServiceRelay.test.ts @@ -174,6 +174,7 @@ function attachAliveRun( }, leadMsgSeq: 0, pendingToolCalls: [], + activeToolCalls: new Map(), pendingDirectCrossTeamSendRefresh: false, lastLeadTextEmitMs: 0, activeCrossTeamReplyHints: [], @@ -348,6 +349,19 @@ describe('TeamProvisioningService relayLeadInboxMessages', () => { (service as unknown as { runs: Map }).runs.set('run-1', { runId: 'run-1', teamName, + request: { + teamName, + members: [{ name: 'team-lead', role: 'team-lead' }], + }, + activeToolCalls: new Map(), + pendingToolCalls: [], + leadMsgSeq: 0, + pendingDirectCrossTeamSendRefresh: false, + lastLeadTextEmitMs: 0, + activeCrossTeamReplyHints: [], + pendingInboxRelayCandidates: [], + silentUserDmForward: null, + silentUserDmForwardClearHandle: null, child: { stdin: { writable: true, write: writeSpy } }, processKilled: false, cancelRequested: false,