1- import { ClineProvider } from "../ClineProvider"
1+ // npx jest src/core/webview/__tests__/ClineProvider.test.ts
2+
23import * as vscode from "vscode"
4+ import axios from "axios"
5+
6+ import { ClineProvider } from "../ClineProvider"
37import { ExtensionMessage , ExtensionState } from "../../../shared/ExtensionMessage"
48import { setSoundEnabled } from "../../../utils/sound"
5- import { defaultModeSlug , modes } from "../../../shared/modes"
6- import { addCustomInstructions } from "../../prompts/sections/custom-instructions"
7- import { experimentDefault , experiments } from "../../../shared/experiments"
9+ import { defaultModeSlug } from "../../../shared/modes"
10+ import { experimentDefault } from "../../../shared/experiments"
811
912// Mock custom-instructions module
1013const mockAddCustomInstructions = jest . fn ( )
14+
1115jest . mock ( "../../prompts/sections/custom-instructions" , ( ) => ( {
1216 addCustomInstructions : mockAddCustomInstructions ,
1317} ) )
@@ -202,7 +206,6 @@ describe("ClineProvider", () => {
202206 let mockOutputChannel : vscode . OutputChannel
203207 let mockWebviewView : vscode . WebviewView
204208 let mockPostMessage : jest . Mock
205- let visibilityChangeCallback : ( e ?: unknown ) => void
206209
207210 beforeEach ( ( ) => {
208211 // Reset mocks
@@ -270,13 +273,13 @@ describe("ClineProvider", () => {
270273 return { dispose : jest . fn ( ) }
271274 } ) ,
272275 onDidChangeVisibility : jest . fn ( ) . mockImplementation ( ( callback ) => {
273- visibilityChangeCallback = callback
274276 return { dispose : jest . fn ( ) }
275277 } ) ,
276278 } as unknown as vscode . WebviewView
277279
278280 provider = new ClineProvider ( mockContext , mockOutputChannel )
279- // @ts -ignore - accessing private property for testing
281+
282+ // @ts -ignore - Accessing private property for testing.
280283 provider . customModesManager = mockCustomModesManager
281284 } )
282285
@@ -288,18 +291,36 @@ describe("ClineProvider", () => {
288291 expect ( ClineProvider . getVisibleInstance ( ) ) . toBe ( provider )
289292 } )
290293
291- test ( "resolveWebviewView sets up webview correctly" , ( ) => {
292- provider . resolveWebviewView ( mockWebviewView )
294+ test ( "resolveWebviewView sets up webview correctly" , async ( ) => {
295+ await provider . resolveWebviewView ( mockWebviewView )
293296
294297 expect ( mockWebviewView . webview . options ) . toEqual ( {
295298 enableScripts : true ,
296299 localResourceRoots : [ mockContext . extensionUri ] ,
297300 } )
301+
302+ expect ( mockWebviewView . webview . html ) . toContain ( "<!DOCTYPE html>" )
303+ } )
304+
305+ test ( "resolveWebviewView sets up webview correctly in development mode even if local server is not running" , async ( ) => {
306+ provider = new ClineProvider (
307+ { ...mockContext , extensionMode : vscode . ExtensionMode . Development } ,
308+ mockOutputChannel ,
309+ )
310+ ; ( axios . get as jest . Mock ) . mockRejectedValueOnce ( new Error ( "Network error" ) )
311+
312+ await provider . resolveWebviewView ( mockWebviewView )
313+
314+ expect ( mockWebviewView . webview . options ) . toEqual ( {
315+ enableScripts : true ,
316+ localResourceRoots : [ mockContext . extensionUri ] ,
317+ } )
318+
298319 expect ( mockWebviewView . webview . html ) . toContain ( "<!DOCTYPE html>" )
299320 } )
300321
301322 test ( "postMessageToWebview sends message to webview" , async ( ) => {
302- provider . resolveWebviewView ( mockWebviewView )
323+ await provider . resolveWebviewView ( mockWebviewView )
303324
304325 const mockState : ExtensionState = {
305326 version : "1.0.0" ,
@@ -341,7 +362,7 @@ describe("ClineProvider", () => {
341362 } )
342363
343364 test ( "handles webviewDidLaunch message" , async ( ) => {
344- provider . resolveWebviewView ( mockWebviewView )
365+ await provider . resolveWebviewView ( mockWebviewView )
345366
346367 // Get the message handler from onDidReceiveMessage
347368 const messageHandler = ( mockWebviewView . webview . onDidReceiveMessage as jest . Mock ) . mock . calls [ 0 ] [ 0 ]
@@ -420,7 +441,7 @@ describe("ClineProvider", () => {
420441 } )
421442
422443 test ( "handles writeDelayMs message" , async ( ) => {
423- provider . resolveWebviewView ( mockWebviewView )
444+ await provider . resolveWebviewView ( mockWebviewView )
424445 const messageHandler = ( mockWebviewView . webview . onDidReceiveMessage as jest . Mock ) . mock . calls [ 0 ] [ 0 ]
425446
426447 await messageHandler ( { type : "writeDelayMs" , value : 2000 } )
@@ -430,7 +451,7 @@ describe("ClineProvider", () => {
430451 } )
431452
432453 test ( "updates sound utility when sound setting changes" , async ( ) => {
433- provider . resolveWebviewView ( mockWebviewView )
454+ await provider . resolveWebviewView ( mockWebviewView )
434455
435456 // Get the message handler from onDidReceiveMessage
436457 const messageHandler = ( mockWebviewView . webview . onDidReceiveMessage as jest . Mock ) . mock . calls [ 0 ] [ 0 ]
@@ -470,7 +491,7 @@ describe("ClineProvider", () => {
470491 } )
471492
472493 test ( "loads saved API config when switching modes" , async ( ) => {
473- provider . resolveWebviewView ( mockWebviewView )
494+ await provider . resolveWebviewView ( mockWebviewView )
474495 const messageHandler = ( mockWebviewView . webview . onDidReceiveMessage as jest . Mock ) . mock . calls [ 0 ] [ 0 ]
475496
476497 // Mock ConfigManager methods
@@ -491,7 +512,7 @@ describe("ClineProvider", () => {
491512 } )
492513
493514 test ( "saves current config when switching to mode without config" , async ( ) => {
494- provider . resolveWebviewView ( mockWebviewView )
515+ await provider . resolveWebviewView ( mockWebviewView )
495516 const messageHandler = ( mockWebviewView . webview . onDidReceiveMessage as jest . Mock ) . mock . calls [ 0 ] [ 0 ]
496517
497518 // Mock ConfigManager methods
@@ -519,7 +540,7 @@ describe("ClineProvider", () => {
519540 } )
520541
521542 test ( "saves config as default for current mode when loading config" , async ( ) => {
522- provider . resolveWebviewView ( mockWebviewView )
543+ await provider . resolveWebviewView ( mockWebviewView )
523544 const messageHandler = ( mockWebviewView . webview . onDidReceiveMessage as jest . Mock ) . mock . calls [ 0 ] [ 0 ]
524545
525546 provider . configManager = {
@@ -540,7 +561,7 @@ describe("ClineProvider", () => {
540561 } )
541562
542563 test ( "handles request delay settings messages" , async ( ) => {
543- provider . resolveWebviewView ( mockWebviewView )
564+ await provider . resolveWebviewView ( mockWebviewView )
544565 const messageHandler = ( mockWebviewView . webview . onDidReceiveMessage as jest . Mock ) . mock . calls [ 0 ] [ 0 ]
545566
546567 // Test alwaysApproveResubmit
@@ -555,7 +576,7 @@ describe("ClineProvider", () => {
555576 } )
556577
557578 test ( "handles updatePrompt message correctly" , async ( ) => {
558- provider . resolveWebviewView ( mockWebviewView )
579+ await provider . resolveWebviewView ( mockWebviewView )
559580 const messageHandler = ( mockWebviewView . webview . onDidReceiveMessage as jest . Mock ) . mock . calls [ 0 ] [ 0 ]
560581
561582 // Mock existing prompts
@@ -650,7 +671,7 @@ describe("ClineProvider", () => {
650671 )
651672 } )
652673 test ( "handles mode-specific custom instructions updates" , async ( ) => {
653- provider . resolveWebviewView ( mockWebviewView )
674+ await provider . resolveWebviewView ( mockWebviewView )
654675 const messageHandler = ( mockWebviewView . webview . onDidReceiveMessage as jest . Mock ) . mock . calls [ 0 ] [ 0 ]
655676
656677 // Mock existing prompts
@@ -707,7 +728,7 @@ describe("ClineProvider", () => {
707728
708729 // Create new provider with updated mock context
709730 provider = new ClineProvider ( mockContext , mockOutputChannel )
710- provider . resolveWebviewView ( mockWebviewView )
731+ await provider . resolveWebviewView ( mockWebviewView )
711732 const messageHandler = ( mockWebviewView . webview . onDidReceiveMessage as jest . Mock ) . mock . calls [ 0 ] [ 0 ]
712733
713734 provider . configManager = {
@@ -732,10 +753,10 @@ describe("ClineProvider", () => {
732753 } )
733754
734755 describe ( "deleteMessage" , ( ) => {
735- beforeEach ( ( ) => {
756+ beforeEach ( async ( ) => {
736757 // Mock window.showInformationMessage
737758 ; ( vscode . window . showInformationMessage as jest . Mock ) = jest . fn ( )
738- provider . resolveWebviewView ( mockWebviewView )
759+ await provider . resolveWebviewView ( mockWebviewView )
739760 } )
740761
741762 test ( 'handles "Just this message" deletion correctly' , async ( ) => {
@@ -861,9 +882,9 @@ describe("ClineProvider", () => {
861882 } )
862883
863884 describe ( "getSystemPrompt" , ( ) => {
864- beforeEach ( ( ) => {
885+ beforeEach ( async ( ) => {
865886 mockPostMessage . mockClear ( )
866- provider . resolveWebviewView ( mockWebviewView )
887+ await provider . resolveWebviewView ( mockWebviewView )
867888 // Reset and setup mock
868889 mockAddCustomInstructions . mockClear ( )
869890 mockAddCustomInstructions . mockImplementation (
@@ -1111,7 +1132,7 @@ describe("ClineProvider", () => {
11111132 } )
11121133
11131134 // Resolve webview and trigger getSystemPrompt
1114- provider . resolveWebviewView ( mockWebviewView )
1135+ await provider . resolveWebviewView ( mockWebviewView )
11151136 const architectHandler = ( mockWebviewView . webview . onDidReceiveMessage as jest . Mock ) . mock . calls [ 0 ] [ 0 ]
11161137 await architectHandler ( { type : "getSystemPrompt" } )
11171138
@@ -1125,9 +1146,9 @@ describe("ClineProvider", () => {
11251146 } )
11261147
11271148 describe ( "handleModeSwitch" , ( ) => {
1128- beforeEach ( ( ) => {
1149+ beforeEach ( async ( ) => {
11291150 // Set up webview for each test
1130- provider . resolveWebviewView ( mockWebviewView )
1151+ await provider . resolveWebviewView ( mockWebviewView )
11311152 } )
11321153
11331154 test ( "loads saved API config when switching modes" , async ( ) => {
@@ -1188,7 +1209,7 @@ describe("ClineProvider", () => {
11881209
11891210 describe ( "updateCustomMode" , ( ) => {
11901211 test ( "updates both file and state when updating custom mode" , async ( ) => {
1191- provider . resolveWebviewView ( mockWebviewView )
1212+ await provider . resolveWebviewView ( mockWebviewView )
11921213 const messageHandler = ( mockWebviewView . webview . onDidReceiveMessage as jest . Mock ) . mock . calls [ 0 ] [ 0 ]
11931214
11941215 // Mock CustomModesManager methods
0 commit comments