-
Notifications
You must be signed in to change notification settings - Fork 120
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
071e6fb
commit 64d4afd
Showing
7 changed files
with
232 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
const Author = require('../../../lib/validators/author') | ||
const Helper = require('../../../__fixtures__/unit/helper') | ||
const Teams = require('../../../lib/validators/options_processor/teams') | ||
|
||
const authorName = 'mergeabletestauthorname' | ||
const otherAuthorName = 'someone-else' | ||
|
||
test('should fail with unexpected author', async () => { | ||
const author = new Author() | ||
const settings = { | ||
do: 'author', | ||
must_include: { | ||
regex: otherAuthorName | ||
} | ||
} | ||
const validation = await author.processValidate(createMockContext(authorName), settings) | ||
expect(validation.status).toBe('fail') | ||
}) | ||
|
||
test('should pass with expected author', async () => { | ||
const author = new Author() | ||
const settings = { | ||
do: 'author', | ||
must_include: { | ||
regex: authorName | ||
} | ||
} | ||
const validation = await author.processValidate(createMockContext(authorName), settings) | ||
expect(validation.status).toBe('pass') | ||
}) | ||
|
||
test('should fail with excluded author', async () => { | ||
const author = new Author() | ||
const settings = { | ||
do: 'author', | ||
must_exclude: { | ||
regex: authorName | ||
} | ||
} | ||
const validation = await author.processValidate(createMockContext(authorName), settings) | ||
expect(validation.status).toBe('fail') | ||
}) | ||
|
||
test('should pass with excluded author', async () => { | ||
const author = new Author() | ||
const settings = { | ||
do: 'author', | ||
must_exclude: { | ||
regex: otherAuthorName | ||
} | ||
} | ||
const validation = await author.processValidate(createMockContext(authorName), settings) | ||
expect(validation.status).toBe('pass') | ||
}) | ||
|
||
test('should pass with expected author from correct team', async () => { | ||
const author = new Author() | ||
const settings = { | ||
do: 'author', | ||
must_include: { | ||
regex: authorName | ||
}, | ||
team: 'org/team-slug' | ||
} | ||
Teams.extractTeamMemberships = jest.fn().mockReturnValue([authorName]) | ||
const validation = await author.processValidate(createMockContext(authorName), settings) | ||
expect(validation.status).toBe('pass') | ||
}) | ||
|
||
test('should fail with expected author from incorrect team', async () => { | ||
const author = new Author() | ||
const settings = { | ||
do: 'author', | ||
must_include: { | ||
regex: authorName | ||
}, | ||
team: 'org/team-slug' | ||
} | ||
Teams.extractTeamMemberships = jest.fn().mockReturnValue([]) | ||
const validation = await author.processValidate(createMockContext(authorName), settings) | ||
expect(validation.status).toBe('fail') | ||
}) | ||
|
||
test('should fail with unexpected author from correct team', async () => { | ||
const author = new Author() | ||
const settings = { | ||
do: 'author', | ||
must_include: { | ||
regex: otherAuthorName | ||
}, | ||
team: 'org/team-slug' | ||
} | ||
Teams.extractTeamMemberships = jest.fn().mockReturnValue([authorName]) | ||
const validation = await author.processValidate(createMockContext(authorName), settings) | ||
expect(validation.status).toBe('fail') | ||
}) | ||
|
||
test('should pass when the author is a member of the team', async () => { | ||
const author = new Author() | ||
const settings = { | ||
do: 'author', | ||
team: 'org/team-slug' | ||
} | ||
Teams.extractTeamMemberships = jest.fn().mockReturnValue([authorName]) | ||
const validation = await author.processValidate(createMockContext(authorName), settings) | ||
expect(validation.status).toBe('pass') | ||
}) | ||
|
||
test('should fail when the author is not a member of the team', async () => { | ||
const author = new Author() | ||
const authorName = 'mergeable' | ||
const settings = { | ||
do: 'author', | ||
team: 'org/team-slug' | ||
} | ||
Teams.extractTeamMemberships = jest.fn().mockReturnValue([otherAuthorName]) | ||
const validation = await author.processValidate(createMockContext(authorName), settings) | ||
expect(validation.status).toBe('fail') | ||
}) | ||
|
||
const createMockContext = (author) => { | ||
return Helper.mockContext({ author }) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
Author | ||
^^^^^^^^^^^^^^ | ||
|
||
:: | ||
|
||
- do: author | ||
must_include: | ||
regex: 'user-1' | ||
message: 'Custom include message...' | ||
must_exclude: | ||
regex: 'user-2' | ||
message: 'Custom exclude message...' | ||
team: 'org/team-slug' # verify that the author is in the team | ||
# all of the message sub-option is optional | ||
|
||
you can use ``and`` and ``or`` options to create more complex filters | ||
|
||
:: | ||
|
||
- do: author | ||
and: | ||
- must_exclude: | ||
regex: 'bot-user-1' | ||
message: 'Custom message...' | ||
or: | ||
- must_include: | ||
regex: 'user-1' | ||
message: 'Custom message...' | ||
- must_include: | ||
regex: 'user-2' | ||
message: 'Custom message...' | ||
|
||
you can also nest ``and`` and ``or`` options | ||
|
||
:: | ||
|
||
- do: author | ||
and: | ||
- or: | ||
- must_include: | ||
regex: 'user-1' | ||
message: 'Custom message...' | ||
- must_include: | ||
regex: 'user-2' | ||
message: 'Custom message...' | ||
- must_exclude: | ||
regex: 'bot-user-1' | ||
message: 'Custom message...' | ||
|
||
Supported Events: | ||
:: | ||
|
||
'pull_request.*', 'pull_request_review.*' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
const { Validator } = require('./validator') | ||
|
||
class Author extends Validator { | ||
constructor () { | ||
super('author') | ||
this.supportedEvents = [ | ||
'pull_request.*', | ||
'pull_request_review.*' | ||
] | ||
this.supportedSettings = { | ||
must_include: { | ||
regex: 'string', | ||
regex_flag: 'string', | ||
message: 'string' | ||
}, | ||
must_exclude: { | ||
regex: 'string', | ||
regex_flag: 'string', | ||
message: 'string' | ||
}, | ||
team: 'string' | ||
} | ||
} | ||
|
||
async validate (context, settings) { | ||
const payload = this.getPayload(context) | ||
return this.processOptions(settings, payload.user.login) | ||
} | ||
} | ||
|
||
module.exports = Author |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
const Teams = require('../teams') | ||
|
||
class TeamProcessor { | ||
static async process (context, input, rule) { | ||
const userName = input | ||
const teamName = rule.team | ||
|
||
const SUCCESS_MESSAGE = `'${userName}' is part of the '${teamName}' team'` | ||
const FAILURE_MESSAGE = `'${userName}' is not part of the '${teamName}' team'` | ||
|
||
const teamMemberships = await Teams.extractTeamMemberships(context, [teamName], [userName]) | ||
const isMember = teamMemberships.includes(userName) | ||
|
||
return { | ||
status: isMember ? 'pass' : 'fail', | ||
description: isMember ? SUCCESS_MESSAGE : FAILURE_MESSAGE | ||
} | ||
} | ||
} | ||
|
||
module.exports = TeamProcessor |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters