diff --git a/.eslintrc.json b/.eslintrc.json index b6721aca..e60c096e 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -8,9 +8,16 @@ "standard" ], "parserOptions": { - "ecmaVersion": 12 + "ecmaVersion": 13 }, "rules": { }, - "ignorePatterns": ["test/**/*.js"] + "overrides": [ + { + "files": ["test/**/*.js"], + "env": { + "jest": true + } + } + ] } diff --git a/index.js b/index.js index 7e4ef032..40e05739 100644 --- a/index.js +++ b/index.js @@ -9,9 +9,7 @@ const env = require('./lib/env') let deploymentConfig - module.exports = (robot, { getRouter }, Settings = require('./lib/settings')) => { - let appName = 'safe-settings' let appSlug = 'safe-settings' async function syncAllSettings (nop, context, repo = context.repo(), ref) { try { @@ -101,7 +99,7 @@ module.exports = (robot, { getRouter }, Settings = require('./lib/settings')) => const config = Object.assign({}, deploymentConfig, runtimeConfig) const renameConfig = Object.assign({}, config, rename) robot.log.debug(`config for ref ${ref} is ${JSON.stringify(config)}`) - return Settings.sync(nop, context, repo, renameConfig, ref ) + return Settings.sync(nop, context, repo, renameConfig, ref) } catch (e) { if (nop) { let filename = env.SETTINGS_FILE_PATH @@ -217,7 +215,7 @@ module.exports = (robot, { getRouter }, Settings = require('./lib/settings')) => robot.log.debug(JSON.stringify(res, null)) } - async function info() { + async function info () { const github = await robot.auth() const installations = await github.paginate( github.apps.listInstallations.endpoint.merge({ per_page: 100 }) @@ -227,13 +225,11 @@ module.exports = (robot, { getRouter }, Settings = require('./lib/settings')) => const installation = installations[0] const github = await robot.auth(installation.id) const app = await github.apps.getAuthenticated() - appName = app.data.name appSlug = app.data.slug robot.log.debug(`Validated the app is configured properly = \n${JSON.stringify(app.data, null, 2)}`) } } - async function syncInstallation () { robot.log.trace('Fetching installations') const github = await robot.auth() @@ -395,8 +391,8 @@ module.exports = (robot, { getRouter }, Settings = require('./lib/settings')) => }) robot.on('repository.renamed', async context => { - if (env.BLOCK_REPO_RENAME_BY_HUMAN!== 'true') { - robot.log.debug(`"env.BLOCK_REPO_RENAME_BY_HUMAN" is 'false' by default. Repo rename is not managed by Safe-settings. Continue with the default behavior.`) + if (env.BLOCK_REPO_RENAME_BY_HUMAN !== 'true') { + robot.log.debug('"env.BLOCK_REPO_RENAME_BY_HUMAN" is \'false\' by default. Repo rename is not managed by Safe-settings. Continue with the default behavior.') return } const { payload } = context @@ -414,7 +410,7 @@ module.exports = (robot, { getRouter }, Settings = require('./lib/settings')) => const newPath = `.github/repos/${payload.repository.name}.yml` robot.log.debug(oldPath) try { - const repofile = await context.octokit.request('GET /repos/{owner}/{repo}/contents/{path}', { + const repofile = await context.octokit.request('GET /repos/{owner}/{repo}/contents/{path}', { owner: payload.repository.owner.login, repo: env.ADMIN_REPO, path: oldPath, @@ -439,12 +435,12 @@ module.exports = (robot, { getRouter }, Settings = require('./lib/settings')) => } catch (error) { if (error.status === 404) { // if the a config file does not exist, create one from the old one - const update = await context.octokit.request('PUT /repos/{owner}/{repo}/contents/{path}', { + await context.octokit.request('PUT /repos/{owner}/{repo}/contents/{path}', { owner: payload.repository.owner.login, repo: env.ADMIN_REPO, path: newPath, - name: `${payload.repository.name}.yml`, - content: content, + name: `${payload.repository.name}.yml`, + content, message: `Repo Renamed and safe-settings renamed the file from ${payload.changes.repository.name.from} to ${payload.repository.name}`, sha: repofile.data.sha, headers: { @@ -455,26 +451,23 @@ module.exports = (robot, { getRouter }, Settings = require('./lib/settings')) => } else { robot.log.error(error) } - } - + } } catch (error) { if (error.status === 404) { - //nop - } else { + // nop + } else { robot.log.error(error) } - } - return + } } else { robot.log.debug('Repository Edited by a Human') // Create a repository config to reset the name back to the previous name - const rename = {repository: { name: payload.changes.repository.name.from, oldname: payload.repository.name}} - const repo = {repo: payload.changes.repository.name.from, owner: payload.repository.owner.login} + const rename = { repository: { name: payload.changes.repository.name.from, oldname: payload.repository.name } } + const repo = { repo: payload.changes.repository.name.from, owner: payload.repository.owner.login } return renameSync(false, context, repo, rename) } }) - robot.on('check_suite.requested', async context => { const { payload } = context const { repository } = payload @@ -663,7 +656,7 @@ module.exports = (robot, { getRouter }, Settings = require('./lib/settings')) => syncInstallation() }) } - + // Get info about the app info() diff --git a/lib/commentmessage.js b/lib/commentmessage.js index 93d97039..b54f81bb 100644 --- a/lib/commentmessage.js +++ b/lib/commentmessage.js @@ -28,4 +28,4 @@ module.exports = `* Run on: \` <%= new Date() %> \` <% }) %> <% }) %> -<% } %>` \ No newline at end of file +<% } %>` diff --git a/lib/deploymentConfig.js b/lib/deploymentConfig.js index f8fdeb27..7dd8b932 100644 --- a/lib/deploymentConfig.js +++ b/lib/deploymentConfig.js @@ -8,46 +8,47 @@ const env = require('./env') * The settings are loaded from the deployment-settings.yml file during initialization and stored as static properties. */ class DeploymentConfig { - //static config - static configvalidators = {} - static overridevalidators = {} + // static config + static configvalidators = {} + static overridevalidators = {} - static { - const deploymentConfigPath = process.env.DEPLOYMENT_CONFIG_FILE ? process.env.DEPLOYMENT_CONFIG_FILE : 'deployment-settings.yml' - if (fs.existsSync(deploymentConfigPath)) { - this.config = yaml.load(fs.readFileSync(deploymentConfigPath)) - } else { - this.config = { restrictedRepos: ['admin', '.github', 'safe-settings'] } - } - - const overridevalidators = this.config.overridevalidators - if (this.isIterable(overridevalidators)) { - for (const validator of overridevalidators) { - // eslint-disable-next-line no-new-func - const f = new Function('baseconfig', 'overrideconfig', 'githubContext', validator.script) - this.overridevalidators[validator.plugin] = { canOverride: f, error: validator.error } - } - } - const configvalidators = this.config.configvalidators - if (this.isIterable(configvalidators)) { - for (const validator of configvalidators) { - // eslint-disable-next-line no-new-func - const f = new Function('baseconfig', 'githubContext', validator.script) - this.configvalidators[validator.plugin] = { isValid: f, error: validator.error } - } - } + static { + const deploymentConfigPath = process.env.DEPLOYMENT_CONFIG_FILE ? process.env.DEPLOYMENT_CONFIG_FILE : 'deployment-settings.yml' + if (fs.existsSync(deploymentConfigPath)) { + this.config = yaml.load(fs.readFileSync(deploymentConfigPath)) + } else { + this.config = { restrictedRepos: ['admin', '.github', 'safe-settings'] } } - static isIterable (obj) { - // checks for null and undefined - if (obj == null) { - return false - } - return typeof obj[Symbol.iterator] === 'function' + const overridevalidators = this.config.overridevalidators + if (this.isIterable(overridevalidators)) { + for (const validator of overridevalidators) { + // eslint-disable-next-line no-new-func + const f = new Function('baseconfig', 'overrideconfig', 'githubContext', validator.script) + this.overridevalidators[validator.plugin] = { canOverride: f, error: validator.error } + } + } + const configvalidators = this.config.configvalidators + if (this.isIterable(configvalidators)) { + for (const validator of configvalidators) { + // eslint-disable-next-line no-new-func + const f = new Function('baseconfig', 'githubContext', validator.script) + this.configvalidators[validator.plugin] = { isValid: f, error: validator.error } } + } + } - constructor (nop, context, repo, config, ref, suborg) { + static isIterable (obj) { + // checks for null and undefined + if (obj == null) { + return false } + return typeof obj[Symbol.iterator] === 'function' + } + + // eslint-disable-next-line no-useless-constructor + constructor (nop, context, repo, config, ref, suborg) { + } } DeploymentConfig.FILE_NAME = `${env.CONFIG_PATH}/settings.yml` diff --git a/lib/error.js b/lib/error.js index f268ac6c..3e23ad60 100644 --- a/lib/error.js +++ b/lib/error.js @@ -9,4 +9,4 @@ module.exports = `Run on: \`<%= new Date().toISOString() %>\` <% }) -%> -` \ No newline at end of file +` diff --git a/lib/plugins/environments.js b/lib/plugins/environments.js index 4ceaa9ff..4d064746 100644 --- a/lib/plugins/environments.js +++ b/lib/plugins/environments.js @@ -3,361 +3,357 @@ const MergeDeep = require('../mergeDeep') const NopCommand = require('../nopcommand') module.exports = class Environments extends Diffable { - constructor(...args) { - super(...args) - - if (this.entries) { - // Force all names to lowercase to avoid comparison issues. - this.entries.forEach(environment => { - environment.name = environment.name.toLowerCase(); - if(environment.variables) { - environment.variables.forEach(variable => { - variable.name = variable.name.toLowerCase(); - }); - } - }) + constructor (...args) { + super(...args) + + if (this.entries) { + // Force all names to lowercase to avoid comparison issues. + this.entries.forEach(environment => { + environment.name = environment.name.toLowerCase() + if (environment.variables) { + environment.variables.forEach(variable => { + variable.name = variable.name.toLowerCase() + }) } + }) + } + } + + async find () { + const { data: { environments } } = await this.github.request('GET /repos/:org/:repo/environments', { + org: this.repo.owner, + repo: this.repo.repo + }) + + const environmentsMapped = [] + + for (const environment of environments) { + const mapped = { + name: environment.name.toLowerCase(), + repo: this.repo.repo, + wait_timer: (environment.protection_rules.find(rule => rule.type === 'wait_timer') || { wait_timer: 0 }).wait_timer, + prevent_self_review: (environment.protection_rules.find(rule => rule.type === 'required_reviewers') || { prevent_self_review: false }).prevent_self_review, + reviewers: (environment.protection_rules.find(rule => rule.type === 'required_reviewers') || { reviewers: [] }).reviewers.map(reviewer => ({ id: reviewer.reviewer.id, type: reviewer.type })), + deployment_branch_policy: environment.deployment_branch_policy === null + ? null + : { + protected_branches: (environment.deployment_branch_policy || { protected_branches: false }).protected_branches, + custom_branch_policies: (environment.deployment_branch_policy || { custom_branch_policies: false }).custom_branch_policies && (await this.github.request('GET /repos/:org/:repo/environments/:environment_name/deployment-branch-policies', { + org: this.repo.owner, + repo: this.repo.repo, + environment_name: environment.name + })).data.branch_policies.map(policy => ({ + name: policy.name + })) + }, + variables: (await this.github.request('GET /repos/:org/:repo/environments/:environment_name/variables', { + org: this.repo.owner, + repo: this.repo.repo, + environment_name: environment.name + })).data.variables.map(variable => ({ name: variable.name.toLowerCase(), value: variable.value })), + deployment_protection_rules: (await this.github.request('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { + org: this.repo.owner, + repo: this.repo.repo, + environment_name: environment.name + })).data.custom_deployment_protection_rules.map(rule => ({ + app_id: rule.app.id, + id: rule.id + })) + } + environmentsMapped.push(mapped) + // console.log(mapped); } - async find() { - const { data: { environments } } = await this.github.request('GET /repos/:org/:repo/environments', { - org: this.repo.owner, - repo: this.repo.repo - }); + return environmentsMapped + } - let environments_mapped = []; + comparator (existing, attrs) { + return existing.name === attrs.name + } - for(let environment of environments) { - const mapped = { - name: environment.name.toLowerCase(), - repo: this.repo.repo, - wait_timer: (environment.protection_rules.find(rule => rule.type === 'wait_timer') || { wait_timer: 0 }).wait_timer, - prevent_self_review: (environment.protection_rules.find(rule => rule.type === 'required_reviewers') || { prevent_self_review: false }).prevent_self_review, - reviewers: (environment.protection_rules.find(rule => rule.type === 'required_reviewers') || { reviewers: [] }).reviewers.map(reviewer => ({id: reviewer.reviewer.id, type: reviewer.type})), - deployment_branch_policy: environment.deployment_branch_policy === null ? null : { - protected_branches: (environment.deployment_branch_policy || { protected_branches: false }).protected_branches, - custom_branch_policies: (environment.deployment_branch_policy || { custom_branch_policies: false }).custom_branch_policies && (await this.github.request('GET /repos/:org/:repo/environments/:environment_name/deployment-branch-policies', { - org: this.repo.owner, - repo: this.repo.repo, - environment_name: environment.name - })).data.branch_policies.map(policy => ({ - name: policy.name - })) - }, - variables: (await this.github.request('GET /repos/:org/:repo/environments/:environment_name/variables', { - org: this.repo.owner, - repo: this.repo.repo, - environment_name: environment.name - })).data.variables.map(variable => ({name: variable.name.toLowerCase(), value: variable.value})), - deployment_protection_rules: (await this.github.request('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { - org: this.repo.owner, - repo: this.repo.repo, - environment_name: environment.name - })).data.custom_deployment_protection_rules.map(rule => ({ - app_id: rule.app.id, - id: rule.id - })) - } - environments_mapped.push(mapped); - //console.log(mapped); - } + getChanged (existing, attrs) { + if (!attrs.wait_timer) attrs.wait_timer = 0 + if (!attrs.prevent_self_review) attrs.prevent_self_review = false + if (!attrs.reviewers) attrs.reviewers = [] + if (!attrs.deployment_branch_policy) attrs.deployment_branch_policy = null + if (!attrs.variables) attrs.variables = [] + if (!attrs.deployment_protection_rules) attrs.deployment_protection_rules = [] - return environments_mapped; - } + const waitTimer = existing.wait_timer !== attrs.wait_timer + const preventSelfReview = existing.prevent_self_review !== attrs.prevent_self_review + const reviewers = JSON.stringify(existing.reviewers.sort((x1, x2) => x1.id - x2.id)) !== JSON.stringify(attrs.reviewers.sort((x1, x2) => x1.id - x2.id)) - comparator(existing, attrs) { - return existing.name === attrs.name + let existingCustomBranchPolicies = existing.deployment_branch_policy === null ? null : existing.deployment_branch_policy.custom_branch_policies + if (typeof (existingCustomBranchPolicies) === 'object' && existingCustomBranchPolicies !== null) { + existingCustomBranchPolicies = existingCustomBranchPolicies.sort() } - - getChanged(existing, attrs) { - if (!attrs.wait_timer) attrs.wait_timer = 0; - if (!attrs.prevent_self_review) attrs.prevent_self_review = false; - if (!attrs.reviewers) attrs.reviewers = []; - if (!attrs.deployment_branch_policy) attrs.deployment_branch_policy = null; - if(!attrs.variables) attrs.variables = []; - if(!attrs.deployment_protection_rules) attrs.deployment_protection_rules = []; - - const wait_timer = existing.wait_timer !== attrs.wait_timer; - const prevent_self_review = existing.prevent_self_review !== attrs.prevent_self_review; - const reviewers = JSON.stringify(existing.reviewers.sort((x1, x2) => x1.id - x2.id)) !== JSON.stringify(attrs.reviewers.sort((x1, x2) => x1.id - x2.id)); - - let existing_custom_branch_policies = existing.deployment_branch_policy === null ? null : existing.deployment_branch_policy.custom_branch_policies; - if(typeof(existing_custom_branch_policies) === 'object' && existing_custom_branch_policies !== null) { - existing_custom_branch_policies = existing_custom_branch_policies.sort(); - } - let attrs_custom_branch_policies = attrs.deployment_branch_policy === null ? null : attrs.deployment_branch_policy.custom_branch_policies; - if(typeof(attrs_custom_branch_policies) === 'object' && attrs_custom_branch_policies !== null) { - attrs_custom_branch_policies = attrs_custom_branch_policies.sort(); - } - let deployment_branch_policy; - if(existing.deployment_branch_policy === attrs.deployment_branch_policy) { - deployment_branch_policy = false; - } - else { - deployment_branch_policy = ( - (existing.deployment_branch_policy === null && attrs.deployment_branch_policy !== null) || + let attrsCustomBranchPolicies = attrs.deployment_branch_policy === null ? null : attrs.deployment_branch_policy.custom_branch_policies + if (typeof (attrsCustomBranchPolicies) === 'object' && attrsCustomBranchPolicies !== null) { + attrsCustomBranchPolicies = attrsCustomBranchPolicies.sort() + } + let deploymentBranchPolicy + if (existing.deployment_branch_policy === attrs.deployment_branch_policy) { + deploymentBranchPolicy = false + } else { + deploymentBranchPolicy = ( + (existing.deployment_branch_policy === null && attrs.deployment_branch_policy !== null) || (existing.deployment_branch_policy !== null && attrs.deployment_branch_policy === null) || (existing.deployment_branch_policy.protected_branches !== attrs.deployment_branch_policy.protected_branches) || - (JSON.stringify(existing_custom_branch_policies) !== JSON.stringify(attrs_custom_branch_policies)) - ); - } - - const variables = JSON.stringify(existing.variables.sort((x1, x2) => x1.name - x2.name)) !== JSON.stringify(attrs.variables.sort((x1, x2) => x1.name - x2.name)); - const deployment_protection_rules = JSON.stringify(existing.deployment_protection_rules.map(x => ({app_id: x.app_id})).sort((x1, x2) => x1.app_id - x2.app_id)) !== JSON.stringify(attrs.deployment_protection_rules.map(x => ({app_id: x.app_id})).sort((x1, x2) => x1.app_id - x2.app_id)); + (JSON.stringify(existingCustomBranchPolicies) !== JSON.stringify(attrsCustomBranchPolicies)) + ) + } - return {wait_timer, prevent_self_review, reviewers, deployment_branch_policy, variables, deployment_protection_rules}; + const variables = JSON.stringify(existing.variables.sort((x1, x2) => x1.name - x2.name)) !== JSON.stringify(attrs.variables.sort((x1, x2) => x1.name - x2.name)) + const deploymentProtectionRules = JSON.stringify(existing.deployment_protection_rules.map(x => ({ app_id: x.app_id })).sort((x1, x2) => x1.app_id - x2.app_id)) !== JSON.stringify(attrs.deployment_protection_rules.map(x => ({ app_id: x.app_id })).sort((x1, x2) => x1.app_id - x2.app_id)) + + return { waitTimer, preventSelfReview, reviewers, deploymentBranchPolicy, variables, deploymentProtectionRules } + } + + changed (existing, attrs) { + const { waitTimer, preventSelfReview, reviewers, deploymentBranchPolicy, variables, deploymentProtectionRules } = this.getChanged(existing, attrs) + + return waitTimer || preventSelfReview || reviewers || deploymentBranchPolicy || variables || deploymentProtectionRules + } + + async update (existing, attrs) { + const { waitTimer, preventSelfReview, reviewers, deploymentBranchPolicy, variables, deploymentProtectionRules } = this.getChanged(existing, attrs) + + if (waitTimer || preventSelfReview || reviewers || deploymentBranchPolicy) { + await this.github.request('PUT /repos/:org/:repo/environments/:environment_name', { + org: this.repo.owner, + repo: this.repo.repo, + environment_name: attrs.name, + wait_timer: attrs.wait_timer, + prevent_self_review: attrs.prevent_self_review, + reviewers: attrs.reviewers, + deployment_branch_policy: attrs.deployment_branch_policy === null + ? null + : { + protected_branches: attrs.deployment_branch_policy.protected_branches, + custom_branch_policies: !!attrs.deployment_branch_policy.custom_branch_policies + } + }) } - changed(existing, attrs) { - const {wait_timer, prevent_self_review, reviewers, deployment_branch_policy, variables, deployment_protection_rules} = this.getChanged(existing, attrs); + if (deploymentBranchPolicy && attrs.deployment_branch_policy && attrs.deployment_branch_policy.custom_branch_policies) { + const existingPolicies = (await this.github.request('GET /repos/:org/:repo/environments/:environment_name/deployment-branch-policies', { + org: this.repo.owner, + repo: this.repo.repo, + environment_name: attrs.name + })).data.branch_policies + + for (const policy of existingPolicies) { + await this.github.request('DELETE /repos/:org/:repo/environments/:environment_name/deployment-branch-policies/:branch_policy_id', { + org: this.repo.owner, + repo: this.repo.repo, + environment_name: attrs.name, + branch_policy_id: policy.id + }) + } - return wait_timer || prevent_self_review || reviewers || deployment_branch_policy || variables || deployment_protection_rules; + for (const policy of attrs.deployment_branch_policy.custom_branch_policies) { + await this.github.request('POST /repos/:org/:repo/environments/:environment_name/deployment-branch-policies', { + org: this.repo.owner, + repo: this.repo.repo, + environment_name: attrs.name, + name: policy + }) + } } - async update(existing, attrs) { - const {wait_timer, prevent_self_review, reviewers, deployment_branch_policy, variables, deployment_protection_rules} = this.getChanged(existing, attrs); - - if(wait_timer || prevent_self_review || reviewers || deployment_branch_policy) { - await this.github.request(`PUT /repos/:org/:repo/environments/:environment_name`, { - org: this.repo.owner, - repo: this.repo.repo, - environment_name: attrs.name, - wait_timer: attrs.wait_timer, - prevent_self_review: attrs.prevent_self_review, - reviewers: attrs.reviewers, - deployment_branch_policy: attrs.deployment_branch_policy === null ? null : { - protected_branches: attrs.deployment_branch_policy.protected_branches, - custom_branch_policies: !!attrs.deployment_branch_policy.custom_branch_policies - } + if (variables) { + let existingVariables = [...existing.variables] + + for (const variable of attrs.variables) { + const existingVariable = existingVariables.find((_var) => _var.name === variable.name) + if (existingVariable) { + existingVariables = existingVariables.filter(_var => _var.name !== variable.name) + if (existingVariable.value !== variable.value) { + await this.github.request('PATCH /repos/:org/:repo/environments/:environment_name/variables/:variable_name', { + org: this.repo.owner, + repo: this.repo.repo, + environment_name: attrs.name, + variable_name: variable.name, + value: variable.value }) + } + } else { + await this.github.request('POST /repos/:org/:repo/environments/:environment_name/variables', { + org: this.repo.owner, + repo: this.repo.repo, + environment_name: attrs.name, + name: variable.name, + value: variable.value + }) } + } - if(deployment_branch_policy && attrs.deployment_branch_policy && attrs.deployment_branch_policy.custom_branch_policies) { - const existingPolicies = (await this.github.request('GET /repos/:org/:repo/environments/:environment_name/deployment-branch-policies', { - org: this.repo.owner, - repo: this.repo.repo, - environment_name: attrs.name - })).data.branch_policies; - - for(let policy of existingPolicies) { - await this.github.request('DELETE /repos/:org/:repo/environments/:environment_name/deployment-branch-policies/:branch_policy_id', { - org: this.repo.owner, - repo: this.repo.repo, - environment_name: attrs.name, - branch_policy_id: policy.id - }); - } - - for(let policy of attrs.deployment_branch_policy.custom_branch_policies) { - await this.github.request('POST /repos/:org/:repo/environments/:environment_name/deployment-branch-policies', { - org: this.repo.owner, - repo: this.repo.repo, - environment_name: attrs.name, - name: policy - }); - } - } - - if(variables) { - let existingVariables = [...existing.variables]; - - for(let variable of attrs.variables) { - const existingVariable = existingVariables.find((_var) => _var.name === variable.name); - if(existingVariable) { - existingVariables = existingVariables.filter(_var => _var.name !== variable.name); - if(existingVariable.value !== variable.value) { - await this.github.request(`PATCH /repos/:org/:repo/environments/:environment_name/variables/:variable_name`, { - org: this.repo.owner, - repo: this.repo.repo, - environment_name: attrs.name, - variable_name: variable.name, - value: variable.value - }); - } - } - else { - await this.github.request(`POST /repos/:org/:repo/environments/:environment_name/variables`, { - org: this.repo.owner, - repo: this.repo.repo, - environment_name: attrs.name, - name: variable.name, - value: variable.value - }); - } - } - - for(let variable of existingVariables) { - await this.github.request('DELETE /repos/:org/:repo/environments/:environment_name/variables/:variable_name', { - org: this.repo.owner, - repo: this.repo.repo, - environment_name: attrs.name, - variable_name: variable.name - }); - } - } - - if(deployment_protection_rules) { - let existingRules = [...existing.deployment_protection_rules]; + for (const variable of existingVariables) { + await this.github.request('DELETE /repos/:org/:repo/environments/:environment_name/variables/:variable_name', { + org: this.repo.owner, + repo: this.repo.repo, + environment_name: attrs.name, + variable_name: variable.name + }) + } + } - for(let rule of attrs.deployment_protection_rules) { - const existingRule = existingRules.find((_rule) => _rule.id === rule.id); + if (deploymentProtectionRules) { + const existingRules = [...existing.deployment_protection_rules] - if(!existingRule) { - await this.github.request(`POST /repos/:org/:repo/environments/:environment_name/deployment_protection_rules`, { - org: this.repo.owner, - repo: this.repo.repo, - environment_name: attrs.name, - integration_id: rule.app_id - }); - } - } + for (const rule of attrs.deployment_protection_rules) { + const existingRule = existingRules.find((_rule) => _rule.id === rule.id) - for(let rule of existingRules) { - await this.github.request('DELETE /repos/:org/:repo/environments/:environment_name/deployment_protection_rules/:rule_id', { - org: this.repo.owner, - repo: this.repo.repo, - environment_name: attrs.name, - rule_id: rule.id - }); - } - } - } - - async add(attrs) { - await this.github.request(`PUT /repos/:org/:repo/environments/:environment_name`, { + if (!existingRule) { + await this.github.request('POST /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org: this.repo.owner, repo: this.repo.repo, environment_name: attrs.name, - wait_timer: attrs.wait_timer, - prevent_self_review: attrs.prevent_self_review, - reviewers: attrs.reviewers, - deployment_branch_policy: attrs.deployment_branch_policy == null ? null : { - protected_branches: !!attrs.deployment_branch_policy.protected_branches, - custom_branch_policies: !!attrs.deployment_branch_policy.custom_branch_policies - } - }); - - if(attrs.deployment_branch_policy && attrs.deployment_branch_policy.custom_branch_policies) { - - for(let policy of attrs.deployment_branch_policy.custom_branch_policies) { - await this.github.request('POST /repos/:org/:repo/environments/:environment_name/deployment-branch-policies', { - org: this.repo.owner, - repo: this.repo.repo, - environment_name: attrs.name, - name: policy.name - }); - } - + integration_id: rule.app_id + }) } + } - if(attrs.variables) { - - for(let variable of attrs.variables) { - await this.github.request(`POST /repos/:org/:repo/environments/:environment_name/variables`, { - org: this.repo.owner, - repo: this.repo.repo, - environment_name: attrs.name, - name: variable.name, - value: variable.value - }); - } - + for (const rule of existingRules) { + await this.github.request('DELETE /repos/:org/:repo/environments/:environment_name/deployment_protection_rules/:rule_id', { + org: this.repo.owner, + repo: this.repo.repo, + environment_name: attrs.name, + rule_id: rule.id + }) + } + } + } + + async add (attrs) { + await this.github.request('PUT /repos/:org/:repo/environments/:environment_name', { + org: this.repo.owner, + repo: this.repo.repo, + environment_name: attrs.name, + wait_timer: attrs.wait_timer, + prevent_self_review: attrs.prevent_self_review, + reviewers: attrs.reviewers, + deployment_branch_policy: attrs.deployment_branch_policy == null + ? null + : { + protected_branches: !!attrs.deployment_branch_policy.protected_branches, + custom_branch_policies: !!attrs.deployment_branch_policy.custom_branch_policies } + }) + + if (attrs.deployment_branch_policy && attrs.deployment_branch_policy.custom_branch_policies) { + for (const policy of attrs.deployment_branch_policy.custom_branch_policies) { + await this.github.request('POST /repos/:org/:repo/environments/:environment_name/deployment-branch-policies', { + org: this.repo.owner, + repo: this.repo.repo, + environment_name: attrs.name, + name: policy.name + }) + } + } - if(attrs.deployment_protection_rules) { + if (attrs.variables) { + for (const variable of attrs.variables) { + await this.github.request('POST /repos/:org/:repo/environments/:environment_name/variables', { + org: this.repo.owner, + repo: this.repo.repo, + environment_name: attrs.name, + name: variable.name, + value: variable.value + }) + } + } - for(let rule of attrs.deployment_protection_rules) { - await this.github.request(`POST /repos/:org/:repo/environments/:environment_name/deployment_protection_rules`, { - org: this.repo.owner, - repo: this.repo.repo, - environment_name: attrs.name, - integration_id: rule.app_id - }); + if (attrs.deployment_protection_rules) { + for (const rule of attrs.deployment_protection_rules) { + await this.github.request('POST /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { + org: this.repo.owner, + repo: this.repo.repo, + environment_name: attrs.name, + integration_id: rule.app_id + }) + } + } + } + + async remove (existing) { + await this.github.request('DELETE /repos/:org/:repo/environments/:environment_name', { + org: this.repo.owner, + repo: this.repo.repo, + environment_name: existing.name + }) + } + + sync () { + const resArray = [] + if (this.entries) { + let filteredEntries = this.filterEntries() + return this.find().then(existingRecords => { + // Remove any null or undefined values from the diffables (usually comes from repo override) + for (const entry of filteredEntries) { + for (const key of Object.keys(entry)) { + if (entry[key] === null || entry[key] === undefined) { + delete entry[key] } - + } } - } + // For environments, we want to keep the entries with only name defined. - async remove(existing) { - await this.github.request(`DELETE /repos/:org/:repo/environments/:environment_name`, { - org: this.repo.owner, - repo: this.repo.repo, - environment_name: existing.name - }); - } + const changes = [] - sync () { - const resArray = [] - if (this.entries) { - let filteredEntries = this.filterEntries() - return this.find().then(existingRecords => { - - // Remove any null or undefined values from the diffables (usually comes from repo override) - for (const entry of filteredEntries) { - for (const key of Object.keys(entry)) { - if (entry[key] === null || entry[key] === undefined) { - delete entry[key] + existingRecords.forEach(x => { + if (!filteredEntries.find(y => this.comparator(x, y))) { + const change = this.remove(x).then(res => { + if (this.nop) { + return resArray.push(res) } - } + return res + }) + changes.push(change) } - // For environments, we want to keep the entries with only name defined. - - const changes = [] - - existingRecords.forEach(x => { - if (!filteredEntries.find(y => this.comparator(x, y))) { - const change = this.remove(x).then(res => { - if (this.nop) { - return resArray.push(res) - } - return res - }) - changes.push(change) - } + }) + + filteredEntries.forEach(attrs => { + const existing = existingRecords.find(record => { + return this.comparator(record, attrs) }) - filteredEntries.forEach(attrs => { - const existing = existingRecords.find(record => { - return this.comparator(record, attrs) + if (!existing) { + const change = this.add(attrs).then(res => { + if (this.nop) { + return resArray.push(res) + } + return res }) + changes.push(change) + } else if (this.changed(existing, attrs)) { + const change = this.update(existing, attrs).then(res => { + if (this.nop) { + return resArray.push(res) + } + return res + }) + changes.push(change) + } + }) - if (!existing) { - const change = this.add(attrs).then(res => { - if (this.nop) { - return resArray.push(res) - } - return res - }) - changes.push(change) - } else if (this.changed(existing, attrs)) { - const change = this.update(existing, attrs).then(res => { - if (this.nop) { - return resArray.push(res) - } - return res - }) - changes.push(change) - } - }) - - if (this.nop) { + if (this.nop) { + return Promise.resolve(resArray) + } + return Promise.all(changes) + }).catch(e => { + if (this.nop) { + if (e.status === 404) { + // Ignore 404s which can happen in dry-run as the repo may not exist. return Promise.resolve(resArray) - } - return Promise.all(changes) - }).catch(e => { - if (this.nop) { - if (e.status === 404) { - // Ignore 404s which can happen in dry-run as the repo may not exist. - return Promise.resolve(resArray) - } else { - resArray.push(new NopCommand(this.constructor.name, this.repo, null, `error ${e} in ${this.constructor.name} for repo: ${JSON.stringify(this.repo)} entries ${JSON.stringify(this.entries)}`, 'ERROR')) - return Promise.resolve(resArray) - } } else { - this.logError(`Error ${e} in ${this.constructor.name} for repo: ${JSON.stringify(this.repo)} entries ${JSON.stringify(this.entries)}`) + resArray.push(new NopCommand(this.constructor.name, this.repo, null, `error ${e} in ${this.constructor.name} for repo: ${JSON.stringify(this.repo)} entries ${JSON.stringify(this.entries)}`, 'ERROR')) + return Promise.resolve(resArray) } - }) - } + } else { + this.logError(`Error ${e} in ${this.constructor.name} for repo: ${JSON.stringify(this.repo)} entries ${JSON.stringify(this.entries)}`) + } + }) } - + } } diff --git a/lib/plugins/repository.js b/lib/plugins/repository.js index 42bbd28e..6512ea79 100644 --- a/lib/plugins/repository.js +++ b/lib/plugins/repository.js @@ -73,12 +73,12 @@ module.exports = class Repository extends ErrorStash { const topicChanges = mergeDeep.compareDeep({ entries: resp.data.topics }, { entries: this.topics }) // hasTopicChanges = topicChanges.additions.length > 0 || topicChanges.modifications.length > 0 - //const results = JSON.stringify(changes, null, 2) + // const results = JSON.stringify(changes, null, 2) const results = { msg: `${this.constructor.name} settings changes`, additions: changes.additions, modifications: changes.modifications, deletions: changes.deletions } this.log.debug(`Result of comparing repo for changes = ${results}`) - //const topicResults = JSON.stringify(topicChanges, null, 2) + // const topicResults = JSON.stringify(topicChanges, null, 2) const topicResults = { msg: `${this.constructor.name} settings changes for topics`, additions: topicChanges.additions, modifications: topicChanges.modifications, deletions: topicChanges.deletions } this.log.debug(`Result of comparing topics for changes source ${JSON.stringify(resp.data.topics)} target ${JSON.stringify(this.topics)} = ${topicResults}`) @@ -91,7 +91,7 @@ module.exports = class Repository extends ErrorStash { const promises = [] if (topicChanges.hasChanges) { promises.push(this.updatetopics(resp.data, resArray)) - } + } if (changes.hasChanges) { this.log.debug('There are repo changes') let updateDefaultBranchPromise = Promise.resolve() @@ -189,7 +189,7 @@ module.exports = class Repository extends ErrorStash { }) } - renameBranch(oldname, newname, resArray) { + renameBranch (oldname, newname, resArray) { this.log.error(`Branch ${newname} does not exist. So renaming the current default branch ${oldname} to ${newname}`) const parms = { owner: this.settings.owner, @@ -227,12 +227,12 @@ module.exports = class Repository extends ErrorStash { if (this.topics) { // if (repoData.data?.topics.length !== this.topics.length || // !repoData.data?.topics.every(t => this.topics.includes(t))) { - this.log.debug(`Updating repo with topics ${this.topics.join(',')}`) - if (this.nop) { - resArray.push((new NopCommand(this.constructor.name, this.repo, this.github.repos.replaceAllTopics.endpoint(parms), 'Update Topics'))) - return Promise.resolve(resArray) - } - return this.github.repos.replaceAllTopics(parms) + this.log.debug(`Updating repo with topics ${this.topics.join(',')}`) + if (this.nop) { + resArray.push((new NopCommand(this.constructor.name, this.repo, this.github.repos.replaceAllTopics.endpoint(parms), 'Update Topics'))) + return Promise.resolve(resArray) + } + return this.github.repos.replaceAllTopics(parms) // } else { // this.log.debug(`no need to update topics for ${repoData.data.name}`) // if (this.nop) { @@ -277,7 +277,7 @@ module.exports = class Repository extends ErrorStash { } else { this.log.debug(`no need to update security for ${repoData.name}`) if (this.nop) { - //resArray.push((new NopCommand(this.constructor.name, this.repo, null, `no need to update security for ${repoData.name}`))) + // resArray.push((new NopCommand(this.constructor.name, this.repo, null, `no need to update security for ${repoData.name}`))) return Promise.resolve([]) } } diff --git a/lib/settings.js b/lib/settings.js index 961aa4c6..57862d2a 100644 --- a/lib/settings.js +++ b/lib/settings.js @@ -798,14 +798,13 @@ ${this.results.reduce((x, y) => { } async getReposForCustomProperty (customPropertyTuple) { - const name=Object.keys(customPropertyTuple)[0] + const name = Object.keys(customPropertyTuple)[0] let q = `props.${name}:${customPropertyTuple[name]}` q = encodeURIComponent(q) const options = this.github.request.endpoint((`/orgs/${this.repo.owner}/properties/values?repository_query=${q}`)) return this.github.paginate(options) } - isObject (item) { return (item && typeof item === 'object' && !Array.isArray(item)) } @@ -819,7 +818,7 @@ ${this.results.reduce((x, y) => { } } -function prettify(obj) { +function prettify (obj) { if (obj === null || obj === undefined) { return '' } diff --git a/test/unit/index.test.js b/test/unit/index.test.js index 9d09804d..feae42d9 100644 --- a/test/unit/index.test.js +++ b/test/unit/index.test.js @@ -1,4 +1,4 @@ -const { Probot, ProbotOctokit } = require('probot') +const { Probot } = require('probot') const plugin = require('../../index') describe.skip('plugin', () => { @@ -24,7 +24,7 @@ describe.skip('plugin', () => { } } - app = new Probot({ secret: "abcdef", Octokit }) + app = new Probot({ secret: 'abcdef', Octokit }) github = { repos: { getContents: jest.fn(() => Promise.resolve({ data: { content: '' } })) @@ -151,5 +151,4 @@ describe.skip('plugin', () => { expect(sync).toHaveBeenCalled() }) }) - }) diff --git a/test/unit/lib/env.test.js b/test/unit/lib/env.test.js index e2b95305..56f78a88 100644 --- a/test/unit/lib/env.test.js +++ b/test/unit/lib/env.test.js @@ -1,8 +1,6 @@ /* eslint-disable no-undef */ describe('env', () => { - describe('load default values without override', () => { - const envTest = require('../../../lib/env') it('loads default ADMIN_REPO if not passed', () => { @@ -29,11 +27,9 @@ describe('env', () => { const CREATE_PR_COMMENT = envTest.CREATE_PR_COMMENT expect(CREATE_PR_COMMENT).toEqual('true') }) - }) describe('load override values', () => { - beforeAll(() => { jest.resetModules() process.env.ADMIN_REPO = '.github' @@ -57,5 +53,4 @@ describe('env', () => { expect(CREATE_PR_COMMENT).toEqual('false') }) }) - }) diff --git a/test/unit/lib/plugins/autolinks.test.js b/test/unit/lib/plugins/autolinks.test.js index 63d82927..10413cc1 100644 --- a/test/unit/lib/plugins/autolinks.test.js +++ b/test/unit/lib/plugins/autolinks.test.js @@ -16,7 +16,7 @@ describe('Autolinks', () => { repos: { listAutolinks: jest.fn().mockResolvedValue([]), createAutolink: jest.fn().mockResolvedValue(), - deleteAutolink: jest.fn().mockResolvedValue(), + deleteAutolink: jest.fn().mockResolvedValue() } } }) @@ -32,7 +32,7 @@ describe('Autolinks', () => { { key_prefix: 'SAME_ALPHA-TRUE-', url_template: 'https://test/', is_alphanumeric: true }, { key_prefix: 'NEW_ALPHA-UNDEFINED-', url_template: 'https://test/' }, { key_prefix: 'NEW_ALPHA-FALSE-', url_template: 'https://test/', is_alphanumeric: false }, - { key_prefix: 'NEW_ALPHA-TRUE-', url_template: 'https://test/', is_alphanumeric: true }, + { key_prefix: 'NEW_ALPHA-TRUE-', url_template: 'https://test/', is_alphanumeric: true } ]) github.repos.listAutolinks.mockResolvedValueOnce({ @@ -45,7 +45,7 @@ describe('Autolinks', () => { { id: '6', key_prefix: 'SAME_ALPHA-TRUE-', url_template: 'https://test/', is_alphanumeric: true }, { id: '7', key_prefix: 'NEW_ALPHA-UNDEFINED-', url_template: 'https://test/', is_alphanumeric: false }, { id: '8', key_prefix: 'NEW_ALPHA-FALSE-', url_template: 'https://test/', is_alphanumeric: true }, - { id: '9', key_prefix: 'NEW_ALPHA-TRUE-', url_template: 'https://test/', is_alphanumeric: false }, + { id: '9', key_prefix: 'NEW_ALPHA-TRUE-', url_template: 'https://test/', is_alphanumeric: false } ] }) @@ -54,89 +54,89 @@ describe('Autolinks', () => { key_prefix: 'ADD-', url_template: 'https://test/', is_alphanumeric: true, - ...repo + ...repo }) expect(github.repos.deleteAutolink).toHaveBeenCalledWith({ autolink_id: '2', - ...repo + ...repo }) expect(github.repos.deleteAutolink).toHaveBeenCalledWith({ autolink_id: '3', - ...repo + ...repo }) expect(github.repos.createAutolink).toHaveBeenCalledWith({ key_prefix: 'NEW_URL-', url_template: 'https://new-url/', is_alphanumeric: true, - ...repo + ...repo }) expect(github.repos.deleteAutolink).not.toHaveBeenCalledWith({ autolink_id: '4', - ...repo + ...repo }) expect(github.repos.createAutolink).not.toHaveBeenCalledWith({ key_prefix: 'SAME_ALPHA-UNDEFINED-', url_template: 'https://test/', is_alphanumeric: true, - ...repo + ...repo }) expect(github.repos.deleteAutolink).not.toHaveBeenCalledWith({ autolink_id: '5', - ...repo + ...repo }) expect(github.repos.createAutolink).not.toHaveBeenCalledWith({ key_prefix: 'SAME_ALPHA-FALSE-', url_template: 'https://test/', is_alphanumeric: false, - ...repo + ...repo }) expect(github.repos.deleteAutolink).not.toHaveBeenCalledWith({ autolink_id: '6', - ...repo + ...repo }) expect(github.repos.createAutolink).not.toHaveBeenCalledWith({ key_prefix: 'SAME_ALPHA-TRUE-', url_template: 'https://test/', is_alphanumeric: true, - ...repo + ...repo }) expect(github.repos.deleteAutolink).toHaveBeenCalledWith({ autolink_id: '7', - ...repo + ...repo }) expect(github.repos.createAutolink).toHaveBeenCalledWith({ key_prefix: 'NEW_ALPHA-UNDEFINED-', url_template: 'https://test/', is_alphanumeric: true, - ...repo + ...repo }) expect(github.repos.deleteAutolink).toHaveBeenCalledWith({ autolink_id: '8', - ...repo + ...repo }) expect(github.repos.createAutolink).toHaveBeenCalledWith({ key_prefix: 'NEW_ALPHA-FALSE-', url_template: 'https://test/', is_alphanumeric: false, - ...repo + ...repo }) expect(github.repos.deleteAutolink).toHaveBeenCalledWith({ autolink_id: '9', - ...repo + ...repo }) expect(github.repos.createAutolink).toHaveBeenCalledWith({ key_prefix: 'NEW_ALPHA-TRUE-', url_template: 'https://test/', is_alphanumeric: true, - ...repo + ...repo }) expect(github.repos.deleteAutolink).toHaveBeenCalledTimes(5) diff --git a/test/unit/lib/plugins/custom_properties.test.js b/test/unit/lib/plugins/custom_properties.test.js index 69568a28..f1148837 100644 --- a/test/unit/lib/plugins/custom_properties.test.js +++ b/test/unit/lib/plugins/custom_properties.test.js @@ -1,128 +1,127 @@ const CustomProperties = require('../../../../lib/plugins/custom_properties') describe('CustomProperties', () => { - let github - const repo = { owner: 'owner', repo: 'repo' } - let log + let github + let log - function configure (config) { - const nop = false; - const errors = [] - return new CustomProperties(nop, github, { owner: 'bkeepers', repo: 'test' }, config, log, errors) - } + function configure (config) { + const nop = false + const errors = [] + return new CustomProperties(nop, github, { owner: 'bkeepers', repo: 'test' }, config, log, errors) + } - beforeEach(() => { - github = { - request: jest.fn() - // .mockResolvedValue({ - // data: [ - // { property_name: 'test', value: 'test' } - // ] - // }) - } - log = { debug: jest.fn(), error: console.error } - }) + beforeEach(() => { + github = { + request: jest.fn() + // .mockResolvedValue({ + // data: [ + // { property_name: 'test', value: 'test' } + // ] + // }) + } + log = { debug: jest.fn(), error: console.error } + }) - describe('sync', () => { - it('syncs custom properties', async () => { - const plugin = configure([ - { name: 'test', value: 'test' } - ]) + describe('sync', () => { + it('syncs custom properties', async () => { + const plugin = configure([ + { name: 'test', value: 'test' } + ]) - github.request.mockResolvedValue({ - data: [ - { property_name: 'test', value: 'test' } - ] - }) + github.request.mockResolvedValue({ + data: [ + { property_name: 'test', value: 'test' } + ] + }) - return plugin.sync().then(() => { - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/properties/values', { - org: 'bkeepers', - repo: 'test' - }) - }) + return plugin.sync().then(() => { + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/properties/values', { + org: 'bkeepers', + repo: 'test' }) + }) }) - describe('sync', () => { - it('add custom properties', async () => { - const plugin = configure([ - { name: 'test', value: 'test' } - ]) + }) + describe('sync', () => { + it('add custom properties', async () => { + const plugin = configure([ + { name: 'test', value: 'test' } + ]) - github.request.mockResolvedValue({ - data: [] - }) + github.request.mockResolvedValue({ + data: [] + }) - return plugin.sync().then(() => { - expect(github.request).toHaveBeenNthCalledWith(1, 'GET /repos/:org/:repo/properties/values', { - org: 'bkeepers', - repo: 'test' - }) - expect(github.request).toHaveBeenNthCalledWith(2, 'PATCH /repos/:org/:repo/properties/values', { - org: 'bkeepers', - repo: 'test', - properties: [ - { - property_name: 'test', - value: 'test' - } - ] - }) - }) + return plugin.sync().then(() => { + expect(github.request).toHaveBeenNthCalledWith(1, 'GET /repos/:org/:repo/properties/values', { + org: 'bkeepers', + repo: 'test' }) + expect(github.request).toHaveBeenNthCalledWith(2, 'PATCH /repos/:org/:repo/properties/values', { + org: 'bkeepers', + repo: 'test', + properties: [ + { + property_name: 'test', + value: 'test' + } + ] + }) + }) }) - describe('sync', () => { - it('remove custom properties', async () => { - const plugin = configure([]) + }) + describe('sync', () => { + it('remove custom properties', async () => { + const plugin = configure([]) - github.request.mockResolvedValue({ - data: [{ property_name: 'test', value: 'test' }] - }) + github.request.mockResolvedValue({ + data: [{ property_name: 'test', value: 'test' }] + }) - return plugin.sync().then(() => { - expect(github.request).toHaveBeenNthCalledWith(1, 'GET /repos/:org/:repo/properties/values', { - org: 'bkeepers', - repo: 'test' - }) - expect(github.request).toHaveBeenNthCalledWith(2, 'PATCH /repos/:org/:repo/properties/values', { - org: 'bkeepers', - repo: 'test', - properties: [ - { - property_name: 'test', - value: null - } - ] - }) - }) + return plugin.sync().then(() => { + expect(github.request).toHaveBeenNthCalledWith(1, 'GET /repos/:org/:repo/properties/values', { + org: 'bkeepers', + repo: 'test' + }) + expect(github.request).toHaveBeenNthCalledWith(2, 'PATCH /repos/:org/:repo/properties/values', { + org: 'bkeepers', + repo: 'test', + properties: [ + { + property_name: 'test', + value: null + } + ] }) + }) }) - describe('sync', () => { - it('update custom properties', async () => { - const plugin = configure([ - { name: 'test', value: 'foobar' } - ]) + }) + describe('sync', () => { + it('update custom properties', async () => { + const plugin = configure([ + { name: 'test', value: 'foobar' } + ]) - github.request.mockResolvedValue({ - data: [{ property_name: 'test', value: 'test' }] - }) + github.request.mockResolvedValue({ + data: [{ property_name: 'test', value: 'test' }] + }) - return plugin.sync().then(() => { - expect(github.request).toHaveBeenNthCalledWith(1, 'GET /repos/:org/:repo/properties/values', { - org: 'bkeepers', - repo: 'test' - }) - expect(github.request).toHaveBeenNthCalledWith(2, 'PATCH /repos/:org/:repo/properties/values', { - org: 'bkeepers', - repo: 'test', - properties: [ - { - property_name: 'test', - value: 'foobar' - } - ] - }) - }) + return plugin.sync().then(() => { + expect(github.request).toHaveBeenNthCalledWith(1, 'GET /repos/:org/:repo/properties/values', { + org: 'bkeepers', + repo: 'test' + }) + expect(github.request).toHaveBeenNthCalledWith(2, 'PATCH /repos/:org/:repo/properties/values', { + org: 'bkeepers', + repo: 'test', + properties: [ + { + property_name: 'test', + value: 'foobar' + } + ] }) + }) }) -}) \ No newline at end of file + }) +}) diff --git a/test/unit/lib/plugins/environments.test.js b/test/unit/lib/plugins/environments.test.js index 276a82cd..87e1bf97 100644 --- a/test/unit/lib/plugins/environments.test.js +++ b/test/unit/lib/plugins/environments.test.js @@ -3,7 +3,7 @@ const Environments = require('../../../../lib/plugins/environments') describe('Environments Plugin test suite', () => { let github - let environment_name = '' + let environmentName = '' const org = 'bkeepers' const repo = 'test' const PrimaryEnvironmentNamesBeingTested = ['wait-timer_environment', 'wait-timer_2_environment', 'reviewers_environment', 'prevent-self-review_environment', 'deployment-branch-policy_environment', 'deployment-branch-policy-custom_environment', 'variables_environment', 'deployment-protection-rules_environment', 'new_environment', 'old_environment'] @@ -12,41 +12,41 @@ describe('Environments Plugin test suite', () => { const log = { debug: jest.fn(), error: console.error } const errors = [] - function fillEnvironment(attrs) { - if (!attrs.wait_timer) attrs.wait_timer = 0; - if (!attrs.prevent_self_review) attrs.prevent_self_review = false; - if (!attrs.reviewers) attrs.reviewers = []; - if (!attrs.deployment_branch_policy) attrs.deployment_branch_policy = null; - if (!attrs.variables) attrs.variables = []; - if (!attrs.deployment_protection_rules) attrs.deployment_protection_rules = []; - if (!attrs.protection_rules) attrs.protection_rules = []; + function fillEnvironment (attrs) { + if (!attrs.wait_timer) attrs.wait_timer = 0 + if (!attrs.prevent_self_review) attrs.prevent_self_review = false + if (!attrs.reviewers) attrs.reviewers = [] + if (!attrs.deployment_branch_policy) attrs.deployment_branch_policy = null + if (!attrs.variables) attrs.variables = [] + if (!attrs.deployment_protection_rules) attrs.deployment_protection_rules = [] + if (!attrs.protection_rules) attrs.protection_rules = [] - return attrs; + return attrs } beforeEach(() => { - //arrange for all + // arrange for all github = { request: jest.fn(() => Promise.resolve(true)) } - AllEnvironmentNamesBeingTested.forEach((environment_name) => { + AllEnvironmentNamesBeingTested.forEach((environmentName) => { when(github.request) - .calledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name }) + .calledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name: environmentName }) .mockResolvedValue({ data: { variables: [] } }) - when(github.request) - .calledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name }) + when(github.request) + .calledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name: environmentName }) .mockResolvedValue({ data: { custom_deployment_protection_rules: [] } }) - } - ); + } + ) when(github.request) .calledWith('GET /repos/:org/:repo/environments/:environment_name/deployment-branch-policies', { org, repo, environment_name: 'deployment-branch-policy-custom_environment' }) @@ -55,79 +55,78 @@ describe('Environments Plugin test suite', () => { branch_policies: [] } } - ); + ) when(github.request) .calledWith('DELETE /repos/:org/:repo/environments/:environment_name/deployment-branch-policies/:branch_policy_id') - .mockResolvedValue({}); + .mockResolvedValue({}) when(github.request) .calledWith('POST /repos/:org/:repo/environments/:environment_name/deployment-branch-policies') - .mockResolvedValue({}); + .mockResolvedValue({}) when(github.request) .calledWith('PUT /repos/:org/:repo/environments/:environment_name') - .mockResolvedValue({}); + .mockResolvedValue({}) when(github.request) .calledWith('POST /repos/:org/:repo/environments/:environment_name/variables') - .mockResolvedValue({}); + .mockResolvedValue({}) when(github.request) .calledWith('POST /repos/:org/:repo/environments/:environment_name/deployment_protection_rules') - .mockResolvedValue({}); + .mockResolvedValue({}) when(github.request) .calledWith('DELETE /repos/:org/:repo/environments/:environment_name/deployment_protection_rules/:rule_id') - .mockResolvedValue({}); - + .mockResolvedValue({}) }) afterEach(() => { - jest.clearAllMocks(); - }); + jest.clearAllMocks() + }) // start individual tests // wait-timer describe('When the existing wait-timer is 0 and the config is set to 1', () => { it('detect divergence and set wait-timer to 1', async () => { - //arrange - environment_name = 'wait-timer_environment' + // arrange + environmentName = 'wait-timer_environment' // represent config with a wait timer of 1 const plugin = new Environments(undefined, github, { owner: org, repo }, [ { - name: environment_name, + name: environmentName, wait_timer: 1 } - ], log, errors); + ], log, errors) - //model an existing environment with a wait timer of 0 + // model an existing environment with a wait timer of 0 when(github.request) .calledWith('GET /repos/:org/:repo/environments', { org, repo }) .mockResolvedValue({ data: { environments: [ fillEnvironment({ - name: environment_name, + name: environmentName, wait_timer: 0 }) ] } - }); + }) - //act - run sync() in environments.js + // act - run sync() in environments.js await plugin.sync().then(() => { - //assert - update to the wait timer was requested with value 1 - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments', { org, repo }); - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name }); - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name }); + // assert - update to the wait timer was requested with value 1 + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments', { org, repo }) + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name: environmentName }) + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name: environmentName }) expect(github.request).toHaveBeenCalledWith('PUT /repos/:org/:repo/environments/:environment_name', expect.objectContaining({ org, repo, - environment_name: environment_name, + environment_name: environmentName, wait_timer: 1 - })); + })) }) }) }) @@ -135,12 +134,12 @@ describe('Environments Plugin test suite', () => { // add reviewers describe('When there are no existing reviewers and config calls for a user and a team', () => { it('detect divergence and set reviewers', async () => { - //arrange - environment_name = 'reviewers_environment' + // arrange + environmentName = 'reviewers_environment' // represent config with a reviewers being a user and a team const plugin = new Environments(undefined, github, { owner: org, repo }, [ { - name: environment_name, + name: environmentName, reviewers: [ { type: 'User', @@ -148,16 +147,16 @@ describe('Environments Plugin test suite', () => { } ] } - ], log, errors); + ], log, errors) - //model an existing environment with no reviewers + // model an existing environment with no reviewers when(github.request) .calledWith('GET /repos/:org/:repo/environments', { org, repo }) .mockResolvedValue({ data: { environments: [ fillEnvironment({ - name: environment_name, + name: environmentName, protection_rules: [ { type: 'required_reviewers', @@ -175,25 +174,25 @@ describe('Environments Plugin test suite', () => { }) ] } - }); + }) - //act - run sync() in environments.js + // act - run sync() in environments.js await plugin.sync().then(() => { - //assert - update the reviewers - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments', { org, repo }); - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name }); - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name }); + // assert - update the reviewers + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments', { org, repo }) + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name: environmentName }) + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name: environmentName }) expect(github.request).toHaveBeenCalledWith('PUT /repos/:org/:repo/environments/:environment_name', expect.objectContaining({ org, repo, - environment_name: environment_name, + environment_name: environmentName, reviewers: [ { type: 'User', id: 1 } ] - })); + })) }) }) }) @@ -201,42 +200,42 @@ describe('Environments Plugin test suite', () => { // prevent self review describe('When prevent self review is false, and the config calls for it to be true', () => { it('detect divergence and set prevent self review to true', async () => { - //arrange - environment_name = 'prevent-self-review_environment' + // arrange + environmentName = 'prevent-self-review_environment' // const plugin = new Environments(undefined, github, { owner: org, repo }, [ { - name: environment_name, + name: environmentName, prevent_self_review: true } - ], log, errors); + ], log, errors) - //model an existing environment with prevent self review false + // model an existing environment with prevent self review false when(github.request) .calledWith('GET /repos/:org/:repo/environments', { org, repo }) .mockResolvedValue({ data: { environments: [ fillEnvironment({ - name: environment_name, + name: environmentName, prevent_self_review: false }) ] } - }); + }) - //act - run sync() in environments.js + // act - run sync() in environments.js await plugin.sync().then(() => { - //assert - update the prevent self review boolean - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments', { org, repo }); - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name }); - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name }); + // assert - update the prevent self review boolean + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments', { org, repo }) + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name: environmentName }) + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name: environmentName }) expect(github.request).toHaveBeenCalledWith('PUT /repos/:org/:repo/environments/:environment_name', expect.objectContaining({ org, repo, - environment_name: environment_name, + environment_name: environmentName, prevent_self_review: true - })); + })) }) }) }) @@ -244,48 +243,48 @@ describe('Environments Plugin test suite', () => { // deployment branch policy describe('When there is no existing deployment branch policy and the config sets a policy', () => { it('detect divergence and set the deployment branch policy from the config', async () => { - //arrange - environment_name = 'deployment-branch-policy_environment' + // arrange + environmentName = 'deployment-branch-policy_environment' // represent config with a reviewers being a user and a team const plugin = new Environments(undefined, github, { owner: org, repo }, [ { - name: environment_name, + name: environmentName, deployment_branch_policy: { protected_branches: true, custom_branch_policies: false } } - ], log, errors); + ], log, errors) - //model an existing environment with prevent self review false + // model an existing environment with prevent self review false when(github.request) .calledWith('GET /repos/:org/:repo/environments', { org, repo }) .mockResolvedValue({ data: { environments: [ fillEnvironment({ - name: environment_name, + name: environmentName, deployment_branch_policy: null }) ] } - }); + }) - //act - run sync() in environments.js + // act - run sync() in environments.js await plugin.sync().then(() => { - //assert - update branch policy - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments', { org, repo }); - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name }); - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name }); + // assert - update branch policy + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments', { org, repo }) + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name: environmentName }) + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name: environmentName }) expect(github.request).toHaveBeenCalledWith('PUT /repos/:org/:repo/environments/:environment_name', expect.objectContaining({ org, repo, - environment_name: environment_name, + environment_name: environmentName, deployment_branch_policy: { protected_branches: true, custom_branch_policies: false } - })); + })) }) }) }) @@ -293,12 +292,12 @@ describe('Environments Plugin test suite', () => { // custom deployment branch policy describe('When there is no existing deployment branch policy and the config sets a custom policy', () => { it('detect divergence and set the custom deployment branch policy from the config', async () => { - //arrange - environment_name = 'deployment-branch-policy-custom_environment' + // arrange + environmentName = 'deployment-branch-policy-custom_environment' // represent config with a custom branch policy const plugin = new Environments(undefined, github, { owner: org, repo }, [ { - name: environment_name, + name: environmentName, deployment_branch_policy: { protected_branches: false, custom_branch_policies: [ @@ -307,49 +306,49 @@ describe('Environments Plugin test suite', () => { ] } } - ], log, errors); + ], log, errors) - //model an existing environment with no branch policies + // model an existing environment with no branch policies when(github.request) .calledWith('GET /repos/:org/:repo/environments', { org, repo }) .mockResolvedValue({ data: { environments: [ fillEnvironment({ - name: environment_name, + name: environmentName, deployment_branch_policy: null }) ] } - }); + }) - //act - run sync() in environments.js + // act - run sync() in environments.js await plugin.sync().then(() => { - //assert - update the custom branch policies - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments', { org, repo }); - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name }); - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name }); + // assert - update the custom branch policies + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments', { org, repo }) + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name: environmentName }) + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name: environmentName }) expect(github.request).toHaveBeenCalledWith('PUT /repos/:org/:repo/environments/:environment_name', expect.objectContaining({ org, repo, - environment_name: environment_name, + environment_name: environmentName, deployment_branch_policy: { protected_branches: false, custom_branch_policies: true } - })); + })) expect(github.request).toHaveBeenCalledWith('POST /repos/:org/:repo/environments/:environment_name/deployment-branch-policies', expect.objectContaining({ org, repo, - environment_name: environment_name, + environment_name: environmentName, name: 'master' - })); + })) expect(github.request).toHaveBeenCalledWith('POST /repos/:org/:repo/environments/:environment_name/deployment-branch-policies', expect.objectContaining({ org, repo, - environment_name: environment_name, + environment_name: environmentName, name: 'dev' - })); + })) }) }) }) @@ -357,12 +356,12 @@ describe('Environments Plugin test suite', () => { // add variable describe('When there are no existing variables and config calls for one', () => { it('detect divergence and add the variable', async () => { - //arrange - environment_name = 'variables_environment' + // arrange + environmentName = 'variables_environment' // represent config with a reviewers being a user and a team const plugin = new Environments(undefined, github, { owner: org, repo }, [ { - name: environment_name, + name: environmentName, variables: [ { name: 'test', @@ -370,35 +369,35 @@ describe('Environments Plugin test suite', () => { } ] } - ], log, errors); + ], log, errors) - //model an existing environment with no reviewers + // model an existing environment with no reviewers when(github.request) .calledWith('GET /repos/:org/:repo/environments', { org, repo }) .mockResolvedValue({ data: { environments: [ fillEnvironment({ - name: environment_name, + name: environmentName, variables: [] }) ] } - }); + }) - //act - run sync() in environments.js + // act - run sync() in environments.js await plugin.sync().then(() => { - //assert - update the variables - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments', { org, repo }); - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name }); - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name }); + // assert - update the variables + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments', { org, repo }) + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name: environmentName }) + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name: environmentName }) expect(github.request).toHaveBeenCalledWith('POST /repos/:org/:repo/environments/:environment_name/variables', expect.objectContaining({ org, repo, - environment_name: environment_name, + environment_name: environmentName, name: 'test', value: 'test' - })); + })) }) }) }) @@ -406,46 +405,46 @@ describe('Environments Plugin test suite', () => { // add deployment protection rules describe('When there are no existing deployment protection rules, but config calls for one', () => { it('detect divergence and add the deployment protection rule', async () => { - //arrange - environment_name = 'deployment-protection-rules_environment' + // arrange + environmentName = 'deployment-protection-rules_environment' // represent config with a deployment protection rule const plugin = new Environments(undefined, github, { owner: org, repo }, [ { - name: environment_name, + name: environmentName, deployment_protection_rules: [ { app_id: 1 } ] } - ], log, errors); + ], log, errors) - //model an existing environment with no deployment protection rules + // model an existing environment with no deployment protection rules when(github.request) .calledWith('GET /repos/:org/:repo/environments', { org, repo }) .mockResolvedValue({ data: { environments: [ fillEnvironment({ - name: environment_name, + name: environmentName, deployment_protection_rules: [] }) ] } - }); + }) - //act - run sync() in environments.js + // act - run sync() in environments.js await plugin.sync().then(() => { - //assert - update the deployment protection rules - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments', { org, repo }); - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name }); - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name }); + // assert - update the deployment protection rules + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments', { org, repo }) + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name: environmentName }) + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name: environmentName }) expect(github.request).toHaveBeenCalledWith('POST /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', expect.objectContaining({ org, repo, - environment_name: environment_name, - integration_id: 1 // weird that this is integration_id, but above it's app_id - })); + environment_name: environmentName, + integration_id: 1 // weird that this is integration_id, but above it's app_id + })) }) }) }) @@ -453,24 +452,24 @@ describe('Environments Plugin test suite', () => { // wait-timer unchanged describe('When the existing wait-timer is 2 and the config is set to 2', () => { it('detect that the value is unchanged, and do nothing', async () => { - //arrange - environment_name = 'wait-timer_2_environment' + // arrange + environmentName = 'wait-timer_2_environment' // represent config with a wait timer of 2 const plugin = new Environments(undefined, github, { owner: org, repo }, [ { - name: environment_name, + name: environmentName, wait_timer: 2 } - ], log, errors); + ], log, errors) - //model an existing environment with no reviewers + // model an existing environment with no reviewers when(github.request) .calledWith('GET /repos/:org/:repo/environments', { org, repo }) .mockResolvedValue({ data: { environments: [ fillEnvironment({ - name: environment_name, + name: environmentName, protection_rules: [ { type: 'wait_timer', @@ -480,20 +479,20 @@ describe('Environments Plugin test suite', () => { }) ] } - }); + }) - //act - run sync() in environments.js + // act - run sync() in environments.js await plugin.sync().then(() => { - //assert - update to the wait timer was requested with value 2 - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments', { org, repo }); - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name }); - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name }); + // assert - update to the wait timer was requested with value 2 + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments', { org, repo }) + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name: environmentName }) + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name: environmentName }) expect(github.request).not.toHaveBeenCalledWith('PUT /repos/:org/:repo/environments/:environment_name', expect.objectContaining({ org, repo, - environment_name: environment_name, + environment_name: environmentName, wait_timer: 2 - })); + })) }) }) }) @@ -501,16 +500,16 @@ describe('Environments Plugin test suite', () => { // Zero existing environments describe('When there are no existing environments, and the config has one environment', () => { it('detect that and environment needs to be added, and add it', async () => { - //arrange - environment_name = 'new_environment' + // arrange + environmentName = 'new_environment' // represent a new environment const plugin = new Environments(undefined, github, { owner: org, repo }, [ { - name: environment_name, + name: environmentName } - ], log, errors); + ], log, errors) - //model an existing state which has zero environments + // model an existing state which has zero environments when(github.request) .calledWith('GET /repos/:org/:repo/environments', { org, repo }) .mockResolvedValue({ @@ -519,19 +518,19 @@ describe('Environments Plugin test suite', () => { ] } - }); + }) - //act - run sync() in environments.js + // act - run sync() in environments.js await plugin.sync().then(() => { - //assert - the new environment was added - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments', { org, repo }); - expect(github.request).not.toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name }); - expect(github.request).not.toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name }); + // assert - the new environment was added + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments', { org, repo }) + expect(github.request).not.toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name: environmentName }) + expect(github.request).not.toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name: environmentName }) expect(github.request).toHaveBeenCalledWith('PUT /repos/:org/:repo/environments/:environment_name', expect.objectContaining({ org, repo, - environment_name: environment_name - })); + environment_name: environmentName + })) }) }) }) @@ -539,51 +538,50 @@ describe('Environments Plugin test suite', () => { // Single environment name change describe('When there is one existing environment with an old name, and the config has one environment with a new name', () => { it('detect that an environment name has changed, add the new one, and delete the old one', async () => { - //arrange - environment_name = 'new_environment' - const old_environment_name = 'old_environment' + // arrange + environmentName = 'new_environment' + const oldEnvironmentName = 'old_environment' // represent a new environment const plugin = new Environments(undefined, github, { owner: org, repo }, [ { - name: environment_name, + name: environmentName } - ], log, errors); + ], log, errors) - //model an existing environment with an old name + // model an existing environment with an old name when(github.request) .calledWith('GET /repos/:org/:repo/environments', { org, repo }) .mockResolvedValue({ data: { environments: [ fillEnvironment({ - name: old_environment_name + name: oldEnvironmentName }) ] } - }); + }) - //act - run sync() in environments.js + // act - run sync() in environments.js await plugin.sync().then(() => { - //assert - the new environment was added - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments', { org, repo }); - expect(github.request).not.toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name }); - expect(github.request).not.toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name }); + // assert - the new environment was added + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments', { org, repo }) + expect(github.request).not.toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name: environmentName }) + expect(github.request).not.toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name: environmentName }) expect(github.request).toHaveBeenCalledWith('PUT /repos/:org/:repo/environments/:environment_name', expect.objectContaining({ org, repo, - environment_name: environment_name - })); + environment_name: environmentName + })) - //assert - the old environment was deleted - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments', { org, repo }); - expect(github.request).not.toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, old_environment_name }); - expect(github.request).not.toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, old_environment_name }); + // assert - the old environment was deleted + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments', { org, repo }) + expect(github.request).not.toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, old_environment_name: oldEnvironmentName }) + expect(github.request).not.toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, old_environment_name: oldEnvironmentName }) expect(github.request).toHaveBeenCalledWith('DELETE /repos/:org/:repo/environments/:environment_name', expect.objectContaining({ org, repo, - environment_name: old_environment_name - })); - + environment_name: oldEnvironmentName + })) }) }) }) @@ -591,7 +589,7 @@ describe('Environments Plugin test suite', () => { // original 7 changes all combined together test describe('When there are changes across 7 environments', () => { it('detect and apply all changes', async () => { - //arrange + // arrange // represent 7 environments and their desired settings const plugin = new Environments(undefined, github, { owner: org, repo }, [ { @@ -649,7 +647,7 @@ describe('Environments Plugin test suite', () => { } ] } - ], log, errors); + ], log, errors) // model 7 existing environments and their settings // note: wait-timer, required_reviewers, and branch_policy are modeled incorrectly here as they are not wrapped by protection_rules[] @@ -689,105 +687,105 @@ describe('Environments Plugin test suite', () => { }) ] } - }); + }) - //act - run sync() in environments.js + // act - run sync() in environments.js await plugin.sync().then(() => { - //assert - update to the wait timer was requested with value 1, etc. + // assert - update to the wait timer was requested with value 1, etc. expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments', { org, repo }); - ['wait-timer_environment', 'reviewers_environment', 'prevent-self-review_environment', 'deployment-branch-policy_environment', 'deployment-branch-policy-custom_environment', 'variables_environment', 'deployment-protection-rules_environment'].forEach((environment_name) => { - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name }); + ['wait-timer_environment', 'reviewers_environment', 'prevent-self-review_environment', 'deployment-branch-policy_environment', 'deployment-branch-policy-custom_environment', 'variables_environment', 'deployment-protection-rules_environment'].forEach((environmentName) => { + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name: environmentName }) - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name }); - }); + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name: environmentName }) + }) expect(github.request).toHaveBeenCalledWith('PUT /repos/:org/:repo/environments/:environment_name', expect.objectContaining({ - org, - repo, - environment_name: 'wait-timer_environment', - wait_timer: 1 - })); + org, + repo, + environment_name: 'wait-timer_environment', + wait_timer: 1 + })) expect(github.request).toHaveBeenCalledWith('PUT /repos/:org/:repo/environments/:environment_name', expect.objectContaining({ - org, - repo, - environment_name: 'reviewers_environment', - reviewers: [ - { - type: 'User', - id: 1 - }, - { - type: 'Team', - id: 2 - } - ] - })); + org, + repo, + environment_name: 'reviewers_environment', + reviewers: [ + { + type: 'User', + id: 1 + }, + { + type: 'Team', + id: 2 + } + ] + })) expect(github.request).toHaveBeenCalledWith('PUT /repos/:org/:repo/environments/:environment_name', expect.objectContaining({ - org, - repo, - environment_name: 'prevent-self-review_environment', - prevent_self_review: true - })); + org, + repo, + environment_name: 'prevent-self-review_environment', + prevent_self_review: true + })) expect(github.request).toHaveBeenCalledWith('PUT /repos/:org/:repo/environments/:environment_name', expect.objectContaining({ - org, - repo, - environment_name: 'prevent-self-review_environment', - prevent_self_review: true - })); + org, + repo, + environment_name: 'prevent-self-review_environment', + prevent_self_review: true + })) expect(github.request).toHaveBeenCalledWith('PUT /repos/:org/:repo/environments/:environment_name', expect.objectContaining({ - org, - repo, - environment_name: 'deployment-branch-policy_environment', - deployment_branch_policy: { - protected_branches: true, - custom_branch_policies: false - } - })); + org, + repo, + environment_name: 'deployment-branch-policy_environment', + deployment_branch_policy: { + protected_branches: true, + custom_branch_policies: false + } + })) expect(github.request).toHaveBeenCalledWith('PUT /repos/:org/:repo/environments/:environment_name', expect.objectContaining({ - org, - repo, - environment_name: 'deployment-branch-policy-custom_environment', - deployment_branch_policy: { - protected_branches: false, - custom_branch_policies: true - } - })); + org, + repo, + environment_name: 'deployment-branch-policy-custom_environment', + deployment_branch_policy: { + protected_branches: false, + custom_branch_policies: true + } + })) expect(github.request).toHaveBeenCalledWith('POST /repos/:org/:repo/environments/:environment_name/deployment-branch-policies', expect.objectContaining({ - org, - repo, - environment_name: 'deployment-branch-policy-custom_environment', - name: 'master' - })); + org, + repo, + environment_name: 'deployment-branch-policy-custom_environment', + name: 'master' + })) expect(github.request).toHaveBeenCalledWith('POST /repos/:org/:repo/environments/:environment_name/deployment-branch-policies', expect.objectContaining({ - org, - repo, - environment_name: 'deployment-branch-policy-custom_environment', - name: 'dev' - })); + org, + repo, + environment_name: 'deployment-branch-policy-custom_environment', + name: 'dev' + })) expect(github.request).toHaveBeenCalledWith('POST /repos/:org/:repo/environments/:environment_name/variables', expect.objectContaining({ - org, - repo, - environment_name: 'variables_environment', - name: 'test', - value: 'test' - })); + org, + repo, + environment_name: 'variables_environment', + name: 'test', + value: 'test' + })) expect(github.request).toHaveBeenCalledWith('POST /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', expect.objectContaining({ - org, - repo, - environment_name: 'deployment-protection-rules_environment', - integration_id: 1 - })); + org, + repo, + environment_name: 'deployment-protection-rules_environment', + integration_id: 1 + })) }) }) }) @@ -795,7 +793,7 @@ describe('Environments Plugin test suite', () => { // Add 7 new environments, each with one environment attribute set describe('When there are 7 existing environments and 7 new environments each with one environment attribute in the config', () => { it('make changes in the existing environments and also add the 7 new environments', async () => { - //arrange + // arrange // represent 14 environments (7 new) and their desired settings const plugin = new Environments(undefined, github, { owner: org, repo }, [ { @@ -854,61 +852,61 @@ describe('Environments Plugin test suite', () => { ] }, { - name: 'new-wait-timer', - wait_timer: 1 + name: 'new-wait-timer', + wait_timer: 1 }, { - name: 'new-reviewers', - reviewers: [ - { - type: 'User', - id: 1 - }, - { - type: 'Team', - id: 2 - } - ] + name: 'new-reviewers', + reviewers: [ + { + type: 'User', + id: 1 + }, + { + type: 'Team', + id: 2 + } + ] }, { - name: 'new-prevent-self-review', - prevent_self_review: true + name: 'new-prevent-self-review', + prevent_self_review: true }, { - name: 'new-deployment-branch-policy', - deployment_branch_policy: { - protected_branches: true, - custom_branch_policies: false - } + name: 'new-deployment-branch-policy', + deployment_branch_policy: { + protected_branches: true, + custom_branch_policies: false + } }, { - name: 'new-deployment-branch-policy-custom', - deployment_branch_policy: { - protected_branches: false, - custom_branch_policies: [ - 'master', - 'dev' - ] - } + name: 'new-deployment-branch-policy-custom', + deployment_branch_policy: { + protected_branches: false, + custom_branch_policies: [ + 'master', + 'dev' + ] + } }, { - name: 'new-variables', - variables: [ - { - name: 'test', - value: 'test' - } - ] + name: 'new-variables', + variables: [ + { + name: 'test', + value: 'test' + } + ] }, { - name: 'new-deployment-protection-rules', - deployment_protection_rules: [ - { - app_id: 1 - } - ] + name: 'new-deployment-protection-rules', + deployment_protection_rules: [ + { + app_id: 1 + } + ] } - ], log, errors); + ], log, errors) // model 7 existing environments and their settings // note: wait-timer, required_reviewers, and branch_policy are modeled incorrectly here as they are not wrapped by protection_rules[] @@ -948,119 +946,117 @@ describe('Environments Plugin test suite', () => { }) ] } - }); + }) - //act - run sync() in environments.js + // act - run sync() in environments.js await plugin.sync().then(() => { - //assert - update to the wait timer was requested with value 1, etc. + // assert - update to the wait timer was requested with value 1, etc. expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments', { org, repo }); - ['wait-timer_environment', 'reviewers_environment', 'prevent-self-review_environment', 'deployment-branch-policy_environment', 'deployment-branch-policy-custom_environment', 'variables_environment', 'deployment-protection-rules_environment'].forEach((environment_name) => { - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name }); + ['wait-timer_environment', 'reviewers_environment', 'prevent-self-review_environment', 'deployment-branch-policy_environment', 'deployment-branch-policy-custom_environment', 'variables_environment', 'deployment-protection-rules_environment'].forEach((environmentName) => { + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, environment_name: environmentName }) - expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name }); - }); + expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, environment_name: environmentName }) + }) expect(github.request).toHaveBeenCalledWith('PUT /repos/:org/:repo/environments/:environment_name', expect.objectContaining({ - org, - repo, - environment_name: 'wait-timer_environment', - wait_timer: 1 - })); + org, + repo, + environment_name: 'wait-timer_environment', + wait_timer: 1 + })) expect(github.request).toHaveBeenCalledWith('PUT /repos/:org/:repo/environments/:environment_name', expect.objectContaining({ - org, - repo, - environment_name: 'reviewers_environment', - reviewers: [ - { - type: 'User', - id: 1 - }, - { - type: 'Team', - id: 2 - } - ] - })); + org, + repo, + environment_name: 'reviewers_environment', + reviewers: [ + { + type: 'User', + id: 1 + }, + { + type: 'Team', + id: 2 + } + ] + })) expect(github.request).toHaveBeenCalledWith('PUT /repos/:org/:repo/environments/:environment_name', expect.objectContaining({ - org, - repo, - environment_name: 'prevent-self-review_environment', - prevent_self_review: true - })); + org, + repo, + environment_name: 'prevent-self-review_environment', + prevent_self_review: true + })) expect(github.request).toHaveBeenCalledWith('PUT /repos/:org/:repo/environments/:environment_name', expect.objectContaining({ - org, - repo, - environment_name: 'prevent-self-review_environment', - prevent_self_review: true - })); + org, + repo, + environment_name: 'prevent-self-review_environment', + prevent_self_review: true + })) expect(github.request).toHaveBeenCalledWith('PUT /repos/:org/:repo/environments/:environment_name', expect.objectContaining({ - org, - repo, - environment_name: 'deployment-branch-policy_environment', - deployment_branch_policy: { - protected_branches: true, - custom_branch_policies: false - } - })); + org, + repo, + environment_name: 'deployment-branch-policy_environment', + deployment_branch_policy: { + protected_branches: true, + custom_branch_policies: false + } + })) expect(github.request).toHaveBeenCalledWith('PUT /repos/:org/:repo/environments/:environment_name', expect.objectContaining({ - org, - repo, - environment_name: 'deployment-branch-policy-custom_environment', - deployment_branch_policy: { - protected_branches: false, - custom_branch_policies: true - } - })); + org, + repo, + environment_name: 'deployment-branch-policy-custom_environment', + deployment_branch_policy: { + protected_branches: false, + custom_branch_policies: true + } + })) expect(github.request).toHaveBeenCalledWith('POST /repos/:org/:repo/environments/:environment_name/deployment-branch-policies', expect.objectContaining({ - org, - repo, - environment_name: 'deployment-branch-policy-custom_environment', - name: 'master' - })); + org, + repo, + environment_name: 'deployment-branch-policy-custom_environment', + name: 'master' + })) expect(github.request).toHaveBeenCalledWith('POST /repos/:org/:repo/environments/:environment_name/deployment-branch-policies', expect.objectContaining({ - org, - repo, - environment_name: 'deployment-branch-policy-custom_environment', - name: 'dev' - })); + org, + repo, + environment_name: 'deployment-branch-policy-custom_environment', + name: 'dev' + })) expect(github.request).toHaveBeenCalledWith('POST /repos/:org/:repo/environments/:environment_name/variables', expect.objectContaining({ - org, - repo, - environment_name: 'variables_environment', - name: 'test', - value: 'test' - })); + org, + repo, + environment_name: 'variables_environment', + name: 'test', + value: 'test' + })) expect(github.request).toHaveBeenCalledWith('POST /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', expect.objectContaining({ - org, - repo, - environment_name: 'deployment-protection-rules_environment', - integration_id: 1 - })); - - //assert - seven new environments were also added - EnvironmentNamesForTheNewEnvironmentsTest.forEach(new_environment_name => { - expect(github.request).not.toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, new_environment_name }); - expect(github.request).not.toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, new_environment_name }); + org, + repo, + environment_name: 'deployment-protection-rules_environment', + integration_id: 1 + })) + + // assert - seven new environments were also added + EnvironmentNamesForTheNewEnvironmentsTest.forEach(newEnvironmentName => { + expect(github.request).not.toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/variables', { org, repo, new_environment_name: newEnvironmentName }) + expect(github.request).not.toHaveBeenCalledWith('GET /repos/:org/:repo/environments/:environment_name/deployment_protection_rules', { org, repo, new_environment_name: newEnvironmentName }) expect(github.request).toHaveBeenCalledWith('PUT /repos/:org/:repo/environments/:environment_name', expect.objectContaining({ org, repo, - environment_name: new_environment_name - })); - }); - + environment_name: newEnvironmentName + })) + }) }) }) }) - }) diff --git a/test/unit/lib/plugins/labels.test.js b/test/unit/lib/plugins/labels.test.js index a94ffb5b..71eaf2c8 100644 --- a/test/unit/lib/plugins/labels.test.js +++ b/test/unit/lib/plugins/labels.test.js @@ -4,8 +4,8 @@ describe('Labels', () => { let github let log - function configure(config) { - const nop = false; + function configure (config) { + const nop = false return new Labels(nop, github, { owner: 'bkeepers', repo: 'test' }, config, log) } @@ -112,7 +112,7 @@ describe('Labels', () => { const plugin = configure({ exclude: [ { name: 'keep' }, - { name: '^released' }, + { name: '^released' } ], include: [ { name: 'no-change', color: 'FF0000', description: '' }, diff --git a/test/unit/lib/plugins/teams.test.js b/test/unit/lib/plugins/teams.test.js index f289421e..60ef23db 100644 --- a/test/unit/lib/plugins/teams.test.js +++ b/test/unit/lib/plugins/teams.test.js @@ -84,7 +84,7 @@ describe('Teams', () => { expectTeamDeleted(removedTeamName) }) - function expectTeamDeleted(teamSlug) { + function expectTeamDeleted (teamSlug) { expect(github.request).toHaveBeenCalledWith( 'DELETE /orgs/:owner/teams/:team_slug/repos/:owner/:repo', {