forked from MergeFi/frontend
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathadapters.test.ts
More file actions
122 lines (110 loc) · 3.49 KB
/
Copy pathadapters.test.ts
File metadata and controls
122 lines (110 loc) · 3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/**
* adapters.test.ts
*
* Tests for adaptBounty's mapping of milestoneId (#86) — declared on the
* Bounty type but never actually set by adaptBounty prior to this fix.
*/
import { adaptBounty, type RawBounty } from "./adapters";
function rawBounty(overrides: Partial<RawBounty> = {}): RawBounty {
return {
id: "bounty-1",
amount: "500",
asset: "USDC",
difficulty: "intermediate",
status: "open",
deadline: "2026-01-01T00:00:00.000Z",
escrowId: null,
issue: {
number: 42,
title: "Fix the thing",
body: "Description",
labels: ["bug"],
repository: { owner: "acme", name: "widgets" },
},
...overrides,
};
}
describe("adaptBounty — milestoneId mapping (#86)", () => {
it("maps milestoneId from the nested issue when the issue belongs to a milestone", () => {
const raw = rawBounty({
issue: {
number: 42,
title: "Fix the thing",
body: "Description",
labels: ["bug"],
repository: { owner: "acme", name: "widgets" },
milestoneId: "milestone-7",
},
});
expect(adaptBounty(raw).milestoneId).toBe("milestone-7");
});
it("leaves milestoneId undefined when the issue has no milestone association", () => {
// issue.milestoneId omitted entirely — the realistic shape for most
// issues, which aren't part of any milestone.
const raw = rawBounty();
expect(adaptBounty(raw).milestoneId).toBeUndefined();
});
it("normalizes a null milestoneId (no association) the same as an omitted one", () => {
// mergefi-backend's Issue.milestoneId is a nullable column, so the
// real backend response says "no milestone" via `null`, not by
// omitting the key entirely.
const raw = rawBounty({
issue: {
number: 42,
title: "Fix the thing",
body: "Description",
labels: ["bug"],
repository: { owner: "acme", name: "widgets" },
milestoneId: null,
},
});
expect(adaptBounty(raw).milestoneId).toBeUndefined();
});
it("leaves milestoneId undefined when the bounty has no issue at all", () => {
const raw = rawBounty({ issue: undefined });
expect(adaptBounty(raw).milestoneId).toBeUndefined();
});
});
describe("adaptBounty — field coverage audit (#86)", () => {
// Every key the Bounty interface declares (src/types/index.ts). Kept as
// an explicit list, checked against adaptBounty's actual output below,
// so a future field added to Bounty but never mapped here — exactly
// milestoneId's bug — fails this test instead of silently shipping.
const EXPECTED_BOUNTY_FIELDS = [
"id",
"repo",
"org",
"issueNumber",
"title",
"description",
"reward",
"asset",
"difficulty",
"status",
"deadline",
"labels",
"claimedBy",
"teamSplits",
"milestoneId",
"escrowId",
] as const;
it("sets every Bounty field to a defined value given a fully-populated raw bounty", () => {
const raw = rawBounty({
escrowId: "escrow-1",
claimedBy: { username: "alice" },
team: { splits: [{ role: "Lead", percentage: "100", user: { username: "alice" } }] },
issue: {
number: 42,
title: "Fix the thing",
body: "Description",
labels: ["bug"],
repository: { owner: "acme", name: "widgets" },
milestoneId: "milestone-7",
},
});
const bounty = adaptBounty(raw);
for (const field of EXPECTED_BOUNTY_FIELDS) {
expect(bounty[field]).not.toBeUndefined();
}
});
});