11/** @vitest -environment node */
22import { beforeEach , describe , expect , it , vi } from 'vitest'
33
4- const { read, mint } = vi . hoisted ( ( ) => ( { read : vi . fn ( ) , mint : vi . fn ( ) } ) )
4+ const { read, mint, fetchBootstrap, baseURL } = vi . hoisted ( ( ) => ( {
5+ read : vi . fn ( ) ,
6+ mint : vi . fn ( ) ,
7+ fetchBootstrap : vi . fn ( ) ,
8+ baseURL : vi . fn ( ) ,
9+ } ) )
510vi . mock ( 'node:fs/promises' , ( ) => ( { readFile : read } ) )
611vi . mock ( '@/lib/mothership/chat/delegation' , ( ) => ( { mintDelegationToken : mint } ) )
712vi . mock ( '@/lib/core/config/env' , ( ) => ( {
813 env : { MOTHERSHIP_SANDBOX_CLI_ENDPOINT : 'https://sim.test' } ,
914} ) )
1015vi . mock ( '@/lib/core/utils/urls' , ( ) => ( { getBaseUrl : ( ) => 'https://unused.test' } ) )
16+ vi . mock ( '@/lib/mothership/request/go/fetch' , ( ) => ( { fetchGo : fetchBootstrap } ) )
17+ vi . mock ( '@/lib/mothership/request/headers' , ( ) => ( {
18+ mothershipRequestHeaders : ( ) => ( { 'x-api-key' : 'worker-test-key' } ) ,
19+ } ) )
20+ vi . mock ( '@/lib/mothership/server/agent-url' , ( ) => ( { getMothershipBaseURL : baseURL } ) )
1121
1222import { buildMothershipSandboxSession } from '@/lib/mothership/tools/sandbox-session'
1323
@@ -17,16 +27,30 @@ describe('deployment-owned workbench tooling', () => {
1727 beforeEach ( ( ) => {
1828 vi . resetAllMocks ( )
1929 mint . mockResolvedValue ( 'test-delegation' )
30+ baseURL . mockResolvedValue ( 'https://worker.test' )
31+ fetchBootstrap . mockImplementation ( async ( ) =>
32+ Response . json ( { version : 1 , entrypoint : 'private-entry' } )
33+ )
2034 } )
2135
2236 it ( 'stages the current deployment bundle and keeps credentials out of installed files' , async ( ) => {
2337 read . mockResolvedValueOnce ( 'bundle-one' ) . mockResolvedValueOnce ( 'bundle-two' )
2438 const first = await buildMothershipSandboxSession ( request )
2539 const second = await buildMothershipSandboxSession ( request )
2640 expect ( first . cli ) . toMatchObject ( {
27- content : 'bundle-one ' ,
41+ content : 'private-entry ' ,
2842 path : expect . stringMatching ( / ^ \/ h o m e \/ u s e r \/ \. s i m - c l i \/ [ a - f 0 - 9 ] { 64 } \/ c l i \. m j s $ / ) ,
43+ runtime : { content : 'bundle-one' , path : expect . stringMatching ( / \/ r u n t i m e \. m j s $ / ) } ,
2944 } )
45+ expect ( read ) . toHaveBeenCalledWith ( expect . stringContaining ( '/dist/runtime.js' ) , 'utf8' )
46+ expect ( baseURL ) . toHaveBeenCalledWith ( { userId : 'user' } )
47+ expect ( fetchBootstrap ) . toHaveBeenCalledWith (
48+ 'https://worker.test/api/workbench/bootstrap' ,
49+ expect . objectContaining ( {
50+ headers : { 'x-api-key' : 'worker-test-key' } ,
51+ redirect : 'error' ,
52+ } )
53+ )
3054 expect ( second . cli ?. path ) . not . toBe ( first . cli ?. path )
3155 expect ( JSON . stringify ( first . cli ) ) . not . toContain ( 'test-delegation' )
3256 expect ( first . envs ) . toEqual ( {
@@ -41,4 +65,34 @@ describe('deployment-owned workbench tooling', () => {
4165 await expect ( buildMothershipSandboxSession ( request ) ) . rejects . toThrow ( 'missing workbench bundle' )
4266 expect ( mint ) . not . toHaveBeenCalled ( )
4367 } )
68+
69+ it ( 'pins both policy and runtime versions and refuses unavailable or malformed private bootstrap' , async ( ) => {
70+ read . mockResolvedValue ( 'same-public-runtime' )
71+ const first = await buildMothershipSandboxSession ( request )
72+ fetchBootstrap . mockResolvedValueOnce (
73+ Response . json ( { version : 1 , entrypoint : 'private-entry-v2' } )
74+ )
75+ const second = await buildMothershipSandboxSession ( request )
76+ expect ( second . cli ?. path ) . not . toBe ( first . cli ?. path )
77+ for ( const response of [
78+ new Response ( 'Unavailable' , { status : 503 } ) ,
79+ Response . json ( { version : 2 , entrypoint : 'unknown' } ) ,
80+ ] ) {
81+ mint . mockClear ( )
82+ fetchBootstrap . mockResolvedValueOnce ( response )
83+ await expect ( buildMothershipSandboxSession ( request ) ) . rejects . toThrow ( )
84+ expect ( mint ) . not . toHaveBeenCalled ( )
85+ }
86+ } )
87+
88+ it ( 'cancels private bootstrap loading before provider or credential work' , async ( ) => {
89+ const controller = new AbortController ( )
90+ controller . abort ( new Error ( 'Stopped' ) )
91+ await expect (
92+ buildMothershipSandboxSession ( { ...request , signal : controller . signal } )
93+ ) . rejects . toThrow ( 'Stopped' )
94+ expect ( read ) . not . toHaveBeenCalled ( )
95+ expect ( fetchBootstrap ) . not . toHaveBeenCalled ( )
96+ expect ( mint ) . not . toHaveBeenCalled ( )
97+ } )
4498} )
0 commit comments