11// ---------------------------------------------------------------------------
22// Dispatch tests for non-JSON request bodies.
33//
4- // Each case spins up a tiny http server, declares a POST endpoint in a
5- // minimal OpenAPI spec with the content type under test , and asserts both
6- // the wire-level content type and body shape the plugin actually sent.
4+ // Each case spins up an Effect HttpApi-backed test server, derives the
5+ // OpenAPI spec from that API , and asserts both the wire-level content type
6+ // and body shape the plugin actually sent.
77//
88// The scenarios mirror what real specs commonly carry — multipart uploads
99// (files + scalar fields), XML bodies declared as pre-serialized strings,
@@ -28,7 +28,11 @@ import {
2828 type SecretProvider ,
2929} from "@executor-js/sdk" ;
3030import { makeTestConfig } from "@executor-js/sdk/testing" ;
31- import { serveOpenApiHttpApiTestServer } from "@executor-js/plugin-openapi/testing" ;
31+ import {
32+ addOpenApiTestSource ,
33+ makeOpenApiTestSourceConfig ,
34+ serveOpenApiHttpApiTestServer ,
35+ } from "@executor-js/plugin-openapi/testing" ;
3236
3337import { openApiPlugin } from "./plugin" ;
3438
@@ -104,7 +108,7 @@ const startEchoServer = (options: {
104108 handlersLayer,
105109 transformSpec : options . transformSpec ,
106110 } ) ;
107- return { baseUrl : server . baseUrl , specJson : server . specJson , captured } ;
111+ return { server, captured } ;
108112 } ) ;
109113
110114const ObjectBody = Schema . Struct ( {
@@ -154,7 +158,7 @@ const replaceRequestBodyContent =
154158describe ( "OpenAPI non-JSON request body dispatch" , ( ) => {
155159 it . effect ( "multipart/form-data: object body is encoded as real multipart" , ( ) =>
156160 Effect . gen ( function * ( ) {
157- const { baseUrl , specJson , captured } = yield * startEchoServer ( {
161+ const { server , captured } = yield * startEchoServer ( {
158162 payload : ObjectBody . pipe ( HttpApiSchema . asMultipart ( ) ) ,
159163 } ) ;
160164
@@ -167,11 +171,9 @@ describe("OpenAPI non-JSON request body dispatch", () => {
167171 } ) ,
168172 ) ;
169173
170- yield * executor . openapi . addSpec ( {
171- spec : specJson ,
174+ yield * addOpenApiTestSource ( executor , server , {
172175 scope : TEST_SCOPE ,
173176 namespace : "mp" ,
174- baseUrl,
175177 } ) ;
176178
177179 yield * executor . tools . invoke (
@@ -195,7 +197,7 @@ describe("OpenAPI non-JSON request body dispatch", () => {
195197
196198 it . effect ( "application/xml: string body passes through with xml content-type" , ( ) =>
197199 Effect . gen ( function * ( ) {
198- const { baseUrl , specJson , captured } = yield * startEchoServer ( {
200+ const { server , captured } = yield * startEchoServer ( {
199201 payload : Schema . String . pipe ( HttpApiSchema . asText ( { contentType : "application/xml" } ) ) ,
200202 } ) ;
201203
@@ -208,11 +210,9 @@ describe("OpenAPI non-JSON request body dispatch", () => {
208210 } ) ,
209211 ) ;
210212
211- yield * executor . openapi . addSpec ( {
212- spec : specJson ,
213+ yield * addOpenApiTestSource ( executor , server , {
213214 scope : TEST_SCOPE ,
214215 namespace : "xml" ,
215- baseUrl,
216216 } ) ;
217217
218218 const xml = '<?xml version="1.0"?><root><name>Acme</name></root>' ;
@@ -225,7 +225,7 @@ describe("OpenAPI non-JSON request body dispatch", () => {
225225
226226 it . effect ( "text/xml: object body is JSON-stringified (never '[object Object]')" , ( ) =>
227227 Effect . gen ( function * ( ) {
228- const { baseUrl , specJson , captured } = yield * startEchoServer ( {
228+ const { server , captured } = yield * startEchoServer ( {
229229 payload : JsonNameObject ,
230230 transformSpec : replaceRequestBodyContent ( "/submit" , "post" , contentFor ( "text/xml" ) ) ,
231231 } ) ;
@@ -239,11 +239,9 @@ describe("OpenAPI non-JSON request body dispatch", () => {
239239 } ) ,
240240 ) ;
241241
242- yield * executor . openapi . addSpec ( {
243- spec : specJson ,
242+ yield * addOpenApiTestSource ( executor , server , {
244243 scope : TEST_SCOPE ,
245244 namespace : "tx" ,
246- baseUrl,
247245 } ) ;
248246
249247 yield * executor . tools . invoke ( "tx.body.submit" , { body : { name : "Acme" } } , autoApprove ) ;
@@ -257,7 +255,7 @@ describe("OpenAPI non-JSON request body dispatch", () => {
257255
258256 it . effect ( "text/plain: string body passes through with text/plain" , ( ) =>
259257 Effect . gen ( function * ( ) {
260- const { baseUrl , specJson , captured } = yield * startEchoServer ( {
258+ const { server , captured } = yield * startEchoServer ( {
261259 payload : Schema . String . pipe ( HttpApiSchema . asText ( ) ) ,
262260 } ) ;
263261
@@ -270,11 +268,9 @@ describe("OpenAPI non-JSON request body dispatch", () => {
270268 } ) ,
271269 ) ;
272270
273- yield * executor . openapi . addSpec ( {
274- spec : specJson ,
271+ yield * addOpenApiTestSource ( executor , server , {
275272 scope : TEST_SCOPE ,
276273 namespace : "tp" ,
277- baseUrl,
278274 } ) ;
279275
280276 yield * executor . tools . invoke ( "tp.body.submit" , { body : "hello, world" } , autoApprove ) ;
@@ -286,7 +282,7 @@ describe("OpenAPI non-JSON request body dispatch", () => {
286282
287283 it . effect ( "application/octet-stream: Uint8Array passes through as bytes" , ( ) =>
288284 Effect . gen ( function * ( ) {
289- const { baseUrl , specJson , captured } = yield * startEchoServer ( {
285+ const { server , captured } = yield * startEchoServer ( {
290286 payload : Schema . Uint8Array . pipe ( HttpApiSchema . asUint8Array ( ) ) ,
291287 } ) ;
292288
@@ -299,11 +295,9 @@ describe("OpenAPI non-JSON request body dispatch", () => {
299295 } ) ,
300296 ) ;
301297
302- yield * executor . openapi . addSpec ( {
303- spec : specJson ,
298+ yield * addOpenApiTestSource ( executor , server , {
304299 scope : TEST_SCOPE ,
305300 namespace : "bin" ,
306- baseUrl,
307301 } ) ;
308302
309303 const payload = new Uint8Array ( [ 0xde , 0xad , 0xbe , 0xef , 0x00 , 0x01 , 0x02 ] ) ;
@@ -328,7 +322,7 @@ describe("OpenAPI non-JSON request body dispatch", () => {
328322
329323 it . effect ( "multi-content: defaults to first-declared (not JSON-first)" , ( ) =>
330324 Effect . gen ( function * ( ) {
331- const { baseUrl , specJson , captured } = yield * startEchoServer ( {
325+ const { server , captured } = yield * startEchoServer ( {
332326 payload : multiContentPayload ,
333327 } ) ;
334328
@@ -341,11 +335,9 @@ describe("OpenAPI non-JSON request body dispatch", () => {
341335 } ) ,
342336 ) ;
343337
344- yield * executor . openapi . addSpec ( {
345- spec : specJson ,
338+ yield * addOpenApiTestSource ( executor , server , {
346339 scope : TEST_SCOPE ,
347340 namespace : "mc" ,
348- baseUrl,
349341 } ) ;
350342
351343 yield * executor . tools . invoke ( "mc.body.submit" , { body : { name : "Acme" } } , autoApprove ) ;
@@ -358,7 +350,7 @@ describe("OpenAPI non-JSON request body dispatch", () => {
358350
359351 it . effect ( "multi-content: caller can override via args.contentType" , ( ) =>
360352 Effect . gen ( function * ( ) {
361- const { baseUrl , specJson , captured } = yield * startEchoServer ( {
353+ const { server , captured } = yield * startEchoServer ( {
362354 payload : multiContentPayload ,
363355 } ) ;
364356
@@ -371,11 +363,9 @@ describe("OpenAPI non-JSON request body dispatch", () => {
371363 } ) ,
372364 ) ;
373365
374- yield * executor . openapi . addSpec ( {
375- spec : specJson ,
366+ yield * addOpenApiTestSource ( executor , server , {
376367 scope : TEST_SCOPE ,
377368 namespace : "mc2" ,
378- baseUrl,
379369 } ) ;
380370
381371 yield * executor . tools . invoke (
@@ -393,7 +383,7 @@ describe("OpenAPI non-JSON request body dispatch", () => {
393383
394384 it . effect ( "multi-content: tool input schema exposes contentType enum" , ( ) =>
395385 Effect . gen ( function * ( ) {
396- const { specJson } = yield * startEchoServer ( {
386+ const { server } = yield * startEchoServer ( {
397387 payload : multiContentPayload ,
398388 } ) ;
399389 const executor = yield * createExecutor (
@@ -405,12 +395,13 @@ describe("OpenAPI non-JSON request body dispatch", () => {
405395 } ) ,
406396 ) ;
407397
408- yield * executor . openapi . addSpec ( {
409- spec : specJson ,
410- scope : TEST_SCOPE ,
411- namespace : "mc3" ,
412- baseUrl : "https://example.com" ,
413- } ) ;
398+ yield * executor . openapi . addSpec (
399+ makeOpenApiTestSourceConfig ( server , {
400+ scope : TEST_SCOPE ,
401+ namespace : "mc3" ,
402+ baseUrl : "https://example.com" ,
403+ } ) ,
404+ ) ;
414405
415406 const tools = yield * executor . tools . list ( ) ;
416407 const submit = tools . find ( ( t ) => t . id === "mc3.body.submit" ) ;
@@ -436,7 +427,7 @@ describe("OpenAPI non-JSON request body dispatch", () => {
436427
437428 it . effect ( "multipart encoding.contentType: JSON metadata part has typed header" , ( ) =>
438429 Effect . gen ( function * ( ) {
439- const { baseUrl , specJson , captured } = yield * startEchoServer ( {
430+ const { server , captured } = yield * startEchoServer ( {
440431 name : "upload" ,
441432 path : "/upload" ,
442433 payload : Schema . Struct ( {
@@ -462,11 +453,9 @@ describe("OpenAPI non-JSON request body dispatch", () => {
462453 } ) ,
463454 ) ;
464455
465- yield * executor . openapi . addSpec ( {
466- spec : specJson ,
456+ yield * addOpenApiTestSource ( executor , server , {
467457 scope : TEST_SCOPE ,
468458 namespace : "mpe" ,
469- baseUrl,
470459 } ) ;
471460
472461 yield * executor . tools . invoke (
@@ -499,7 +488,7 @@ describe("OpenAPI non-JSON request body dispatch", () => {
499488
500489 it . effect ( "form-urlencoded explode:false: arrays comma-join" , ( ) =>
501490 Effect . gen ( function * ( ) {
502- const { baseUrl , specJson , captured } = yield * startEchoServer ( {
491+ const { server , captured } = yield * startEchoServer ( {
503492 payload : ObjectBody . pipe ( HttpApiSchema . asFormUrlEncoded ( ) ) ,
504493 transformSpec : replaceRequestBodyContent (
505494 "/submit" ,
@@ -520,11 +509,9 @@ describe("OpenAPI non-JSON request body dispatch", () => {
520509 } ) ,
521510 ) ;
522511
523- yield * executor . openapi . addSpec ( {
524- spec : specJson ,
512+ yield * addOpenApiTestSource ( executor , server , {
525513 scope : TEST_SCOPE ,
526514 namespace : "fe" ,
527- baseUrl,
528515 } ) ;
529516
530517 yield * executor . tools . invoke (
@@ -544,7 +531,7 @@ describe("OpenAPI non-JSON request body dispatch", () => {
544531
545532 it . effect ( "form-urlencoded deepObject: nested keys use bracket notation" , ( ) =>
546533 Effect . gen ( function * ( ) {
547- const { baseUrl , specJson , captured } = yield * startEchoServer ( {
534+ const { server , captured } = yield * startEchoServer ( {
548535 payload : ObjectBody . pipe ( HttpApiSchema . asFormUrlEncoded ( ) ) ,
549536 transformSpec : replaceRequestBodyContent (
550537 "/submit" ,
@@ -565,11 +552,9 @@ describe("OpenAPI non-JSON request body dispatch", () => {
565552 } ) ,
566553 ) ;
567554
568- yield * executor . openapi . addSpec ( {
569- spec : specJson ,
555+ yield * addOpenApiTestSource ( executor , server , {
570556 scope : TEST_SCOPE ,
571557 namespace : "fd" ,
572- baseUrl,
573558 } ) ;
574559
575560 yield * executor . tools . invoke (
@@ -587,7 +572,7 @@ describe("OpenAPI non-JSON request body dispatch", () => {
587572
588573 it . effect ( "form-urlencoded default: arrays use form+explode=true (repeat key)" , ( ) =>
589574 Effect . gen ( function * ( ) {
590- const { baseUrl , specJson , captured } = yield * startEchoServer ( {
575+ const { server , captured } = yield * startEchoServer ( {
591576 payload : ObjectBody . pipe ( HttpApiSchema . asFormUrlEncoded ( ) ) ,
592577 transformSpec : replaceRequestBodyContent (
593578 "/submit" ,
@@ -606,12 +591,10 @@ describe("OpenAPI non-JSON request body dispatch", () => {
606591 } ) ,
607592 ) ;
608593
609- yield * executor . openapi . addSpec ( {
594+ yield * addOpenApiTestSource ( executor , server , {
610595 // No encoding → OAS3 defaults: style=form, explode=true.
611- spec : specJson ,
612596 scope : TEST_SCOPE ,
613597 namespace : "fdx" ,
614- baseUrl,
615598 } ) ;
616599
617600 yield * executor . tools . invoke (
0 commit comments