Skip to content

g1t/apps/web/app/lib/pull-detail.test.ts

67 lines2,798 bytesCodeBlame

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar1import assert from "node:assert/strict";
2import { test } from "node:test";
3
4import { pullDetailFromWire, workClient } from "../../../../packages/contracts/src/clients.ts";
5
6/** A pull request's detail as the work service writes it: its own fields in snake_case. */
7const wire = {
8 pull: { number: 7, headCommit: "abc" },
9 issue: null,
10 comments: [],
11 checks: null,
12 overlaps: [],
13 behind: false,
14 review_pending: true,
15 lifecycle: null,
16 landing: false,
17 stalled: null,
18 messages: [],
19 statuses: [],
20 mergeable: "clean",
21 conflicts: [],
22 earlier_checks: [{ id: "chk_1", status: "failed" }],
23 required_checks: [{ name: "CI", state: "failure", description: null, targetUrl: null }],
24 code_owners: { path: ".g1t/CODEOWNERS", required: true, missing: ["@acme/web"] },
25};
26
27test("a pull request's own snake_case fields are read into camelCase", () => {
28 const detail = pullDetailFromWire(wire);
29 assert.equal(detail.reviewPending, true);
30 assert.deepEqual(detail.earlierChecks, wire.earlier_checks);
31 assert.deepEqual(detail.requiredChecks, wire.required_checks);
32 assert.deepEqual(detail.codeOwners, wire.code_owners);
33 // The snake_case names are gone, and what they hold is untouched.
34 for (const key of ["review_pending", "earlier_checks", "required_checks", "code_owners"]) assert.ok(!(key in detail), key);
35 assert.equal(detail.requiredChecks?.[0]?.targetUrl, null);
36 assert.equal(detail.pull.number, 7);
37});
38
39test("camelCase is taken as it is, and a missing review_pending is false", () => {
40 const detail = pullDetailFromWire({ pull: {}, requiredChecks: [{ name: "CI" }], reviewPending: false });
41 assert.deepEqual(detail.requiredChecks, [{ name: "CI" }]);
42 assert.equal(detail.reviewPending, false);
43 assert.equal(pullDetailFromWire({ pull: {} }).reviewPending, false);
44});
45
46test("getPull reads the work service's answer at the edge", async () => {
47 const calls: string[] = [];
48 const service = {
49 fetch: async (url: string) => {
50 calls.push(url);
51 return Response.json({ ok: true, value: wire });
52 },
53 };
54 const found = await workClient(service).getPull({ namespace: "acme", name: "web" }, 7, null);
55 assert.deepEqual(calls, ["https://service/rpc/get_pull"]);
56 assert.ok(found.ok);
57 assert.equal(found.value.reviewPending, true);
58 assert.equal(found.value.requiredChecks?.[0]?.name, "CI");
59 assert.equal(found.value.earlierChecks?.length, 1);
60 assert.deepEqual(found.value.codeOwners?.missing, ["@acme/web"]);
61});
62
63test("getPull passes a refusal through", async () => {
64 const service = { fetch: async () => Response.json({ ok: false, error: { code: "not_found", message: "No such pull request." } }) };
65 const found = await workClient(service).getPull({ namespace: "acme", name: "web" }, 8, null);
66 assert.equal(found.ok, false);
67});