-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Created 'OR' rule #48
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
56a8970
added type for "or" rule
Bullrich 67d9bf9
added evaluation logic for OR rule
Bullrich 1131ee4
added or tests
Bullrich 72ebba1
fixed the amount of missing reviews
Bullrich ab10d84
added logic tests
Bullrich c95b60e
fixed reduce method
Bullrich 615ac17
moved check event to action
Bullrich 73fb957
Fixed wrong test name
Bullrich File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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
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,200 @@ | ||
/* eslint-disable @typescript-eslint/unbound-method */ | ||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */ | ||
/* eslint-disable @typescript-eslint/no-unsafe-call */ | ||
import { mock, MockProxy } from "jest-mock-extended"; | ||
|
||
import { PullRequestApi } from "../../github/pullRequest"; | ||
import { TeamApi } from "../../github/teams"; | ||
import { OrRule } from "../../rules/types"; | ||
import { ActionRunner } from "../../runner"; | ||
import { TestLogger } from "../logger"; | ||
|
||
describe("'Or' rule parsing", () => { | ||
let api: MockProxy<PullRequestApi>; | ||
let runner: ActionRunner; | ||
let teamsApi: MockProxy<TeamApi>; | ||
let logger: TestLogger; | ||
beforeEach(() => { | ||
logger = new TestLogger(); | ||
api = mock<PullRequestApi>(); | ||
runner = new ActionRunner(api, teamsApi, logger); | ||
}); | ||
test("should get minimal config", async () => { | ||
api.getConfigFile.mockResolvedValue(` | ||
rules: | ||
- name: Test review | ||
condition: | ||
include: | ||
- '.*' | ||
exclude: | ||
- 'example' | ||
type: or | ||
reviewers: | ||
- teams: | ||
- team-example | ||
- teams: | ||
- team-abc | ||
`); | ||
const config = await runner.getConfigFile(""); | ||
expect(config.rules[0].name).toEqual("Test review"); | ||
expect(config.rules[0].type).toEqual("or"); | ||
}); | ||
|
||
describe("reviewers", () => { | ||
test("should require teams", async () => { | ||
api.getConfigFile.mockResolvedValue(` | ||
rules: | ||
- name: Test review | ||
condition: | ||
include: | ||
- '.*' | ||
exclude: | ||
- 'example' | ||
type: or | ||
reviewers: | ||
- teams: | ||
- team-example | ||
- teams: | ||
- team-abc | ||
`); | ||
const config = await runner.getConfigFile(""); | ||
const rule = config.rules[0] as OrRule; | ||
expect(rule.reviewers).toHaveLength(2); | ||
expect(rule.reviewers[0].teams).toContainEqual("team-example"); | ||
expect(rule.reviewers[0].users).toBeUndefined(); | ||
expect(rule.reviewers[1].teams).toContainEqual("team-abc"); | ||
expect(rule.reviewers[1].users).toBeUndefined(); | ||
}); | ||
test("should require users", async () => { | ||
api.getConfigFile.mockResolvedValue(` | ||
rules: | ||
- name: Test review | ||
condition: | ||
include: | ||
- '.*' | ||
exclude: | ||
- 'example' | ||
type: or | ||
reviewers: | ||
- users: | ||
- user-example | ||
- users: | ||
- user-special | ||
`); | ||
const config = await runner.getConfigFile(""); | ||
const rule = config.rules[0] as OrRule; | ||
expect(rule.reviewers[0].users).toContainEqual("user-example"); | ||
expect(rule.reviewers[0].teams).toBeUndefined(); | ||
expect(rule.reviewers[1].users).toContainEqual("user-special"); | ||
expect(rule.reviewers[1].teams).toBeUndefined(); | ||
}); | ||
|
||
test("should fail without reviewers", async () => { | ||
api.getConfigFile.mockResolvedValue(` | ||
rules: | ||
- name: Test review | ||
condition: | ||
include: | ||
- '.*' | ||
exclude: | ||
- 'example' | ||
type: or | ||
`); | ||
await expect(runner.getConfigFile("")).rejects.toThrowError('"reviewers" is required'); | ||
}); | ||
|
||
test("should fill the reviewers array", async () => { | ||
api.getConfigFile.mockResolvedValue(` | ||
rules: | ||
- name: Test review | ||
condition: | ||
include: | ||
- '.*' | ||
exclude: | ||
- 'example' | ||
type: or | ||
reviewers: | ||
- teams: | ||
- team-example | ||
- min_approvals: 2 | ||
users: | ||
- abc | ||
teams: | ||
- xyz | ||
`); | ||
const config = await runner.getConfigFile(""); | ||
const rule = config.rules[0] as OrRule; | ||
expect(rule.reviewers).toHaveLength(2); | ||
expect(rule.reviewers[0].teams).toContainEqual("team-example"); | ||
expect(rule.reviewers[0].users).toBeUndefined(); | ||
expect(rule.reviewers[1].min_approvals).toEqual(2); | ||
expect(rule.reviewers[1].users).toContainEqual("abc"); | ||
expect(rule.reviewers[1].teams).toContainEqual("xyz"); | ||
}); | ||
}); | ||
|
||
test("should default min_approvals to 1", async () => { | ||
api.getConfigFile.mockResolvedValue(` | ||
rules: | ||
- name: Test review | ||
condition: | ||
include: | ||
- '.*' | ||
exclude: | ||
- 'example' | ||
type: or | ||
reviewers: | ||
- users: | ||
- user-example | ||
- teams: | ||
- team-example | ||
`); | ||
const config = await runner.getConfigFile(""); | ||
const [rule] = config.rules; | ||
if (rule.type === "or") { | ||
expect(rule.reviewers[0].min_approvals).toEqual(1); | ||
} else { | ||
throw new Error(`Rule type ${rule.type} is invalid`); | ||
} | ||
}); | ||
|
||
test("should fail with min_approvals in negative", async () => { | ||
api.getConfigFile.mockResolvedValue(` | ||
rules: | ||
- name: Test review | ||
condition: | ||
include: | ||
- '.*' | ||
exclude: | ||
- 'example' | ||
type: or | ||
reviewers: | ||
- min_approvals: -99 | ||
users: | ||
- user-example | ||
`); | ||
await expect(runner.getConfigFile("")).rejects.toThrowError( | ||
'"reviewers[0].min_approvals" must be greater than or equal to 1', | ||
); | ||
}); | ||
|
||
test("should fail with min_approvals in 0", async () => { | ||
api.getConfigFile.mockResolvedValue(` | ||
rules: | ||
- name: Test review | ||
condition: | ||
include: | ||
- '.*' | ||
exclude: | ||
- 'example' | ||
type: or | ||
reviewers: | ||
- min_approvals: 0 | ||
users: | ||
- user-example | ||
`); | ||
await expect(runner.getConfigFile("")).rejects.toThrowError( | ||
'"reviewers[0].min_approvals" must be greater than or equal to 1', | ||
); | ||
}); | ||
}); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kinda feels like these rules can be joined so the validation would work in one execution
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am afraid I don't follow. What do you mean by joined? Could you please show me an example?
I want to keep the "else" to throw if the rule is invalid, but overall, I don't worry much about removing the hardcoded code as, maybe with one or two exception, I don't think we will be adding more cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean, you validate
config
, and then validate each rule independently.Can't we just join it all in a single schema to validate in one call?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah, I see your point.
It is because the "Basic" rule has different parameters, so I thought it would be easier to do:
And that's is simply because I don't know how to make a conditional rule with JOI in which:
basic
it should use a particular schema typebasic
it needs to have a different schema validating it.I don't know how to do a conditional check like that. If you do know, please let me know, as I have spend some time researching that and decided to go for the simplest solution instead of fighting for the most elegant one.
I'll be merging this PR as the union should be handled in a different PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean like
Joi.alternatives()
?