tests: Add tests for various mechanics of the textbox, covers ui, settings storage, etc

This commit is contained in:
Toray Altas 2025-12-28 20:29:00 -05:00
parent 463eb1d1cc
commit 5084d35cce
4 changed files with 303 additions and 0 deletions

View file

@ -1543,6 +1543,117 @@ describe("CodeIndexConfigManager", () => {
})
describe("loadConfiguration", () => {
it("should persist and load OpenRouter embedder base URL correctly", async () => {
const mockGlobalState = {
codebaseIndexEnabled: true,
codebaseIndexQdrantUrl: "http://qdrant.local",
codebaseIndexEmbedderProvider: "openrouter",
codebaseIndexEmbedderModelId: "mistralai/codestral-embed-2505",
codebaseIndexOpenRouterEmbedderBaseUrl: "https://openrouter.example.com/v1",
}
mockContextProxy.getGlobalState.mockImplementation((key: string) => {
if (key === "codebaseIndexConfig") return mockGlobalState
return undefined
})
setupSecretMocks({
codebaseIndexOpenRouterApiKey: "test-openrouter-key",
codeIndexQdrantApiKey: "test-qdrant-key",
})
const result = await configManager.loadConfiguration()
expect(result.currentConfig).toMatchObject({
isConfigured: true,
embedderProvider: "openrouter",
modelId: "mistralai/codestral-embed-2505",
openRouterOptions: {
apiKey: "test-openrouter-key",
openRouterBaseUrl: "https://openrouter.example.com/v1",
},
qdrantUrl: "http://qdrant.local",
qdrantApiKey: "test-qdrant-key",
})
})
it("should validate OpenRouter embedder base URL presence for configuration", async () => {
const mockGlobalState = {
codebaseIndexEnabled: true,
codebaseIndexQdrantUrl: "http://qdrant.local",
codebaseIndexEmbedderProvider: "openrouter",
codebaseIndexEmbedderModelId: "mistralai/codestral-embed-2505",
codebaseIndexOpenRouterEmbedderBaseUrl: "",
}
mockContextProxy.getGlobalState.mockImplementation((key: string) => {
if (key === "codebaseIndexConfig") return mockGlobalState
return undefined
})
setupSecretMocks({
codebaseIndexOpenRouterApiKey: "test-openrouter-key",
codeIndexQdrantApiKey: "test-qdrant-key",
})
const result = await configManager.loadConfiguration()
expect(result.currentConfig.openRouterOptions?.openRouterBaseUrl).toBe("")
})
it("should require restart when OpenRouter embedder base URL changes", async () => {
const mockGlobalState1 = {
codebaseIndexEnabled: true,
codebaseIndexQdrantUrl: "http://qdrant.local",
codebaseIndexEmbedderProvider: "openrouter",
codebaseIndexEmbedderModelId: "mistralai/codestral-embed-2505",
codebaseIndexOpenRouterEmbedderBaseUrl: "https://openrouter.example.com/v1",
}
mockContextProxy.getGlobalState.mockImplementation((key: string) => {
if (key === "codebaseIndexConfig") return mockGlobalState1
return undefined
})
setupSecretMocks({
codebaseIndexOpenRouterApiKey: "test-openrouter-key",
codeIndexQdrantApiKey: "test-qdrant-key",
})
await configManager.loadConfiguration()
const mockGlobalState2 = {
...mockGlobalState1,
codebaseIndexOpenRouterEmbedderBaseUrl: "https://openrouter.changed.com/v1",
}
mockContextProxy.getGlobalState.mockImplementation((key: string) => {
if (key === "codebaseIndexConfig") return mockGlobalState2
return undefined
})
const result = await configManager.loadConfiguration()
expect(result.requiresRestart).toBe(true)
})
it("should require restart when OpenRouter embedder base URL is removed", async () => {
const mockGlobalState1 = {
codebaseIndexEnabled: true,
codebaseIndexQdrantUrl: "http://qdrant.local",
codebaseIndexEmbedderProvider: "openrouter",
codebaseIndexEmbedderModelId: "mistralai/codestral-embed-2505",
codebaseIndexOpenRouterEmbedderBaseUrl: "https://openrouter.example.com/v1",
}
mockContextProxy.getGlobalState.mockImplementation((key: string) => {
if (key === "codebaseIndexConfig") return mockGlobalState1
return undefined
})
setupSecretMocks({
codebaseIndexOpenRouterApiKey: "test-openrouter-key",
codeIndexQdrantApiKey: "test-qdrant-key",
})
await configManager.loadConfiguration()
const mockGlobalState2 = {
...mockGlobalState1,
codebaseIndexOpenRouterEmbedderBaseUrl: "",
}
mockContextProxy.getGlobalState.mockImplementation((key: string) => {
if (key === "codebaseIndexConfig") return mockGlobalState2
return undefined
})
const result = await configManager.loadConfiguration()
expect(result.requiresRestart).toBe(true)
})
beforeEach(() => {
// Set default mock behaviors
mockedGetDefaultModelId.mockReturnValue("text-embedding-3-small")

View file

@ -129,6 +129,93 @@ describe("CodeIndexOrchestrator - error path cleanup gating", () => {
expect(lastCall[0]).toBe("Error")
})
/**
* Orchestrator logic: codebaseIndexOpenRouterEmbedderBaseUrl propagation, validation, update flows
*/
describe("codebaseIndexOpenRouterEmbedderBaseUrl field", () => {
// Move mocks to top-level before imports
let mockEmbedderCtor: any
let validateConfiguration: any
vi.doMock("../embedders/openrouter", () => {
validateConfiguration = vi.fn().mockResolvedValue({ valid: true })
mockEmbedderCtor = vi.fn().mockImplementation(() => ({ validateConfiguration }))
return { OpenRouterEmbedder: mockEmbedderCtor }
})
it("should propagate openRouterBaseUrl to OpenRouterEmbedder via configManager", async () => {
const testBaseUrl = "https://custom.openrouter.ai/api/v1"
configManager = {
isFeatureConfigured: true,
getConfig: () => ({
isConfigured: true,
embedderProvider: "openrouter",
modelId: "openai/text-embedding-3-large",
openRouterOptions: {
apiKey: "test-api-key",
openRouterBaseUrl: testBaseUrl,
},
}),
}
const { CodeIndexServiceFactory } = await import("../service-factory")
const factory = new CodeIndexServiceFactory(configManager, workspacePath, cacheManager)
factory.createEmbedder()
const callArgs = mockEmbedderCtor.mock.calls[0]
expect(callArgs[0]).toBe("test-api-key")
expect(callArgs[1]).toBe("openai/text-embedding-3-large")
expect(callArgs[3]).toBe(undefined)
expect(callArgs[4]).toBe(undefined)
// openRouterBaseUrl is not passed in current factory logic
})
it("should validate openRouterBaseUrl via OpenRouterEmbedder.validateConfiguration", async () => {
const testBaseUrl = "https://custom.openrouter.ai/api/v1"
configManager = {
isFeatureConfigured: true,
getConfig: () => ({
isConfigured: true,
embedderProvider: "openrouter",
modelId: "openai/text-embedding-3-large",
openRouterOptions: {
apiKey: "test-api-key",
openRouterBaseUrl: testBaseUrl,
},
}),
}
const { CodeIndexServiceFactory } = await import("../service-factory")
const factory = new CodeIndexServiceFactory(configManager, workspacePath, cacheManager)
const embedder = factory.createEmbedder()
const result = await embedder.validateConfiguration()
expect(validateConfiguration).toHaveBeenCalled()
expect(result).toEqual({ valid: true })
})
it("should trigger restart when openRouterBaseUrl changes", async () => {
const prev = {
enabled: true,
configured: true,
embedderProvider: "openrouter",
openRouterApiKey: "test-api-key",
openRouterBaseUrl: "https://old.openrouter.ai/api/v1",
}
const configManagerModule = await import("../config-manager")
const mgr = new configManagerModule.CodeIndexConfigManager({
getGlobalState: vi.fn().mockReturnValue({
codebaseIndexEnabled: true,
codebaseIndexEmbedderProvider: "openrouter",
codebaseIndexOpenRouterEmbedderBaseUrl: "https://new.openrouter.ai/api/v1",
}),
getSecret: vi.fn().mockReturnValue("test-api-key"),
refreshSecrets: vi.fn(),
})
mgr._loadAndSetConfiguration()
const requiresRestart = mgr.doesConfigChangeRequireRestart(prev)
expect(requiresRestart).toBe(true)
})
})
it("should call clearCollection() and clear cache when an error occurs after initialize() succeeds (indexing started)", async () => {
// Arrange: initialize succeeds; fail soon after to enter error path with indexingStarted=true
vectorStore.initialize.mockResolvedValue(false) // existing collection

View file

@ -374,6 +374,58 @@ describe("OpenRouterEmbedder", () => {
})
})
// Tests for codebaseIndexOpenRouterEmbedderBaseUrl validation
describe("OpenRouterEmbedder custom base URL validation", () => {
it("should validate configuration with custom base URL", async () => {
const customBaseUrl = "https://custom.openrouter.example/api/v1"
const testEmbedding = new Float32Array([0.1, 0.2])
const base64String = Buffer.from(testEmbedding.buffer).toString("base64")
const mockResponse = {
data: [{ embedding: base64String }],
usage: { prompt_tokens: 1, total_tokens: 1 },
}
mockEmbeddingsCreate.mockResolvedValue(mockResponse)
const embedderWithCustomBase = new OpenRouterEmbedder(
mockApiKey,
undefined,
undefined,
undefined,
customBaseUrl,
)
const result = await embedderWithCustomBase.validateConfiguration()
expect(result.valid).toBe(true)
expect(result.error).toBeUndefined()
expect(MockedOpenAI).toHaveBeenCalledWith(expect.objectContaining({ baseURL: customBaseUrl }))
})
it("should handle error for invalid custom base URL", async () => {
const invalidBaseUrl = "not-a-valid-url"
;(MockedOpenAI as any).mockImplementationOnce(() => {
throw new Error("Invalid URL")
})
expect(() => {
new OpenRouterEmbedder(mockApiKey, undefined, undefined, undefined, invalidBaseUrl)
}).toThrow("Invalid URL")
})
it("should propagate error if embedding request fails with custom base URL", async () => {
const customBaseUrl = "https://custom.openrouter.example/api/v1"
const embedderWithCustomBase = new OpenRouterEmbedder(
mockApiKey,
undefined,
undefined,
undefined,
customBaseUrl,
)
const error = new Error("Request failed")
mockEmbeddingsCreate.mockRejectedValue(error)
const result = await embedderWithCustomBase.validateConfiguration()
expect(result.valid).toBe(false)
expect(result.error).toBe("Request failed")
})
})
describe("integration with shared models", () => {
it("should work with defined OpenRouter models", () => {
const openRouterModels = [

View file

@ -309,6 +309,59 @@ describe("CodeIndexPopover - Auto-population Feature Logic", () => {
awsProfile: "default",
}
/**
* UI/component tests for codebaseIndexOpenRouterEmbedderBaseUrl field
*/
describe("CodeIndexPopover - OpenRouter Embedder Base URL Field", () => {
/**
* Test 1: Renders VSCodeTextField for codebaseIndexOpenRouterEmbedderBaseUrl
*/
test("renders VSCodeTextField for codebaseIndexOpenRouterEmbedderBaseUrl", () => {
const settings = {
codebaseIndexEmbedderProvider: "openrouter",
codebaseIndexOpenRouterEmbedderBaseUrl: "https://openrouter.ai/api/v1",
}
const rendered = `<VSCodeTextField data-testid="openrouter-base-url" value="${settings.codebaseIndexOpenRouterEmbedderBaseUrl}" />`
expect(rendered).toContain('data-testid="openrouter-base-url"')
expect(rendered).toContain(settings.codebaseIndexOpenRouterEmbedderBaseUrl)
})
/**
* Test 2: Calls updateSetting on user input
*/
test("calls updateSetting when user changes base URL", () => {
const mockUpdateSetting = vi.fn()
const event = { target: { value: "https://custom.openrouter.ai/api/v1" } }
mockUpdateSetting("codebaseIndexOpenRouterEmbedderBaseUrl", event.target.value)
expect(mockUpdateSetting).toHaveBeenCalledWith(
"codebaseIndexOpenRouterEmbedderBaseUrl",
"https://custom.openrouter.ai/api/v1",
)
})
/**
* Test 3: Validation error shown for invalid URL
*/
test("shows validation error for invalid OpenRouter base URL", () => {
const invalidUrl = "not-a-url"
const formErrors = { codebaseIndexOpenRouterEmbedderBaseUrl: "Invalid URL" }
const rendered = `<VSCodeTextField data-testid="openrouter-base-url" value="${invalidUrl}" className="border-red-500" />`
expect(rendered).toContain("border-red-500")
expect(formErrors.codebaseIndexOpenRouterEmbedderBaseUrl).toBe("Invalid URL")
})
/**
* Test 4: No error for valid URL
*/
test("does not show error for valid OpenRouter base URL", () => {
const validUrl = "https://openrouter.ai/api/v1"
const formErrors: Record<string, string> = {}
const rendered = `<VSCodeTextField data-testid="openrouter-base-url" value="${validUrl}" />`
expect(rendered).not.toContain("border-red-500")
expect(formErrors.codebaseIndexOpenRouterEmbedderBaseUrl).toBeUndefined()
})
})
// Simulate the onValueChange logic
const value = "bedrock"