125 lines
3.8 KiB
TypeScript
125 lines
3.8 KiB
TypeScript
// kilocode_change - new file
|
|
// Regression test: OAuth accountId must flow into model fetch as kilocodeOrganizationId
|
|
// When a user logs in via OAuth and selects an enterprise organization, the model fetch
|
|
// should use the organization-specific endpoint, not the personal endpoint.
|
|
|
|
import { test, expect, mock } from "bun:test"
|
|
import path from "path"
|
|
|
|
// Capture the options passed to fetchKiloModels
|
|
let captured: any = undefined
|
|
|
|
mock.module("@kilocode/kilo-gateway", () => ({
|
|
fetchKiloModels: async (options: any) => {
|
|
captured = options
|
|
return {
|
|
"test-model": {
|
|
id: "test-model",
|
|
name: "Test Model",
|
|
cost: { input: 0.001, output: 0.002 },
|
|
limit: { context: 128000, output: 4096 },
|
|
},
|
|
}
|
|
},
|
|
KILO_OPENROUTER_BASE: "https://api.kilo.ai/api/openrouter",
|
|
}))
|
|
|
|
// Mock BunProc and default plugins to prevent actual installations during tests
|
|
mock.module("../../src/bun/index", () => ({
|
|
BunProc: {
|
|
install: async (pkg: string) => {
|
|
const lastAtIndex = pkg.lastIndexOf("@")
|
|
return lastAtIndex > 0 ? pkg.substring(0, lastAtIndex) : pkg
|
|
},
|
|
run: async () => {
|
|
throw new Error("BunProc.run should not be called in tests")
|
|
},
|
|
which: () => process.execPath,
|
|
InstallFailedError: class extends Error {},
|
|
},
|
|
}))
|
|
|
|
const mockPlugin = () => ({})
|
|
mock.module("opencode-copilot-auth", () => ({ default: mockPlugin }))
|
|
mock.module("opencode-anthropic-auth", () => ({ default: mockPlugin }))
|
|
mock.module("@gitlab/opencode-gitlab-auth", () => ({ default: mockPlugin }))
|
|
|
|
import { tmpdir } from "../fixture/fixture"
|
|
import { Instance } from "../../src/project/instance"
|
|
import { Auth } from "../../src/auth"
|
|
import { ModelCache } from "../../src/provider/model-cache"
|
|
|
|
test("model fetch uses accountId from OAuth auth as kilocodeOrganizationId", async () => {
|
|
await using tmp = await tmpdir({
|
|
init: async (dir) => {
|
|
await Bun.write(
|
|
path.join(dir, "opencode.json"),
|
|
JSON.stringify({
|
|
$schema: "https://app.kilo.ai/config.json",
|
|
}),
|
|
)
|
|
},
|
|
})
|
|
await Instance.provide({
|
|
directory: tmp.path,
|
|
init: async () => {
|
|
// Simulate an OAuth login where user selected an enterprise organization
|
|
await Auth.set("kilo", {
|
|
type: "oauth",
|
|
access: "test-oauth-token",
|
|
refresh: "test-refresh-token",
|
|
expires: Date.now() + 3600000,
|
|
accountId: "org-enterprise-123",
|
|
})
|
|
},
|
|
fn: async () => {
|
|
// Reset captured and cache
|
|
captured = undefined
|
|
ModelCache.clear("kilo")
|
|
|
|
// Trigger model fetch through the cache
|
|
await ModelCache.fetch("kilo")
|
|
|
|
// The fetchKiloModels call should have received the organization ID
|
|
expect(captured).toBeDefined()
|
|
expect(captured.kilocodeToken).toBe("test-oauth-token")
|
|
expect(captured.kilocodeOrganizationId).toBe("org-enterprise-123")
|
|
},
|
|
})
|
|
})
|
|
|
|
test("model fetch without OAuth accountId does not set kilocodeOrganizationId", async () => {
|
|
await using tmp = await tmpdir({
|
|
init: async (dir) => {
|
|
await Bun.write(
|
|
path.join(dir, "opencode.json"),
|
|
JSON.stringify({
|
|
$schema: "https://app.kilo.ai/config.json",
|
|
}),
|
|
)
|
|
},
|
|
})
|
|
await Instance.provide({
|
|
directory: tmp.path,
|
|
init: async () => {
|
|
// Simulate an OAuth login for a personal account (no accountId)
|
|
await Auth.set("kilo", {
|
|
type: "oauth",
|
|
access: "test-personal-token",
|
|
refresh: "test-refresh-token",
|
|
expires: Date.now() + 3600000,
|
|
})
|
|
},
|
|
fn: async () => {
|
|
captured = undefined
|
|
ModelCache.clear("kilo")
|
|
|
|
await ModelCache.fetch("kilo")
|
|
|
|
expect(captured).toBeDefined()
|
|
expect(captured.kilocodeToken).toBe("test-personal-token")
|
|
expect(captured.kilocodeOrganizationId).toBeUndefined()
|
|
},
|
|
})
|
|
})
|