ded9671a82
- 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.
127 lines
4.1 KiB
TypeScript
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
|
|
});
|
|
});
|