diff --git a/packages/source-control-gitlab/src/server/GitLabPullRequestProvider.test.ts b/packages/source-control-gitlab/src/server/GitLabPullRequestProvider.test.ts index d506aace948929752948cb39339cd8d861eb314f..6800bc4675416ddf5fc09960718022dd140b9b5a 100644 --- a/packages/source-control-gitlab/src/server/GitLabPullRequestProvider.test.ts +++ b/packages/source-control-gitlab/src/server/GitLabPullRequestProvider.test.ts @@ -212,3 +212,69 @@ describe("rewriting what has already been said", () => { }), ); }); + +describe("expanding unchanged lines", () => { + const change = { + cwd: "/w", + repository: "acme/web", + host: "gitlab.com", + number: 7, + changeType: "change" as const, + oldPath: "src/page.ts", + newPath: "src/page.ts", + }; + + it.effect("reads both sides of a file through the merge request or one of its commits", () => + Effect.gen(function* () { + const getMergeRequestDiffFileContents = vi.fn(() => + Effect.succeed({ oldContents: "before\n", newContents: "after\n" }), + ); + const provider = yield* make.pipe( + Effect.provide( + Layer.mock(GitLabPullRequestCli.GitLabPullRequestCli)({ + getMergeRequestDiffFileContents, + }), + ), + ); + assert.isDefined(provider.getDiffFileContents); + const oneCommit = { ...change, commit: "a1b2c3d" }; + + expect(yield* provider.getDiffFileContents(change)).toEqual({ + oldContents: "before\n", + newContents: "after\n", + }); + yield* provider.getDiffFileContents(oneCommit); + expect(getMergeRequestDiffFileContents).toHaveBeenNthCalledWith(1, change); + expect(getMergeRequestDiffFileContents).toHaveBeenNthCalledWith(2, oneCommit); + }), + ); + + it.effect("reports a file GitLab cannot expand as a failed read", () => + Effect.gen(function* () { + const provider = yield* make.pipe( + Effect.provide( + Layer.mock(GitLabPullRequestCli.GitLabPullRequestCli)({ + getMergeRequestDiffFileContents: () => + Effect.fail( + new GitLabPullRequestCli.GitLabDiffFileContentsUnavailableError({ + command: "glab", + cwd: "/w", + path: "assets/logo.png", + reason: "binary", + }), + ), + }), + ), + ); + assert.isDefined(provider.getDiffFileContents); + + expect(yield* Effect.flip(provider.getDiffFileContents(change))).toMatchObject({ + _tag: "PullRequestProviderError", + provider: "gitlab", + operation: "getDiffFileContents", + reason: "failed", + detail: "The diff file 'assets/logo.png' is binary.", + }); + }), + ); +}); diff --git a/packages/source-control-gitlab/src/server/GitLabPullRequestProvider.ts b/packages/source-control-gitlab/src/server/GitLabPullRequestProvider.ts index 89307f696d7ae3e4f816d82aab8f38b1c6a761ff..a25d5314ef4db77331d4e12b2cac7b17829a1a4d 100644 --- a/packages/source-control-gitlab/src/server/GitLabPullRequestProvider.ts +++ b/packages/source-control-gitlab/src/server/GitLabPullRequestProvider.ts @@ -223,6 +223,9 @@ export const make = Effect.gen(function* () { getDiff: (input) => cli.getMergeRequestDiff(input).pipe(Effect.mapError(fail("getDiff"))), + getDiffFileContents: (input) => + cli.getMergeRequestDiffFileContents(input).pipe(Effect.mapError(fail("getDiffFileContents"))), + // What each marked file is at the head, which is what tells a mark that still stands from one // the branch has moved past. GitLab's own local-storage marks are keyed on the blob id too, // so this stales at the same moment its web UI would.