@@ -1273,4 +1273,129 @@ describe("ClineProvider", () => {
12731273 )
12741274 } )
12751275 } )
1276+
1277+ describe ( "upsertApiConfiguration" , ( ) => {
1278+ test ( "handles error in upsertApiConfiguration gracefully" , async ( ) => {
1279+ provider . resolveWebviewView ( mockWebviewView )
1280+ const messageHandler = ( mockWebviewView . webview . onDidReceiveMessage as jest . Mock ) . mock . calls [ 0 ] [ 0 ]
1281+
1282+ // Mock ConfigManager methods to simulate error
1283+ provider . configManager = {
1284+ setModeConfig : jest . fn ( ) . mockRejectedValue ( new Error ( "Failed to update mode config" ) ) ,
1285+ listConfig : jest
1286+ . fn ( )
1287+ . mockResolvedValue ( [ { name : "test-config" , id : "test-id" , apiProvider : "anthropic" } ] ) ,
1288+ } as any
1289+
1290+ // Mock getState to provide necessary data
1291+ jest . spyOn ( provider , "getState" ) . mockResolvedValue ( {
1292+ mode : "code" ,
1293+ currentApiConfigName : "test-config" ,
1294+ } as any )
1295+
1296+ // Trigger updateApiConfiguration
1297+ await messageHandler ( {
1298+ type : "upsertApiConfiguration" ,
1299+ text : "test-config" ,
1300+ apiConfiguration : {
1301+ apiProvider : "anthropic" ,
1302+ apiKey : "test-key" ,
1303+ } ,
1304+ } )
1305+
1306+ // Verify error was logged and user was notified
1307+ expect ( mockOutputChannel . appendLine ) . toHaveBeenCalledWith (
1308+ expect . stringContaining ( "Error create new api configuration" ) ,
1309+ )
1310+ expect ( vscode . window . showErrorMessage ) . toHaveBeenCalledWith ( "Failed to create api configuration" )
1311+ } )
1312+
1313+ test ( "handles successful upsertApiConfiguration" , async ( ) => {
1314+ provider . resolveWebviewView ( mockWebviewView )
1315+ const messageHandler = ( mockWebviewView . webview . onDidReceiveMessage as jest . Mock ) . mock . calls [ 0 ] [ 0 ]
1316+
1317+ // Mock ConfigManager methods
1318+ provider . configManager = {
1319+ saveConfig : jest . fn ( ) . mockResolvedValue ( undefined ) ,
1320+ listConfig : jest
1321+ . fn ( )
1322+ . mockResolvedValue ( [ { name : "test-config" , id : "test-id" , apiProvider : "anthropic" } ] ) ,
1323+ } as any
1324+
1325+ const testApiConfig = {
1326+ apiProvider : "anthropic" as const ,
1327+ apiKey : "test-key" ,
1328+ }
1329+
1330+ // Trigger upsertApiConfiguration
1331+ await messageHandler ( {
1332+ type : "upsertApiConfiguration" ,
1333+ text : "test-config" ,
1334+ apiConfiguration : testApiConfig ,
1335+ } )
1336+
1337+ // Verify config was saved
1338+ expect ( provider . configManager . saveConfig ) . toHaveBeenCalledWith ( "test-config" , testApiConfig )
1339+
1340+ // Verify state updates
1341+ expect ( mockContext . globalState . update ) . toHaveBeenCalledWith ( "listApiConfigMeta" , [
1342+ { name : "test-config" , id : "test-id" , apiProvider : "anthropic" } ,
1343+ ] )
1344+ expect ( mockContext . globalState . update ) . toHaveBeenCalledWith ( "currentApiConfigName" , "test-config" )
1345+
1346+ // Verify state was posted to webview
1347+ expect ( mockPostMessage ) . toHaveBeenCalledWith ( expect . objectContaining ( { type : "state" } ) )
1348+ } )
1349+
1350+ test ( "handles buildApiHandler error in updateApiConfiguration" , async ( ) => {
1351+ provider . resolveWebviewView ( mockWebviewView )
1352+ const messageHandler = ( mockWebviewView . webview . onDidReceiveMessage as jest . Mock ) . mock . calls [ 0 ] [ 0 ]
1353+
1354+ // Mock buildApiHandler to throw an error
1355+ const { buildApiHandler } = require ( "../../../api" )
1356+ ; ( buildApiHandler as jest . Mock ) . mockImplementationOnce ( ( ) => {
1357+ throw new Error ( "API handler error" )
1358+ } )
1359+
1360+ // Mock ConfigManager methods
1361+ provider . configManager = {
1362+ saveConfig : jest . fn ( ) . mockResolvedValue ( undefined ) ,
1363+ listConfig : jest
1364+ . fn ( )
1365+ . mockResolvedValue ( [ { name : "test-config" , id : "test-id" , apiProvider : "anthropic" } ] ) ,
1366+ } as any
1367+
1368+ // Setup mock Cline instance
1369+ const mockCline = {
1370+ api : undefined ,
1371+ abortTask : jest . fn ( ) ,
1372+ }
1373+ // @ts -ignore - accessing private property for testing
1374+ provider . cline = mockCline
1375+
1376+ const testApiConfig = {
1377+ apiProvider : "anthropic" as const ,
1378+ apiKey : "test-key" ,
1379+ }
1380+
1381+ // Trigger upsertApiConfiguration
1382+ await messageHandler ( {
1383+ type : "upsertApiConfiguration" ,
1384+ text : "test-config" ,
1385+ apiConfiguration : testApiConfig ,
1386+ } )
1387+
1388+ // Verify error handling
1389+ expect ( mockOutputChannel . appendLine ) . toHaveBeenCalledWith (
1390+ expect . stringContaining ( "Error create new api configuration" ) ,
1391+ )
1392+ expect ( vscode . window . showErrorMessage ) . toHaveBeenCalledWith ( "Failed to create api configuration" )
1393+
1394+ // Verify state was still updated
1395+ expect ( mockContext . globalState . update ) . toHaveBeenCalledWith ( "listApiConfigMeta" , [
1396+ { name : "test-config" , id : "test-id" , apiProvider : "anthropic" } ,
1397+ ] )
1398+ expect ( mockContext . globalState . update ) . toHaveBeenCalledWith ( "currentApiConfigName" , "test-config" )
1399+ } )
1400+ } )
12761401} )
0 commit comments