1+ // npx jest src/components/chat/__tests__/ChatView.test.tsx
2+
13import React from "react"
24import { render , waitFor , act } from "@testing-library/react"
3- import ChatView from "../ChatView"
5+ import { QueryClient , QueryClientProvider } from "@tanstack/react-query"
6+
47import { ExtensionStateContextProvider } from "@src/context/ExtensionStateContext"
58import { vscode } from "@src/utils/vscode"
69
10+ import ChatView , { ChatViewProps } from "../ChatView"
11+
712// Define minimal types needed for testing
813interface ClineMessage {
914 type : "say" | "ask"
@@ -85,13 +90,6 @@ jest.mock("../ChatTextArea", () => {
8590 }
8691} )
8792
88- jest . mock ( "../TaskHeader" , ( ) => ( {
89- __esModule : true ,
90- default : function MockTaskHeader ( { task } : { task : ClineMessage } ) {
91- return < div data-testid = "task-header" > { JSON . stringify ( task ) } </ div >
92- } ,
93- } ) )
94-
9593// Mock VSCode components
9694jest . mock ( "@vscode/webview-ui-toolkit/react" , ( ) => ( {
9795 VSCodeButton : function MockVSCodeButton ( {
@@ -151,22 +149,30 @@ const mockPostMessage = (state: Partial<ExtensionState>) => {
151149 )
152150}
153151
152+ const defaultProps : ChatViewProps = {
153+ isHidden : false ,
154+ showAnnouncement : false ,
155+ hideAnnouncement : ( ) => { } ,
156+ showHistoryView : ( ) => { } ,
157+ }
158+
159+ const queryClient = new QueryClient ( )
160+
161+ const renderChatView = ( props : Partial < ChatViewProps > = { } ) => {
162+ return render (
163+ < ExtensionStateContextProvider >
164+ < QueryClientProvider client = { queryClient } >
165+ < ChatView { ...defaultProps } { ...props } />
166+ </ QueryClientProvider >
167+ </ ExtensionStateContextProvider > ,
168+ )
169+ }
170+
154171describe ( "ChatView - Auto Approval Tests" , ( ) => {
155- beforeEach ( ( ) => {
156- jest . clearAllMocks ( )
157- } )
172+ beforeEach ( ( ) => jest . clearAllMocks ( ) )
158173
159174 it ( "does not auto-approve any actions when autoApprovalEnabled is false" , ( ) => {
160- render (
161- < ExtensionStateContextProvider >
162- < ChatView
163- isHidden = { false }
164- showAnnouncement = { false }
165- hideAnnouncement = { ( ) => { } }
166- showHistoryView = { ( ) => { } }
167- />
168- </ ExtensionStateContextProvider > ,
169- )
175+ renderChatView ( )
170176
171177 // First hydrate state with initial task
172178 mockPostMessage ( {
@@ -240,16 +246,7 @@ describe("ChatView - Auto Approval Tests", () => {
240246 } )
241247
242248 it ( "auto-approves browser actions when alwaysAllowBrowser is enabled" , async ( ) => {
243- render (
244- < ExtensionStateContextProvider >
245- < ChatView
246- isHidden = { false }
247- showAnnouncement = { false }
248- hideAnnouncement = { ( ) => { } }
249- showHistoryView = { ( ) => { } }
250- />
251- </ ExtensionStateContextProvider > ,
252- )
249+ renderChatView ( )
253250
254251 // First hydrate state with initial task
255252 mockPostMessage ( {
@@ -296,16 +293,7 @@ describe("ChatView - Auto Approval Tests", () => {
296293 } )
297294
298295 it ( "auto-approves read-only tools when alwaysAllowReadOnly is enabled" , async ( ) => {
299- render (
300- < ExtensionStateContextProvider >
301- < ChatView
302- isHidden = { false }
303- showAnnouncement = { false }
304- hideAnnouncement = { ( ) => { } }
305- showHistoryView = { ( ) => { } }
306- />
307- </ ExtensionStateContextProvider > ,
308- )
296+ renderChatView ( )
309297
310298 // First hydrate state with initial task
311299 mockPostMessage ( {
@@ -353,16 +341,7 @@ describe("ChatView - Auto Approval Tests", () => {
353341
354342 describe ( "Write Tool Auto-Approval Tests" , ( ) => {
355343 it ( "auto-approves write tools when alwaysAllowWrite is enabled and message is a tool request" , async ( ) => {
356- render (
357- < ExtensionStateContextProvider >
358- < ChatView
359- isHidden = { false }
360- showAnnouncement = { false }
361- hideAnnouncement = { ( ) => { } }
362- showHistoryView = { ( ) => { } }
363- />
364- </ ExtensionStateContextProvider > ,
365- )
344+ renderChatView ( )
366345
367346 // First hydrate state with initial task
368347 mockPostMessage ( {
@@ -411,16 +390,7 @@ describe("ChatView - Auto Approval Tests", () => {
411390 } )
412391
413392 it ( "does not auto-approve write operations when alwaysAllowWrite is enabled but message is not a tool request" , ( ) => {
414- render (
415- < ExtensionStateContextProvider >
416- < ChatView
417- isHidden = { false }
418- showAnnouncement = { false }
419- hideAnnouncement = { ( ) => { } }
420- showHistoryView = { ( ) => { } }
421- />
422- </ ExtensionStateContextProvider > ,
423- )
393+ renderChatView ( )
424394
425395 // First hydrate state with initial task
426396 mockPostMessage ( {
@@ -466,16 +436,7 @@ describe("ChatView - Auto Approval Tests", () => {
466436 } )
467437
468438 it ( "auto-approves allowed commands when alwaysAllowExecute is enabled" , async ( ) => {
469- render (
470- < ExtensionStateContextProvider >
471- < ChatView
472- isHidden = { false }
473- showAnnouncement = { false }
474- hideAnnouncement = { ( ) => { } }
475- showHistoryView = { ( ) => { } }
476- />
477- </ ExtensionStateContextProvider > ,
478- )
439+ renderChatView ( )
479440
480441 // First hydrate state with initial task
481442 mockPostMessage ( {
@@ -524,16 +485,7 @@ describe("ChatView - Auto Approval Tests", () => {
524485 } )
525486
526487 it ( "does not auto-approve disallowed commands even when alwaysAllowExecute is enabled" , ( ) => {
527- render (
528- < ExtensionStateContextProvider >
529- < ChatView
530- isHidden = { false }
531- showAnnouncement = { false }
532- hideAnnouncement = { ( ) => { } }
533- showHistoryView = { ( ) => { } }
534- />
535- </ ExtensionStateContextProvider > ,
536- )
488+ renderChatView ( )
537489
538490 // First hydrate state with initial task
539491 mockPostMessage ( {
@@ -581,16 +533,7 @@ describe("ChatView - Auto Approval Tests", () => {
581533
582534 describe ( "Command Chaining Tests" , ( ) => {
583535 it ( "auto-approves chained commands when all parts are allowed" , async ( ) => {
584- render (
585- < ExtensionStateContextProvider >
586- < ChatView
587- isHidden = { false }
588- showAnnouncement = { false }
589- hideAnnouncement = { ( ) => { } }
590- showHistoryView = { ( ) => { } }
591- />
592- </ ExtensionStateContextProvider > ,
593- )
536+ renderChatView ( )
594537
595538 // Test various allowed command chaining scenarios
596539 const allowedChainedCommands = [
@@ -656,16 +599,7 @@ describe("ChatView - Auto Approval Tests", () => {
656599 } )
657600
658601 it ( "does not auto-approve chained commands when any part is disallowed" , ( ) => {
659- render (
660- < ExtensionStateContextProvider >
661- < ChatView
662- isHidden = { false }
663- showAnnouncement = { false }
664- hideAnnouncement = { ( ) => { } }
665- showHistoryView = { ( ) => { } }
666- />
667- </ ExtensionStateContextProvider > ,
668- )
602+ renderChatView ( )
669603
670604 // Test various command chaining scenarios with disallowed parts
671605 const disallowedChainedCommands = [
@@ -728,16 +662,7 @@ describe("ChatView - Auto Approval Tests", () => {
728662 } )
729663
730664 it ( "handles complex PowerShell command chains correctly" , async ( ) => {
731- render (
732- < ExtensionStateContextProvider >
733- < ChatView
734- isHidden = { false }
735- showAnnouncement = { false }
736- hideAnnouncement = { ( ) => { } }
737- showHistoryView = { ( ) => { } }
738- />
739- </ ExtensionStateContextProvider > ,
740- )
665+ renderChatView ( )
741666
742667 // Test PowerShell specific command chains
743668 const powershellCommands = {
@@ -849,21 +774,10 @@ describe("ChatView - Auto Approval Tests", () => {
849774} )
850775
851776describe ( "ChatView - Sound Playing Tests" , ( ) => {
852- beforeEach ( ( ) => {
853- jest . clearAllMocks ( )
854- } )
777+ beforeEach ( ( ) => jest . clearAllMocks ( ) )
855778
856779 it ( "does not play sound for auto-approved browser actions" , async ( ) => {
857- render (
858- < ExtensionStateContextProvider >
859- < ChatView
860- isHidden = { false }
861- showAnnouncement = { false }
862- hideAnnouncement = { ( ) => { } }
863- showHistoryView = { ( ) => { } }
864- />
865- </ ExtensionStateContextProvider > ,
866- )
780+ renderChatView ( )
867781
868782 // First hydrate state with initial task and streaming
869783 mockPostMessage ( {
@@ -915,16 +829,7 @@ describe("ChatView - Sound Playing Tests", () => {
915829 } )
916830
917831 it ( "plays notification sound for non-auto-approved browser actions" , async ( ) => {
918- render (
919- < ExtensionStateContextProvider >
920- < ChatView
921- isHidden = { false }
922- showAnnouncement = { false }
923- hideAnnouncement = { ( ) => { } }
924- showHistoryView = { ( ) => { } }
925- />
926- </ ExtensionStateContextProvider > ,
927- )
832+ renderChatView ( )
928833
929834 // First hydrate state with initial task and streaming
930835 mockPostMessage ( {
@@ -978,16 +883,7 @@ describe("ChatView - Sound Playing Tests", () => {
978883 } )
979884
980885 it ( "plays celebration sound for completion results" , async ( ) => {
981- render (
982- < ExtensionStateContextProvider >
983- < ChatView
984- isHidden = { false }
985- showAnnouncement = { false }
986- hideAnnouncement = { ( ) => { } }
987- showHistoryView = { ( ) => { } }
988- />
989- </ ExtensionStateContextProvider > ,
990- )
886+ renderChatView ( )
991887
992888 // First hydrate state with initial task and streaming
993889 mockPostMessage ( {
@@ -1037,16 +933,7 @@ describe("ChatView - Sound Playing Tests", () => {
1037933 } )
1038934
1039935 it ( "plays progress_loop sound for api failures" , async ( ) => {
1040- render (
1041- < ExtensionStateContextProvider >
1042- < ChatView
1043- isHidden = { false }
1044- showAnnouncement = { false }
1045- hideAnnouncement = { ( ) => { } }
1046- showHistoryView = { ( ) => { } }
1047- />
1048- </ ExtensionStateContextProvider > ,
1049- )
936+ renderChatView ( )
1050937
1051938 // First hydrate state with initial task and streaming
1052939 mockPostMessage ( {
@@ -1097,9 +984,7 @@ describe("ChatView - Sound Playing Tests", () => {
1097984} )
1098985
1099986describe ( "ChatView - Focus Grabbing Tests" , ( ) => {
1100- beforeEach ( ( ) => {
1101- jest . clearAllMocks ( )
1102- } )
987+ beforeEach ( ( ) => jest . clearAllMocks ( ) )
1103988
1104989 it ( "does not grab focus when follow-up question presented" , async ( ) => {
1105990 const sleep = async ( timeout : number ) => {
@@ -1108,16 +993,7 @@ describe("ChatView - Focus Grabbing Tests", () => {
1108993 } )
1109994 }
1110995
1111- render (
1112- < ExtensionStateContextProvider >
1113- < ChatView
1114- isHidden = { false }
1115- showAnnouncement = { false }
1116- hideAnnouncement = { ( ) => { } }
1117- showHistoryView = { ( ) => { } }
1118- />
1119- </ ExtensionStateContextProvider > ,
1120- )
996+ renderChatView ( )
1121997
1122998 // First hydrate state with initial task and streaming
1123999 mockPostMessage ( {
0 commit comments