From 091346cddc37ba5db2df00bd57e51b5c5bb92226 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Thu, 3 Sep 2026 05:15:23 +0000 Subject: [PATCH] test(route-unit): pin the provider fixture seam of the route harness (#95) renderRoute mounts context.providers as the request's frozen provider map and never executes conventional src/providers modules on a test's behalf; document the seam beside the provider conventions. --- docs/entry-conventions.md | 5 +++ .../tests/route-unit/render-route.test.ts | 34 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/docs/entry-conventions.md b/docs/entry-conventions.md index 98a638981..ddad32882 100644 --- a/docs/entry-conventions.md +++ b/docs/entry-conventions.md @@ -154,6 +154,11 @@ of throwing. `invocation.kind` stays surface-specific (`tool`, `event`, `cli`, `processLifetime` is reserved for the framework-owned process identity and hit counter, so provider filenames must not derive that key. +Route-unit and CLI-dispatch tests inject provider values through the same +`context` seam as identity axes (`renderRoute(id, { context: { providers: +{ library: fixture } } })`); the harness never executes conventional provider +modules, so a test chooses exactly the values a component observes. + ### Handler request context Conventional route components receive only their surface props, such as diff --git a/packages/agent-bundle/tests/route-unit/render-route.test.ts b/packages/agent-bundle/tests/route-unit/render-route.test.ts index 534f171d2..6247961ce 100644 --- a/packages/agent-bundle/tests/route-unit/render-route.test.ts +++ b/packages/agent-bundle/tests/route-unit/render-route.test.ts @@ -1,4 +1,6 @@ +import { Agent, agent } from '@agent-bundle/runtime'; import { describe, expect, it } from '@rstest/core'; +import { createElement } from 'react'; import Echo from '../../fixtures/route-harness/src/mcp/harness/tools/echo.tsx'; import { AgentTestError } from '../../src/test/errors.ts'; @@ -261,6 +263,38 @@ describe('renderRoute through the real renderer', () => { .toHaveValue(undefined); }); + it('mounts provider fixture values through the context seam instead of executing provider modules', async () => { + const library = { stages: ['discover', 'curate'], tooling: { ffmpeg: { available: false } } }; + const Providers = async (): Promise => { + const { providers } = await agent(); + return createElement(Agent.Result, { + value: { + frozen: Object.isFrozen(providers), + keys: Object.keys(providers).sort(), + library: providers['library'] as never, + }, + }, createElement(Agent.Text, null, 'providers observed')); + }; + + const rendered = await renderRoute({ default: Providers as never }, { + context: { providers: { library } }, + routeId: 'tool:harness/providers (module)', + }); + + expectDocument(rendered).toHaveStatus('success').toHaveValue({ + frozen: true, + keys: ['library'], + library, + }); + + // A render without fixtures observes an empty, frozen provider map — the + // harness never runs conventional src/providers modules on the test's behalf. + const unfixtured = await renderRoute({ default: Providers as never }, { + routeId: 'tool:harness/providers (module)', + }); + expectDocument(unfixtured).toHaveValue({ frozen: true, keys: [], library: undefined }); + }); + it('renders a route module handed in directly, without the compiled manifest', async () => { const rendered = await renderRoute({ default: Echo }, { input: { message: 'module form' },