@@ -5,25 +5,51 @@ const request = { target_repo: "owner/repo", workload: { id: "run-1", label: "Up
55const publicationFiles = [ { path : "README.md" , mode : "100644" , content : Buffer . from ( "changed\n" ) . toString ( "base64" ) , deleted : false } ]
66
77function response ( status , body ) { return { ok : status >= 200 && status < 300 , status, json : async ( ) => body } }
8- function fetchMock ( existing = false ) {
8+ function fetchMock ( existing = false , base = "main" , defaultBranch ) {
99 const calls = [ ]
1010 return { calls, fetch : async ( url , init ) => {
1111 calls . push ( [ url , init . method , init . body ? JSON . parse ( init . body ) : undefined ] )
1212 const parsed = new URL ( url )
1313 const path = parsed . pathname . replace ( "/repos/owner/repo" , "" )
14- if ( path === "/git/ref/heads/main" ) return response ( 200 , { object : { sha : "base" } } )
14+ if ( path === "" ) return response ( 200 , { default_branch : defaultBranch } )
15+ if ( path === `/git/ref/heads/${ base } ` ) return response ( 200 , { object : { sha : "base" } } )
1516 if ( path === "/git/commits/base" || path === "/git/commits/old" ) return response ( 200 , { tree : { sha : path . endsWith ( "old" ) ? "prior-tree" : "tree" } } )
1617 if ( path . includes ( "/git/ref/heads/wp-codebox/agent-task/run-1" ) ) return existing ? response ( 200 , { object : { sha : "old" } } ) : response ( 404 , { } )
1718 if ( path === "/git/blobs" ) return response ( 201 , { sha : "blob" } )
1819 if ( path === "/git/trees" ) return response ( 201 , { sha : "next-tree" } )
1920 if ( path === "/git/commits" ) return response ( 201 , { sha : "commit" } )
2021 if ( path === "/git/refs" ) return response ( 201 , { } )
2122 if ( path . includes ( "/git/refs/heads/" ) ) return response ( 200 , { } )
22- if ( path === "/pulls" && parsed . search ) return response ( 200 , existing ? [ { number : 4 , html_url : "https://github.com/owner/repo/pull/4" , base : { repo : { full_name : "owner/repo" } , ref : "main" } , head : { ref : "wp-codebox/agent-task/run-1" } } ] : [ ] )
23- if ( path === "/pulls" ) return response ( 201 , { number : 5 , html_url : "https://github.com/owner/repo/pull/5" , base : { repo : { full_name : "owner/repo" } , ref : "main" } , head : { ref : "wp-codebox/agent-task/run-1" } } )
23+ if ( path === "/pulls" && parsed . search ) return response ( 200 , existing ? [ { number : 4 , html_url : "https://github.com/owner/repo/pull/4" , base : { repo : { full_name : "owner/repo" } , ref : base } , head : { ref : "wp-codebox/agent-task/run-1" } } ] : [ ] )
24+ if ( path === "/pulls" ) return response ( 201 , { number : 5 , html_url : "https://github.com/owner/repo/pull/5" , base : { repo : { full_name : "owner/repo" } , ref : base } , head : { ref : "wp-codebox/agent-task/run-1" } } )
2425 throw new Error ( `unexpected ${ path } ` )
2526 } }
2627}
28+ {
29+ const nonMainRequest = { ...request , runner_workspace : { ...request . runner_workspace , base : "release" , base_branch : "legacy" } }
30+ const mock = fetchMock ( false , "release" )
31+ const result = await publishRunnerWorkspace ( { request : nonMainRequest , changedFiles : [ "README.md" ] , publicationFiles, token : "secret" , fetchImpl : mock . fetch } )
32+ assert . equal ( result . branch . base , "release" , "explicit base must remain authoritative" )
33+ assert ( ! mock . calls . some ( ( [ url ] ) => new URL ( url ) . pathname === "/repos/owner/repo" ) , "explicit base must not look up repository metadata" )
34+ }
35+ {
36+ const aliasRequest = { ...request , runner_workspace : { ...request . runner_workspace , base : undefined , base_branch : "stable" } }
37+ const mock = fetchMock ( false , "stable" )
38+ const result = await publishRunnerWorkspace ( { request : aliasRequest , changedFiles : [ "README.md" ] , publicationFiles, token : "secret" , fetchImpl : mock . fetch } )
39+ assert . equal ( result . branch . base , "stable" , "base_branch remains a supported base alias" )
40+ assert ( ! mock . calls . some ( ( [ url ] ) => new URL ( url ) . pathname === "/repos/owner/repo" ) , "base_branch must not look up repository metadata" )
41+ }
42+ {
43+ const metadataRequest = { ...request , runner_workspace : { ...request . runner_workspace , base : undefined , base_branch : undefined } }
44+ const mock = fetchMock ( false , "trunk" , "trunk" )
45+ const result = await publishRunnerWorkspace ( { request : metadataRequest , changedFiles : [ "README.md" ] , publicationFiles, token : "secret" , fetchImpl : mock . fetch } )
46+ assert . equal ( result . branch . base , "trunk" , "omitted base must use the repository default branch" )
47+ assert ( mock . calls . some ( ( [ url ] ) => new URL ( url ) . pathname === "/repos/owner/repo" ) , "omitted base must look up repository metadata" )
48+ }
49+ for ( const defaultBranch of [ undefined , "invalid branch" ] ) {
50+ const metadataRequest = { ...request , runner_workspace : { ...request . runner_workspace , base : undefined , base_branch : undefined } }
51+ await assert . rejects ( ( ) => publishRunnerWorkspace ( { request : metadataRequest , changedFiles : [ "README.md" ] , publicationFiles, token : "secret" , fetchImpl : fetchMock ( false , "main" , defaultBranch ) . fetch } ) , / m e t a d a t a m u s t p r o v i d e a v a l i d d e f a u l t b r a n c h / )
52+ }
2753
2854{
2955 const mock = fetchMock ( false )
0 commit comments