Skip to content

Commit 903d5e8

Browse files
feat: Add team option to author filter (#696)
Co-authored-by: Shine Lee <aungshine@gmail.com>
1 parent a1d02ab commit 903d5e8

File tree

5 files changed

+106
-10
lines changed

5 files changed

+106
-10
lines changed

__tests__/unit/filters/author.test.js

Lines changed: 77 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
const Author = require('../../../lib/filters/author')
22
const Helper = require('../../../__fixtures__/unit/helper')
3+
const Teams = require('../../../lib/validators/options_processor/teams')
4+
5+
const authorName = 'mergeabletestauthorname'
6+
const otherAuthorName = 'someone-else'
37

48
test('should fail with unexpected author', async () => {
59
const author = new Author()
610
const settings = {
711
do: 'author',
812
must_include: {
9-
regex: 'someone-else'
13+
regex: otherAuthorName
1014
}
1115
}
12-
const filter = await author.processFilter(createMockContext('mergeable'), settings)
16+
const filter = await author.processFilter(createMockContext(authorName), settings)
1317
expect(filter.status).toBe('fail')
1418
})
1519

@@ -18,10 +22,10 @@ test('should pass with expected author', async () => {
1822
const settings = {
1923
do: 'author',
2024
must_include: {
21-
regex: 'mergeable'
25+
regex: authorName
2226
}
2327
}
24-
const filter = await author.processFilter(createMockContext('mergeable'), settings)
28+
const filter = await author.processFilter(createMockContext(authorName), settings)
2529
expect(filter.status).toBe('pass')
2630
})
2731

@@ -30,10 +34,10 @@ test('should fail with excluded author', async () => {
3034
const settings = {
3135
do: 'author',
3236
must_exclude: {
33-
regex: 'mergeable'
37+
regex: authorName
3438
}
3539
}
36-
const filter = await author.processFilter(createMockContext('mergeable'), settings)
40+
const filter = await author.processFilter(createMockContext(authorName), settings)
3741
expect(filter.status).toBe('fail')
3842
})
3943

@@ -42,13 +46,78 @@ test('should pass with excluded author', async () => {
4246
const settings = {
4347
do: 'author',
4448
must_exclude: {
45-
regex: 'someone-else'
49+
regex: otherAuthorName
4650
}
4751
}
48-
const filter = await author.processFilter(createMockContext('mergeable'), settings)
52+
const filter = await author.processFilter(createMockContext(authorName), settings)
53+
expect(filter.status).toBe('pass')
54+
})
55+
56+
test('should pass with expected author from correct team', async () => {
57+
const author = new Author()
58+
const settings = {
59+
do: 'author',
60+
must_include: {
61+
regex: authorName
62+
},
63+
team: 'org/team-slug'
64+
}
65+
Teams.extractTeamMemberships = jest.fn().mockReturnValue([authorName])
66+
const filter = await author.processFilter(createMockContext(authorName), settings)
4967
expect(filter.status).toBe('pass')
5068
})
5169

70+
test('should fail with expected author from incorrect team', async () => {
71+
const author = new Author()
72+
const settings = {
73+
do: 'author',
74+
must_include: {
75+
regex: authorName
76+
},
77+
team: 'org/team-slug'
78+
}
79+
Teams.extractTeamMemberships = jest.fn().mockReturnValue([])
80+
const filter = await author.processFilter(createMockContext(authorName), settings)
81+
expect(filter.status).toBe('fail')
82+
})
83+
84+
test('should fail with unexpected author from correct team', async () => {
85+
const author = new Author()
86+
const settings = {
87+
do: 'author',
88+
must_include: {
89+
regex: otherAuthorName
90+
},
91+
team: 'org/team-slug'
92+
}
93+
Teams.extractTeamMemberships = jest.fn().mockReturnValue([authorName])
94+
const filter = await author.processFilter(createMockContext(authorName), settings)
95+
expect(filter.status).toBe('fail')
96+
})
97+
98+
test('should pass when the author is a member of the team', async () => {
99+
const author = new Author()
100+
const settings = {
101+
do: 'author',
102+
team: 'org/team-slug'
103+
}
104+
Teams.extractTeamMemberships = jest.fn().mockReturnValue([authorName])
105+
const filter = await author.processFilter(createMockContext(authorName), settings)
106+
expect(filter.status).toBe('pass')
107+
})
108+
109+
test('should fail when the author is not a member of the team', async () => {
110+
const author = new Author()
111+
const authorName = 'mergeable'
112+
const settings = {
113+
do: 'author',
114+
team: 'org/team-slug'
115+
}
116+
Teams.extractTeamMemberships = jest.fn().mockReturnValue([otherAuthorName])
117+
const filter = await author.processFilter(createMockContext(authorName), settings)
118+
expect(filter.status).toBe('fail')
119+
})
120+
52121
const createMockContext = (author) => {
53122
return Helper.mockContext({ author })
54123
}

docs/changelog.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
CHANGELOG
22
=====================================
3+
| February 03, 2023: feat: Add team option to author filter `#696 <https://github.com/mergeability/mergeable/pull/696>`_
34
| February 3, 2023: chore: Update node version for release workflow `#699 <https://github.com/mergeability/mergeable/pull/699>`_
45
| February 3, 2023: feat: Add Not operator `#695 <https://github.com/mergeability/mergeable/pull/695>`_
56
| September 28, 2022: feat: Add last comment validator `#668 <https://github.com/mergeability/mergeable/pull/668>`_

docs/filters/author.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ Author
66
- do: author
77
must_include:
88
regex: 'user-1'
9-
message: 'Custom message...'
9+
message: 'Custom include message...'
10+
must_exclude:
11+
regex: 'user-2'
12+
message: 'Custom exclude message...'
13+
team: 'org/team-slug' # verify that the author is in the team
1014
# all of the message sub-option is optional
1115

1216
you can use ``and`` and ``or`` options to create more complex filters

lib/filters/author.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ class Author extends Filter {
1717
regex: 'string',
1818
regex_flag: 'string',
1919
message: 'string'
20-
}
20+
},
21+
team: 'string'
2122
}
2223
}
2324

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const Teams = require('../../../validators/options_processor/teams')
2+
3+
class TeamProcessor {
4+
static async process (context, filter, input, rule) {
5+
const userName = input
6+
const teamName = rule.team
7+
8+
const SUCCESS_MESSAGE = `'${userName}' is part of the '${teamName}' team'`
9+
const FAILURE_MESSAGE = `'${userName}' is not part of the '${teamName}' team'`
10+
11+
const teamMemberships = await Teams.extractTeamMemberships(context, [teamName], [userName])
12+
const isMember = teamMemberships.includes(userName)
13+
14+
return {
15+
status: isMember ? 'pass' : 'fail',
16+
description: isMember ? SUCCESS_MESSAGE : FAILURE_MESSAGE
17+
}
18+
}
19+
}
20+
21+
module.exports = TeamProcessor

0 commit comments

Comments
 (0)