Skip to content

Commit 1043d0b

Browse files
committed
fix(rest): build a real IHttpRequest in the #7541 pin instead of a partial literal
The new test drove both handlers with `{ params, query }` object literals, which do not satisfy `IHttpRequest` — 2 x TS2345, taking @objectstack/rest's TEST_DEBT from its recorded 155 to 157. That ledger is a ratchet: it may only shrink. Fixed at the source rather than by raising the entry, and the fix is not bookkeeping. `enforceAuth` runs BEFORE either predicate under test and reads `req.method` and `req.path` — both `undefined` in the old literals — so the pin was measuring statuses a real caller would not necessarily get. The helper now returns a complete `IHttpRequest` typed against the contract, so the gate reads zero errors from this file AND the measured 200/404/501 are the statuses the real request shape produces. Not cast to `any`: the neighbouring conformance test casts its handler that way, but a cast here would have hidden exactly the missing members that make the measurement faithful. Measured with the gate's own command (packages/rest/tsconfig.json with the test globs dropped from `exclude`): 157 before, 155 after — equal to the recorded ledger entry, which is left untouched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GHTC2SvMXprxV9eEHqfbCP
1 parent 328149f commit 1043d0b

1 file changed

Lines changed: 14 additions & 2 deletions

File tree

packages/rest/src/discovery-search-capability-agreement.test.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,21 @@
2323
// keep the agreement from holding vacuously.
2424

2525
import { describe, it, expect, vi } from 'vitest';
26+
import type { IHttpRequest } from '@objectstack/spec/contracts';
2627
import { ObjectStackProtocolImplementation } from '@objectstack/metadata-protocol';
2728
import { RestServer } from './rest-server.js';
2829

30+
/**
31+
* A complete `IHttpRequest`, typed against the contract rather than cast to
32+
* `any`. Not ceremony: `enforceAuth` — which runs before either predicate under
33+
* test — reads `method` and `path`, so a partial literal would exercise the
34+
* gate with `undefined` on both. Building the real shape is what makes the
35+
* measured statuses below the statuses a real caller gets.
36+
*/
37+
function request(path: string, query: Record<string, string> = {}): IHttpRequest {
38+
return { params: {}, query, headers: {}, method: 'GET', path };
39+
}
40+
2941
function createMockServer() {
3042
return {
3143
get: vi.fn(), post: vi.fn(), put: vi.fn(), delete: vi.fn(), patch: vi.fn(),
@@ -109,7 +121,7 @@ async function measure(opts: {
109121
json: (b: any) => { discoveryBody = b; },
110122
status: () => discoveryRes,
111123
};
112-
await discoveryEntry.handler({ params: {}, query: {} }, discoveryRes);
124+
await discoveryEntry.handler(request('/api/v1/discovery'), discoveryRes);
113125
const declared = discoveryBody?.capabilities?.search?.enabled;
114126

115127
const searchEntry = routes.get('GET', '/api/v1/search');
@@ -124,7 +136,7 @@ async function measure(opts: {
124136
status: (s: number) => { status = s; return searchRes; },
125137
json: (b: any) => { searchBody = b; },
126138
};
127-
await searchEntry.handler({ params: {}, query: { q: 'audit' } }, searchRes);
139+
await searchEntry.handler(request('/api/v1/search', { q: 'audit' }), searchRes);
128140
return { declared, status, hits: searchBody?.hits?.length ?? 0 };
129141
}
130142

0 commit comments

Comments
 (0)