@@ -1962,6 +1962,130 @@ describe("ClineProvider", () => {
19621962 } )
19631963} )
19641964
1965+ describe ( "Project MCP Settings" , ( ) => {
1966+ let provider : ClineProvider
1967+ let mockContext : vscode . ExtensionContext
1968+ let mockOutputChannel : vscode . OutputChannel
1969+ let mockWebviewView : vscode . WebviewView
1970+ let mockPostMessage : jest . Mock
1971+
1972+ beforeEach ( ( ) => {
1973+ jest . clearAllMocks ( )
1974+
1975+ mockContext = {
1976+ extensionPath : "/test/path" ,
1977+ extensionUri : { } as vscode . Uri ,
1978+ globalState : {
1979+ get : jest . fn ( ) ,
1980+ update : jest . fn ( ) ,
1981+ keys : jest . fn ( ) . mockReturnValue ( [ ] ) ,
1982+ } ,
1983+ secrets : {
1984+ get : jest . fn ( ) ,
1985+ store : jest . fn ( ) ,
1986+ delete : jest . fn ( ) ,
1987+ } ,
1988+ subscriptions : [ ] ,
1989+ extension : {
1990+ packageJSON : { version : "1.0.0" } ,
1991+ } ,
1992+ globalStorageUri : {
1993+ fsPath : "/test/storage/path" ,
1994+ } ,
1995+ } as unknown as vscode . ExtensionContext
1996+
1997+ mockOutputChannel = {
1998+ appendLine : jest . fn ( ) ,
1999+ clear : jest . fn ( ) ,
2000+ dispose : jest . fn ( ) ,
2001+ } as unknown as vscode . OutputChannel
2002+
2003+ mockPostMessage = jest . fn ( )
2004+ mockWebviewView = {
2005+ webview : {
2006+ postMessage : mockPostMessage ,
2007+ html : "" ,
2008+ options : { } ,
2009+ onDidReceiveMessage : jest . fn ( ) ,
2010+ asWebviewUri : jest . fn ( ) ,
2011+ } ,
2012+ visible : true ,
2013+ onDidDispose : jest . fn ( ) ,
2014+ onDidChangeVisibility : jest . fn ( ) ,
2015+ } as unknown as vscode . WebviewView
2016+
2017+ provider = new ClineProvider ( mockContext , mockOutputChannel )
2018+ } )
2019+
2020+ test ( "handles openProjectMcpSettings message" , async ( ) => {
2021+ await provider . resolveWebviewView ( mockWebviewView )
2022+ const messageHandler = ( mockWebviewView . webview . onDidReceiveMessage as jest . Mock ) . mock . calls [ 0 ] [ 0 ]
2023+
2024+ // Mock workspace folders
2025+ ; ( vscode . workspace as any ) . workspaceFolders = [ { uri : { fsPath : "/test/workspace" } } ]
2026+
2027+ // Mock fs functions
2028+ const fs = require ( "fs/promises" )
2029+ fs . mkdir . mockResolvedValue ( undefined )
2030+ fs . writeFile . mockResolvedValue ( undefined )
2031+
2032+ // Trigger openProjectMcpSettings
2033+ await messageHandler ( {
2034+ type : "openProjectMcpSettings" ,
2035+ } )
2036+
2037+ // Verify directory was created
2038+ expect ( fs . mkdir ) . toHaveBeenCalledWith (
2039+ expect . stringContaining ( ".roo" ) ,
2040+ expect . objectContaining ( { recursive : true } ) ,
2041+ )
2042+
2043+ // Verify file was created with default content
2044+ expect ( fs . writeFile ) . toHaveBeenCalledWith (
2045+ expect . stringContaining ( "mcp.json" ) ,
2046+ JSON . stringify ( { mcpServers : { } } , null , 2 ) ,
2047+ )
2048+ } )
2049+
2050+ test ( "handles openProjectMcpSettings when workspace is not open" , async ( ) => {
2051+ await provider . resolveWebviewView ( mockWebviewView )
2052+ const messageHandler = ( mockWebviewView . webview . onDidReceiveMessage as jest . Mock ) . mock . calls [ 0 ] [ 0 ]
2053+
2054+ // Mock no workspace folders
2055+ ; ( vscode . workspace as any ) . workspaceFolders = [ ]
2056+
2057+ // Trigger openProjectMcpSettings
2058+ await messageHandler ( {
2059+ type : "openProjectMcpSettings" ,
2060+ } )
2061+
2062+ // Verify error message was shown
2063+ expect ( vscode . window . showErrorMessage ) . toHaveBeenCalledWith ( "Please open a project folder first" )
2064+ } )
2065+
2066+ test ( "handles openProjectMcpSettings file creation error" , async ( ) => {
2067+ await provider . resolveWebviewView ( mockWebviewView )
2068+ const messageHandler = ( mockWebviewView . webview . onDidReceiveMessage as jest . Mock ) . mock . calls [ 0 ] [ 0 ]
2069+
2070+ // Mock workspace folders
2071+ ; ( vscode . workspace as any ) . workspaceFolders = [ { uri : { fsPath : "/test/workspace" } } ]
2072+
2073+ // Mock fs functions to fail
2074+ const fs = require ( "fs/promises" )
2075+ fs . mkdir . mockRejectedValue ( new Error ( "Failed to create directory" ) )
2076+
2077+ // Trigger openProjectMcpSettings
2078+ await messageHandler ( {
2079+ type : "openProjectMcpSettings" ,
2080+ } )
2081+
2082+ // Verify error message was shown
2083+ expect ( vscode . window . showErrorMessage ) . toHaveBeenCalledWith (
2084+ expect . stringContaining ( "Failed to create or open .roo/mcp.json" ) ,
2085+ )
2086+ } )
2087+ } )
2088+
19652089describe ( "ContextProxy integration" , ( ) => {
19662090 let provider : ClineProvider
19672091 let mockContext : vscode . ExtensionContext
0 commit comments