Skip to content

Commit f42038f

Browse files
committed
undo
1 parent 0f4a846 commit f42038f

5 files changed

Lines changed: 102 additions & 92 deletions

File tree

.github/workflows/tests.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,7 @@ jobs:
4747
run: bun lint
4848

4949
- name: Run Unit Tests
50-
run: |
51-
SEED=${RANDOM} && echo "Running tests with seed: $SEED" && bun test --seed $SEED
50+
run: bun test
5251

5352
- name: Package
5453
run: bun package

test/helpers/add-pr-approval-label.test.ts

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,38 @@ See the License for the specific language governing permissions and
1111
limitations under the License.
1212
*/
1313

14-
import { describe, it, expect, beforeEach, mock } from 'bun:test';
14+
import { describe, it, expect, beforeEach, afterEach, mock, spyOn } from 'bun:test';
1515
import { setupMocks } from '../setup';
1616

1717
setupMocks();
1818

19-
// Mock getCoreMemberLogins
20-
mock.module('../../src/utils/get-core-member-logins', () => ({
21-
getCoreMemberLogins: mock(() => Promise.resolve(['user1', 'user2', 'user3', 'user4', 'user5'])),
22-
getRequiredCodeOwnersEntries: mock(() => Promise.resolve([]))
23-
}));
24-
2519
const { CORE_APPROVED_PR_LABEL, PEER_APPROVED_PR_LABEL } = await import('../../src/constants');
2620
const { addPrApprovalLabel } = await import('../../src/helpers/add-pr-approval-label');
2721
const { context } = await import('@actions/github');
28-
const { getCoreMemberLogins } = await import('../../src/utils/get-core-member-logins');
22+
const getCoreMemberLoginsModule = await import('../../src/utils/get-core-member-logins');
2923
const { octokit } = await import('../../src/octokit');
3024

3125
const teams = 'team1\nteam2';
3226

