mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-09-30 12:39:42 +02:00
test: add coverage for lastUsedCase partial update and strict schema rejection
Tests that partial PUT /api/settings with just lastUsedCase works correctly and that including modelConfig triggers strict Zod schema rejection (the bug fixed in #49). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
||||
|
||||
| Task | Command |
|
||||
|------|---------|
|
||||
| Dev server | `npx tsx src/index.ts web` |
|
||||
| Dev server | `npm run dev` (or `npx tsx src/index.ts web`) |
|
||||
| Type check | `tsc --noEmit` |
|
||||
| Lint | `npm run lint` (fix: `npm run lint:fix`) |
|
||||
| Format | `npm run format` (check: `npm run format:check`) |
|
||||
@@ -78,7 +78,7 @@ Codeman is a Claude Code session manager with web interface and autonomous Ralph
|
||||
| Production start | `npm run start` |
|
||||
| Production logs | `journalctl --user -u codeman-web -f` |
|
||||
|
||||
**CI**: `.github/workflows/ci.yml` runs `typecheck`, `lint`, `format:check` on push to master (Node 22). Tests excluded (they spawn tmux).
|
||||
**CI**: `.github/workflows/ci.yml` runs `typecheck`, `lint`, `format:check` on push to master/main and on PRs (Node 22). Tests excluded (they spawn tmux).
|
||||
|
||||
**Code style**: Prettier (`singleQuote: true`, `printWidth: 120`, `trailingComma: "es5"`). ESLint flat config (`eslint.config.js`) allows `no-console`, warns on `@typescript-eslint/no-explicit-any`. Ignores: `app.js`, `scripts/**/*.mjs`, `src/web/public/vendor/**`, `tools/**`, `remotion/**`.
|
||||
|
||||
|
||||
@@ -366,6 +366,36 @@ describe('system-routes', () => {
|
||||
expect(body.success).toBe(false);
|
||||
});
|
||||
|
||||
it('saves lastUsedCase as partial update without overwriting other settings', async () => {
|
||||
mockedReadFile.mockResolvedValue(
|
||||
JSON.stringify({ showCost: true, showTokenCount: false, subagentTrackingEnabled: true }) as never
|
||||
);
|
||||
|
||||
const res = await harness.app.inject({
|
||||
method: 'PUT',
|
||||
url: '/api/settings',
|
||||
payload: { lastUsedCase: 'my-test-case' },
|
||||
});
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(JSON.parse(res.body).success).toBe(true);
|
||||
|
||||
const writtenContent = JSON.parse(mockedWriteFile.mock.calls[0][1] as string);
|
||||
expect(writtenContent.lastUsedCase).toBe('my-test-case');
|
||||
expect(writtenContent.showCost).toBe(true);
|
||||
expect(writtenContent.showTokenCount).toBe(false);
|
||||
expect(writtenContent.subagentTrackingEnabled).toBe(true);
|
||||
});
|
||||
|
||||
it('rejects settings with modelConfig (strict schema prevents full-object PUT)', async () => {
|
||||
const res = await harness.app.inject({
|
||||
method: 'PUT',
|
||||
url: '/api/settings',
|
||||
payload: { lastUsedCase: 'test', modelConfig: { model: 'something' } },
|
||||
});
|
||||
// Fastify rejects unknown fields at schema validation level (400) before handler runs
|
||||
expect(res.statusCode).toBe(400);
|
||||
});
|
||||
|
||||
it('rejects non-object body', async () => {
|
||||
const res = await harness.app.inject({
|
||||
method: 'PUT',
|
||||
|
||||
Reference in New Issue
Block a user