Code-review follow-ups (Approve-with-comments) for batch #197 (context badge #189 / e2e in CI #187 / inline MCP test #170): - server: extract the duplicated chatContextWindow ::text->positive-int coercion (resolve() + getMasked()) into an exported parsePositiveInt helper and unit-test its branches (200000/1.9/0/-5/""/abc/undefined), closing the untested read-path gap. - client: merge the two backward scans over messageRows into one pure, exported selectContextBadge helper (numerator and denominator still taken from the most recent row carrying EACH value) and unit-test the different-rows and fresh-zero-doesn't-shadow cases. - client: extract the MCP "Test" button tristate presentation into a pure mcpTestButtonView helper (collapses the two parallel if/else chains) and unit-test idle/ok-with-tools/ok-no-tools/failed label+tooltip branches. - ci: redirect the backgrounded prod server's stdout/stderr to a log file in e2e-mcp and cat it on failure, so a start-up crash is diagnosable instead of surfacing only as the generic health timeout. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
44 lines
1.4 KiB
TypeScript
44 lines
1.4 KiB
TypeScript
import { parsePositiveInt } from './ai-settings.service';
|
|
|
|
/**
|
|
* Round-trip coercion for numeric `::text` provider settings (e.g.
|
|
* chatContextWindow). Values are stored as text and read back as strings, so
|
|
* this guards the read path the DTO write-validation does not cover: a silent
|
|
* loss of `Math.floor` or a `> 0` → `>= 0` drift would otherwise go unnoticed.
|
|
*/
|
|
describe('parsePositiveInt', () => {
|
|
it('keeps a valid positive integer string', () => {
|
|
expect(parsePositiveInt('200000')).toBe(200000);
|
|
});
|
|
|
|
it('floors a fractional string', () => {
|
|
expect(parsePositiveInt('1.9')).toBe(1);
|
|
expect(parsePositiveInt('1.0')).toBe(1);
|
|
});
|
|
|
|
it('returns undefined for zero', () => {
|
|
expect(parsePositiveInt('0')).toBeUndefined();
|
|
});
|
|
|
|
it('returns undefined for a negative value', () => {
|
|
expect(parsePositiveInt('-5')).toBeUndefined();
|
|
});
|
|
|
|
it('returns undefined for an empty string', () => {
|
|
expect(parsePositiveInt('')).toBeUndefined();
|
|
});
|
|
|
|
it('returns undefined for a non-numeric string', () => {
|
|
expect(parsePositiveInt('abc')).toBeUndefined();
|
|
});
|
|
|
|
it('returns undefined for undefined / null', () => {
|
|
expect(parsePositiveInt(undefined)).toBeUndefined();
|
|
expect(parsePositiveInt(null)).toBeUndefined();
|
|
});
|
|
|
|
it('accepts a real number too (not only ::text strings)', () => {
|
|
expect(parsePositiveInt(42)).toBe(42);
|
|
});
|
|
});
|