@@ -25,6 +25,7 @@ import {
2525 appEndpointMountPrefix ,
2626 isAppEndpointPath ,
2727 runAppEndpointStep ,
28+ type AppEndpointExecutionInput ,
2829} from './api-endpoint-step.js' ;
2930import {
3031 createEndpointRateLimiterRegistry ,
@@ -123,7 +124,7 @@ describe('the step writes nothing unless a declaration owns the request', () =>
123124 } ) ;
124125} ) ;
125126
126- describe ( 'a match answers 501 until the executor lands (#5040 E5) ' , ( ) => {
127+ describe ( 'a match with no wiring answers an honest 501 ' , ( ) => {
127128 it ( 'reports NOT_IMPLEMENTED in the declared error envelope' , async ( ) => {
128129 const { service } = matcherFor ( [ TASKS ] ) ;
129130 const answer = await step ( '/api/v1/apps/showcase/tasks' , 'GET' , service ) ;
@@ -136,7 +137,7 @@ describe('a match answers 501 until the executor lands (#5040 E5)', () => {
136137 // Names the endpoint it matched and says plainly that nothing ran —
137138 // "matched but not executed" must never read as "executed and empty".
138139 expect ( body . error . message ) . toContain ( 'showcase_tasks' ) ;
139- expect ( body . error . message ) . toContain ( 'not enabled ' ) ;
140+ expect ( body . error . message ) . toContain ( 'no wiring ' ) ;
140141 expect ( String ( body . error . hint ) ) . toContain ( '#5040' ) ;
141142 } ) ;
142143
@@ -266,3 +267,130 @@ describe('the policy chain runs between the match and the answer', () => {
266267 expect ( [ ...entries . keys ( ) ] ) . toEqual ( [ endpointBucketKey ( 'showcase_tasks' , 'principal:usr_7' ) ] ) ;
267268 } ) ;
268269} ) ;
270+
271+ /**
272+ * Execution, wired to the far side of the policy chain (#5040 E5b / #5129).
273+ *
274+ * The delegation itself is `endpoint-executor.test.ts`'s subject; what is
275+ * asserted here is the JOIN — that a passing request reaches the executor with
276+ * the request's own coordinates and identity, that a denial never does, and
277+ * that `cacheTtl`'s header lands on a success and on nothing else.
278+ */
279+ describe ( 'execution runs on the far side of the policy chain' , ( ) => {
280+ const OPEN : ApiEndpoint = ApiEndpointSchema . parse ( { ...TASKS , name : 'showcase_open' , authRequired : false } ) ;
281+
282+ const limiters = ( ) => createEndpointRateLimiterRegistry ( { resolveCache : async ( ) => undefined } ) ;
283+
284+ /** Records every delegated `callData` call and answers with a stub result. */
285+ function callDataSpy ( result : unknown = { object : 'showcase_task' , records : [ ] , total : 0 } ) {
286+ const calls : unknown [ ] [ ] = [ ] ;
287+ return {
288+ calls,
289+ fn : async ( ...args : unknown [ ] ) => { calls . push ( args ) ; return result ; } ,
290+ } ;
291+ }
292+
293+ const wiredStep = (
294+ endpoints : ApiEndpoint [ ] ,
295+ execution : Partial < AppEndpointExecutionInput > & { deps : AppEndpointExecutionInput [ 'deps' ] } ,
296+ policy : Partial < EndpointPolicyContext > = { } ,
297+ method = 'GET' ,
298+ ) => runAppEndpointStep ( {
299+ method,
300+ path : endpoints [ 0 ] ! . path ,
301+ prefix : '/api/v1' ,
302+ metadataService : matcherFor ( endpoints ) . service as never ,
303+ policy : { limiters : limiters ( ) , ...policy } ,
304+ execution : {
305+ request : {
306+ method,
307+ path : endpoints [ 0 ] ! . path ,
308+ query : { limit : '5' } ,
309+ headers : { 'x-caller' : 'integration' } ,
310+ body : undefined ,
311+ } ,
312+ ...execution ,
313+ } ,
314+ } ) ;
315+
316+ it ( 'delegates a passing request with the request\'s own identity envelope' , async ( ) => {
317+ const spy = callDataSpy ( ) ;
318+ const executionContext = { userId : 'usr_7' , isSystem : false } as never ;
319+ const answer = await wiredStep ( [ OPEN ] , {
320+ deps : { callData : spy . fn as never } ,
321+ executionContext,
322+ environmentId : 'env_1' ,
323+ dataDriver : { driver : true } ,
324+ } ) ;
325+
326+ expect ( answer ?. status ) . toBe ( 200 ) ;
327+ expect ( answer ?. body ) . toEqual ( {
328+ success : true ,
329+ data : { object : 'showcase_task' , records : [ ] , total : 0 } ,
330+ meta : undefined ,
331+ } ) ;
332+ // The identity envelope, the driver and the scope ride on the delegated
333+ // call — #5040 §4's red line, and the exact thing #4936's dead branch
334+ // dropped (it would have read as `system`, RLS bypassed).
335+ expect ( spy . calls ) . toEqual ( [ [
336+ 'query' ,
337+ { object : 'showcase_task' , query : { limit : '5' } } ,
338+ { driver : true } ,
339+ 'env_1' ,
340+ executionContext ,
341+ ] ] ) ;
342+ } ) ;
343+
344+ it ( 'puts the cacheTtl Cache-Control on a SUCCESS answer' , async ( ) => {
345+ const cached = ApiEndpointSchema . parse ( { ...OPEN , name : 'showcase_cached' , cacheTtl : 30 } ) ;
346+ const answer = await wiredStep ( [ cached ] , { deps : { callData : callDataSpy ( ) . fn as never } } ) ;
347+
348+ expect ( answer ?. status ) . toBe ( 200 ) ;
349+ expect ( answer ?. headers ) . toEqual ( { 'Cache-Control' : 'private, max-age=30' } ) ;
350+ } ) ;
351+
352+ it ( 'never puts it on an ERROR answer, however the failure arose' , async ( ) => {
353+ const cached = ApiEndpointSchema . parse ( { ...OPEN , name : 'showcase_cached' , cacheTtl : 30 } ) ;
354+ // A delegated pipeline that throws — the executor maps it to a 4xx/5xx
355+ // answer, and a client must not be told to reuse a failure for 30s.
356+ const answer = await wiredStep ( [ cached ] , {
357+ deps : { callData : async ( ) => { throw { statusCode : 404 , message : 'no such object' } ; } } ,
358+ } ) ;
359+
360+ expect ( answer ?. status ) . toBe ( 404 ) ;
361+ expect ( answer ?. headers ) . toBeUndefined ( ) ;
362+
363+ // Same for a declaration this runtime does not execute (501 from the
364+ // executor's own `unsupported` arm, not from the no-wiring branch).
365+ const proxied = ApiEndpointSchema . parse ( {
366+ ...OPEN , name : 'showcase_proxy' , type : 'proxy' , target : 'https://example.invalid' , cacheTtl : 30 ,
367+ } ) ;
368+ const unsupported = await wiredStep ( [ proxied ] , { deps : { callData : async ( ) => ( { } ) } } ) ;
369+ expect ( unsupported ?. status ) . toBe ( 501 ) ;
370+ expect ( unsupported ?. headers ) . toBeUndefined ( ) ;
371+ expect ( String ( ( unsupported ! . body as { error : { message : string } } ) . error . message ) ) . toContain ( 'proxy' ) ;
372+ } ) ;
373+
374+ it ( 'never reaches the executor when a policy denied the request' , async ( ) => {
375+ const spy = callDataSpy ( ) ;
376+ // `TASKS` keeps the default `authRequired: true`; the caller is anonymous.
377+ const answer = await wiredStep ( [ TASKS ] , { deps : { callData : spy . fn as never } } ) ;
378+
379+ expect ( answer ?. status ) . toBe ( 401 ) ;
380+ expect ( spy . calls , 'the executor ran for a request the policy chain denied' ) . toEqual ( [ ] ) ;
381+ } ) ;
382+
383+ it ( 'answers an honest 501 when a caller wired policies but no executor' , async ( ) => {
384+ const answer = await runAppEndpointStep ( {
385+ method : 'GET' ,
386+ path : OPEN . path ,
387+ prefix : '/api/v1' ,
388+ metadataService : matcherFor ( [ OPEN ] ) . service as never ,
389+ policy : { limiters : limiters ( ) } ,
390+ } ) ;
391+ expect ( answer ?. status ) . toBe ( 501 ) ;
392+ const hint = String ( ( answer ! . body as { error : { hint : unknown } } ) . error . hint ) ;
393+ expect ( hint ) . toContain ( 'enforced' ) ;
394+ expect ( hint ) . toContain ( 'no execution wiring' ) ;
395+ } ) ;
396+ } ) ;
0 commit comments