diff --git a/.travis.yml b/.travis.yml index e25f6f4..8593141 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,3 +6,5 @@ cache: - node_modules script: - npm run lint + - npm run test:cov +after_script: "npm install coveralls && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage" diff --git a/README.md b/README.md index 95f6438..3c39b5c 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ github 机器人:在服务端上启动一个基于 [koajs](http://koajs.com/) [![Build Status](https://travis-ci.org/xuexb/github-bot.svg?branch=master)](https://travis-ci.org/xuexb/github-bot) [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com) +[![Test Coverage](https://img.shields.io/coveralls/xuexb/github-bot/master.svg)](https://coveralls.io/r/xuexb/github-bot?branch=master) ## 声明 diff --git a/package.json b/package.json index 16629c4..59e26eb 100644 --- a/package.json +++ b/package.json @@ -5,10 +5,13 @@ "main": "src/app.js", "scripts": { "start": "NODE_ENV=development node src/app", - "lint": "eslint src/**/*.js --quiet", + "lint": "eslint src/**/*.js test/**/*.js --quiet", "deploy": "pm2 start src/app.js --name=github-bot", "precommit": "npm run lint", - "commitmsg": "validate-commit-msg" + "commitmsg": "validate-commit-msg", + "test:watch": "npm run test -- --watch", + "test:cov": "istanbul cover node_modules/mocha/bin/_mocha -- -t 5000 --recursive -R spec test/", + "test": "mocha --reporter spec --timeout 5000 --recursive test/" }, "repository": { "type": "git", @@ -58,6 +61,8 @@ } }, "devDependencies": { + "chai": "^4.1.2", + "chai-as-promised": "^7.1.1", "eslint": "^4.9.0", "eslint-config-standard": "^10.2.1", "eslint-friendly-formatter": "^3.0.0", @@ -66,6 +71,11 @@ "eslint-plugin-promise": "^3.6.0", "eslint-plugin-standard": "^3.0.1", "husky": "^0.14.3", + "istanbul": ">=1.0.0-alpha.2", + "mocha": "^4.0.1", + "mock-require": "^2.0.2", + "sinon": "^4.0.2", + "sinon-chai": "^2.14.0", "validate-commit-msg": "^2.14.0" } } diff --git a/src/github.js b/src/github.js index 61be693..acb5f46 100755 --- a/src/github.js +++ b/src/github.js @@ -258,7 +258,7 @@ module.exports = { async removeLabelsToIssue (payload, name) { const owner = payload.repository.owner.login const repo = payload.repository.name - const number = payload.issues.number + const number = payload.issue.number try { await github.issues.removeLabel({ owner, @@ -285,7 +285,7 @@ module.exports = { * @param {boolean} options.prerelease 是否预发布 * @return {boolean} 是否成功 */ - async createRelease (payload, { tag_name, target_commitish, name, body, draft, prerelease }) { + async createRelease (payload, { tag_name, target_commitish, name, body, draft, prerelease } = {}) { const owner = payload.repository.owner.login const repo = payload.repository.name try { @@ -314,7 +314,7 @@ module.exports = { * * @return {Object | null} */ - async getReleaseByTag (payload, { tag_name }) { + async getReleaseByTag (payload, { tag_name } = {}) { const owner = payload.repository.owner.login const repo = payload.repository.name try { @@ -339,7 +339,7 @@ module.exports = { * * @return {boolean} 是否成功 */ - async createReviewRequest (payload, { reviewers, team_reviewers }) { + async createReviewRequest (payload, { reviewers, team_reviewers } = {}) { const owner = payload.repository.owner.login const repo = payload.repository.name const number = payload.pull_request.number @@ -387,7 +387,7 @@ module.exports = { * @param {string} options.head diff * @return {Array | null} */ - async compareCommits (payload, { base, head }) { + async compareCommits (payload, { base, head } = {}) { const owner = payload.repository.owner.login const repo = payload.repository.name try { diff --git a/test/github.js b/test/github.js new file mode 100644 index 0000000..add5ac4 --- /dev/null +++ b/test/github.js @@ -0,0 +1,1156 @@ +/** + * @file github.js test case + * @author xuexb + */ + +/* eslint-disable camelcase */ +const mock = require('mock-require') +mock.stopAll() +const chai = require('chai') +const expect = chai.expect +const chaiAsPromised = require('chai-as-promised') +const clean = require('./utils/clean') +chai.use(chaiAsPromised) + +const payload = { + repository: { + owner: { + login: 'xuexb' + }, + name: 'github-bot' + }, + pull_request: { + number: 1 + }, + issue: { + number: 1 + } +} + +const createClass = (constructor, prototype) => { + function Class (...args) { + if ('function' === typeof constructor) { + constructor.apply(this, args) + } + } + Object.assign(Class.prototype, { + authenticate() {} + }, prototype) + + return Class +} + +const mockGithub = (...args) => { + return mock('github', createClass(...args)) +} + +describe('github.js', () => { + beforeEach('clear node cache', () => { + clean('src/github') + }) + + describe('.issueHasLabel', () => { + it('should be a method', () => { + mockGithub(null, { + issues: { + getIssueLabels() { + return Promise.resolve({ + data: [] + }) + } + } + }) + const github = require('../src/github') + expect(github.issueHasLabel).to.be.a('function') + }) + + describe('should return boolean', () => { + it('true', () => { + mockGithub(null, { + issues: { + getIssueLabels() { + return Promise.resolve({ + data: [ + { + name: 'nofond' + } + ] + }) + } + } + }) + const github = require('../src/github') + expect(github.issueHasLabel(payload, 'nofond')).to.eventually.be.true + }) + + it('false', () => { + mockGithub(null, { + issues: { + getIssueLabels() { + return Promise.resolve({ + data: [ + { + name: 'test' + } + ] + }) + } + } + }) + const github = require('../src/github') + expect(github.issueHasLabel(payload, 'nofond')).to.eventually.be.false + }) + + it('error', () => { + mock('../src/logger', { + appLog: { + error(err) { + expect(err).to.not.be.undefined + } + } + }) + mockGithub(null) + const github = require('../src/github') + expect(github.issueHasLabel(payload, 'nofond')).to.eventually.be.false + }) + }) + + it('check param', () => { + mockGithub(null, { + issues: { + getIssueLabels({owner, repo, number}) { + expect(owner).to.equal('xuexb') + expect(repo).to.equal('github-bot') + expect(number).to.equal(1) + return Promise.resolve({ + data: [] + }) + } + } + }) + const github = require('../src/github') + return github.issueHasLabel(payload) + }) + + }) + + describe('.pullRequestHasLabel', () => { + it('should be a method', () => { + mockGithub(null, { + issues: { + getIssueLabels() { + return Promise.resolve({ + data: [] + }) + } + } + }) + const github = require('../src/github') + expect(github.pullRequestHasLabel).to.be.a('function') + }) + + describe('should return boolean', () => { + it('true', () => { + mockGithub(null, { + issues: { + getIssueLabels() { + return Promise.resolve({ + data: [ + { + name: 'nofond' + } + ] + }) + } + } + }) + const github = require('../src/github') + expect(github.pullRequestHasLabel(payload, 'nofond')).to.eventually.be.true + }) + + it('false', () => { + mockGithub(null, { + issues: { + getIssueLabels() { + return Promise.resolve({ + data: [ + { + name: 'test' + } + ] + }) + } + } + }) + const github = require('../src/github') + expect(github.pullRequestHasLabel(payload, 'nofond')).to.eventually.be.false + }) + + it('error', () => { + mock('../src/logger', { + appLog: { + error(err) { + expect(err).to.not.be.undefined + } + } + }) + mockGithub(null) + const github = require('../src/github') + expect(github.pullRequestHasLabel(payload)).to.eventually.be.false + }) + }) + + it('check param', () => { + mockGithub(null, { + issues: { + getIssueLabels({owner, repo, number}) { + expect(owner).to.equal('xuexb') + expect(repo).to.equal('github-bot') + expect(number).to.equal(1) + return Promise.resolve({ + data: [] + }) + } + } + }) + const github = require('../src/github') + return github.pullRequestHasLabel(payload) + }) + }) + + describe('.commentIssue', () => { + it('should be a method', () => { + mockGithub(null, { + issues: { + createComment() { + return Promise.resolve() + } + } + }) + const github = require('../src/github') + expect(github.commentIssue).to.be.a('function') + }) + + describe('should return boolean', () => { + it('true', () => { + mockGithub(null, { + issues: { + createComment() { + return Promise.resolve() + } + } + }) + const github = require('../src/github') + expect(github.commentIssue(payload, 'message')).to.eventually.be.true + }) + + it('false', () => { + mockGithub(null, { + issues: { + createComment() { + throw new TypeError('error') + } + } + }) + const github = require('../src/github') + expect(github.commentIssue(payload)).to.eventually.be.false + }) + + it('error', () => { + mock('../src/logger', { + appLog: { + error(err) { + expect(err).to.not.be.undefined + } + } + }) + mockGithub(null) + const github = require('../src/github') + expect(github.commentIssue(payload)).to.eventually.be.false + }) + }) + + it('check param', () => { + mockGithub(null, { + issues: { + createComment({owner, repo, number}) { + expect(owner).to.equal('xuexb') + expect(repo).to.equal('github-bot') + expect(number).to.equal(1) + expect(body).to.equal('message') + return Promise.resolve() + } + } + }) + const github = require('../src/github') + return github.commentIssue(payload, 'message') + }) + }) + + describe('.commentPullRequest', () => { + it('should be a method', () => { + mockGithub(null, { + issues: { + createComment() { + return Promise.resolve() + } + } + }) + const github = require('../src/github') + expect(github.commentPullRequest).to.be.a('function') + }) + + describe('should return boolean', () => { + it('true', () => { + mockGithub(null, { + issues: { + createComment() { + return Promise.resolve() + } + } + }) + const github = require('../src/github') + expect(github.commentPullRequest(payload, 'message')).to.eventually.be.true + }) + + it('false', () => { + mockGithub(null, { + issues: { + createComment() { + throw new TypeError('error') + } + } + }) + const github = require('../src/github') + expect(github.commentPullRequest(payload)).to.eventually.be.false + }) + + it('error', () => { + mock('../src/logger', { + appLog: { + error(err) { + expect(err).to.not.be.undefined + } + } + }) + mockGithub(null) + const github = require('../src/github') + expect(github.commentPullRequest(payload)).to.eventually.be.false + }) + }) + + it('check param', () => { + mockGithub(null, { + issues: { + createComment({owner, repo, number}) { + expect(owner).to.equal('xuexb') + expect(repo).to.equal('github-bot') + expect(number).to.equal(1) + expect(body).to.equal('message') + return Promise.resolve() + } + } + }) + const github = require('../src/github') + return github.commentPullRequest(payload, 'message') + }) + }) + + describe('.closeIssue', () => { + it('should be a method', () => { + mockGithub(null, { + issues: { + edit() { + return Promise.resolve() + } + } + }) + const github = require('../src/github') + expect(github.closeIssue).to.be.a('function') + }) + + describe('should return boolean', () => { + it('true', () => { + mockGithub(null, { + issues: { + edit() { + return Promise.resolve() + } + } + }) + const github = require('../src/github') + expect(github.closeIssue(payload)).to.eventually.be.true + }) + + it('false', () => { + mockGithub(null, { + issues: { + edit() { + throw new TypeError('error') + } + } + }) + const github = require('../src/github') + expect(github.closeIssue(payload)).to.eventually.be.false + }) + + it('error', () => { + mock('../src/logger', { + appLog: { + error(err) { + expect(err).to.not.be.undefined + } + } + }) + mockGithub(null) + const github = require('../src/github') + expect(github.closeIssue(payload)).to.eventually.be.false + }) + }) + + it('check param', () => { + mockGithub(null, { + issues: { + edit({owner, repo, number, state}) { + expect(owner).to.equal('xuexb') + expect(repo).to.equal('github-bot') + expect(number).to.equal(1) + expect(state).to.equal('closed') + return Promise.resolve() + } + } + }) + const github = require('../src/github') + return github.closeIssue(payload) + }) + }) + + describe('.addAssigneesToIssue', () => { + it('should be a method', () => { + mockGithub(null, { + issues: { + edit() { + return Promise.resolve() + } + } + }) + const github = require('../src/github') + expect(github.addAssigneesToIssue).to.be.a('function') + }) + + describe('should return boolean', () => { + it('true', () => { + mockGithub(null, { + issues: { + edit() { + return Promise.resolve() + } + } + }) + const github = require('../src/github') + expect(github.addAssigneesToIssue(payload)).to.eventually.be.true + }) + + it('false', () => { + mockGithub(null, { + issues: { + edit() { + throw new TypeError('error') + } + } + }) + const github = require('../src/github') + expect(github.addAssigneesToIssue(payload)).to.eventually.be.false + }) + + it('error', () => { + mock('../src/logger', { + appLog: { + error(err) { + expect(err).to.not.be.undefined + } + } + }) + mockGithub(null, null) + const github = require('../src/github') + expect(github.addAssigneesToIssue(payload)).to.eventually.be.false + }) + }) + + it('check param', () => { + mockGithub(null, { + issues: { + edit({owner, repo, number, state}) { + expect(owner).to.equal('xuexb') + expect(repo).to.equal('github-bot') + expect(number).to.equal(1) + expect(assignees).to.deep.equal(['ok']) + return Promise.resolve() + } + } + }) + const github = require('../src/github') + return github.addAssigneesToIssue(payload, 'ok') + }) + }) + + describe('.addLabelsToIssue', () => { + it('should be a method', () => { + mockGithub(null, { + issues: { + addLabels() { + return Promise.resolve() + } + } + }) + const github = require('../src/github') + expect(github.addLabelsToIssue).to.be.a('function') + }) + + describe('should return boolean', () => { + it('true', () => { + mockGithub(null, { + issues: { + addLabels() { + return Promise.resolve() + } + } + }) + const github = require('../src/github') + expect(github.addLabelsToIssue(payload, 'label')).to.eventually.be.true + }) + + it('false', () => { + mockGithub(null, { + issues: { + addLabels() { + throw new TypeError('error') + } + } + }) + const github = require('../src/github') + expect(github.addLabelsToIssue(payload)).to.eventually.be.false + }) + + it('error', () => { + mock('../src/logger', { + appLog: { + error(err) { + expect(err).to.not.be.undefined + } + } + }) + mockGithub(null) + const github = require('../src/github') + expect(github.addLabelsToIssue(payload)).to.eventually.be.false + }) + }) + + it('check param', () => { + mockGithub(null, { + issues: { + addLabels({owner, repo, number, state}) { + expect(owner).to.equal('xuexb') + expect(repo).to.equal('github-bot') + expect(number).to.equal(1) + expect(assignees).to.deep.equal(['ok']) + return Promise.resolve() + } + } + }) + const github = require('../src/github') + return github.addLabelsToIssue(payload, 'ok') + }) + }) + + describe('.addLabelsToPullRequest', () => { + it('should be a method', () => { + mockGithub(null, { + issues: { + addLabels() { + return Promise.resolve() + } + } + }) + const github = require('../src/github') + expect(github.addLabelsToPullRequest).to.be.a('function') + }) + + describe('should return boolean', () => { + it('true', () => { + mockGithub(null, { + issues: { + addLabels() { + return Promise.resolve() + } + } + }) + const github = require('../src/github') + expect(github.addLabelsToPullRequest(payload, 'label')).to.eventually.be.true + }) + + it('false', () => { + mockGithub(null, { + issues: { + addLabels() { + throw new TypeError('error') + } + } + }) + const github = require('../src/github') + expect(github.addLabelsToPullRequest(payload)).to.eventually.be.false + }) + + it('error', () => { + mock('../src/logger', { + appLog: { + error(err) { + expect(err).to.not.be.undefined + } + } + }) + mockGithub(null) + const github = require('../src/github') + expect(github.addLabelsToPullRequest(payload)).to.eventually.be.false + }) + }) + + it('check param', () => { + mockGithub(null, { + issues: { + addLabels({owner, repo, number, state}) { + expect(owner).to.equal('xuexb') + expect(repo).to.equal('github-bot') + expect(number).to.equal(1) + expect(assignees).to.deep.equal(['ok']) + return Promise.resolve() + } + } + }) + const github = require('../src/github') + return github.addLabelsToPullRequest(payload, 'ok') + }) + }) + + describe('.removeLabelsToPullRequest', () => { + it('should be a method', () => { + mockGithub(null, { + issues: { + removeLabel() { + return Promise.resolve() + } + } + }) + const github = require('../src/github') + expect(github.removeLabelsToPullRequest).to.be.a('function') + }) + + describe('should return boolean', () => { + it('true', () => { + mockGithub(null, { + issues: { + removeLabel() { + return Promise.resolve() + } + } + }) + const github = require('../src/github') + expect(github.removeLabelsToPullRequest(payload, 'label')).to.eventually.be.true + }) + + it('false', () => { + mockGithub(null, { + issues: { + removeLabel() { + throw new TypeError('error') + } + } + }) + const github = require('../src/github') + expect(github.removeLabelsToPullRequest(payload)).to.eventually.be.false + }) + + it('error', () => { + mock('../src/logger', { + appLog: { + error(err) { + expect(err).to.not.be.undefined + } + } + }) + mockGithub(null) + const github = require('../src/github') + expect(github.removeLabelsToPullRequest(payload)).to.eventually.be.false + }) + }) + + it('check param', () => { + mockGithub(null, { + issues: { + removeLabel({owner, repo, number, state}) { + expect(owner).to.equal('xuexb') + expect(repo).to.equal('github-bot') + expect(number).to.equal(1) + expect(assignees).to.equal('ok') + return Promise.resolve() + } + } + }) + const github = require('../src/github') + return github.removeLabelsToPullRequest(payload, 'ok') + }) + }) + + describe('.removeLabelsToIssue', () => { + it('should be a method', () => { + mockGithub(null, { + issues: { + removeLabel() { + return Promise.resolve() + } + } + }) + const github = require('../src/github') + expect(github.removeLabelsToIssue).to.be.a('function') + }) + + describe('should return boolean', () => { + it('true', () => { + mockGithub(null, { + issues: { + removeLabel() { + return Promise.resolve() + } + } + }) + const github = require('../src/github') + expect(github.removeLabelsToIssue(payload, 'label')).to.eventually.be.true + }) + + it('false', () => { + mockGithub(null, { + issues: { + removeLabel() { + throw new TypeError('error') + } + } + }) + const github = require('../src/github') + expect(github.removeLabelsToIssue(payload)).to.eventually.be.false + }) + + it('error', () => { + mock('../src/logger', { + appLog: { + error(err) { + expect(err).to.not.be.undefined + } + } + }) + mockGithub(null) + const github = require('../src/github') + expect(github.removeLabelsToIssue(payload)).to.eventually.be.false + }) + }) + + it('check param', () => { + mockGithub(null, { + issues: { + removeLabel({owner, repo, number, state}) { + expect(owner).to.equal('xuexb') + expect(repo).to.equal('github-bot') + expect(number).to.equal(1) + expect(assignees).to.equal('ok') + return Promise.resolve() + } + } + }) + const github = require('../src/github') + return github.removeLabelsToIssue(payload, 'ok') + }) + }) + + describe('.createRelease', () => { + it('should be a method', () => { + mockGithub(null, { + repos: { + createRelease() { + return Promise.resolve() + } + } + }) + const github = require('../src/github') + expect(github.createRelease).to.be.a('function') + }) + + describe('should return boolean', () => { + it('true', () => { + mockGithub(null, { + repos: { + createRelease() { + return Promise.resolve() + } + } + }) + const github = require('../src/github') + expect(github.createRelease(payload, {})).to.eventually.be.true + }) + + it('false', () => { + mockGithub(null, { + repos: { + createRelease() { + throw new TypeError('error') + } + } + }) + const github = require('../src/github') + expect(github.createRelease(payload)).to.eventually.be.false + }) + + it('error', () => { + mock('../src/logger', { + appLog: { + error(err) { + expect(err).to.not.be.undefined + } + } + }) + mockGithub(null) + const github = require('../src/github') + expect(github.createRelease(payload)).to.eventually.be.false + }) + }) + + it('check param', () => { + mockGithub(null, { + repos: { + createRelease({owner, repo, number, tag_name, target_commitish, name, body, draft, prerelease}) { + expect(owner).to.equal('xuexb') + expect(repo).to.equal('github-bot') + expect(number).to.equal(1) + expect(tag_name).to.equal('tag_name') + expect(target_commitish).to.equal('target_commitish') + expect(name).to.equal('name') + expect(body).to.equal('body') + expect(draft).to.equal('draft') + expect(prerelease).to.equal('prerelease') + return Promise.resolve() + } + } + }) + const github = require('../src/github') + return github.createRelease(payload, { + tag_name: 'tag_name', + target_commitish: 'target_commitish', + name: 'name', + body: 'body', + draft: 'draft', + prerelease: 'prerelease' + }) + }) + }) + + describe('.getReleaseByTag', () => { + it('should be a method', () => { + mockGithub(null, { + repos: { + getReleaseByTag() { + return Promise.resolve() + } + } + }) + const github = require('../src/github') + expect(github.getReleaseByTag).to.be.a('function') + }) + + describe('should return boolean', () => { + it('true', () => { + mockGithub(null, { + repos: { + getReleaseByTag() { + return Promise.resolve({ + data: true + }) + } + } + }) + const github = require('../src/github') + expect(github.getReleaseByTag(payload, { + tag_name: 'ok' + })).to.eventually.be.true + }) + + it('false', () => { + mockGithub(null, { + repos: { + getReleaseByTag() { + return Promise.resolve({ + data: false + }) + } + } + }) + const github = require('../src/github') + expect(github.getReleaseByTag(payload)).to.eventually.be.false + }) + + it('error', () => { + mock('../src/logger', { + appLog: { + error(err) { + expect(err).to.not.be.undefined + } + } + }) + mockGithub(null) + const github = require('../src/github') + expect(github.getReleaseByTag(payload)).to.eventually.be.null + }) + }) + + it('check param', () => { + mockGithub(null, { + repos: { + getReleaseByTag({owner, repo, number, name}) { + expect(owner).to.equal('xuexb') + expect(repo).to.equal('github-bot') + expect(number).to.equal(1) + expect(name).to.equal('tag_name') + return Promise.resolve() + } + } + }) + const github = require('../src/github') + return github.getReleaseByTag(payload, { + tag_name: 'tag_name' + }) + }) + }) + + describe('.createReviewRequest', () => { + it('should be a method', () => { + mockGithub(null, { + pullRequests: { + createReviewRequest() { + return Promise.resolve() + } + } + }) + const github = require('../src/github') + expect(github.createReviewRequest).to.be.a('function') + }) + + describe('should return boolean', () => { + it('true', () => { + mockGithub(null, { + pullRequests: { + createReviewRequest() { + return Promise.resolve() + } + } + }) + const github = require('../src/github') + expect(github.createReviewRequest(payload, { + reviewers: 'reviewers', + team_reviewers: 'team_reviewers' + })).to.eventually.be.true + }) + + it('false', () => { + mockGithub(null, { + pullRequests: { + createReviewRequest() { + throw new TypeError('error') + } + } + }) + const github = require('../src/github') + expect(github.createReviewRequest(payload)).to.eventually.be.false + }) + + it('error', () => { + mock('../src/logger', { + appLog: { + error(err) { + expect(err).to.not.be.undefined + } + } + }) + mockGithub(null) + const github = require('../src/github') + expect(github.createReviewRequest(payload)).to.eventually.be.false + }) + }) + + it('check param', () => { + mockGithub(null, { + pullRequests: { + createReviewRequest({owner, repo, number, team_reviewers, reviewers}) { + expect(owner).to.equal('xuexb') + expect(repo).to.equal('github-bot') + expect(number).to.equal(1) + expect(reviewers).to.equal('reviewers') + expect(team_reviewers).to.equal('team_reviewers') + return Promise.resolve() + } + } + }) + const github = require('../src/github') + return github.createReviewRequest(payload, { + reviewers: 'reviewers', + team_reviewers: 'team_reviewers' + }) + }) + }) + + describe('.getTags', () => { + it('should be a method', () => { + mockGithub(null, { + repos: { + getTags() { + return Promise.resolve() + } + } + }) + const github = require('../src/github') + expect(github.getTags).to.be.a('function') + }) + + describe('should return boolean', () => { + it('true', () => { + mockGithub(null, { + repos: { + getTags() { + return Promise.resolve({ + data: true + }) + } + } + }) + const github = require('../src/github') + expect(github.getTags(payload)).to.eventually.be.true + }) + + it('false', () => { + mockGithub(null, { + repos: { + getTags() { + return Promise.resolve({ + data: false + }) + } + } + }) + const github = require('../src/github') + expect(github.getTags(payload)).to.eventually.be.false + }) + + it('error', () => { + mock('../src/logger', { + appLog: { + error(err) { + expect(err).to.not.be.undefined + } + } + }) + mockGithub(null) + const github = require('../src/github') + expect(github.getTags(payload)).to.eventually.be.deep.equal([]) + }) + }) + + it('check param', () => { + mockGithub(null, { + repos: { + getTags({owner, repo}) { + expect(owner).to.equal('xuexb') + expect(repo).to.equal('github-bot') + return Promise.resolve() + } + } + }) + const github = require('../src/github') + return github.getTags(payload) + }) + }) + + describe('.compareCommits', () => { + it('should be a method', () => { + mockGithub(null, { + repos: { + compareCommits() { + return Promise.resolve() + } + } + }) + const github = require('../src/github') + expect(github.compareCommits).to.be.a('function') + }) + + describe('should return boolean', () => { + it('true', () => { + mockGithub(null, { + repos: { + compareCommits() { + return Promise.resolve({ + data: true + }) + } + } + }) + const github = require('../src/github') + expect(github.compareCommits(payload, { + base: 'base', + head: 'head' + })).to.eventually.be.true + }) + + it('false', () => { + mockGithub(null, { + repos: { + compareCommits() { + return Promise.resolve({ + data: false + }) + } + } + }) + const github = require('../src/github') + expect(github.compareCommits(payload)).to.eventually.be.false + }) + + it('error', () => { + mock('../src/logger', { + appLog: { + error(err) { + expect(err).to.not.be.undefined + } + } + }) + mockGithub(null) + const github = require('../src/github') + expect(github.compareCommits(payload)).to.eventually.be.null + }) + }) + + it('check param', () => { + mockGithub(null, { + repos: { + compareCommits({owner, repo, base, head}) { + expect(owner).to.equal('xuexb') + expect(repo).to.equal('github-bot') + expect(base).to.equal('base') + expect(head).to.equal('head') + return Promise.resolve() + } + } + }) + const github = require('../src/github') + return github.compareCommits(payload, { + base: 'base', + head: 'head' + }) + }) + }) +}) diff --git a/test/modules/issues/autoAssign.js b/test/modules/issues/autoAssign.js new file mode 100644 index 0000000..5e425a4 --- /dev/null +++ b/test/modules/issues/autoAssign.js @@ -0,0 +1,86 @@ +/** + * @file modules/issues/autoAssign.js test case + * @author xuexb + */ + +const expect = require('chai').expect +const mock = require('mock-require') +mock.stopAll() +const clean = require('../../utils/clean') + +describe('modules/issues/autoAssign.js', () => { + beforeEach('clear node cache', () => { + clean('src/github') + clean('src/utils') + clean('src/modules/issues/autoAssign') + + mock('../../../src/utils', { + getPkgConfig() { + return {} + } + }) + mock('../../../src/github', { + addAssigneesToIssue() { + } + }) + }) + + it('event name', () => { + const autoAssign = require('../../../src/modules/issues/autoAssign') + autoAssign(name => { + expect(name).to.equal('issues_labeled') + }) + }) + + describe('set label', () => { + it('is ok', (done) => { + mock('../../../src/utils', { + getPkgConfig() { + return { + labelToAuthor: { + autoAssign: 'github-bot' + } + } + } + }) + mock('../../../src/github', { + addAssigneesToIssue(payload, label) { + expect(payload).to.be.a('object').and.not.empty + expect(label).to.equal('github-bot') + done() + } + }) + + const autoAssign = require('../../../src/modules/issues/autoAssign') + autoAssign(function (name, callback) { + callback({ + payload: { + label: { + name: 'autoAssign' + } + } + }) + }) + }) + + it('is false', (done) => { + mock('../../../src/github', { + addAssigneesToIssue() { + done('error') + } + }) + + const autoAssign = require('../../../src/modules/issues/autoAssign') + autoAssign(function (name, callback) { + callback({ + payload: { + label: { + name: 'error' + } + } + }) + }) + setTimeout(done) + }) + }) +}) diff --git a/test/utils.js b/test/utils.js new file mode 100644 index 0000000..d0afd79 --- /dev/null +++ b/test/utils.js @@ -0,0 +1,47 @@ +/** + * @file utils.js test case + * @author xuexb + */ +require('mock-require').stopAll() +const utils = require('../src/utils') +const expect = require('chai').expect + +describe('utils.js', () => { + describe('.toArray', () => { + it('should return self if empty', () => { + expect(utils.toArray()).to.be.undefined + expect(utils.toArray('')).to.equal('') + expect(utils.toArray(null)).to.be.null + }) + it('should return array if not the empty string', () => { + expect(utils.toArray('string')).to.be.a('array').and.to.deep.equal(['string']) + }) + }) + + describe('.getPkgConfig', () => { + it('should return object', () => { + expect(utils.getPkgConfig()).to.be.a('object').and.to.not.empty + }) + }) + + describe('.getPkgCommitPrefix', () => { + it('should return array', () => { + expect(utils.getPkgCommitPrefix()).to.be.a('array').and.to.not.empty + }) + }) + + it('.verifySignature', () => { + const GITHUB_SECRET_TOKEN = process.env['GITHUB_SECRET_TOKEN'] + + process.env['GITHUB_SECRET_TOKEN'] = 'test' + const flag = utils.verifySignature({ + rawBody: 'test', + headers: { + 'x-hub-signature': 'test' + } + }) + process.env['GITHUB_SECRET_TOKEN'] = GITHUB_SECRET_TOKEN + + expect(flag).to.be.false + }) +}) diff --git a/test/utils/clean.js b/test/utils/clean.js new file mode 100644 index 0000000..4bb11d4 --- /dev/null +++ b/test/utils/clean.js @@ -0,0 +1,11 @@ +/** + * @file 清除 node 缓存,以根目录为基础路径 + * @author xuexb + */ + +const resolve = require('path').resolve +const extname = require('path').extname + +module.exports = path => { + delete require.cache[resolve(__dirname, '../../', path) + (extname(path) === '' ? '.js' : '')] +}