import { test, expect } from "bun:test" import path from "path" import { tmpdir } from "../fixture/fixture" import { Instance } from "../../src/project/instance" import { Provider } from "../../src/provider/provider" import { Env } from "../../src/env" import { Global } from "../../src/global" test("GitLab Duo: loads provider with API key from environment", async () => { await using tmp = await tmpdir({ init: async (dir) => { await Bun.write( path.join(dir, "opencode.json"), JSON.stringify({ $schema: "https://opencode.ai/config.json", }), ) }, }) await Instance.provide({ directory: tmp.path, init: async () => { Env.set("GITLAB_TOKEN", "test-gitlab-token") }, fn: async () => { const providers = await Provider.list() expect(providers["gitlab"]).toBeDefined() expect(providers["gitlab"].key).toBe("test-gitlab-token") }, }) }) test("GitLab Duo: config instanceUrl option sets baseURL", async () => { await using tmp = await tmpdir({ init: async (dir) => { await Bun.write( path.join(dir, "opencode.json"), JSON.stringify({ $schema: "https://opencode.ai/config.json", provider: { gitlab: { options: { instanceUrl: "https://gitlab.example.com", }, }, }, }), ) }, }) await Instance.provide({ directory: tmp.path, init: async () => { Env.set("GITLAB_TOKEN", "test-token") Env.set("GITLAB_INSTANCE_URL", "https://gitlab.example.com") }, fn: async () => { const providers = await Provider.list() expect(providers["gitlab"]).toBeDefined() expect(providers["gitlab"].options?.instanceUrl).toBe("https://gitlab.example.com") }, }) }) test("GitLab Duo: loads with OAuth token from auth.json", async () => { await using tmp = await tmpdir({ init: async (dir) => { await Bun.write( path.join(dir, "opencode.json"), JSON.stringify({ $schema: "https://opencode.ai/config.json", }), ) }, }) const authPath = path.join(Global.Path.data, "auth.json") await Bun.write( authPath, JSON.stringify({ gitlab: { type: "oauth", access: "test-access-token", refresh: "test-refresh-token", expires: Date.now() + 3600000, }, }), ) await Instance.provide({ directory: tmp.path, init: async () => { Env.set("GITLAB_TOKEN", "") }, fn: async () => { const providers = await Provider.list() expect(providers["gitlab"]).toBeDefined() }, }) }) test("GitLab Duo: loads with Personal Access Token from auth.json", async () => { await using tmp = await tmpdir({ init: async (dir) => { await Bun.write( path.join(dir, "opencode.json"), JSON.stringify({ $schema: "https://opencode.ai/config.json", }), ) }, }) const authPath2 = path.join(Global.Path.data, "auth.json") await Bun.write( authPath2, JSON.stringify({ gitlab: { type: "api", key: "glpat-test-pat-token", }, }), ) await Instance.provide({ directory: tmp.path, init: async () => { Env.set("GITLAB_TOKEN", "") }, fn: async () => { const providers = await Provider.list() expect(providers["gitlab"]).toBeDefined() expect(providers["gitlab"].key).toBe("glpat-test-pat-token") }, }) }) test("GitLab Duo: supports self-hosted instance configuration", async () => { await using tmp = await tmpdir({ init: async (dir) => { await Bun.write( path.join(dir, "opencode.json"), JSON.stringify({ $schema: "https://opencode.ai/config.json", provider: { gitlab: { options: { instanceUrl: "https://gitlab.company.internal", apiKey: "glpat-internal-token", }, }, }, }), ) }, }) await Instance.provide({ directory: tmp.path, init: async () => { Env.set("GITLAB_INSTANCE_URL", "https://gitlab.company.internal") }, fn: async () => { const providers = await Provider.list() expect(providers["gitlab"]).toBeDefined() expect(providers["gitlab"].options?.instanceUrl).toBe("https://gitlab.company.internal") }, }) }) test("GitLab Duo: config apiKey takes precedence over environment variable", async () => { await using tmp = await tmpdir({ init: async (dir) => { await Bun.write( path.join(dir, "opencode.json"), JSON.stringify({ $schema: "https://opencode.ai/config.json", provider: { gitlab: { options: { apiKey: "config-token", }, }, }, }), ) }, }) await Instance.provide({ directory: tmp.path, init: async () => { Env.set("GITLAB_TOKEN", "env-token") }, fn: async () => { const providers = await Provider.list() expect(providers["gitlab"]).toBeDefined() }, }) }) test("GitLab Duo: supports feature flags configuration", async () => { await using tmp = await tmpdir({ init: async (dir) => { await Bun.write( path.join(dir, "opencode.json"), JSON.stringify({ $schema: "https://opencode.ai/config.json", provider: { gitlab: { options: { featureFlags: { duo_agent_platform_agentic_chat: true, duo_agent_platform: true, }, }, }, }, }), ) }, }) await Instance.provide({ directory: tmp.path, init: async () => { Env.set("GITLAB_TOKEN", "test-token") }, fn: async () => { const providers = await Provider.list() expect(providers["gitlab"]).toBeDefined() expect(providers["gitlab"].options?.featureFlags).toBeDefined() expect(providers["gitlab"].options?.featureFlags?.duo_agent_platform_agentic_chat).toBe(true) }, }) }) test("GitLab Duo: has multiple agentic chat models available", async () => { await using tmp = await tmpdir({ init: async (dir) => { await Bun.write( path.join(dir, "opencode.json"), JSON.stringify({ $schema: "https://opencode.ai/config.json", }), ) }, }) await Instance.provide({ directory: tmp.path, init: async () => { Env.set("GITLAB_TOKEN", "test-token") }, fn: async () => { const providers = await Provider.list() expect(providers["gitlab"]).toBeDefined() const models = Object.keys(providers["gitlab"].models) expect(models.length).toBeGreaterThan(0) expect(models).toContain("duo-chat-haiku-4-5") expect(models).toContain("duo-chat-sonnet-4-5") expect(models).toContain("duo-chat-opus-4-5") }, }) })