@@ -26,7 +26,7 @@ describe('Custom Integrations Module', () => {
2626
2727 test ( 'custom.call() should convert camelCase params to snake_case for backend' , async ( ) => {
2828 const slug = 'github' ;
29- const operationId = 'listIssues ' ;
29+ const operationId = 'get:/repos/{owner}/{repo}/issues ' ;
3030
3131 // SDK call uses camelCase (JS convention)
3232 const sdkParams = {
@@ -48,9 +48,10 @@ describe('Custom Integrations Module', () => {
4848 data : { issues : [ { id : 1 , title : 'Test Issue' } ] } ,
4949 } ;
5050
51- // Mock expects snake_case body
51+ // Mock expects snake_case body (curly braces in operationId must be URL-encoded for nock matching)
52+ const encodedOperationId = operationId . replace ( / { / g, '%7B' ) . replace ( / } / g, '%7D' ) ;
5253 scope
53- . post ( `/api/apps/${ appId } /integrations/custom/${ slug } /${ operationId } ` , expectedBody )
54+ . post ( `/api/apps/${ appId } /integrations/custom/${ slug } /${ encodedOperationId } ` , expectedBody )
5455 . reply ( 200 , mockResponse ) ;
5556
5657 // SDK call uses camelCase
@@ -135,11 +136,12 @@ describe('Custom Integrations Module', () => {
135136
136137 test ( 'custom.call() should handle 502 error from external API' , async ( ) => {
137138 const slug = 'github' ;
138- const operationId = 'listIssues ' ;
139+ const operationId = 'get:/repos/{owner}/{repo}/issues ' ;
139140
140- // Mock a 502 error response (external API failure)
141+ // Mock a 502 error response (external API failure) - curly braces in operationId must be URL-encoded
142+ const encodedOperationId = operationId . replace ( / { / g, '%7B' ) . replace ( / } / g, '%7D' ) ;
141143 scope
142- . post ( `/api/apps/${ appId } /integrations/custom/${ slug } /${ operationId } ` , { } )
144+ . post ( `/api/apps/${ appId } /integrations/custom/${ slug } /${ encodedOperationId } ` , { } )
143145 . reply ( 502 , {
144146 detail : 'Failed to connect to external API: Connection refused' ,
145147 } ) ;
@@ -169,13 +171,13 @@ describe('Custom Integrations Module', () => {
169171 } ) ;
170172
171173 test ( 'custom.call() should throw error when slug is empty string' , async ( ) => {
172- await expect ( base44 . integrations . custom . call ( '' , 'listIssues ' ) ) . rejects . toThrow (
174+ await expect ( base44 . integrations . custom . call ( '' , 'get:/repos/{owner}/{repo}/issues ' ) ) . rejects . toThrow (
173175 'Integration slug is required and cannot be empty'
174176 ) ;
175177 } ) ;
176178
177179 test ( 'custom.call() should throw error when slug is whitespace only' , async ( ) => {
178- await expect ( base44 . integrations . custom . call ( ' ' , 'listIssues ' ) ) . rejects . toThrow (
180+ await expect ( base44 . integrations . custom . call ( ' ' , 'get:/repos/{owner}/{repo}/issues ' ) ) . rejects . toThrow (
179181 'Integration slug is required and cannot be empty'
180182 ) ;
181183 } ) ;
@@ -294,7 +296,7 @@ describe('Custom Integrations Module', () => {
294296
295297 test ( 'custom.call() should only include defined params in body' , async ( ) => {
296298 const slug = 'github' ;
297- const operationId = 'getUser ' ;
299+ const operationId = 'get:/users/{username} ' ;
298300
299301 // SDK call with only pathParams
300302 const sdkParams = {
@@ -312,8 +314,10 @@ describe('Custom Integrations Module', () => {
312314 data : { login : 'octocat' } ,
313315 } ;
314316
317+ // Curly braces in operationId must be URL-encoded for nock matching
318+ const encodedOperationId = operationId . replace ( / { / g, '%7B' ) . replace ( / } / g, '%7D' ) ;
315319 scope
316- . post ( `/api/apps/${ appId } /integrations/custom/${ slug } /${ operationId } ` , expectedBody )
320+ . post ( `/api/apps/${ appId } /integrations/custom/${ slug } /${ encodedOperationId } ` , expectedBody )
317321 . reply ( 200 , mockResponse ) ;
318322
319323 const result = await base44 . integrations . custom . call ( slug , operationId , sdkParams ) ;
0 commit comments