@@ -85,26 +85,51 @@ describe('W&B Inference generation', () => {
8585 } ) ;
8686
8787 it ( 'supports text-style choices from compatible responses' , async ( ) => {
88- vi . stubGlobal ( 'fetch' , vi . fn ( ) . mockResolvedValue ( {
88+ const fetchMock = vi . fn ( ) . mockResolvedValue ( {
8989 ok : true ,
9090 json : async ( ) => ( {
9191 choices : [ { text : 'legacy text response' } ] ,
9292 } ) ,
93- } ) ) ;
93+ } ) ;
94+ vi . stubGlobal ( 'fetch' , fetchMock ) ;
9495
9596 const result = await adapter . generate (
9697 ctx ( ) ,
9798 'hello' ,
9899 { model : 'deepseek-ai/DeepSeek-V3-0324' } ,
99- { baseUrl : 'https://wandb.test/v1' } ,
100+ { baseUrl : 'https://wandb.test/v1/ ' } ,
100101 ) ;
101102
103+ expect ( fetchMock . mock . calls [ 0 ] ?. [ 0 ] ) . toBe ( 'https://wandb.test/v1/chat/completions' ) ;
102104 expect ( result ) . toEqual ( {
103105 text : 'legacy text response' ,
104106 model : 'deepseek-ai/DeepSeek-V3-0324' ,
105107 } ) ;
106108 } ) ;
107109
110+ it ( 'rejects invalid or unclean custom base URLs before network calls' , async ( ) => {
111+ const fetchMock = vi . fn ( ) ;
112+ vi . stubGlobal ( 'fetch' , fetchMock ) ;
113+
114+ await expect (
115+ adapter . generate ( ctx ( ) , 'hello' , { } , { baseUrl : 'wandb.test/v1' } ) ,
116+ ) . rejects . toThrow ( 'valid URL' ) ;
117+ await expect (
118+ adapter . generate ( ctx ( ) , 'hello' , { } , { baseUrl : 'ftp://wandb.test/v1' } ) ,
119+ ) . rejects . toThrow ( 'http or https' ) ;
120+ await expect (
121+ adapter . generate ( ctx ( ) , 'hello' , { } , { baseUrl : 'https://user:pass@wandb.test/v1' } ) ,
122+ ) . rejects . toThrow ( 'clean API base' ) ;
123+ await expect (
124+ adapter . generate ( ctx ( ) , 'hello' , { } , { baseUrl : 'https://wandb.test/v1?target=chat' } ) ,
125+ ) . rejects . toThrow ( 'clean API base' ) ;
126+ await expect (
127+ adapter . generate ( ctx ( ) , 'hello' , { } , { baseUrl : 'https://wandb.test/v1#chat' } ) ,
128+ ) . rejects . toThrow ( 'clean API base' ) ;
129+
130+ expect ( fetchMock ) . not . toHaveBeenCalled ( ) ;
131+ } ) ;
132+
108133 it ( 'includes status and response body excerpt on errors' , async ( ) => {
109134 vi . stubGlobal ( 'fetch' , vi . fn ( ) . mockResolvedValue ( {
110135 ok : false ,
0 commit comments