|
| 1 | +/** |
| 2 | + * Isolated tests for setCommitsAuto |
| 3 | + * |
| 4 | + * Uses mock.module() for git helpers, so must run in isolation |
| 5 | + * to avoid polluting other test files' module state. |
| 6 | + */ |
| 7 | + |
| 8 | +import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"; |
| 9 | +import type { OrgReleaseResponse } from "@sentry/api"; |
| 10 | +import { setAuthToken } from "../../src/lib/db/auth.js"; |
| 11 | +import { setOrgRegion } from "../../src/lib/db/regions.js"; |
| 12 | +import { mockFetch, useTestConfigDir } from "../helpers.js"; |
| 13 | + |
| 14 | +useTestConfigDir("set-commits-auto-"); |
| 15 | + |
| 16 | +mock.module("../../src/lib/git.js", () => ({ |
| 17 | + getRepositoryName: () => "getsentry/cli", |
| 18 | + getHeadCommit: () => "abc123def456789012345678901234567890abcd", |
| 19 | + isInsideGitWorkTree: () => true, |
| 20 | + isShallowRepository: () => false, |
| 21 | + getCommitLog: () => [], |
| 22 | + getUncommittedFiles: () => [], |
| 23 | + parseRemoteUrl: (url: string) => url, |
| 24 | +})); |
| 25 | + |
| 26 | +// Import after mock.module so the mocked git helpers are used |
| 27 | +const { setCommitsAuto } = await import("../../src/lib/api/releases.js"); |
| 28 | + |
| 29 | +const SAMPLE_RELEASE: OrgReleaseResponse = { |
| 30 | + id: 1, |
| 31 | + version: "1.0.0", |
| 32 | + shortVersion: "1.0.0", |
| 33 | + status: "open", |
| 34 | + dateCreated: "2025-01-01T00:00:00Z", |
| 35 | + dateReleased: null, |
| 36 | + firstEvent: null, |
| 37 | + lastEvent: null, |
| 38 | + ref: null, |
| 39 | + url: null, |
| 40 | + commitCount: 0, |
| 41 | + deployCount: 0, |
| 42 | + newGroups: 0, |
| 43 | + authors: [], |
| 44 | + projects: [ |
| 45 | + { |
| 46 | + id: 1, |
| 47 | + slug: "test-project", |
| 48 | + name: "Test Project", |
| 49 | + platform: "javascript", |
| 50 | + platforms: ["javascript"], |
| 51 | + hasHealthData: false, |
| 52 | + newGroups: 0, |
| 53 | + }, |
| 54 | + ], |
| 55 | + data: {}, |
| 56 | + versionInfo: null, |
| 57 | +}; |
| 58 | + |
| 59 | +const SAMPLE_REPO = { |
| 60 | + id: "1", |
| 61 | + name: "getsentry/cli", |
| 62 | + url: "https://github.com/getsentry/cli", |
| 63 | + provider: { id: "integrations:github", name: "GitHub" }, |
| 64 | + status: "active", |
| 65 | +}; |
| 66 | + |
| 67 | +let originalFetch: typeof globalThis.fetch; |
| 68 | + |
| 69 | +beforeEach(async () => { |
| 70 | + originalFetch = globalThis.fetch; |
| 71 | + await setAuthToken("test-token"); |
| 72 | + setOrgRegion("test-org", "https://us.sentry.io"); |
| 73 | +}); |
| 74 | + |
| 75 | +afterEach(() => { |
| 76 | + globalThis.fetch = originalFetch; |
| 77 | +}); |
| 78 | + |
| 79 | +describe("setCommitsAuto", () => { |
| 80 | + test("lists repos, discovers HEAD, and sends refs to the API", async () => { |
| 81 | + const withCommits = { ...SAMPLE_RELEASE, commitCount: 5 }; |
| 82 | + const requests: { method: string; url: string }[] = []; |
| 83 | + |
| 84 | + globalThis.fetch = mockFetch(async (input, init) => { |
| 85 | + const req = new Request(input!, init); |
| 86 | + requests.push({ method: req.method, url: req.url }); |
| 87 | + |
| 88 | + // First request: list org repositories (SDK uses /repos/ endpoint) |
| 89 | + if (req.url.includes("/repos/")) { |
| 90 | + expect(req.method).toBe("GET"); |
| 91 | + return new Response(JSON.stringify([SAMPLE_REPO]), { |
| 92 | + status: 200, |
| 93 | + headers: { "Content-Type": "application/json" }, |
| 94 | + }); |
| 95 | + } |
| 96 | + |
| 97 | + // Second request: PUT refs on the release |
| 98 | + expect(req.method).toBe("PUT"); |
| 99 | + expect(req.url).toContain("/releases/1.0.0/"); |
| 100 | + const body = (await req.json()) as { |
| 101 | + refs: Array<{ repository: string; commit: string }>; |
| 102 | + }; |
| 103 | + expect(body.refs).toEqual([ |
| 104 | + { |
| 105 | + repository: "getsentry/cli", |
| 106 | + commit: "abc123def456789012345678901234567890abcd", |
| 107 | + }, |
| 108 | + ]); |
| 109 | + return new Response(JSON.stringify(withCommits), { |
| 110 | + status: 200, |
| 111 | + headers: { "Content-Type": "application/json" }, |
| 112 | + }); |
| 113 | + }); |
| 114 | + |
| 115 | + const release = await setCommitsAuto("test-org", "1.0.0", "/tmp"); |
| 116 | + |
| 117 | + expect(release.commitCount).toBe(5); |
| 118 | + expect(requests).toHaveLength(2); |
| 119 | + }); |
| 120 | + |
| 121 | + test("throws when org has no repositories", async () => { |
| 122 | + globalThis.fetch = mockFetch( |
| 123 | + async () => |
| 124 | + new Response(JSON.stringify([]), { |
| 125 | + status: 200, |
| 126 | + headers: { "Content-Type": "application/json" }, |
| 127 | + }) |
| 128 | + ); |
| 129 | + |
| 130 | + expect(setCommitsAuto("test-org", "1.0.0", "/tmp")).rejects.toThrow( |
| 131 | + /No repository integrations/ |
| 132 | + ); |
| 133 | + }); |
| 134 | +}); |
0 commit comments