11// npx vitest run src/api/__tests__/index.spec.ts
22
3- import fs from "node:fs"
4-
53// Mock vscode first to avoid import errors
64vitest . mock ( "vscode" , ( ) => ( {
75 workspace : {
@@ -11,40 +9,110 @@ vitest.mock("vscode", () => ({
119 } ,
1210} ) )
1311
14- import {
15- providerIdentifiers ,
16- retiredProviderIdentifiers ,
17- type ProviderSettings ,
18- type ProviderNameWithRetired ,
19- } from "@roo-code/types"
12+ // Handler constructors can require credentials or initialize SDK clients. Replace them
13+ // with inert classes so these tests exercise only the factory's routing behavior.
14+ vitest . mock ( "../providers" , async ( ) => {
15+ const providers = await vitest . importActual < Record < string , unknown > > ( "../providers" )
2016
21- import { buildApiHandler } from "../index"
22- import { AnthropicHandler } from "../providers/anthropic"
23- import { KenariHandler } from "../providers/kenari"
24- import { OpenRouterHandler } from "../providers/openrouter"
17+ return Object . fromEntries ( Object . keys ( providers ) . map ( ( name ) => [ name , class { } ] ) )
18+ } )
2519
26- describe ( "buildApiHandler" , ( ) => {
27- it ( "returns a KenariHandler for the kenari provider" , ( ) => {
28- const configuration : ProviderSettings = {
29- apiProvider : providerIdentifiers . kenari ,
30- kenariApiKey : "test-key" ,
31- kenariModelId : "glm-5-2" ,
32- }
20+ vitest . mock ( "../providers/native-ollama" , ( ) => ( {
21+ NativeOllamaHandler : class { } ,
22+ } ) )
3323
34- const handler = buildApiHandler ( configuration )
24+ import { providerIdentifiers , retiredProviderIdentifiers , type ProviderNameWithRetired } from "@roo-code/types"
3525
36- expect ( handler ) . toBeInstanceOf ( KenariHandler )
37- } )
26+ import { buildApiHandler } from "../index"
27+ import {
28+ AnthropicHandler ,
29+ AnthropicVertexHandler ,
30+ AwsBedrockHandler ,
31+ BasetenHandler ,
32+ DeepSeekHandler ,
33+ FakeAIHandler ,
34+ FireworksHandler ,
35+ FriendliHandler ,
36+ GeminiHandler ,
37+ KenariHandler ,
38+ KimiCodeHandler ,
39+ LiteLLMHandler ,
40+ LmStudioHandler ,
41+ MiniMaxHandler ,
42+ MimoHandler ,
43+ MistralHandler ,
44+ MoonshotHandler ,
45+ OpenAiCodexHandler ,
46+ OpenAiHandler ,
47+ OpenAiNativeHandler ,
48+ OpencodeGoHandler ,
49+ OpenRouterHandler ,
50+ PoeHandler ,
51+ QwenCodeHandler ,
52+ RequestyHandler ,
53+ SambaNovaHandler ,
54+ UnboundHandler ,
55+ VercelAiGatewayHandler ,
56+ VertexHandler ,
57+ VsCodeLmHandler ,
58+ XAIHandler ,
59+ ZAiHandler ,
60+ ZooGatewayHandler ,
61+ } from "../providers"
62+ import { NativeOllamaHandler } from "../providers/native-ollama"
3863
64+ describe ( "buildApiHandler" , ( ) => {
3965 it . each ( [
4066 [ providerIdentifiers . anthropic , AnthropicHandler ] ,
4167 [ providerIdentifiers . openrouter , OpenRouterHandler ] ,
68+ [ providerIdentifiers . bedrock , AwsBedrockHandler ] ,
69+ [ providerIdentifiers . openai , OpenAiHandler ] ,
70+ [ providerIdentifiers . ollama , NativeOllamaHandler ] ,
71+ [ providerIdentifiers . lmstudio , LmStudioHandler ] ,
72+ [ providerIdentifiers . gemini , GeminiHandler ] ,
73+ [ providerIdentifiers . openaiCodex , OpenAiCodexHandler ] ,
74+ [ providerIdentifiers . openaiNative , OpenAiNativeHandler ] ,
75+ [ providerIdentifiers . deepseek , DeepSeekHandler ] ,
76+ [ providerIdentifiers . qwenCode , QwenCodeHandler ] ,
77+ [ providerIdentifiers . moonshot , MoonshotHandler ] ,
78+ [ providerIdentifiers . kimiCode , KimiCodeHandler ] ,
79+ [ providerIdentifiers . vscodeLm , VsCodeLmHandler ] ,
80+ [ providerIdentifiers . mistral , MistralHandler ] ,
81+ [ providerIdentifiers . requesty , RequestyHandler ] ,
82+ [ providerIdentifiers . unbound , UnboundHandler ] ,
83+ [ providerIdentifiers . fakeAi , FakeAIHandler ] ,
84+ [ providerIdentifiers . xai , XAIHandler ] ,
85+ [ providerIdentifiers . litellm , LiteLLMHandler ] ,
86+ [ providerIdentifiers . sambanova , SambaNovaHandler ] ,
87+ [ providerIdentifiers . mimo , MimoHandler ] ,
88+ [ providerIdentifiers . zai , ZAiHandler ] ,
89+ [ providerIdentifiers . fireworks , FireworksHandler ] ,
90+ [ providerIdentifiers . friendli , FriendliHandler ] ,
91+ [ providerIdentifiers . vercelAiGateway , VercelAiGatewayHandler ] ,
92+ [ providerIdentifiers . opencodeGo , OpencodeGoHandler ] ,
93+ [ providerIdentifiers . kenari , KenariHandler ] ,
94+ [ providerIdentifiers . zooGateway , ZooGatewayHandler ] ,
95+ [ providerIdentifiers . minimax , MiniMaxHandler ] ,
96+ [ providerIdentifiers . baseten , BasetenHandler ] ,
97+ [ providerIdentifiers . poe , PoeHandler ] ,
4298 ] as const ) ( "returns the expected handler for %s" , ( apiProvider , Handler ) => {
4399 const handler = buildApiHandler ( { apiProvider } )
44100
45101 expect ( handler ) . toBeInstanceOf ( Handler )
46102 } )
47103
104+ it . each ( [
105+ [ "non-Claude models" , "gemini-2.5-pro" , VertexHandler ] ,
106+ [ "Claude models" , "claude-3-7-sonnet" , AnthropicVertexHandler ] ,
107+ ] as const ) ( "returns the expected Vertex handler for %s" , ( _description , apiModelId , Handler ) => {
108+ const handler = buildApiHandler ( {
109+ apiProvider : providerIdentifiers . vertex ,
110+ apiModelId,
111+ } )
112+
113+ expect ( handler ) . toBeInstanceOf ( Handler )
114+ } )
115+
48116 it ( "preserves the dedicated removal error for the retired Roo provider" , ( ) => {
49117 expect ( ( ) =>
50118 buildApiHandler ( {
@@ -68,12 +136,4 @@ describe("buildApiHandler", () => {
68136
69137 expect ( handler ) . toBeInstanceOf ( AnthropicHandler )
70138 } )
71-
72- it ( "uses canonical identifiers instead of provider literals in the handler factory" , ( ) => {
73- const factorySource = fs . readFileSync ( new URL ( "../index.ts" , import . meta. url ) , "utf8" )
74-
75- expect ( factorySource ) . toContain ( "providerIdentifiers.anthropic" )
76- expect ( factorySource ) . toContain ( "retiredProviderIdentifiers.roo" )
77- expect ( factorySource ) . not . toMatch ( / c a s e \s + [ " ' ] / )
78- } )
79139} )
0 commit comments