gitlab-duo.test.ts 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. import { test, expect } from "bun:test"
  2. import path from "path"
  3. import { tmpdir } from "../fixture/fixture"
  4. import { Instance } from "../../src/project/instance"
  5. import { Provider } from "../../src/provider/provider"
  6. import { Env } from "../../src/env"
  7. import { Global } from "../../src/global"
  8. test("GitLab Duo: loads provider with API key from environment", async () => {
  9. await using tmp = await tmpdir({
  10. init: async (dir) => {
  11. await Bun.write(
  12. path.join(dir, "opencode.json"),
  13. JSON.stringify({
  14. $schema: "https://opencode.ai/config.json",
  15. }),
  16. )
  17. },
  18. })
  19. await Instance.provide({
  20. directory: tmp.path,
  21. init: async () => {
  22. Env.set("GITLAB_TOKEN", "test-gitlab-token")
  23. },
  24. fn: async () => {
  25. const providers = await Provider.list()
  26. expect(providers["gitlab"]).toBeDefined()
  27. expect(providers["gitlab"].key).toBe("test-gitlab-token")
  28. },
  29. })
  30. })
  31. test("GitLab Duo: config instanceUrl option sets baseURL", async () => {
  32. await using tmp = await tmpdir({
  33. init: async (dir) => {
  34. await Bun.write(
  35. path.join(dir, "opencode.json"),
  36. JSON.stringify({
  37. $schema: "https://opencode.ai/config.json",
  38. provider: {
  39. gitlab: {
  40. options: {
  41. instanceUrl: "https://gitlab.example.com",
  42. },
  43. },
  44. },
  45. }),
  46. )
  47. },
  48. })
  49. await Instance.provide({
  50. directory: tmp.path,
  51. init: async () => {
  52. Env.set("GITLAB_TOKEN", "test-token")
  53. Env.set("GITLAB_INSTANCE_URL", "https://gitlab.example.com")
  54. },
  55. fn: async () => {
  56. const providers = await Provider.list()
  57. expect(providers["gitlab"]).toBeDefined()
  58. expect(providers["gitlab"].options?.instanceUrl).toBe("https://gitlab.example.com")
  59. },
  60. })
  61. })
  62. test("GitLab Duo: loads with OAuth token from auth.json", async () => {
  63. await using tmp = await tmpdir({
  64. init: async (dir) => {
  65. await Bun.write(
  66. path.join(dir, "opencode.json"),
  67. JSON.stringify({
  68. $schema: "https://opencode.ai/config.json",
  69. }),
  70. )
  71. },
  72. })
  73. const authPath = path.join(Global.Path.data, "auth.json")
  74. await Bun.write(
  75. authPath,
  76. JSON.stringify({
  77. gitlab: {
  78. type: "oauth",
  79. access: "test-access-token",
  80. refresh: "test-refresh-token",
  81. expires: Date.now() + 3600000,
  82. },
  83. }),
  84. )
  85. await Instance.provide({
  86. directory: tmp.path,
  87. init: async () => {
  88. Env.set("GITLAB_TOKEN", "")
  89. },
  90. fn: async () => {
  91. const providers = await Provider.list()
  92. expect(providers["gitlab"]).toBeDefined()
  93. },
  94. })
  95. })
  96. test("GitLab Duo: loads with Personal Access Token from auth.json", async () => {
  97. await using tmp = await tmpdir({
  98. init: async (dir) => {
  99. await Bun.write(
  100. path.join(dir, "opencode.json"),
  101. JSON.stringify({
  102. $schema: "https://opencode.ai/config.json",
  103. }),
  104. )
  105. },
  106. })
  107. const authPath2 = path.join(Global.Path.data, "auth.json")
  108. await Bun.write(
  109. authPath2,
  110. JSON.stringify({
  111. gitlab: {
  112. type: "api",
  113. key: "glpat-test-pat-token",
  114. },
  115. }),
  116. )
  117. await Instance.provide({
  118. directory: tmp.path,
  119. init: async () => {
  120. Env.set("GITLAB_TOKEN", "")
  121. },
  122. fn: async () => {
  123. const providers = await Provider.list()
  124. expect(providers["gitlab"]).toBeDefined()
  125. expect(providers["gitlab"].key).toBe("glpat-test-pat-token")
  126. },
  127. })
  128. })
  129. test("GitLab Duo: supports self-hosted instance configuration", async () => {
  130. await using tmp = await tmpdir({
  131. init: async (dir) => {
  132. await Bun.write(
  133. path.join(dir, "opencode.json"),
  134. JSON.stringify({
  135. $schema: "https://opencode.ai/config.json",
  136. provider: {
  137. gitlab: {
  138. options: {
  139. instanceUrl: "https://gitlab.company.internal",
  140. apiKey: "glpat-internal-token",
  141. },
  142. },
  143. },
  144. }),
  145. )
  146. },
  147. })
  148. await Instance.provide({
  149. directory: tmp.path,
  150. init: async () => {
  151. Env.set("GITLAB_INSTANCE_URL", "https://gitlab.company.internal")
  152. },
  153. fn: async () => {
  154. const providers = await Provider.list()
  155. expect(providers["gitlab"]).toBeDefined()
  156. expect(providers["gitlab"].options?.instanceUrl).toBe("https://gitlab.company.internal")
  157. },
  158. })
  159. })
  160. test("GitLab Duo: config apiKey takes precedence over environment variable", async () => {
  161. await using tmp = await tmpdir({
  162. init: async (dir) => {
  163. await Bun.write(
  164. path.join(dir, "opencode.json"),
  165. JSON.stringify({
  166. $schema: "https://opencode.ai/config.json",
  167. provider: {
  168. gitlab: {
  169. options: {
  170. apiKey: "config-token",
  171. },
  172. },
  173. },
  174. }),
  175. )
  176. },
  177. })
  178. await Instance.provide({
  179. directory: tmp.path,
  180. init: async () => {
  181. Env.set("GITLAB_TOKEN", "env-token")
  182. },
  183. fn: async () => {
  184. const providers = await Provider.list()
  185. expect(providers["gitlab"]).toBeDefined()
  186. },
  187. })
  188. })
  189. test("GitLab Duo: supports feature flags configuration", async () => {
  190. await using tmp = await tmpdir({
  191. init: async (dir) => {
  192. await Bun.write(
  193. path.join(dir, "opencode.json"),
  194. JSON.stringify({
  195. $schema: "https://opencode.ai/config.json",
  196. provider: {
  197. gitlab: {
  198. options: {
  199. featureFlags: {
  200. duo_agent_platform_agentic_chat: true,
  201. duo_agent_platform: true,
  202. },
  203. },
  204. },
  205. },
  206. }),
  207. )
  208. },
  209. })
  210. await Instance.provide({
  211. directory: tmp.path,
  212. init: async () => {
  213. Env.set("GITLAB_TOKEN", "test-token")
  214. },
  215. fn: async () => {
  216. const providers = await Provider.list()
  217. expect(providers["gitlab"]).toBeDefined()
  218. expect(providers["gitlab"].options?.featureFlags).toBeDefined()
  219. expect(providers["gitlab"].options?.featureFlags?.duo_agent_platform_agentic_chat).toBe(true)
  220. },
  221. })
  222. })
  223. test("GitLab Duo: has multiple agentic chat models available", async () => {
  224. await using tmp = await tmpdir({
  225. init: async (dir) => {
  226. await Bun.write(
  227. path.join(dir, "opencode.json"),
  228. JSON.stringify({
  229. $schema: "https://opencode.ai/config.json",
  230. }),
  231. )
  232. },
  233. })
  234. await Instance.provide({
  235. directory: tmp.path,
  236. init: async () => {
  237. Env.set("GITLAB_TOKEN", "test-token")
  238. },
  239. fn: async () => {
  240. const providers = await Provider.list()
  241. expect(providers["gitlab"]).toBeDefined()
  242. const models = Object.keys(providers["gitlab"].models)
  243. expect(models.length).toBeGreaterThan(0)
  244. expect(models).toContain("duo-chat-haiku-4-5")
  245. expect(models).toContain("duo-chat-sonnet-4-5")
  246. expect(models).toContain("duo-chat-opus-4-5")
  247. },
  248. })
  249. })