History

feat(source-control): add Bitbucket & Azure Devops providers (#2473)

Julius Marminge committed 6 months agov0.0.22-nightly.20260504.196

Commit 91a03e01 parent d501ebe59 files · +5834 −2327Browse files

Showing the changes to apps/server/src/sourceControl/BitbucketSourceControlProvider.test.ts (1 of 59 files). Show all

Unified · Split

apps/server/src/sourceControl/BitbucketSourceControlProvider.test.ts+126−0
@@ -0,0 +1,126 @@
1+import { assert, it } from "@effect/vitest";
2+import { Effect, Layer, Option } from "effect";
3+
4+import * as BitbucketApi from "./BitbucketApi.ts";
5+import * as BitbucketSourceControlProvider from "./BitbucketSourceControlProvider.ts";
6+
7+function makeProvider(bitbucket: Partial<BitbucketApi.BitbucketApiShape>) {
8+ return BitbucketSourceControlProvider.make().pipe(
9+ Effect.provide(Layer.mock(BitbucketApi.BitbucketApi)(bitbucket)),
10+ );
11+}
12+
13+it.effect("maps Bitbucket PR summaries into provider-neutral change requests", () =>
14+ Effect.gen(function* () {
15+ const provider = yield* makeProvider({
16+ getPullRequest: () =>
17+ Effect.succeed({
18+ number: 42,
19+ title: "Add Bitbucket provider",
20+ url: "https://bitbucket.org/pingdotgg/t3code/pull-requests/42",
21+ baseRefName: "main",
22+ headRefName: "feature/source-control",
23+ state: "open",
24+ updatedAt: Option.none(),
25+ isCrossRepository: true,
26+ headRepositoryNameWithOwner: "fork/t3code",
27+ headRepositoryOwnerLogin: "fork",
28+ }),
29+ });
30+
31+ const changeRequest = yield* provider.getChangeRequest({
32+ cwd: "/repo",
33+ reference: "42",
34+ });
35+
36+ assert.deepStrictEqual(changeRequest, {
37+ provider: "bitbucket",
38+ number: 42,
39+ title: "Add Bitbucket provider",
40+ url: "https://bitbucket.org/pingdotgg/t3code/pull-requests/42",
41+ baseRefName: "main",
42+ headRefName: "feature/source-control",
43+ state: "open",
44+ updatedAt: Option.none(),
45+ isCrossRepository: true,
46+ headRepositoryNameWithOwner: "fork/t3code",
47+ headRepositoryOwnerLogin: "fork",
48+ });
49+ }),
50+);
51+
52+it.effect("lists Bitbucket PRs through provider-neutral input names", () =>
53+ Effect.gen(function* () {
54+ let listInput: Parameters<BitbucketApi.BitbucketApiShape["listPullRequests"]>[0] | null = null;
55+ const provider = yield* makeProvider({
56+ listPullRequests: (input) => {
57+ listInput = input;
58+ return Effect.succeed([]);
59+ },
60+ });
61+
62+ yield* provider.listChangeRequests({
63+ cwd: "/repo",
64+ headSelector: "feature/provider",
65+ state: "all",
66+ limit: 10,
67+ });
68+
69+ assert.deepStrictEqual(listInput, {
70+ cwd: "/repo",
71+ headSelector: "feature/provider",
72+ state: "all",
73+ limit: 10,
74+ });
75+ }),
76+);
77+
78+it.effect("creates Bitbucket PRs through provider-neutral input names", () =>
79+ Effect.gen(function* () {
80+ let createInput: Parameters<BitbucketApi.BitbucketApiShape["createPullRequest"]>[0] | null =
81+ null;
82+ const provider = yield* makeProvider({
83+ createPullRequest: (input) => {
84+ createInput = input;
85+ return Effect.void;
86+ },
87+ });
88+
89+ yield* provider.createChangeRequest({
90+ cwd: "/repo",
91+ baseRefName: "main",
92+ headSelector: "owner:feature/provider",
93+ title: "Provider PR",
94+ bodyFile: "/tmp/body.md",
95+ });
96+
97+ assert.deepStrictEqual(createInput, {
98+ cwd: "/repo",
99+ baseBranch: "main",
100+ headSelector: "owner:feature/provider",
101+ source: {
102+ owner: "owner",
103+ refName: "feature/provider",
104+ },
105+ title: "Provider PR",
106+ bodyFile: "/tmp/body.md",
107+ });
108+ }),
109+);
110+
111+it.effect("uses Bitbucket API repository detection for default branch lookup", () =>
112+ Effect.gen(function* () {
113+ let cwdInput: string | null = null;
114+ const provider = yield* makeProvider({
115+ getDefaultBranch: (input) => {
116+ cwdInput = input.cwd;
117+ return Effect.succeed("main");
118+ },
119+ });
120+
121+ const defaultBranch = yield* provider.getDefaultBranch({ cwd: "/repo" });
122+
123+ assert.strictEqual(defaultBranch, "main");
124+ assert.strictEqual(cwdInput, "/repo");
125+ }),
126+);