3327
describe('addPrApprovalLabel', () => {
28+
let getCoreMemberLoginsSpy: ReturnType<typeof spyOn>;
29+
let getRequiredCodeOwnersEntriesSpy: ReturnType<typeof spyOn>;
30+
3431
beforeEach(() => {
3532
mock.clearAllMocks();
33+
getCoreMemberLoginsSpy = spyOn(getCoreMemberLoginsModule, 'getCoreMemberLogins').mockResolvedValue([
34+
'user1',
35+
'user2',
36+
'user3',
37+
'user4',
38+
'user5'
39+
]);
40+
getRequiredCodeOwnersEntriesSpy = spyOn(getCoreMemberLoginsModule, 'getRequiredCodeOwnersEntries').mockResolvedValue([]);
41+
});
42+
43+
afterEach(() => {
44+
getCoreMemberLoginsSpy.mockRestore();
45+
getRequiredCodeOwnersEntriesSpy.mockRestore();
3646
});
3747

3848
describe('core approver case', () => {
@@ -46,7 +56,7 @@ describe('addPrApprovalLabel', () => {
4656
});
4757

4858
it('should call getCoreMemberLogins with correct params', () => {
49-
expect(getCoreMemberLogins).toHaveBeenCalledWith({ pull_number: 123, teams: ['team1', 'team2'] });
59+
expect(getCoreMemberLoginsModule.getCoreMemberLogins).toHaveBeenCalledWith({ pull_number: 123, teams: ['team1', 'team2'] });
5060
});
5161

5262
it('should add core approved label to the pr', () => {

test/helpers/approvals-satisfied.test.ts

Lines changed: 48 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ See the License for the specific language governing permissions and
1111
limitations under the License.
1212
*/
1313

14-
import { Mock, beforeEach, describe, expect, it, mock } from 'bun:test';
14+
import { Mock, beforeEach, afterEach, describe, expect, it, mock, spyOn } from 'bun:test';
1515
import { setupMocks } from '../setup';
1616

1717
setupMocks();
@@ -25,23 +25,10 @@ const ownerMap: { [key: string]: { data: { login: string }[] } } = {
2525
team6: { data: [{ login: 'user8' }, { login: 'user9' }] }
2626
};
2727

28-
// Mock paginateMembersInOrg
29-
mock.module('../../src/utils/paginate-members-in-org', () => ({
30-
paginateMembersInOrg: mock(async (team: string) => {
31-
const teamSlug = team.replace('@ExpediaGroup/', '').replace('ExpediaGroup/', '').replace('owner/', '');
32-
return ownerMap[teamSlug]?.data || [];
33-
})
34-
}));
35-
36-
// Mock getRequiredCodeOwnersEntries
37-
mock.module('../../src/utils/get-core-member-logins', () => ({
38-
getRequiredCodeOwnersEntries: mock(() => Promise.resolve([])),
39-
getCoreMemberLogins: mock(() => Promise.resolve([]))
40-
}));
41-
4228
const { approvalsSatisfied } = await import('../../src/helpers/approvals-satisfied');
4329
const { octokit } = await import('../../src/octokit');
44-
const { getRequiredCodeOwnersEntries } = await import('../../src/utils/get-core-member-logins');
30+
const getCoreMemberLoginsModule = await import('../../src/utils/get-core-member-logins');
31+
const paginateMembersInOrgModule = await import('../../src/utils/paginate-members-in-org');
4532
const core = await import('@actions/core');
4633

4734
const mockPagination = (result: unknown) => {
@@ -51,8 +38,24 @@ const mockPagination = (result: unknown) => {
5138
};
5239

5340
describe('approvalsSatisfied', () => {
41+
let paginateMembersInOrgSpy: ReturnType<typeof spyOn>;
42+
let getRequiredCodeOwnersEntriesSpy: ReturnType<typeof spyOn>;
43+
let getCoreMemberLoginsSpy: ReturnType<typeof spyOn>;
44+
5445
beforeEach(() => {
5546
mock.clearAllMocks();
47+
paginateMembersInOrgSpy = spyOn(paginateMembersInOrgModule, 'paginateMembersInOrg').mockImplementation(async (team: string) => {
48+
const teamSlug = team.replace('@ExpediaGroup/', '').replace('ExpediaGroup/', '').replace('owner/', '');
49+
return (ownerMap[teamSlug]?.data || []) as any;
50+
});
51+
getRequiredCodeOwnersEntriesSpy = spyOn(getCoreMemberLoginsModule, 'getRequiredCodeOwnersEntries').mockResolvedValue([]);
52+
getCoreMemberLoginsSpy = spyOn(getCoreMemberLoginsModule, 'getCoreMemberLogins').mockResolvedValue([]);
53+
});
54+
55+
afterEach(() => {
56+
paginateMembersInOrgSpy.mockRestore();
57+
getRequiredCodeOwnersEntriesSpy.mockRestore();
58+
getCoreMemberLoginsSpy.mockRestore();
5659
});
5760

5861
it('should return false when passing teams override and required approvals are not met', async () => {
@@ -67,7 +70,7 @@ describe('approvalsSatisfied', () => {
6770

6871
const result = await approvalsSatisfied({ teams: 'team1', pull_number: '12345' });
6972
expect(octokit.pulls.listReviews).toHaveBeenCalledWith({ pull_number: 12345, repo: 'repo', owner: 'owner', page: 1, per_page: 100 });
70-
expect(getRequiredCodeOwnersEntries).not.toHaveBeenCalled();
73+
expect(getCoreMemberLoginsModule.getRequiredCodeOwnersEntries).not.toHaveBeenCalled();
7174
expect(result).toBe(false);
7275
});
7376

@@ -82,13 +85,13 @@ describe('approvalsSatisfied', () => {
8285
});
8386
const result = await approvalsSatisfied({ teams: 'team1', pull_number: '12345' });
8487
expect(octokit.pulls.listReviews).toHaveBeenCalledWith({ pull_number: 12345, repo: 'repo', owner: 'owner', page: 1, per_page: 100 });
85-
expect(getRequiredCodeOwnersEntries).not.toHaveBeenCalled();
88+
expect(getCoreMemberLoginsModule.getRequiredCodeOwnersEntries).not.toHaveBeenCalled();
8689
expect(result).toBe(true);
8790
});
8891

8992
it('should throw an error when passing teams override with full name and org is different than repo org', async () => {
9093
const result = await approvalsSatisfied({ teams: 'owner/team2\nsomeOtherOrg/team1', pull_number: '12345' });
91-
expect(getRequiredCodeOwnersEntries).not.toHaveBeenCalled();
94+
expect(getCoreMemberLoginsModule.getRequiredCodeOwnersEntries).not.toHaveBeenCalled();
9295
expect(core.setFailed).toHaveBeenCalled();
9396
expect(result).toBe(false);
9497
});
@@ -108,7 +111,7 @@ describe('approvalsSatisfied', () => {
108111
});
109112
const result = await approvalsSatisfied({ teams: 'team1\nteam2', pull_number: '12345', number_of_reviewers: '2' });
110113
expect(octokit.pulls.listReviews).toHaveBeenCalledWith({ pull_number: 12345, repo: 'repo', owner: 'owner', page: 1, per_page: 100 });
111-
expect(getRequiredCodeOwnersEntries).not.toHaveBeenCalled();
114+
expect(getCoreMemberLoginsModule.getRequiredCodeOwnersEntries).not.toHaveBeenCalled();
112115
expect(result).toBe(true);
113116
});
114117

@@ -124,7 +127,7 @@ describe('approvalsSatisfied', () => {
124127

125128
const result = await approvalsSatisfied({ users: 'user1', pull_number: '12345' });
126129
expect(octokit.pulls.listReviews).toHaveBeenCalledWith({ pull_number: 12345, repo: 'repo', owner: 'owner', page: 1, per_page: 100 });
127-
expect(getRequiredCodeOwnersEntries).not.toHaveBeenCalled();
130+
expect(getCoreMemberLoginsModule.getRequiredCodeOwnersEntries).not.toHaveBeenCalled();
128131
expect(result).toBe(false);
129132
});
130133

@@ -139,7 +142,7 @@ describe('approvalsSatisfied', () => {
139142
});
140143
const result = await approvalsSatisfied({ users: 'user1', pull_number: '12345' });
141144
expect(octokit.pulls.listReviews).toHaveBeenCalledWith({ pull_number: 12345, repo: 'repo', owner: 'owner', page: 1, per_page: 100 });
142-
expect(getRequiredCodeOwnersEntries).not.toHaveBeenCalled();
145+
expect(getCoreMemberLoginsModule.getRequiredCodeOwnersEntries).not.toHaveBeenCalled();
143146
expect(result).toBe(true);
144147
});
145148

@@ -162,7 +165,7 @@ describe('approvalsSatisfied', () => {
162165
});
163166
const result = await approvalsSatisfied({ users: 'user1\nuser2\nuser3', pull_number: '12345', number_of_reviewers: '2' });
164167
expect(octokit.pulls.listReviews).toHaveBeenCalledWith({ pull_number: 12345, repo: 'repo', owner: 'owner', page: 1, per_page: 100 });
165-
expect(getRequiredCodeOwnersEntries).not.toHaveBeenCalled();
168+
expect(getCoreMemberLoginsModule.getRequiredCodeOwnersEntries).not.toHaveBeenCalled();
166169
expect(result).toBe(true);
167170
});
168171

@@ -190,12 +193,12 @@ describe('approvalsSatisfied', () => {
190193
number_of_reviewers: '2'
191194
});
192195
expect(octokit.pulls.listReviews).toHaveBeenCalledWith({ pull_number: 12345, repo: 'repo', owner: 'owner', page: 1, per_page: 100 });
193-
expect(getRequiredCodeOwnersEntries).not.toHaveBeenCalled();
196+
expect(getCoreMemberLoginsModule.getRequiredCodeOwnersEntries).not.toHaveBeenCalled();
194197
expect(result).toBe(true);
195198
});
196199

197200
it('should return false when a core member has not approved', async () => {
198-
(getRequiredCodeOwnersEntries as Mock<any>).mockResolvedValue([{ owners: ['@ExpediaGroup/team1'] }]);
201+
getRequiredCodeOwnersEntriesSpy.mockResolvedValue([{ owners: ['@ExpediaGroup/team1'] }]);
199202
mockPagination({
200203
data: [
201204
{
@@ -206,12 +209,12 @@ describe('approvalsSatisfied', () => {
206209
});
207210
const result = await approvalsSatisfied({ pull_number: '12345' });
208211
expect(octokit.pulls.listReviews).toHaveBeenCalledWith({ pull_number: 12345, repo: 'repo', owner: 'owner', page: 1, per_page: 100 });
209-
expect(getRequiredCodeOwnersEntries).toHaveBeenCalledWith(12345, undefined);
212+
expect(getCoreMemberLoginsModule.getRequiredCodeOwnersEntries).toHaveBeenCalledWith(12345, undefined);
210213
expect(result).toBe(false);
211214
});
212215

213216
it('should return true when a member from the team specified in codeowners_overrides has approved', async () => {
214-
(getRequiredCodeOwnersEntries as Mock<any>).mockResolvedValue([{ owners: ['@ExpediaGroup/team6'] }]);
217+
getRequiredCodeOwnersEntriesSpy.mockResolvedValue([{ owners: ['@ExpediaGroup/team6'] }]);
215218
mockPagination({
216219
data: [
217220
{
@@ -223,12 +226,12 @@ describe('approvalsSatisfied', () => {
223226
const codeOwnersOverrides = '* @ExpediaGroup/team6';
224227
const result = await approvalsSatisfied({ pull_number: '12345', codeowners_overrides: codeOwnersOverrides });
225228
expect(octokit.pulls.listReviews).toHaveBeenCalledWith({ pull_number: 12345, repo: 'repo', owner: 'owner', page: 1, per_page: 100 });
226-
expect(getRequiredCodeOwnersEntries).toHaveBeenCalledWith(12345, codeOwnersOverrides);
229+
expect(getCoreMemberLoginsModule.getRequiredCodeOwnersEntries).toHaveBeenCalledWith(12345, codeOwnersOverrides);
227230
expect(result).toBe(true);
228231
});
229232

230233
it('should return true when a core member has approved', async () => {
231-
(getRequiredCodeOwnersEntries as Mock<any>).mockResolvedValue([{ owners: ['@ExpediaGroup/team1'] }]);
234+
getRequiredCodeOwnersEntriesSpy.mockResolvedValue([{ owners: ['@ExpediaGroup/team1'] }]);
232235
mockPagination({
233236
data: [
234237
{
@@ -246,7 +249,7 @@ describe('approvalsSatisfied', () => {
246249
});
247250

248251
it('should return false when not all core teams have approved', async () => {
249-
(getRequiredCodeOwnersEntries as Mock<any>).mockResolvedValue([
252+
getRequiredCodeOwnersEntriesSpy.mockResolvedValue([
250253
{ owners: ['@ExpediaGroup/team1'] },
251254
{ owners: ['@ExpediaGroup/team2'] },
252255
{ owners: ['@ExpediaGroup/team3'] }
@@ -268,7 +271,7 @@ describe('approvalsSatisfied', () => {
268271
});
269272

270273
it('should return true when a member from each core team has approved', async () => {
271-
(getRequiredCodeOwnersEntries as Mock<any>).mockResolvedValue([
274+
getRequiredCodeOwnersEntriesSpy.mockResolvedValue([
272275
{ owners: ['@ExpediaGroup/team1'] },
273276
{ owners: ['@ExpediaGroup/team2'] },
274277
{ owners: ['@ExpediaGroup/team3'] }
@@ -294,7 +297,7 @@ describe('approvalsSatisfied', () => {
294297
});
295298

296299
it('should return true when a member from each owner group (teams and users) has approved', async () => {
297-
(getRequiredCodeOwnersEntries as Mock<any>).mockResolvedValue([
300+
getRequiredCodeOwnersEntriesSpy.mockResolvedValue([
298301
{ owners: ['@ExpediaGroup/team1'] },
299302
{ owners: ['@ExpediaGroup/team2'] },
300303
{ owners: ['@ExpediaGroup/team4', 'user10'] }
@@ -324,10 +327,7 @@ describe('approvalsSatisfied', () => {
324327
});
325328

326329
it('should return false when not enough members from core teams have approved', async () => {
327-
(getRequiredCodeOwnersEntries as Mock<any>).mockResolvedValue([
328-
{ owners: ['@ExpediaGroup/team2'] },
329-
{ owners: ['@ExpediaGroup/team4'] }
330-
]);
330+
getRequiredCodeOwnersEntriesSpy.mockResolvedValue([{ owners: ['@ExpediaGroup/team2'] }, { owners: ['@ExpediaGroup/team4'] }]);
331331
mockPagination({
332332
data: [
333333
{
@@ -349,10 +349,7 @@ describe('approvalsSatisfied', () => {
349349
});
350350

351351
it('should return true when enough members from core teams have approved', async () => {
352-
(getRequiredCodeOwnersEntries as Mock<any>).mockResolvedValue([
353-
{ owners: ['@ExpediaGroup/team2'] },
354-
{ owners: ['@ExpediaGroup/team4'] }
355-
]);
352+
getRequiredCodeOwnersEntriesSpy.mockResolvedValue([{ owners: ['@ExpediaGroup/team2'] }, { owners: ['@ExpediaGroup/team4'] }]);
356353
mockPagination({
357354
data: [
358355
{
@@ -378,7 +375,7 @@ describe('approvalsSatisfied', () => {
378375
});
379376

380377
it('should return false when not enough collective approvals from shared owners are met', async () => {
381-
(getRequiredCodeOwnersEntries as Mock<any>).mockResolvedValue([{ owners: ['@ExpediaGroup/team4', '@ExpediaGroup/team5'] }]);
378+
getRequiredCodeOwnersEntriesSpy.mockResolvedValue([{ owners: ['@ExpediaGroup/team4', '@ExpediaGroup/team5'] }]);
382379
mockPagination({
383380
data: [
384381
{
@@ -392,7 +389,7 @@ describe('approvalsSatisfied', () => {
392389
});
393390

394391
it('should return false when not enough collective approvals from shared owners are met even if user is in both groups', async () => {
395-
(getRequiredCodeOwnersEntries as Mock<any>).mockResolvedValue([{ owners: ['@ExpediaGroup/team4', '@ExpediaGroup/team5'] }]);
392+
getRequiredCodeOwnersEntriesSpy.mockResolvedValue([{ owners: ['@ExpediaGroup/team4', '@ExpediaGroup/team5'] }]);
396393
mockPagination({
397394
data: [
398395
{
@@ -406,7 +403,7 @@ describe('approvalsSatisfied', () => {
406403
});
407404

408405
it('should return true when enough collective approvals from shared owners are met', async () => {
409-
(getRequiredCodeOwnersEntries as Mock<any>).mockResolvedValue([{ owners: ['@ExpediaGroup/team4', '@ExpediaGroup/team5'] }]);
406+
getRequiredCodeOwnersEntriesSpy.mockResolvedValue([{ owners: ['@ExpediaGroup/team4', '@ExpediaGroup/team5'] }]);
410407
mockPagination({
411408
data: [
412409
{
@@ -424,7 +421,7 @@ describe('approvalsSatisfied', () => {
424421
});
425422

426423
it('should return false when collective approvals are met but not standalone approvals', async () => {
427-
(getRequiredCodeOwnersEntries as Mock<any>).mockResolvedValue([
424+
getRequiredCodeOwnersEntriesSpy.mockResolvedValue([
428425
{ owners: ['@ExpediaGroup/team4'] },
429426
{ owners: ['@ExpediaGroup/team5', '@ExpediaGroup/team6'] }
430427
]);
@@ -445,7 +442,7 @@ describe('approvalsSatisfied', () => {
445442
});
446443

447444
it('should return true when both collective and standalone approvals are met', async () => {
448-
(getRequiredCodeOwnersEntries as Mock<any>).mockResolvedValue([
445+
getRequiredCodeOwnersEntriesSpy.mockResolvedValue([
449446
{ owners: ['@ExpediaGroup/team4'] },
450447
{ owners: ['@ExpediaGroup/team5', '@ExpediaGroup/team6'] }
451448
]);
@@ -470,10 +467,7 @@ describe('approvalsSatisfied', () => {
470467
});
471468

472469
it('should return true when there are no code owners for one file and the other file is satisfied', async () => {
473-
(getRequiredCodeOwnersEntries as Mock<any>).mockResolvedValue([
474-
{ owners: [] },
475-
{ owners: ['@ExpediaGroup/team5', '@ExpediaGroup/team6'] }
476-
]);
470+
getRequiredCodeOwnersEntriesSpy.mockResolvedValue([{ owners: [] }, { owners: ['@ExpediaGroup/team5', '@ExpediaGroup/team6'] }]);
477471
mockPagination({
478472
data: [
479473
{
@@ -495,10 +489,7 @@ describe('approvalsSatisfied', () => {
495489
});
496490

497491
it('should return false when there are no code owners for one file and the other file is not satisfied', async () => {
498-
(getRequiredCodeOwnersEntries as Mock<any>).mockResolvedValue([
499-
{ owners: [] },
500-
{ owners: ['@ExpediaGroup/team5', '@ExpediaGroup/team6'] }
501-
]);
492+
getRequiredCodeOwnersEntriesSpy.mockResolvedValue([{ owners: [] }, { owners: ['@ExpediaGroup/team5', '@ExpediaGroup/team6'] }]);
502493
mockPagination({
503494
data: [
504495
{
@@ -512,7 +503,7 @@ describe('approvalsSatisfied', () => {
512503
});
513504

514505
it('should return true when the overridden team config is satisfied', async () => {
515-
(getRequiredCodeOwnersEntries as Mock<any>).mockResolvedValue([
506+
getRequiredCodeOwnersEntriesSpy.mockResolvedValue([
516507
{ owners: ['@ExpediaGroup/team1'] },
517508
{ owners: ['@ExpediaGroup/team2'] },
518509
{ owners: ['@ExpediaGroup/team3'] }
@@ -554,7 +545,7 @@ describe('approvalsSatisfied', () => {
554545
pull_number: '12345'
555546
});
556547
expect(octokit.pulls.listReviews).toHaveBeenCalledWith({ pull_number: 12345, repo: 'repo', owner: 'owner', page: 1, per_page: 100 });
557-
expect(getRequiredCodeOwnersEntries).not.toHaveBeenCalled();
548+
expect(getCoreMemberLoginsModule.getRequiredCodeOwnersEntries).not.toHaveBeenCalled();
558549
expect(result).toBe(true);
559550
});
560551

@@ -572,12 +563,12 @@ describe('approvalsSatisfied', () => {
572563
pull_number: '12345'
573564
});
574565
expect(octokit.pulls.listReviews).toHaveBeenCalledWith({ pull_number: 12345, repo: 'repo', owner: 'owner', page: 1, per_page: 100 });
575-
expect(getRequiredCodeOwnersEntries).not.toHaveBeenCalled();
566+
expect(getCoreMemberLoginsModule.getRequiredCodeOwnersEntries).not.toHaveBeenCalled();
576567
expect(result).toBe(false);
577568
});
578569

579570
it('should return true when approvals are satisfied and users are explicitly defined in CODEOWNERS', async () => {
580-
(getRequiredCodeOwnersEntries as Mock<any>).mockResolvedValue([{ owners: ['@user1', '@user2'] }]);
571+
getRequiredCodeOwnersEntriesSpy.mockResolvedValue([{ owners: ['@user1', '@user2'] }]);
581572
mockPagination({
582573
data: [
583574
{

0 commit comments

Comments
 (0)