@@ -107,6 +107,25 @@ function expectRequestCall(
107107 }
108108}
109109
110+ function schemaForAction (
111+ schema : unknown ,
112+ action : string ,
113+ ) : { properties ?: Record < string , unknown > } {
114+ const variants =
115+ ( schema as { anyOf ?: unknown [ ] ; oneOf ?: unknown [ ] } ) . anyOf ??
116+ ( schema as { anyOf ?: unknown [ ] ; oneOf ?: unknown [ ] } ) . oneOf ??
117+ [ ] ;
118+ const variant = variants . find ( ( entry ) => {
119+ const actionSchema = ( entry as { properties ?: { action ?: { const ?: unknown } } } ) . properties
120+ ?. action ;
121+ return actionSchema ?. const === action ;
122+ } ) ;
123+ if ( ! variant ) {
124+ throw new Error ( `Missing schema variant for action ${ action } ` ) ;
125+ }
126+ return variant as { properties ?: Record < string , unknown > } ;
127+ }
128+
110129describe ( "registerFeishuDriveTools" , ( ) => {
111130 const requestMock = vi . fn ( ) ;
112131
@@ -360,6 +379,60 @@ describe("registerFeishuDriveTools", () => {
360379 expect ( ( replyCommentResult . details as { reply_id ?: string } ) . reply_id ) . toBe ( "r4" ) ;
361380 } ) ;
362381
382+ it ( "lists a folder continuation page when page_token is provided" , async ( ) => {
383+ const registerTool = vi . fn ( ) ;
384+ const listFiles = vi . fn ( ) . mockResolvedValue ( {
385+ code : 0 ,
386+ data : {
387+ files : [ { token : "file_1" , name : "File 1" , type : "docx" , url : "https://example.test/doc" } ] ,
388+ next_page_token : "page-3" ,
389+ } ,
390+ } ) ;
391+ createFeishuToolClientMock . mockReturnValue ( {
392+ drive : { file : { list : listFiles } } ,
393+ } ) ;
394+ registerFeishuDriveTools (
395+ createDriveToolApi ( {
396+ config : {
397+ channels : {
398+ feishu : {
399+ enabled : true ,
400+ appId : "app_id" ,
401+ appSecret : "app_secret" , // pragma: allowlist secret
402+ tools : { drive : true } ,
403+ } ,
404+ } ,
405+ } ,
406+ registerTool,
407+ } ) ,
408+ ) ;
409+
410+ const toolFactory = firstToolFactory ( registerTool ) ;
411+ const tool = toolFactory ( { agentAccountId : undefined } ) ;
412+ const listSchema = schemaForAction ( ( tool as { parameters ?: unknown } ) . parameters , "list" ) ;
413+ expect ( listSchema . properties ?. page_token ) . toMatchObject ( { type : "string" } ) ;
414+ expect ( listSchema . properties ?. page_size ) . toMatchObject ( {
415+ type : "integer" ,
416+ minimum : 1 ,
417+ maximum : 200 ,
418+ } ) ;
419+
420+ const result = await tool . execute ( "call-list-page-2" , {
421+ action : "list" ,
422+ folder_token : "folder_1" ,
423+ page_size : 25 ,
424+ page_token : "page-2" ,
425+ } ) ;
426+
427+ expect ( listFiles ) . toHaveBeenCalledWith ( {
428+ params : { folder_token : "folder_1" , page_size : 25 , page_token : "page-2" } ,
429+ } ) ;
430+ expect ( result . details ) . toMatchObject ( {
431+ files : [ { token : "file_1" , name : "File 1" , type : "docx" , url : "https://example.test/doc" } ] ,
432+ next_page_token : "page-3" ,
433+ } ) ;
434+ } ) ;
435+
363436 it ( "defaults add_comment file_type to docx when omitted" , async ( ) => {
364437 const registerTool = vi . fn ( ) ;
365438 const infoSpy = vi . spyOn ( console , "info" ) . mockImplementation ( ( ) => { } ) ;
0 commit comments