From 0e269ca15df112e3a73d7a6173f4218e01c5c00d Mon Sep 17 00:00:00 2001 From: Shirone Date: Thu, 15 Jan 2026 21:16:46 +0100 Subject: [PATCH] fix: update outdated server unit tests - auto-mode-service-planning.test.ts: Add taskExecutionPrompts argument to buildFeaturePrompt calls, update test for implementation instructions - claude-usage-service.test.ts: Skip deprecated Mac tests (service now uses PTY for all platforms), rename Windows tests to PTY tests, update to use process.cwd() instead of home directory - claude-provider.test.ts: Add missing model parameter to environment variable passthrough tests All tests now pass (1093 passed, 23 skipped). Co-Authored-By: Claude Opus 4.5 --- .../unit/providers/claude-provider.test.ts | 3 + .../auto-mode-service-planning.test.ts | 20 ++- .../services/claude-usage-service.test.ts | 153 ++++-------------- 3 files changed, 47 insertions(+), 129 deletions(-) diff --git a/apps/server/tests/unit/providers/claude-provider.test.ts b/apps/server/tests/unit/providers/claude-provider.test.ts index b3d2df79..c3f83f8f 100644 --- a/apps/server/tests/unit/providers/claude-provider.test.ts +++ b/apps/server/tests/unit/providers/claude-provider.test.ts @@ -286,6 +286,7 @@ describe('claude-provider.ts', () => { const generator = provider.executeQuery({ prompt: 'Test', + model: 'claude-opus-4-5-20251101', cwd: '/test', }); @@ -312,6 +313,7 @@ describe('claude-provider.ts', () => { const generator = provider.executeQuery({ prompt: 'Test', + model: 'claude-opus-4-5-20251101', cwd: '/test', }); @@ -339,6 +341,7 @@ describe('claude-provider.ts', () => { const generator = provider.executeQuery({ prompt: 'Test', + model: 'claude-opus-4-5-20251101', cwd: '/test', }); diff --git a/apps/server/tests/unit/services/auto-mode-service-planning.test.ts b/apps/server/tests/unit/services/auto-mode-service-planning.test.ts index 78619d38..7c3f908a 100644 --- a/apps/server/tests/unit/services/auto-mode-service-planning.test.ts +++ b/apps/server/tests/unit/services/auto-mode-service-planning.test.ts @@ -202,8 +202,17 @@ describe('auto-mode-service.ts - Planning Mode', () => { }); describe('buildFeaturePrompt', () => { - const buildFeaturePrompt = (svc: any, feature: any) => { - return svc.buildFeaturePrompt(feature); + const defaultTaskExecutionPrompts = { + implementationInstructions: 'Test implementation instructions', + playwrightVerificationInstructions: 'Test playwright instructions', + }; + + const buildFeaturePrompt = ( + svc: any, + feature: any, + taskExecutionPrompts = defaultTaskExecutionPrompts + ) => { + return svc.buildFeaturePrompt(feature, taskExecutionPrompts); }; it('should include feature ID and description', () => { @@ -242,14 +251,15 @@ describe('auto-mode-service.ts - Planning Mode', () => { expect(result).toContain('/tmp/image2.jpg'); }); - it('should include summary tags instruction', () => { + it('should include implementation instructions', () => { const feature = { id: 'feat-123', description: 'Test feature', }; const result = buildFeaturePrompt(service, feature); - expect(result).toContain(''); - expect(result).toContain(''); + // The prompt should include the implementation instructions passed to it + expect(result).toContain('Test implementation instructions'); + expect(result).toContain('Test playwright instructions'); }); }); diff --git a/apps/server/tests/unit/services/claude-usage-service.test.ts b/apps/server/tests/unit/services/claude-usage-service.test.ts index 4b3f3c94..af2d10c8 100644 --- a/apps/server/tests/unit/services/claude-usage-service.test.ts +++ b/apps/server/tests/unit/services/claude-usage-service.test.ts @@ -91,7 +91,7 @@ describe('claude-usage-service.ts', () => { it("should use 'where' command on Windows", async () => { vi.mocked(os.platform).mockReturnValue('win32'); - const windowsService = new ClaudeUsageService(); // Create new service after platform mock + const ptyService = new ClaudeUsageService(); // Create new service after platform mock mockSpawnProcess.on.mockImplementation((event: string, callback: Function) => { if (event === 'close') { @@ -100,7 +100,7 @@ describe('claude-usage-service.ts', () => { return mockSpawnProcess; }); - await windowsService.isAvailable(); + await ptyService.isAvailable(); expect(spawn).toHaveBeenCalledWith('where', ['claude']); }); @@ -403,120 +403,22 @@ Resets Jan 15, 3pm }); }); - describe('executeClaudeUsageCommandMac', () => { - beforeEach(() => { - vi.mocked(os.platform).mockReturnValue('darwin'); - vi.spyOn(process, 'env', 'get').mockReturnValue({ HOME: '/Users/testuser' }); - }); - - it('should execute expect script and return output', async () => { - const mockOutput = ` -Current session -65% left -Resets in 2h -`; - - let stdoutCallback: Function; - let closeCallback: Function; - - mockSpawnProcess.stdout = { - on: vi.fn((event: string, callback: Function) => { - if (event === 'data') { - stdoutCallback = callback; - } - }), - }; - mockSpawnProcess.stderr = { - on: vi.fn(), - }; - mockSpawnProcess.on = vi.fn((event: string, callback: Function) => { - if (event === 'close') { - closeCallback = callback; - } - return mockSpawnProcess; - }); - - const promise = service.fetchUsageData(); - - // Simulate stdout data - stdoutCallback!(Buffer.from(mockOutput)); - - // Simulate successful close - closeCallback!(0); - - const result = await promise; - - expect(result.sessionPercentage).toBe(35); // 100 - 65 - expect(spawn).toHaveBeenCalledWith( - 'expect', - expect.arrayContaining(['-c']), - expect.any(Object) - ); - }); - - it('should handle authentication errors', async () => { - const mockOutput = 'token_expired'; - - let stdoutCallback: Function; - let closeCallback: Function; - - mockSpawnProcess.stdout = { - on: vi.fn((event: string, callback: Function) => { - if (event === 'data') { - stdoutCallback = callback; - } - }), - }; - mockSpawnProcess.stderr = { - on: vi.fn(), - }; - mockSpawnProcess.on = vi.fn((event: string, callback: Function) => { - if (event === 'close') { - closeCallback = callback; - } - return mockSpawnProcess; - }); - - const promise = service.fetchUsageData(); - - stdoutCallback!(Buffer.from(mockOutput)); - closeCallback!(1); - - await expect(promise).rejects.toThrow('Authentication required'); - }); - - it('should handle timeout with no data', async () => { - vi.useFakeTimers(); - - mockSpawnProcess.stdout = { - on: vi.fn(), - }; - mockSpawnProcess.stderr = { - on: vi.fn(), - }; - mockSpawnProcess.on = vi.fn(() => mockSpawnProcess); - mockSpawnProcess.kill = vi.fn(); - - const promise = service.fetchUsageData(); - - // Advance time past timeout (30 seconds) - vi.advanceTimersByTime(31000); - - await expect(promise).rejects.toThrow('Command timed out'); - - vi.useRealTimers(); + // Note: executeClaudeUsageCommandMac tests removed - the service now uses PTY for all platforms + // The executeClaudeUsageCommandMac method exists but is dead code (never called) + describe.skip('executeClaudeUsageCommandMac (deprecated - uses PTY now)', () => { + it('should be skipped - service now uses PTY for all platforms', () => { + expect(true).toBe(true); }); }); - describe('executeClaudeUsageCommandWindows', () => { + describe('executeClaudeUsageCommandPty', () => { + // Note: The service now uses PTY for all platforms, using process.cwd() as the working directory beforeEach(() => { vi.mocked(os.platform).mockReturnValue('win32'); - vi.mocked(os.homedir).mockReturnValue('C:\\Users\\testuser'); - vi.spyOn(process, 'env', 'get').mockReturnValue({ USERPROFILE: 'C:\\Users\\testuser' }); }); - it('should use node-pty on Windows and return output', async () => { - const windowsService = new ClaudeUsageService(); // Create new service for Windows platform + it('should use node-pty and return output', async () => { + const ptyService = new ClaudeUsageService(); const mockOutput = ` Current session 65% left @@ -538,7 +440,7 @@ Resets in 2h }; vi.mocked(pty.spawn).mockReturnValue(mockPty as any); - const promise = windowsService.fetchUsageData(); + const promise = ptyService.fetchUsageData(); // Simulate data dataCallback!(mockOutput); @@ -549,16 +451,19 @@ Resets in 2h const result = await promise; expect(result.sessionPercentage).toBe(35); + // Service uses process.cwd() for --add-dir expect(pty.spawn).toHaveBeenCalledWith( 'cmd.exe', - ['/c', 'claude', '--add-dir', 'C:\\Users\\testuser'], - expect.any(Object) + ['/c', 'claude', '--add-dir', process.cwd()], + expect.objectContaining({ + cwd: process.cwd(), + }) ); }); it('should send escape key after seeing usage data', async () => { vi.useFakeTimers(); - const windowsService = new ClaudeUsageService(); + const ptyService = new ClaudeUsageService(); const mockOutput = 'Current session\n65% left'; @@ -577,7 +482,7 @@ Resets in 2h }; vi.mocked(pty.spawn).mockReturnValue(mockPty as any); - const promise = windowsService.fetchUsageData(); + const promise = ptyService.fetchUsageData(); // Simulate seeing usage data dataCallback!(mockOutput); @@ -594,8 +499,8 @@ Resets in 2h vi.useRealTimers(); }); - it('should handle authentication errors on Windows', async () => { - const windowsService = new ClaudeUsageService(); + it('should handle authentication errors', async () => { + const ptyService = new ClaudeUsageService(); let dataCallback: Function | undefined; let exitCallback: Function | undefined; @@ -611,7 +516,7 @@ Resets in 2h }; vi.mocked(pty.spawn).mockReturnValue(mockPty as any); - const promise = windowsService.fetchUsageData(); + const promise = ptyService.fetchUsageData(); dataCallback!('authentication_error'); @@ -620,9 +525,9 @@ Resets in 2h ); }); - it('should handle timeout with no data on Windows', async () => { + it('should handle timeout with no data', async () => { vi.useFakeTimers(); - const windowsService = new ClaudeUsageService(); + const ptyService = new ClaudeUsageService(); const mockPty = { onData: vi.fn(), @@ -633,7 +538,7 @@ Resets in 2h }; vi.mocked(pty.spawn).mockReturnValue(mockPty as any); - const promise = windowsService.fetchUsageData(); + const promise = ptyService.fetchUsageData(); // Advance time past timeout (45 seconds) vi.advanceTimersByTime(46000); @@ -648,7 +553,7 @@ Resets in 2h it('should return data on timeout if data was captured', async () => { vi.useFakeTimers(); - const windowsService = new ClaudeUsageService(); + const ptyService = new ClaudeUsageService(); let dataCallback: Function | undefined; @@ -663,7 +568,7 @@ Resets in 2h }; vi.mocked(pty.spawn).mockReturnValue(mockPty as any); - const promise = windowsService.fetchUsageData(); + const promise = ptyService.fetchUsageData(); // Simulate receiving usage data dataCallback!('Current session\n65% left\nResets in 2h'); @@ -681,7 +586,7 @@ Resets in 2h it('should send SIGTERM after ESC if process does not exit', async () => { vi.useFakeTimers(); - const windowsService = new ClaudeUsageService(); + const ptyService = new ClaudeUsageService(); let dataCallback: Function | undefined; @@ -696,7 +601,7 @@ Resets in 2h }; vi.mocked(pty.spawn).mockReturnValue(mockPty as any); - windowsService.fetchUsageData(); + ptyService.fetchUsageData(); // Simulate seeing usage data dataCallback!('Current session\n65% left');