Files
claude-mem/tests/happy-paths/context-injection.test.ts
T
Alex Newman ded9671a82 Refactor worker port handling and improve logging
- Replaced hardcoded migration port with dynamic port retrieval using `getWorkerPort()` in worker-cli.ts.
- Updated context generator to clarify error handling comments.
- Introduced timeout constants in ProcessManager for better maintainability.
- Configured SQLite settings using constants for mmap size and cache size in DatabaseManager.
- Added timeout constants for Git and NPM commands in BranchManager.
- Enhanced error logging in FormattingService and SearchManager to provide more context on failures.
- Removed deprecated silentDebug function and replaced its usage with logger.debug.
- Updated tests to use dynamic worker port retrieval instead of hardcoded values.
2025-12-11 14:49:47 -05:00

127 lines
4.1 KiB
TypeScript

/**
* Happy Path Test: Context Injection (SessionStart)
*
* Tests that when a session starts, the context hook can retrieve
* formatted context from the worker containing recent observations.
*/
import { describe, it, expect, beforeEach, vi } from 'vitest';
import { sampleObservation, featureObservation } from '../helpers/scenarios.js';
import { getWorkerPort } from '../../src/shared/worker-utils.js';
describe('Context Injection (SessionStart)', () => {
const WORKER_PORT = getWorkerPort();
const PROJECT_NAME = 'claude-mem';
beforeEach(() => {
vi.clearAllMocks();
});
it('returns formatted context when observations exist', async () => {
// This is a component test that verifies the happy path:
// Session starts → Hook calls worker → Worker queries database → Returns formatted context
// Setup: Mock fetch to simulate worker response
const mockContext = `# [claude-mem] recent context
## Recent Work (2 observations)
### [bugfix] Fixed parser bug
The XML parser was not handling empty tags correctly.
Files: /project/src/parser.ts
### [feature] Added search functionality
Implemented full-text search using FTS5.
Files: /project/src/services/search.ts`;
global.fetch = vi.fn().mockResolvedValue({
ok: true,
status: 200,
text: async () => mockContext
});
// Execute: Call context endpoint (what the hook does)
const response = await fetch(
`http://127.0.0.1:${WORKER_PORT}/api/context/inject?project=${encodeURIComponent(PROJECT_NAME)}`
);
// Verify: Response is successful
expect(response.ok).toBe(true);
expect(response.status).toBe(200);
// Verify: Context contains observations
const text = await response.text();
expect(text).toContain('recent context');
expect(text).toContain('Fixed parser bug');
expect(text).toContain('Added search functionality');
expect(text).toContain('bugfix');
expect(text).toContain('feature');
});
it('returns fallback message when worker is down', async () => {
// Setup: Mock fetch to simulate worker not available
global.fetch = vi.fn().mockRejectedValue(new Error('ECONNREFUSED'));
// Execute: Attempt to call context endpoint
try {
await fetch(
`http://127.0.0.1:${WORKER_PORT}/api/context/inject?project=${encodeURIComponent(PROJECT_NAME)}`
);
} catch (error: any) {
// Verify: Error indicates worker is down
expect(error.message).toContain('ECONNREFUSED');
}
// The hook should handle this gracefully and return a fallback message
// (This would be tested in hook-specific tests, not the worker endpoint tests)
});
it('handles empty observations gracefully', async () => {
// Setup: Mock fetch to simulate no observations available
const emptyContext = `# [claude-mem] recent context
No observations found for this project.`;
global.fetch = vi.fn().mockResolvedValue({
ok: true,
status: 200,
text: async () => emptyContext
});
// Execute: Call context endpoint
const response = await fetch(
`http://127.0.0.1:${WORKER_PORT}/api/context/inject?project=${encodeURIComponent(PROJECT_NAME)}`
);
// Verify: Returns success with empty message
expect(response.ok).toBe(true);
const text = await response.text();
expect(text).toContain('No observations found');
});
it('supports colored output when requested', async () => {
// Setup: Mock fetch to simulate colored response
const coloredContext = `# [claude-mem] recent context
## Recent Work (1 observation)
### \x1b[33m[bugfix]\x1b[0m Fixed parser bug
The XML parser was not handling empty tags correctly.`;
global.fetch = vi.fn().mockResolvedValue({
ok: true,
status: 200,
text: async () => coloredContext
});
// Execute: Call context endpoint with colors parameter
const response = await fetch(
`http://127.0.0.1:${WORKER_PORT}/api/context/inject?project=${encodeURIComponent(PROJECT_NAME)}&colors=true`
);
// Verify: Response contains ANSI color codes
expect(response.ok).toBe(true);
const text = await response.text();
expect(text).toContain('\x1b['); // ANSI escape code
});
});