diff --git a/README.md b/README.md index 14528b3..69fdc76 100644 --- a/README.md +++ b/README.md @@ -230,7 +230,7 @@ rules: exclude: - '.github/' type: basic - min_approvals: 2 + minApprovals: 2 teams: - team-1 - team-2 @@ -251,7 +251,7 @@ It has the same parameters as a normal rule: - **exclude**: An array of regular expressions pointing to the files that this rule should ignore when deciding if it should evaluate the Pull Request. - **optional** - **type**: This must be the string `basic`. -- **min_approvals**: The number of approvals that are need to fulfill this condition. +- **minApprovals**: The number of approvals that are need to fulfill this condition. - It can not be lower than 1. - **Optional**: Defaults to 1. - Must be greater than the number of users available (you cannot request 5 approvals from a team of 4 users) @@ -286,7 +286,7 @@ rules: - user-2 - teams: - team-abc - min_approvals: 2 + minApprovals: 2 ``` - The **name** and **conditions** fields have the same requirements that the `basic` rule has. - **type**: Must be `or`, `and` or `and-distinct`. @@ -298,7 +298,7 @@ rules: - Must have at least two options. - If you only need 1 option, then use the `basic` rule. - Each of the options have the following fields: - - **min_approvals**: The number of approvals that are need to fulfill this condition. + - **minApprovals**: The number of approvals that are need to fulfill this condition. - It can not be lower than 1. - **Optional**: Defaults to 1. - Must be greater than the number of users available (you cannot request 5 approvals from a team of 4 users) @@ -319,7 +319,7 @@ reviewers: - user-2 - teams: - team-abc - min_approvals: 2 + minApprovals: 2 ``` This rule will be approved with *any of the following* conditions: - If a user who belongs to `team-example` or is `user-1` or `user-2` approves the PR. @@ -339,7 +339,7 @@ reviewers: - user-2 - teams: - team-abc - min_approvals: 2 + minApprovals: 2 ``` This rule will be approved if *all the following conditions get fulfilled*: - *One* user who belongs to `team-example` or is `user-1` or `user-2` approves the PR. @@ -367,7 +367,7 @@ The fellows rule has a slight difference to all of the rules: - 'example' type: fellows minRank: 2 - min_approvals: 2 + minApprovals: 2 ``` The biggest difference is that it doesn’t have a reviewers type (it doesn’t have a `teams` or `users` field); instead, it has a `minRank` field. diff --git a/src/rules/types.ts b/src/rules/types.ts index 6c48e0a..a69cfb6 100644 --- a/src/rules/types.ts +++ b/src/rules/types.ts @@ -6,12 +6,12 @@ export enum RuleTypes { Fellows = "fellows", } -export type Reviewers = { users?: string[]; teams?: string[]; min_approvals: number }; +export type Reviewers = { users?: string[]; teams?: string[]; minApprovals: number }; export interface Rule { name: string; condition: { include: string[]; exclude?: string[] }; - allowedToSkipRule?: Omit; + allowedToSkipRule?: Omit; countAuthor?: boolean; } @@ -37,7 +37,7 @@ export interface AndDistinctRule extends Rule { export interface FellowsRule extends Rule { type: RuleTypes.Fellows; minRank: number; - min_approvals: number; + minApprovals: number; } export interface ConfigurationFile { diff --git a/src/rules/validator.ts b/src/rules/validator.ts index a5f9d29..59ad233 100644 --- a/src/rules/validator.ts +++ b/src/rules/validator.ts @@ -12,7 +12,7 @@ const reviewersObj = { teams: Joi.array().items(Joi.string()).optional().empty(null), }; -const reviewerConditionObj = { ...reviewersObj, min_approvals: Joi.number().min(1).default(1) }; +const reviewerConditionObj = { ...reviewersObj, minApprovals: Joi.number().min(1).default(1) }; /** Base rule condition. * This are the minimum requirements that all the rules must have. @@ -24,7 +24,7 @@ const ruleSchema = Joi.object().keys({ include: Joi.array().items(Joi.string()).required(), exclude: Joi.array().items(Joi.string()).optional().allow(null), }), - allowedToSkipRule: Joi.object>().keys(reviewersObj).optional().or("users", "teams"), + allowedToSkipRule: Joi.object>().keys(reviewersObj).optional().or("users", "teams"), type: Joi.string() .valid(RuleTypes.Basic, RuleTypes.And, RuleTypes.Or, RuleTypes.AndDistinct, RuleTypes.Fellows) .required(), @@ -40,7 +40,7 @@ export const generalSchema = Joi.object().keys({ }); /** Basic rule schema - * This rule is quite simple as it only has the min_approvals field and the required reviewers + * This rule is quite simple as it only has the minApprovals field and the required reviewers */ export const basicRuleSchema = Joi.object() .keys({ ...reviewerConditionObj, countAuthor: Joi.boolean().default(false) }) @@ -58,7 +58,7 @@ export const otherRulesSchema = Joi.object().keys({ export const fellowsRuleSchema = Joi.object().keys({ countAuthor: Joi.boolean().default(false), minRank: Joi.number().required().min(1).empty(null), - min_approvals: Joi.number().min(1).default(1), + minApprovals: Joi.number().min(1).default(1), }); /** diff --git a/src/runner.ts b/src/runner.ts index 885ff9c..151e0be 100644 --- a/src/runner.ts +++ b/src/runner.ts @@ -282,11 +282,11 @@ export class ActionRunner { // We get all the users belonging to each 'and distinct' review condition for (const reviewers of rule.reviewers) { const users = await this.fetchAllUsers(reviewers); - requirements.push({ users, requiredApprovals: reviewers.min_approvals }); + requirements.push({ users, requiredApprovals: reviewers.minApprovals }); } // We count how many reviews are needed in total - const requiredAmountOfReviews = rule.reviewers.map((r) => r.min_approvals).reduce((a, b) => a + b, 0); + const requiredAmountOfReviews = rule.reviewers.map((r) => r.minApprovals).reduce((a, b) => a + b, 0); // We get the list of users that approved the PR const approvals = await this.prApi.listApprovedReviewsAuthors(rule.countAuthor ?? false); @@ -393,7 +393,7 @@ export class ActionRunner { * @see-also ReviewError */ async evaluateCondition( - rule: { min_approvals: number } & Reviewers, + rule: { minApprovals: number } & Reviewers, countAuthor: boolean = false, ): Promise { this.logger.debug(JSON.stringify(rule)); @@ -405,9 +405,9 @@ export class ActionRunner { throw new Error("No users have been found in the required reviewers"); } - if (requiredUsers.length < rule.min_approvals) { + if (requiredUsers.length < rule.minApprovals) { this.logger.error( - `${rule.min_approvals} approvals are required but only ${requiredUsers.length} user's approval count.`, + `${rule.minApprovals} approvals are required but only ${requiredUsers.length} user's approval count.`, ); if (rule.teams) { this.logger.error(`Allowed teams: ${JSON.stringify(rule.teams)}`); @@ -423,7 +423,7 @@ export class ActionRunner { this.logger.info(`Found ${approvals.length} approvals.`); // This is the amount of reviews required. To succeed this should be 0 or lower - let missingReviews = rule.min_approvals; + let missingReviews = rule.minApprovals; for (const requiredUser of requiredUsers) { // We check for the approvals, if it is a required reviewer we lower the amount of missing reviews if (approvals.indexOf(requiredUser) > -1) { @@ -462,9 +462,9 @@ export class ActionRunner { throw new Error(`No users have been found with the rank ${rule.minRank} or above`); } - if (requiredUsers.length < rule.min_approvals) { + if (requiredUsers.length < rule.minApprovals) { this.logger.error( - `${rule.min_approvals} approvals are required but only ${requiredUsers.length} user's approval count.`, + `${rule.minApprovals} approvals are required but only ${requiredUsers.length} user's approval count.`, ); throw new Error("The amount of required approvals is smaller than the amount of available users."); } @@ -474,7 +474,7 @@ export class ActionRunner { this.logger.info(`Found ${approvals.length} approvals.`); // This is the amount of reviews required. To succeed this should be 0 or lower - let missingReviews = rule.min_approvals; + let missingReviews = rule.minApprovals; for (const requiredUser of requiredUsers) { // We check for the approvals, if it is a required reviewer we lower the amount of missing reviews if (approvals.indexOf(requiredUser) > -1) { @@ -531,7 +531,7 @@ export class ActionRunner { * @param reviewers Object with users or teams to fetch members * @returns an array with all the users */ - async fetchAllUsers(reviewers: Omit): Promise { + async fetchAllUsers(reviewers: Omit): Promise { const users: Set = new Set(); if (reviewers.teams) { for (const team of reviewers.teams) { diff --git a/src/test/config.yml b/src/test/config.yml index 8e7d8ab..c8e75a7 100644 --- a/src/test/config.yml +++ b/src/test/config.yml @@ -10,7 +10,7 @@ rules: - ^\.cargo/.* exclude: - ^./gitlab/pipeline/zombienet.yml$ - min_approvals: 2 + minApprovals: 2 type: basic teams: - ci @@ -27,7 +27,7 @@ rules: exclude: - ^polkadot/runtime\/(kusama|polkadot)\/src\/weights\/.+\.rs$ - ^substrate\/frame\/.+\.md$ - min_approvals: 2 + minApprovals: 2 allowedToSkipRule: teams: - core-devs @@ -51,7 +51,7 @@ rules: - ^\.gitlab-ci\.yml - ^(?!.*\.dic$|.*spellcheck\.toml$)scripts/ci/.* - ^\.github/.* - min_approvals: 2 + minApprovals: 2 type: basic teams: - core-devs @@ -67,10 +67,10 @@ rules: - ^cumulus/parachains/common/src/[^/]+\.rs$ type: and-distinct reviewers: - - min_approvals: 1 + - minApprovals: 1 teams: - locks-review - - min_approvals: 1 + - minApprovals: 1 teams: - polkadot-review @@ -80,7 +80,7 @@ rules: condition: include: - ^cumulus/bridges/.* - min_approvals: 1 + minApprovals: 1 teams: - bridges-core @@ -92,10 +92,10 @@ rules: - ^substrate/frame/(?!.*(nfts/.*|uniques/.*|babe/.*|grandpa/.*|beefy|merkle-mountain-range/.*|contracts/.*|election|nomination-pools/.*|staking/.*|aura/.*)) type: "and" reviewers: - - min_approvals: 2 + - minApprovals: 2 teams: - core-devs - - min_approvals: 1 + - minApprovals: 1 teams: - frame-coders diff --git a/src/test/rules/andDistinct.test.ts b/src/test/rules/andDistinct.test.ts index d882134..9e3fb72 100644 --- a/src/test/rules/andDistinct.test.ts +++ b/src/test/rules/andDistinct.test.ts @@ -114,7 +114,7 @@ describe("'AndDistinctRule' rule parsing", () => { reviewers: - teams: - team-example - - min_approvals: 2 + - minApprovals: 2 users: - abc teams: @@ -125,13 +125,13 @@ describe("'AndDistinctRule' rule parsing", () => { 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].minApprovals).toEqual(2); expect(rule.reviewers[1].users).toContainEqual("abc"); expect(rule.reviewers[1].teams).toContainEqual("xyz"); }); }); - test("should default min_approvals to 1", async () => { + test("should default minApprovals to 1", async () => { api.getConfigFile.mockResolvedValue(` rules: - name: Test review @@ -150,13 +150,13 @@ describe("'AndDistinctRule' rule parsing", () => { const config = await runner.getConfigFile(""); const [rule] = config.rules; if (rule.type === "and-distinct") { - expect(rule.reviewers[0].min_approvals).toEqual(1); + expect(rule.reviewers[0].minApprovals).toEqual(1); } else { throw new Error(`Rule type ${rule.type} is invalid`); } }); - test("should fail with min_approvals in negative", async () => { + test("should fail with minApprovals in negative", async () => { api.getConfigFile.mockResolvedValue(` rules: - name: Test review @@ -167,16 +167,16 @@ describe("'AndDistinctRule' rule parsing", () => { - 'example' type: and-distinct reviewers: - - min_approvals: -99 + - minApprovals: -99 users: - user-example `); await expect(runner.getConfigFile("")).rejects.toThrowError( - '"reviewers[0].min_approvals" must be greater than or equal to 1', + '"reviewers[0].minApprovals" must be greater than or equal to 1', ); }); - test("should fail with min_approvals in 0", async () => { + test("should fail with minApprovals in 0", async () => { api.getConfigFile.mockResolvedValue(` rules: - name: Test review @@ -187,12 +187,12 @@ describe("'AndDistinctRule' rule parsing", () => { - 'example' type: and-distinct reviewers: - - min_approvals: 0 + - minApprovals: 0 users: - user-example `); await expect(runner.getConfigFile("")).rejects.toThrowError( - '"reviewers[0].min_approvals" must be greater than or equal to 1', + '"reviewers[0].minApprovals" must be greater than or equal to 1', ); }); }); diff --git a/src/test/rules/andRule.test.ts b/src/test/rules/andRule.test.ts index e5f8e11..03bf5bf 100644 --- a/src/test/rules/andRule.test.ts +++ b/src/test/rules/andRule.test.ts @@ -114,7 +114,7 @@ describe("'And' rule parsing", () => { reviewers: - teams: - team-example - - min_approvals: 2 + - minApprovals: 2 users: - abc teams: @@ -125,13 +125,13 @@ describe("'And' rule parsing", () => { 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].minApprovals).toEqual(2); expect(rule.reviewers[1].users).toContainEqual("abc"); expect(rule.reviewers[1].teams).toContainEqual("xyz"); }); }); - test("should default min_approvals to 1", async () => { + test("should default minApprovals to 1", async () => { api.getConfigFile.mockResolvedValue(` rules: - name: Test review @@ -150,13 +150,13 @@ describe("'And' rule parsing", () => { const config = await runner.getConfigFile(""); const [rule] = config.rules; if (rule.type === "and") { - expect(rule.reviewers[0].min_approvals).toEqual(1); + expect(rule.reviewers[0].minApprovals).toEqual(1); } else { throw new Error(`Rule type ${rule.type} is invalid`); } }); - test("should fail with min_approvals in negative", async () => { + test("should fail with minApprovals in negative", async () => { api.getConfigFile.mockResolvedValue(` rules: - name: Test review @@ -167,16 +167,16 @@ describe("'And' rule parsing", () => { - 'example' type: and reviewers: - - min_approvals: -99 + - minApprovals: -99 users: - user-example `); await expect(runner.getConfigFile("")).rejects.toThrowError( - '"reviewers[0].min_approvals" must be greater than or equal to 1', + '"reviewers[0].minApprovals" must be greater than or equal to 1', ); }); - test("should fail with min_approvals in 0", async () => { + test("should fail with minApprovals in 0", async () => { api.getConfigFile.mockResolvedValue(` rules: - name: Test review @@ -187,12 +187,12 @@ describe("'And' rule parsing", () => { - 'example' type: and reviewers: - - min_approvals: 0 + - minApprovals: 0 users: - user-example `); await expect(runner.getConfigFile("")).rejects.toThrowError( - '"reviewers[0].min_approvals" must be greater than or equal to 1', + '"reviewers[0].minApprovals" must be greater than or equal to 1', ); }); }); diff --git a/src/test/rules/basicRule.test.ts b/src/test/rules/basicRule.test.ts index 00fcbbf..b2408e3 100644 --- a/src/test/rules/basicRule.test.ts +++ b/src/test/rules/basicRule.test.ts @@ -86,7 +86,7 @@ describe("Basic rule parsing", () => { await expect(runner.getConfigFile("")).rejects.toThrowError('"value" must contain at least one of [users, teams]'); }); - test("should default min_approvals to 1", async () => { + test("should default minApprovals to 1", async () => { api.getConfigFile.mockResolvedValue(` rules: - name: Test review @@ -102,13 +102,13 @@ describe("Basic rule parsing", () => { const config = await runner.getConfigFile(""); const [rule] = config.rules; if (rule.type === "basic") { - expect(rule.min_approvals).toEqual(1); + expect(rule.minApprovals).toEqual(1); } else { throw new Error(`Rule type ${rule.type} is invalid`); } }); - test("should fail with min_approvals in negative", async () => { + test("should fail with minApprovals in negative", async () => { api.getConfigFile.mockResolvedValue(` rules: - name: Test review @@ -118,14 +118,14 @@ describe("Basic rule parsing", () => { exclude: - 'example' type: basic - min_approvals: -99 + minApprovals: -99 users: - user-example `); - await expect(runner.getConfigFile("")).rejects.toThrowError('"min_approvals" must be greater than or equal to 1'); + await expect(runner.getConfigFile("")).rejects.toThrowError('"minApprovals" must be greater than or equal to 1'); }); - test("should fail with min_approvals in 0", async () => { + test("should fail with minApprovals in 0", async () => { api.getConfigFile.mockResolvedValue(` rules: - name: Test review @@ -135,11 +135,11 @@ describe("Basic rule parsing", () => { exclude: - 'example' type: basic - min_approvals: 0 + minApprovals: 0 users: - user-example `); - await expect(runner.getConfigFile("")).rejects.toThrowError('"min_approvals" must be greater than or equal to 1'); + await expect(runner.getConfigFile("")).rejects.toThrowError('"minApprovals" must be greater than or equal to 1'); }); test("should default countAuthor to false", async () => { diff --git a/src/test/rules/fellows.test.ts b/src/test/rules/fellows.test.ts index f5b7bd0..7e34f4c 100644 --- a/src/test/rules/fellows.test.ts +++ b/src/test/rules/fellows.test.ts @@ -95,7 +95,7 @@ describe("Fellows rule parsing", () => { await expect(runner.getConfigFile("")).rejects.toThrowError('"minRank" must be a number'); }); - test("should default min_approvals to 1", async () => { + test("should default minApprovals to 1", async () => { api.getConfigFile.mockResolvedValue(` rules: - name: Test review @@ -110,13 +110,13 @@ describe("Fellows rule parsing", () => { const config = await runner.getConfigFile(""); const [rule] = config.rules; if (rule.type === "fellows") { - expect(rule.min_approvals).toEqual(1); + expect(rule.minApprovals).toEqual(1); } else { throw new Error(`Rule type ${rule.type} is invalid`); } }); - test("should fail with min_approvals in negative", async () => { + test("should fail with minApprovals in negative", async () => { api.getConfigFile.mockResolvedValue(` rules: - name: Test review @@ -126,13 +126,13 @@ describe("Fellows rule parsing", () => { exclude: - 'example' type: fellows - min_approvals: -99 + minApprovals: -99 minRank: 4 `); - await expect(runner.getConfigFile("")).rejects.toThrowError('"min_approvals" must be greater than or equal to 1'); + await expect(runner.getConfigFile("")).rejects.toThrowError('"minApprovals" must be greater than or equal to 1'); }); - test("should fail with min_approvals in 0", async () => { + test("should fail with minApprovals in 0", async () => { api.getConfigFile.mockResolvedValue(` rules: - name: Test review @@ -142,10 +142,10 @@ describe("Fellows rule parsing", () => { exclude: - 'example' type: fellows - min_approvals: 0 + minApprovals: 0 minRank: 4 `); - await expect(runner.getConfigFile("")).rejects.toThrowError('"min_approvals" must be greater than or equal to 1'); + await expect(runner.getConfigFile("")).rejects.toThrowError('"minApprovals" must be greater than or equal to 1'); }); test("should default countAuthor to false", async () => { diff --git a/src/test/rules/or.test.ts b/src/test/rules/or.test.ts index 9fa7a13..8fabba5 100644 --- a/src/test/rules/or.test.ts +++ b/src/test/rules/or.test.ts @@ -114,7 +114,7 @@ describe("'Or' rule parsing", () => { reviewers: - teams: - team-example - - min_approvals: 2 + - minApprovals: 2 users: - abc teams: @@ -125,13 +125,13 @@ describe("'Or' rule parsing", () => { 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].minApprovals).toEqual(2); expect(rule.reviewers[1].users).toContainEqual("abc"); expect(rule.reviewers[1].teams).toContainEqual("xyz"); }); }); - test("should default min_approvals to 1", async () => { + test("should default minApprovals to 1", async () => { api.getConfigFile.mockResolvedValue(` rules: - name: Test review @@ -150,13 +150,13 @@ describe("'Or' rule parsing", () => { const config = await runner.getConfigFile(""); const [rule] = config.rules; if (rule.type === "or") { - expect(rule.reviewers[0].min_approvals).toEqual(1); + expect(rule.reviewers[0].minApprovals).toEqual(1); } else { throw new Error(`Rule type ${rule.type} is invalid`); } }); - test("should fail with min_approvals in negative", async () => { + test("should fail with minApprovals in negative", async () => { api.getConfigFile.mockResolvedValue(` rules: - name: Test review @@ -167,16 +167,16 @@ describe("'Or' rule parsing", () => { - 'example' type: or reviewers: - - min_approvals: -99 + - minApprovals: -99 users: - user-example `); await expect(runner.getConfigFile("")).rejects.toThrowError( - '"reviewers[0].min_approvals" must be greater than or equal to 1', + '"reviewers[0].minApprovals" must be greater than or equal to 1', ); }); - test("should fail with min_approvals in 0", async () => { + test("should fail with minApprovals in 0", async () => { api.getConfigFile.mockResolvedValue(` rules: - name: Test review @@ -187,12 +187,12 @@ describe("'Or' rule parsing", () => { - 'example' type: or reviewers: - - min_approvals: 0 + - minApprovals: 0 users: - user-example `); await expect(runner.getConfigFile("")).rejects.toThrowError( - '"reviewers[0].min_approvals" must be greater than or equal to 1', + '"reviewers[0].minApprovals" must be greater than or equal to 1', ); }); diff --git a/src/test/runner/conditions.test.ts b/src/test/runner/conditions.test.ts index fd4e5f3..4bad1f0 100644 --- a/src/test/runner/conditions.test.ts +++ b/src/test/runner/conditions.test.ts @@ -19,20 +19,20 @@ describe("evaluateCondition tests", () => { }); test("should throw if no teams or users were set", async () => { - await expect(runner.evaluateCondition({ min_approvals: 99 })).rejects.toThrowError( + await expect(runner.evaluateCondition({ minApprovals: 99 })).rejects.toThrowError( "No users have been found in the required reviewers", ); }); test("should throw if not enough users are available", async () => { - await expect(runner.evaluateCondition({ min_approvals: 5, users: ["one-user"] })).rejects.toThrow( + await expect(runner.evaluateCondition({ minApprovals: 5, users: ["one-user"] })).rejects.toThrow( "The amount of required approvals is smaller than the amount of available users.", ); }); test("should throw if not enough users in teams are available", async () => { teamsApi.getTeamMembers.mockResolvedValue(["1", "2", "3"]); - await expect(runner.evaluateCondition({ min_approvals: 4, teams: ["etcetera"] })).rejects.toThrow( + await expect(runner.evaluateCondition({ minApprovals: 4, teams: ["etcetera"] })).rejects.toThrow( "The amount of required approvals is smaller than the amount of available users.", ); }); @@ -40,7 +40,7 @@ describe("evaluateCondition tests", () => { test("should throw if not enough users in teams are available and find duplicates", async () => { teamsApi.getTeamMembers.calledWith("a").mockResolvedValue(["1", "2", "3"]); teamsApi.getTeamMembers.calledWith("b").mockResolvedValue(["2", "3", "4"]); - await expect(runner.evaluateCondition({ min_approvals: 5, teams: ["a", "b"] })).rejects.toThrow( + await expect(runner.evaluateCondition({ minApprovals: 5, teams: ["a", "b"] })).rejects.toThrow( "The amount of required approvals is smaller than the amount of available users.", ); }); @@ -52,18 +52,18 @@ describe("evaluateCondition tests", () => { }); test("should pass if required users approved the PR", async () => { - const [result] = await runner.evaluateCondition({ min_approvals: 1, users: [users[0]] }); + const [result] = await runner.evaluateCondition({ minApprovals: 1, users: [users[0]] }); expect(result).toBeTruthy(); }); test("should pass if required amount of users approved the PR", async () => { - const [result] = await runner.evaluateCondition({ min_approvals: 2, users: [users[0], users[users.length - 1]] }); + const [result] = await runner.evaluateCondition({ minApprovals: 2, users: [users[0], users[users.length - 1]] }); expect(result).toBeTruthy(); }); test("should fail if not all required users approved the PR", async () => { const newUser = "missing-user"; - const [result, missingData] = await runner.evaluateCondition({ min_approvals: 2, users: [users[0], newUser] }); + const [result, missingData] = await runner.evaluateCondition({ minApprovals: 2, users: [users[0], newUser] }); expect(result).toBeFalsy(); expect(missingData?.missingUsers).toContainEqual(newUser); expect(missingData?.missingUsers).not.toContainEqual(users[0]); @@ -82,20 +82,20 @@ describe("evaluateCondition tests", () => { test("should pass if required users approved the PR", async () => { teamsApi.getTeamMembers.mockResolvedValue(users); - const [result] = await runner.evaluateCondition({ min_approvals: 1, teams: [team] }); + const [result] = await runner.evaluateCondition({ minApprovals: 1, teams: [team] }); expect(result).toBeTruthy(); }); test("should pass if required amount of users approved the PR", async () => { teamsApi.getTeamMembers.mockResolvedValue(users); - const [result] = await runner.evaluateCondition({ min_approvals: 2, teams: [team] }); + const [result] = await runner.evaluateCondition({ minApprovals: 2, teams: [team] }); expect(result).toBeTruthy(); }); test("should fail if not enough members of a team approved the PR", async () => { api.listApprovedReviewsAuthors.mockResolvedValue([users[0]]); teamsApi.getTeamMembers.mockResolvedValue(users); - const [result, missingData] = await runner.evaluateCondition({ min_approvals: 2, teams: [team] }); + const [result, missingData] = await runner.evaluateCondition({ minApprovals: 2, teams: [team] }); expect(result).toBeFalsy(); expect(missingData?.missingUsers).toEqual(users.slice(1)); expect(missingData?.missingUsers).not.toContainEqual(users[0]); @@ -116,7 +116,7 @@ describe("evaluateCondition tests", () => { ]); teamsApi.getTeamMembers.calledWith(team1.name).mockResolvedValue(team1.users); teamsApi.getTeamMembers.calledWith(team2.name).mockResolvedValue(team2.users); - const [result] = await runner.evaluateCondition({ min_approvals: 4, teams: [team1.name, team2.name] }); + const [result] = await runner.evaluateCondition({ minApprovals: 4, teams: [team1.name, team2.name] }); expect(result).toBeTruthy(); }); @@ -126,7 +126,7 @@ describe("evaluateCondition tests", () => { teamsApi.getTeamMembers.calledWith(team1.name).mockResolvedValue(team1.users); teamsApi.getTeamMembers.calledWith(team2.name).mockResolvedValue(team2.users); api.listApprovedReviewsAuthors.mockResolvedValue([]); - const [result, report] = await runner.evaluateCondition({ min_approvals: 3, teams: [team1.name, team2.name] }); + const [result, report] = await runner.evaluateCondition({ minApprovals: 3, teams: [team1.name, team2.name] }); expect(result).toBeFalsy(); // Should not send required users more than once expect(report?.missingUsers).toEqual([...team1.users, team2.users[0]]); @@ -138,7 +138,7 @@ describe("evaluateCondition tests", () => { teamsApi.getTeamMembers.calledWith(team).mockResolvedValue(users); api.listApprovedReviewsAuthors.mockResolvedValue([]); const [result, report] = await runner.evaluateCondition({ - min_approvals: 1, + minApprovals: 1, teams: [team], users: [users[0]], }); diff --git a/src/test/runner/runner.test.ts b/src/test/runner/runner.test.ts index 38cc4e5..0893956 100644 --- a/src/test/runner/runner.test.ts +++ b/src/test/runner/runner.test.ts @@ -24,8 +24,8 @@ describe("Shared validations", () => { test("validatePullRequest should return true if no rule matches any files", async () => { const config: ConfigurationFile = { rules: [ - { name: "Rule 1", type: RuleTypes.Basic, condition: { include: ["src"] }, min_approvals: 1 }, - { name: "Rule 2", type: RuleTypes.Basic, condition: { include: ["README.md"] }, min_approvals: 99 }, + { name: "Rule 1", type: RuleTypes.Basic, condition: { include: ["src"] }, minApprovals: 1 }, + { name: "Rule 2", type: RuleTypes.Basic, condition: { include: ["README.md"] }, minApprovals: 99 }, ], }; api.listModifiedFiles.mockResolvedValue([".github/workflows/review-bot.yml", "LICENSE"]); @@ -40,7 +40,7 @@ describe("Shared validations", () => { name: "Rule allowedToSkipRule", type: RuleTypes.Basic, condition: { include: ["src"] }, - min_approvals: 1, + minApprovals: 1, allowedToSkipRule: { teams: ["abc"] }, }, ], diff --git a/src/test/runner/validation/and.test.ts b/src/test/runner/validation/and.test.ts index 34d6df4..51bc9b4 100644 --- a/src/test/runner/validation/and.test.ts +++ b/src/test/runner/validation/and.test.ts @@ -30,7 +30,7 @@ describe("'And' rule validation", () => { name: "And rule", type: RuleTypes.And, condition: { include: ["review-bot.yml"] }, - reviewers: [{ teams: ["abc"], min_approvals: 1 }], + reviewers: [{ teams: ["abc"], minApprovals: 1 }], }, ], }; @@ -47,8 +47,8 @@ describe("'And' rule validation", () => { type: RuleTypes.And, condition: { include: ["review-bot.yml"] }, reviewers: [ - { teams: ["abc"], min_approvals: 1 }, - { users: [users[0]], min_approvals: 1 }, + { teams: ["abc"], minApprovals: 1 }, + { users: [users[0]], minApprovals: 1 }, ], }, ], @@ -67,8 +67,8 @@ describe("'And' rule validation", () => { type: RuleTypes.And, condition: { include: ["review-bot.yml"] }, reviewers: [ - { teams: ["abc"], min_approvals: 1 }, - { users: [users[0]], min_approvals: 1 }, + { teams: ["abc"], minApprovals: 1 }, + { users: [users[0]], minApprovals: 1 }, ], }, ], @@ -89,10 +89,10 @@ describe("'And' rule validation", () => { type: RuleTypes.And, condition: { include: ["review-bot.yml"] }, reviewers: [ - { users: ["abc"], min_approvals: 1 }, - { users: ["def"], min_approvals: 1 }, - { users: ["efg", "hij"], min_approvals: 2 }, - { users: ["klm"], min_approvals: 1 }, + { users: ["abc"], minApprovals: 1 }, + { users: ["def"], minApprovals: 1 }, + { users: ["efg", "hij"], minApprovals: 2 }, + { users: ["klm"], minApprovals: 1 }, ], }, ], @@ -110,8 +110,8 @@ describe("'And' rule validation", () => { type: RuleTypes.And, condition: { include: ["review-bot.yml"] }, reviewers: [ - { teams: ["abc"], min_approvals: 1 }, - { users: [users[0]], min_approvals: 1 }, + { teams: ["abc"], minApprovals: 1 }, + { users: [users[0]], minApprovals: 1 }, ], }, ], @@ -130,8 +130,8 @@ describe("'And' rule validation", () => { type: RuleTypes.And, condition: { include: ["review-bot.yml"] }, reviewers: [ - { teams: ["abc"], min_approvals: 1 }, - { teams: ["cba"], min_approvals: 1 }, + { teams: ["abc"], minApprovals: 1 }, + { teams: ["cba"], minApprovals: 1 }, ], }, ], @@ -157,8 +157,8 @@ describe("'And' rule validation", () => { type: RuleTypes.And, condition: { include: ["review-bot.yml"] }, reviewers: [ - { teams: ["abc"], min_approvals: 1 }, - { users: individualUsers, min_approvals: 2 }, + { teams: ["abc"], minApprovals: 1 }, + { users: individualUsers, minApprovals: 2 }, ], }, ], diff --git a/src/test/runner/validation/andDistinct.test.ts b/src/test/runner/validation/andDistinct.test.ts index 35c1e4d..39a6594 100644 --- a/src/test/runner/validation/andDistinct.test.ts +++ b/src/test/runner/validation/andDistinct.test.ts @@ -30,9 +30,9 @@ describe("'And distinct' rule validation", () => { const rule: AndDistinctRule = { type: RuleTypes.AndDistinct, reviewers: [ - { users: ["abc", "def", "fgh", users[0]], min_approvals: 2 }, - { teams: ["team-abc"], min_approvals: 1 }, - { users: ["abc", "def", users[1], users[2], "hij"], min_approvals: 1 }, + { users: ["abc", "def", "fgh", users[0]], minApprovals: 2 }, + { teams: ["team-abc"], minApprovals: 1 }, + { users: ["abc", "def", users[1], users[2], "hij"], minApprovals: 1 }, ], name: "test", condition: { include: [] }, @@ -47,9 +47,9 @@ describe("'And distinct' rule validation", () => { const rule: AndDistinctRule = { type: RuleTypes.AndDistinct, reviewers: [ - { users: ["abc", "def", "fgh", users[0]], min_approvals: 2 }, - { teams: ["team-abc"], min_approvals: 1 }, - { users: ["abc", "def", users[1], users[2], "hij"], min_approvals: 1 }, + { users: ["abc", "def", "fgh", users[0]], minApprovals: 2 }, + { teams: ["team-abc"], minApprovals: 1 }, + { users: ["abc", "def", users[1], users[2], "hij"], minApprovals: 1 }, ], name: "test", condition: { include: [] }, @@ -66,9 +66,9 @@ describe("'And distinct' rule validation", () => { const rule: AndDistinctRule = { type: RuleTypes.AndDistinct, reviewers: [ - { users: ["abc", "def", "fgh", users[0]], min_approvals: 1 }, - { teams: ["team-abc"], min_approvals: 1 }, - { users: ["abc", "def", "hij"], min_approvals: 1 }, + { users: ["abc", "def", "fgh", users[0]], minApprovals: 1 }, + { teams: ["team-abc"], minApprovals: 1 }, + { users: ["abc", "def", "hij"], minApprovals: 1 }, ], name: "test", condition: { include: [] }, @@ -85,9 +85,9 @@ describe("'And distinct' rule validation", () => { const rule: AndDistinctRule = { type: RuleTypes.AndDistinct, reviewers: [ - { users: ["abc", "def", "fgh"], min_approvals: 1 }, - { teams: ["team-abc"], min_approvals: 1 }, - { users: ["abc", "def", "hij"], min_approvals: 1 }, + { users: ["abc", "def", "fgh"], minApprovals: 1 }, + { teams: ["team-abc"], minApprovals: 1 }, + { users: ["abc", "def", "hij"], minApprovals: 1 }, ], name: "test", condition: { include: [] }, @@ -104,8 +104,8 @@ describe("'And distinct' rule validation", () => { const rule: AndDistinctRule = { type: RuleTypes.AndDistinct, reviewers: [ - { users: [users[0], "def"], min_approvals: 2 }, - { teams: ["team-abc"], min_approvals: 1 }, + { users: [users[0], "def"], minApprovals: 2 }, + { teams: ["team-abc"], minApprovals: 1 }, ], name: "test", condition: { include: [] }, @@ -122,8 +122,8 @@ describe("'And distinct' rule validation", () => { const rule: AndDistinctRule = { type: RuleTypes.AndDistinct, reviewers: [ - { users: [users[0], "def"], min_approvals: 2 }, - { teams: ["team-abc"], min_approvals: 1 }, + { users: [users[0], "def"], minApprovals: 2 }, + { teams: ["team-abc"], minApprovals: 1 }, ], name: "test", condition: { include: [] }, @@ -140,8 +140,8 @@ describe("'And distinct' rule validation", () => { type: RuleTypes.AndDistinct, countAuthor: false, reviewers: [ - { users: [users[0], "example", "random"], min_approvals: 2 }, - { teams: ["team-abc"], min_approvals: 1 }, + { users: [users[0], "example", "random"], minApprovals: 2 }, + { teams: ["team-abc"], minApprovals: 1 }, ], name: "test", condition: { include: [] }, @@ -158,8 +158,8 @@ describe("'And distinct' rule validation", () => { const rule: AndDistinctRule = { type: RuleTypes.AndDistinct, reviewers: [ - { users: ["abc", "def", "fgh"], min_approvals: 1 }, - { teams: ["team-abc"], min_approvals: 1 }, + { users: ["abc", "def", "fgh"], minApprovals: 1 }, + { teams: ["team-abc"], minApprovals: 1 }, ], name: "test", condition: { include: [] }, @@ -173,8 +173,8 @@ describe("'And distinct' rule validation", () => { const rule: AndDistinctRule = { type: RuleTypes.AndDistinct, reviewers: [ - { users: ["abc", "def", "fgh", users[0]], min_approvals: 1 }, - { teams: ["team-abc"], min_approvals: 1 }, + { users: ["abc", "def", "fgh", users[0]], minApprovals: 1 }, + { teams: ["team-abc"], minApprovals: 1 }, ], name: "test", condition: { include: [] }, @@ -188,9 +188,9 @@ describe("'And distinct' rule validation", () => { const rule: AndDistinctRule = { type: RuleTypes.AndDistinct, reviewers: [ - { users: ["abc", "def", "fgh", users[0]], min_approvals: 1 }, - { teams: ["team-abc"], min_approvals: 1 }, - { users: ["abc", "def", users[1], users[2], "hij"], min_approvals: 1 }, + { users: ["abc", "def", "fgh", users[0]], minApprovals: 1 }, + { teams: ["team-abc"], minApprovals: 1 }, + { users: ["abc", "def", users[1], users[2], "hij"], minApprovals: 1 }, ], name: "test", condition: { include: [] }, @@ -204,9 +204,9 @@ describe("'And distinct' rule validation", () => { const rule: AndDistinctRule = { type: RuleTypes.AndDistinct, reviewers: [ - { users: ["abc", "def", "fgh", users[0]], min_approvals: 2 }, - { teams: ["team-abc"], min_approvals: 1 }, - { users: ["abc", "def", users[1], users[2], "hij"], min_approvals: 1 }, + { users: ["abc", "def", "fgh", users[0]], minApprovals: 2 }, + { teams: ["team-abc"], minApprovals: 1 }, + { users: ["abc", "def", users[1], users[2], "hij"], minApprovals: 1 }, ], name: "test", condition: { include: [] }, @@ -220,9 +220,9 @@ describe("'And distinct' rule validation", () => { const rule: AndDistinctRule = { type: RuleTypes.AndDistinct, reviewers: [ - { users: ["abc", "def", "fgh", users[0]], min_approvals: 2 }, - { teams: ["team-abc"], min_approvals: 1 }, - { users: ["abc", "def", users[1], users[2], "hij"], min_approvals: 2 }, + { users: ["abc", "def", "fgh", users[0]], minApprovals: 2 }, + { teams: ["team-abc"], minApprovals: 1 }, + { users: ["abc", "def", users[1], users[2], "hij"], minApprovals: 2 }, ], name: "test", condition: { include: [] }, @@ -237,8 +237,8 @@ describe("'And distinct' rule validation", () => { type: RuleTypes.AndDistinct, countAuthor: true, reviewers: [ - { users: [users[0], "example"], min_approvals: 1 }, - { teams: ["team-abc"], min_approvals: 2 }, + { users: [users[0], "example"], minApprovals: 1 }, + { teams: ["team-abc"], minApprovals: 2 }, ], name: "test", condition: { include: [] }, diff --git a/src/test/runner/validation/fellows.test.ts b/src/test/runner/validation/fellows.test.ts index 58bceda..f0ac700 100644 --- a/src/test/runner/validation/fellows.test.ts +++ b/src/test/runner/validation/fellows.test.ts @@ -32,7 +32,7 @@ describe("'Fellows' rule validation", () => { type: RuleTypes.Fellows, condition: { include: ["review-bot.yml"] }, minRank: 1, - min_approvals: 2, + minApprovals: 2, }, ], }); @@ -49,7 +49,7 @@ describe("'Fellows' rule validation", () => { type: RuleTypes.Fellows, condition: { include: ["review-bot.yml"] }, minRank: 1, - min_approvals: 1, + minApprovals: 1, countAuthor: true, }, ], @@ -70,7 +70,7 @@ describe("'Fellows' rule validation", () => { type: RuleTypes.Fellows, condition: { include: ["review-bot.yml"] }, minRank: 4, - min_approvals: 1, + minApprovals: 1, }, ], }); @@ -89,7 +89,7 @@ describe("'Fellows' rule validation", () => { type: RuleTypes.Fellows, condition: { include: ["review-bot.yml"] }, minRank: 4, - min_approvals: 1, + minApprovals: 1, }, ], }; @@ -99,7 +99,7 @@ describe("'Fellows' rule validation", () => { ); }); - test("should throw error if not enough fellows of a given rank are found to fulfill min_approvals requirement", async () => { + test("should throw error if not enough fellows of a given rank are found to fulfill minApprovals requirement", async () => { fellowsApi.getTeamMembers.mockResolvedValue([users[2]]); fellowsApi.getTeamMembers.calledWith("4").mockResolvedValue(users); const config: ConfigurationFile = { @@ -109,7 +109,7 @@ describe("'Fellows' rule validation", () => { type: RuleTypes.Fellows, condition: { include: ["review-bot.yml"] }, minRank: 4, - min_approvals: 5, + minApprovals: 5, }, ], }; diff --git a/src/test/runner/validation/or.test.ts b/src/test/runner/validation/or.test.ts index f4e86ae..996bfbd 100644 --- a/src/test/runner/validation/or.test.ts +++ b/src/test/runner/validation/or.test.ts @@ -30,7 +30,7 @@ describe("'Or' rule validation", () => { name: "Or rule", type: RuleTypes.Or, condition: { include: ["review-bot.yml"] }, - reviewers: [{ teams: ["abc"], min_approvals: 1 }], + reviewers: [{ teams: ["abc"], minApprovals: 1 }], }, ], }; @@ -47,8 +47,8 @@ describe("'Or' rule validation", () => { type: RuleTypes.Or, condition: { include: ["review-bot.yml"] }, reviewers: [ - { teams: ["abc"], min_approvals: 1 }, - { users: [users[0]], min_approvals: 1 }, + { teams: ["abc"], minApprovals: 1 }, + { users: [users[0]], minApprovals: 1 }, ], }, ], @@ -66,9 +66,9 @@ describe("'Or' rule validation", () => { type: RuleTypes.Or, condition: { include: ["review-bot.yml"] }, reviewers: [ - { teams: ["abc"], min_approvals: 1 }, - { users: [users[0]], min_approvals: 1 }, - { users: [users[1]], min_approvals: 1 }, + { teams: ["abc"], minApprovals: 1 }, + { users: [users[0]], minApprovals: 1 }, + { users: [users[1]], minApprovals: 1 }, ], }, ], @@ -89,8 +89,8 @@ describe("'Or' rule validation", () => { type: RuleTypes.Or, condition: { include: ["review-bot.yml"] }, reviewers: [ - { teams: ["abc"], min_approvals: 1 }, - { users: individualUsers, min_approvals: 2 }, + { teams: ["abc"], minApprovals: 1 }, + { users: individualUsers, minApprovals: 2 }, ], }, ], @@ -112,10 +112,10 @@ describe("'Or' rule validation", () => { type: RuleTypes.Or, condition: { include: ["review-bot.yml"] }, reviewers: [ - { users: ["abc"], min_approvals: 1 }, - { users: ["bcd", "cef"], min_approvals: 2 }, - { users: ["bds", "cj9", "dij", "ehu"], min_approvals: 4 }, - { users: ["bob", "cat", "dpo", "eio", "fgy"], min_approvals: 5 }, + { users: ["abc"], minApprovals: 1 }, + { users: ["bcd", "cef"], minApprovals: 2 }, + { users: ["bds", "cj9", "dij", "ehu"], minApprovals: 4 }, + { users: ["bob", "cat", "dpo", "eio", "fgy"], minApprovals: 5 }, ], }, ],