@@ -13,36 +13,81 @@ const meetingId = '11111111-2222-4333-8444-555555555555'
1313 * an unrelated read response is attached to a signed reference; malformed wire shapes hide gaps.
1414 */
1515describe ( 'meeting MCP provider wire contracts' , ( ) => {
16- it ( 'finds spoken Fireflies content and continues a full metadata page without inventing modification times' , async ( ) => {
17- const client : ManagedSearchMcpClient = {
18- async call ( name , args ) {
19- if ( name !== 'fireflies_get_transcripts' || args . scope !== 'all' || args . format !== 'json' )
20- throw new Error ( 'Transcript-content search requires all scope and JSON output' )
21- if ( args . skip !== 10 ) throw new Error ( 'Wrong continuation offset' )
22- return {
23- transcripts : [
16+ it . each ( [ 'bare array' , 'data array' , 'transcripts' , 'nested transcripts' ] as const ) (
17+ 'finds spoken Fireflies content and continues a %s page without inventing modification times' ,
18+ async ( shape ) => {
19+ const client : ManagedSearchMcpClient = {
20+ async call ( name , args ) {
21+ if (
22+ name !== 'fireflies_get_transcripts' ||
23+ args . scope !== 'all' ||
24+ args . format !== 'json'
25+ )
26+ throw new Error ( 'Transcript-content search requires all scope and JSON output' )
27+ if ( args . skip !== 10 ) throw new Error ( 'Wrong continuation offset' )
28+ const transcripts = [
2429 {
2530 id : 'meeting-1' ,
2631 title : 'Planning' ,
2732 date : 1788220800000 ,
2833 summary : { overview : 'Launch in September' } ,
2934 } ,
3035 { id : 'meeting-2' , title : 'Next match' } ,
36+ ]
37+ if ( shape === 'bare array' ) return transcripts
38+ if ( shape === 'data array' ) return { data : transcripts }
39+ if ( shape === 'nested transcripts' ) return { data : { transcripts } }
40+ return { transcripts }
41+ } ,
42+ }
43+ const result = await searchFirefliesMcp ( client , {
44+ ...input ,
45+ limit : 1 ,
46+ native : { provider : 'fireflies' , query : 'launch' , cursor : '10' } ,
47+ } )
48+ expect ( result . documents ) . toHaveLength ( 1 )
49+ expect ( result . documents [ 0 ] ) . toMatchObject ( {
50+ id : 'meeting-1' ,
51+ eventStartAt : '2026-09-01T00:00:00.000Z' ,
52+ } )
53+ expect ( result . documents [ 0 ] ?. modifiedAt ) . toBeUndefined ( )
54+ expect ( result . nextCursor ) . toBe ( '11' )
55+ expect ( result . partial ) . toBe ( false )
56+ }
57+ )
58+
59+ it ( 'returns an empty Fireflies data page without reporting unavailable' , async ( ) => {
60+ const client : ManagedSearchMcpClient = {
61+ async call ( ) {
62+ return { data : [ ] }
63+ } ,
64+ }
65+ const result = await searchFirefliesMcp ( client , input )
66+ expect ( result . documents ) . toEqual ( [ ] )
67+ expect ( result . nextCursor ) . toBeUndefined ( )
68+ expect ( result . partial ) . toBe ( false )
69+ } )
70+
71+ it ( 'keeps partial coverage and provider offsets when a Fireflies data page has invalid rows' , async ( ) => {
72+ const client : ManagedSearchMcpClient = {
73+ async call ( ) {
74+ return {
75+ data : [
76+ { id : '../invalid' , title : 'Invalid meeting' } ,
77+ { id : 'meeting-1' , title : 'Planning' } ,
78+ { id : 'meeting-2' , title : 'Next match' } ,
3179 ] ,
3280 }
3381 } ,
3482 }
3583 const result = await searchFirefliesMcp ( client , {
3684 ...input ,
37- limit : 1 ,
85+ limit : 2 ,
3886 native : { provider : 'fireflies' , query : 'launch' , cursor : '10' } ,
3987 } )
40- expect ( result . documents [ 0 ] ) . toMatchObject ( {
41- id : 'meeting-1' ,
42- eventStartAt : '2026-09-01T00:00:00.000Z' ,
43- } )
44- expect ( result . documents [ 0 ] ?. modifiedAt ) . toBeUndefined ( )
45- expect ( result . nextCursor ) . toBe ( '11' )
88+ expect ( result . documents . map ( ( document ) => document . id ) ) . toEqual ( [ 'meeting-1' ] )
89+ expect ( result . nextCursor ) . toBe ( '12' )
90+ expect ( result . partial ) . toBe ( true )
4691 } )
4792
4893 it ( 'keeps meetings earlier on a partial UTC end day and omits keyword scope from termless listings' , async ( ) => {
@@ -149,14 +194,26 @@ describe('meeting MCP provider wire contracts', () => {
149194 expect ( document . content ) . toContain ( transcript )
150195 } )
151196
152- it ( 'fails on unknown Fireflies list formats rather than claiming zero matches' , async ( ) => {
153- const client = {
154- async call ( ) {
155- return { answer : 'No matching meetings' }
156- } ,
197+ it . each ( [
198+ { shape : 'unknown' , response : { answer : 'No matching meetings' } } ,
199+ { shape : 'null data' , response : { data : null } } ,
200+ { shape : 'text data' , response : { data : '[]' } } ,
201+ { shape : 'object data' , response : { data : { } } } ,
202+ {
203+ shape : 'malformed transcripts with a data array' ,
204+ response : { transcripts : 'invalid' , data : [ ] } ,
205+ } ,
206+ ] ) (
207+ 'rejects $shape Fireflies list formats rather than claiming zero matches' ,
208+ async ( { response } ) => {
209+ const client : ManagedSearchMcpClient = {
210+ async call ( ) {
211+ return response
212+ } ,
213+ }
214+ await expect ( searchFirefliesMcp ( client , input ) ) . rejects . toThrow ( 'unsupported' )
157215 }
158- await expect ( searchFirefliesMcp ( client , input ) ) . rejects . toThrow ( 'unsupported' )
159- } )
216+ )
160217
161218 it . each ( [ 'text' , 'json' , 'code_fence' , 'oversized' ] as const ) (
162219 'diagnoses unsupported Fireflies %s envelopes without logging private values or arbitrary keys' ,
0 commit comments