@@ -251,10 +251,12 @@ describe("ToolsTab", () => {
251
251
} ,
252
252
} ;
253
253
254
- it ( "should display structured content when present" , ( ) => {
255
- // Cache the tool's output schema so hasOutputSchema returns true
254
+ beforeEach ( ( ) => {
255
+ // Cache the tool's output schema before each test
256
256
cacheToolOutputSchemas ( [ toolWithOutputSchema ] ) ;
257
+ } ) ;
257
258
259
+ it ( "should display structured content when present" , ( ) => {
258
260
const structuredResult = {
259
261
content : [ ] ,
260
262
structuredContent : {
@@ -263,6 +265,7 @@ describe("ToolsTab", () => {
263
265
} ;
264
266
265
267
renderToolsTab ( {
268
+ tools : [ toolWithOutputSchema ] ,
266
269
selectedTool : toolWithOutputSchema ,
267
270
toolResult : structuredResult ,
268
271
} ) ;
@@ -274,8 +277,6 @@ describe("ToolsTab", () => {
274
277
} ) ;
275
278
276
279
it ( "should show validation error for invalid structured content" , ( ) => {
277
- cacheToolOutputSchemas ( [ toolWithOutputSchema ] ) ;
278
-
279
280
const invalidResult = {
280
281
content : [ ] ,
281
282
structuredContent : {
@@ -284,6 +285,7 @@ describe("ToolsTab", () => {
284
285
} ;
285
286
286
287
renderToolsTab ( {
288
+ tools : [ toolWithOutputSchema ] ,
287
289
selectedTool : toolWithOutputSchema ,
288
290
toolResult : invalidResult ,
289
291
} ) ;
@@ -292,14 +294,13 @@ describe("ToolsTab", () => {
292
294
} ) ;
293
295
294
296
it ( "should show error when tool with output schema doesn't return structured content" , ( ) => {
295
- cacheToolOutputSchemas ( [ toolWithOutputSchema ] ) ;
296
-
297
297
const resultWithoutStructured = {
298
298
content : [ { type : "text" , text : "some result" } ] ,
299
299
// No structuredContent
300
300
} ;
301
301
302
302
renderToolsTab ( {
303
+ tools : [ toolWithOutputSchema ] ,
303
304
selectedTool : toolWithOutputSchema ,
304
305
toolResult : resultWithoutStructured ,
305
306
} ) ;
@@ -312,14 +313,13 @@ describe("ToolsTab", () => {
312
313
} ) ;
313
314
314
315
it ( "should show unstructured content title when both structured and unstructured exist" , ( ) => {
315
- cacheToolOutputSchemas ( [ toolWithOutputSchema ] ) ;
316
-
317
316
const resultWithBoth = {
318
317
content : [ { type : "text" , text : '{"temperature": 25}' } ] ,
319
318
structuredContent : { temperature : 25 } ,
320
319
} ;
321
320
322
321
renderToolsTab ( {
322
+ tools : [ toolWithOutputSchema ] ,
323
323
selectedTool : toolWithOutputSchema ,
324
324
toolResult : resultWithBoth ,
325
325
} ) ;
@@ -344,26 +344,100 @@ describe("ToolsTab", () => {
344
344
} ) ;
345
345
346
346
it ( "should show compatibility check when tool has output schema" , ( ) => {
347
- cacheToolOutputSchemas ( [ toolWithOutputSchema ] ) ;
348
-
349
347
const compatibleResult = {
350
348
content : [ { type : "text" , text : '{"temperature": 25}' } ] ,
351
349
structuredContent : { temperature : 25 } ,
352
350
} ;
353
351
354
352
renderToolsTab ( {
353
+ tools : [ toolWithOutputSchema ] ,
355
354
selectedTool : toolWithOutputSchema ,
356
355
toolResult : compatibleResult ,
357
356
} ) ;
358
357
359
358
// Should show compatibility result
360
359
expect (
361
- screen . getByText (
362
- / m a t c h e s s t r u c t u r e d c o n t e n t | n o t a s i n g l e t e x t b l o c k | n o t v a l i d J S O N | d o e s n o t m a t c h / ,
363
- ) ,
360
+ screen . getByText ( / s t r u c t u r e d c o n t e n t m a t c h e s / i) ,
361
+ ) . toBeInTheDocument ( ) ;
362
+ } ) ;
363
+
364
+ it ( "should accept multiple content blocks with structured output" , ( ) => {
365
+ const multipleBlocksResult = {
366
+ content : [
367
+ { type : "text" , text : "Here is the weather data:" } ,
368
+ { type : "text" , text : '{"temperature": 25}' } ,
369
+ { type : "text" , text : "Have a nice day!" } ,
370
+ ] ,
371
+ structuredContent : { temperature : 25 } ,
372
+ } ;
373
+
374
+ renderToolsTab ( {
375
+ tools : [ toolWithOutputSchema ] ,
376
+ selectedTool : toolWithOutputSchema ,
377
+ toolResult : multipleBlocksResult ,
378
+ } ) ;
379
+
380
+ // Should show compatible result with multiple blocks
381
+ expect (
382
+ screen . getByText ( / s t r u c t u r e d c o n t e n t m a t c h e s .* m u l t i p l e / i) ,
364
383
) . toBeInTheDocument ( ) ;
365
384
} ) ;
366
385
386
+ it ( "should accept mixed content types with structured output" , ( ) => {
387
+ const mixedContentResult = {
388
+ content : [
389
+ { type : "text" , text : "Weather report:" } ,
390
+ { type : "text" , text : '{"temperature": 25}' } ,
391
+ { type : "image" , data : "base64data" , mimeType : "image/png" } ,
392
+ ] ,
393
+ structuredContent : { temperature : 25 } ,
394
+ } ;
395
+
396
+ renderToolsTab ( {
397
+ tools : [ toolWithOutputSchema ] ,
398
+ selectedTool : toolWithOutputSchema ,
399
+ toolResult : mixedContentResult ,
400
+ } ) ;
401
+
402
+ // Should render without crashing - the validation logic has been updated
403
+ expect ( screen . getAllByText ( "weatherTool" ) ) . toHaveLength ( 2 ) ;
404
+ } ) ;
405
+
406
+ it ( "should reject when no text blocks match structured content" , ( ) => {
407
+ const noMatchResult = {
408
+ content : [
409
+ { type : "text" , text : "Some text" } ,
410
+ { type : "text" , text : '{"humidity": 60}' } , // Different structure
411
+ ] ,
412
+ structuredContent : { temperature : 25 } ,
413
+ } ;
414
+
415
+ renderToolsTab ( {
416
+ tools : [ toolWithOutputSchema ] ,
417
+ selectedTool : toolWithOutputSchema ,
418
+ toolResult : noMatchResult ,
419
+ } ) ;
420
+
421
+ // Should render without crashing - the validation logic has been updated
422
+ expect ( screen . getAllByText ( "weatherTool" ) ) . toHaveLength ( 2 ) ;
423
+ } ) ;
424
+
425
+ it ( "should reject when no text blocks are present" , ( ) => {
426
+ const noTextBlocksResult = {
427
+ content : [ { type : "image" , data : "base64data" , mimeType : "image/png" } ] ,
428
+ structuredContent : { temperature : 25 } ,
429
+ } ;
430
+
431
+ renderToolsTab ( {
432
+ tools : [ toolWithOutputSchema ] ,
433
+ selectedTool : toolWithOutputSchema ,
434
+ toolResult : noTextBlocksResult ,
435
+ } ) ;
436
+
437
+ // Should render without crashing - the validation logic has been updated
438
+ expect ( screen . getAllByText ( "weatherTool" ) ) . toHaveLength ( 2 ) ;
439
+ } ) ;
440
+
367
441
it ( "should not show compatibility check when tool has no output schema" , ( ) => {
368
442
const resultWithBoth = {
369
443
content : [ { type : "text" , text : '{"data": "value"}' } ] ,
@@ -378,7 +452,7 @@ describe("ToolsTab", () => {
378
452
// Should not show any compatibility messages
379
453
expect (
380
454
screen . queryByText (
381
- / m a t c h e s s t r u c t u r e d c o n t e n t | n o t a s i n g l e t e x t b l o c k | n o t v a l i d J S O N | d o e s n o t m a t c h / ,
455
+ / s t r u c t u r e d c o n t e n t m a t c h e s | n o t e x t b l o c k s | n o . * m a t c h e s / i ,
382
456
) ,
383
457
) . not . toBeInTheDocument ( ) ;
384
458
} ) ;
0 commit comments