2017-06-29 05:29:41 +00:00
|
|
|
const prWorker = require('../../../lib/workers/pr');
|
|
|
|
const changelogHelper = require('../../../lib/workers/pr/changelog');
|
|
|
|
const defaultConfig = require('../../../lib/config/defaults').getConfig();
|
2017-02-14 07:08:40 +00:00
|
|
|
|
2017-06-29 05:29:41 +00:00
|
|
|
jest.mock('../../../lib/workers/pr/changelog');
|
2017-06-13 09:08:37 +00:00
|
|
|
changelogHelper.getChangeLogJSON = jest.fn();
|
|
|
|
changelogHelper.getChangeLogJSON.mockReturnValue({
|
|
|
|
project: {
|
|
|
|
github: 'renovateapp/dummy',
|
|
|
|
repository: 'https://github.com/renovateapp/dummy',
|
|
|
|
},
|
|
|
|
versions: [
|
|
|
|
{
|
|
|
|
date: new Date('2017-01-01'),
|
|
|
|
version: '1.1.0',
|
|
|
|
changes: [
|
|
|
|
{
|
|
|
|
date: new Date('2017-01-01'),
|
|
|
|
sha: 'abcdefghijklmnopqrstuvwxyz',
|
2017-06-13 10:22:21 +00:00
|
|
|
message: 'foo #3\nbar',
|
2017-06-13 09:08:37 +00:00
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
});
|
2017-02-14 07:08:40 +00:00
|
|
|
|
|
|
|
describe('workers/pr', () => {
|
2017-11-08 05:44:03 +00:00
|
|
|
describe('checkAutoMerge(pr, config)', () => {
|
2017-04-20 11:01:23 +00:00
|
|
|
let config;
|
|
|
|
let pr;
|
|
|
|
beforeEach(() => {
|
2017-08-26 14:10:18 +00:00
|
|
|
config = {
|
|
|
|
...defaultConfig,
|
|
|
|
};
|
2017-04-20 11:01:23 +00:00
|
|
|
pr = {
|
|
|
|
head: {
|
|
|
|
ref: 'somebranch',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
});
|
2017-11-07 10:46:10 +00:00
|
|
|
afterEach(() => {
|
|
|
|
jest.clearAllMocks();
|
|
|
|
});
|
2017-04-20 11:01:23 +00:00
|
|
|
it('should not automerge if not configured', async () => {
|
2017-11-08 05:44:03 +00:00
|
|
|
await prWorker.checkAutoMerge(pr, config);
|
2017-11-07 10:46:10 +00:00
|
|
|
expect(platform.mergePr.mock.calls.length).toBe(0);
|
2017-04-20 11:01:23 +00:00
|
|
|
});
|
2017-06-08 04:18:21 +00:00
|
|
|
it('should automerge if enabled and pr is mergeable', async () => {
|
2017-08-21 11:41:48 +00:00
|
|
|
config.automerge = true;
|
2017-08-21 09:17:47 +00:00
|
|
|
pr.canRebase = true;
|
2017-04-20 11:01:23 +00:00
|
|
|
pr.mergeable = true;
|
2017-11-07 10:46:10 +00:00
|
|
|
platform.getBranchStatus.mockReturnValueOnce('success');
|
2017-11-08 05:44:03 +00:00
|
|
|
await prWorker.checkAutoMerge(pr, config);
|
2017-11-07 10:46:10 +00:00
|
|
|
expect(platform.mergePr.mock.calls.length).toBe(1);
|
2017-04-20 11:01:23 +00:00
|
|
|
});
|
2017-08-21 09:17:47 +00:00
|
|
|
it('should not automerge if enabled and pr is mergeable but cannot rebase', async () => {
|
2017-08-21 11:41:48 +00:00
|
|
|
config.automerge = true;
|
2017-08-21 09:17:47 +00:00
|
|
|
pr.canRebase = false;
|
|
|
|
pr.mergeable = true;
|
2017-11-07 10:46:10 +00:00
|
|
|
platform.getBranchStatus.mockReturnValueOnce('success');
|
2017-11-08 05:44:03 +00:00
|
|
|
await prWorker.checkAutoMerge(pr, config);
|
2017-11-07 10:46:10 +00:00
|
|
|
expect(platform.mergePr.mock.calls.length).toBe(0);
|
2017-08-21 09:17:47 +00:00
|
|
|
});
|
2017-06-08 04:18:21 +00:00
|
|
|
it('should not automerge if enabled and pr is mergeable but branch status is not success', async () => {
|
2017-08-21 11:41:48 +00:00
|
|
|
config.automerge = true;
|
2017-04-20 11:01:23 +00:00
|
|
|
pr.mergeable = true;
|
2017-11-07 10:46:10 +00:00
|
|
|
platform.getBranchStatus.mockReturnValueOnce('pending');
|
2017-11-08 05:44:03 +00:00
|
|
|
await prWorker.checkAutoMerge(pr, config);
|
2017-11-07 10:46:10 +00:00
|
|
|
expect(platform.mergePr.mock.calls.length).toBe(0);
|
2017-04-20 11:01:23 +00:00
|
|
|
});
|
2017-06-08 04:18:21 +00:00
|
|
|
it('should not automerge if enabled and pr is mergeable but unstable', async () => {
|
2017-08-21 11:41:48 +00:00
|
|
|
config.automerge = true;
|
2017-04-20 11:01:23 +00:00
|
|
|
pr.mergeable = true;
|
|
|
|
pr.mergeable_state = 'unstable';
|
2017-11-08 05:44:03 +00:00
|
|
|
await prWorker.checkAutoMerge(pr, config);
|
2017-11-07 10:46:10 +00:00
|
|
|
expect(platform.mergePr.mock.calls.length).toBe(0);
|
2017-04-20 11:01:23 +00:00
|
|
|
});
|
2017-06-08 04:18:21 +00:00
|
|
|
it('should not automerge if enabled and pr is unmergeable', async () => {
|
2017-08-21 11:41:48 +00:00
|
|
|
config.automerge = true;
|
2017-04-20 11:01:23 +00:00
|
|
|
pr.mergeable = false;
|
2017-11-08 05:44:03 +00:00
|
|
|
await prWorker.checkAutoMerge(pr, config);
|
2017-11-07 10:46:10 +00:00
|
|
|
expect(platform.mergePr.mock.calls.length).toBe(0);
|
2017-04-20 11:01:23 +00:00
|
|
|
});
|
|
|
|
});
|
2017-08-26 14:10:18 +00:00
|
|
|
describe('ensurePr', () => {
|
2017-02-14 07:08:40 +00:00
|
|
|
let config;
|
2017-11-08 10:09:26 +00:00
|
|
|
const existingPr = {
|
|
|
|
displayNumber: 'Existing PR',
|
|
|
|
title: 'Update dependency dummy to v1.1.0',
|
|
|
|
};
|
2017-02-14 07:08:40 +00:00
|
|
|
beforeEach(() => {
|
2017-08-26 14:10:18 +00:00
|
|
|
config = {
|
|
|
|
...defaultConfig,
|
2017-02-14 07:08:40 +00:00
|
|
|
};
|
2017-11-08 10:09:26 +00:00
|
|
|
config.branchName = 'renovate/dummy-1.x';
|
|
|
|
config.prTitle = 'Update dependency dummy to v1.1.0';
|
|
|
|
config.depName = 'dummy';
|
|
|
|
config.isGitHub = true;
|
|
|
|
config.privateRepo = true;
|
|
|
|
config.currentVersion = '1.0.0';
|
|
|
|
config.newVersion = '1.1.0';
|
|
|
|
config.repositoryUrl = 'https://github.com/renovateapp/dummy';
|
2017-11-07 10:46:10 +00:00
|
|
|
platform.createPr.mockReturnValue({ displayNumber: 'New Pull Request' });
|
2017-07-07 09:45:48 +00:00
|
|
|
config.upgrades = [config];
|
2017-02-14 07:08:40 +00:00
|
|
|
});
|
2017-11-07 10:46:10 +00:00
|
|
|
afterEach(() => {
|
|
|
|
jest.clearAllMocks();
|
|
|
|
});
|
2017-02-14 07:08:40 +00:00
|
|
|
it('should return null if check fails', async () => {
|
2017-11-07 10:46:10 +00:00
|
|
|
platform.getBranchPr.mockImplementationOnce(() => {
|
2017-02-14 07:08:40 +00:00
|
|
|
throw new Error('oops');
|
|
|
|
});
|
2017-08-26 14:10:18 +00:00
|
|
|
const pr = await prWorker.ensurePr(config);
|
2017-02-14 07:08:40 +00:00
|
|
|
expect(pr).toBe(null);
|
|
|
|
});
|
2017-04-20 10:11:56 +00:00
|
|
|
it('should return null if waiting for success', async () => {
|
2017-11-07 10:46:10 +00:00
|
|
|
platform.getBranchStatus.mockReturnValueOnce('failed');
|
2017-04-20 10:11:56 +00:00
|
|
|
config.prCreation = 'status-success';
|
2017-08-26 14:10:18 +00:00
|
|
|
const pr = await prWorker.ensurePr(config);
|
2017-04-20 10:11:56 +00:00
|
|
|
expect(pr).toBe(null);
|
|
|
|
});
|
|
|
|
it('should create PR if success', async () => {
|
2017-11-07 10:46:10 +00:00
|
|
|
platform.getBranchStatus.mockReturnValueOnce('success');
|
2017-04-20 10:11:56 +00:00
|
|
|
config.prCreation = 'status-success';
|
2017-08-26 14:10:18 +00:00
|
|
|
const pr = await prWorker.ensurePr(config);
|
2017-04-20 10:11:56 +00:00
|
|
|
expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
|
2017-11-08 10:09:26 +00:00
|
|
|
expect(platform.createPr.mock.calls[0]).toMatchSnapshot();
|
|
|
|
existingPr.body = platform.createPr.mock.calls[0][2];
|
|
|
|
});
|
|
|
|
it('should convert to HTML PR for gitlab', async () => {
|
|
|
|
platform.getBranchStatus.mockReturnValueOnce('success');
|
|
|
|
config.prCreation = 'status-success';
|
2017-11-10 08:15:51 +00:00
|
|
|
config.isGitLab = true;
|
2017-11-08 10:09:26 +00:00
|
|
|
const pr = await prWorker.ensurePr(config);
|
|
|
|
expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
|
|
|
|
expect(platform.createPr.mock.calls[0]).toMatchSnapshot();
|
|
|
|
expect(platform.createPr.mock.calls[0][2].indexOf('<p>This MR')).not.toBe(
|
|
|
|
-1
|
|
|
|
);
|
2017-04-20 10:11:56 +00:00
|
|
|
});
|
2017-09-03 08:02:48 +00:00
|
|
|
it('should delete branch and return null if creating PR fails', async () => {
|
2017-11-07 10:46:10 +00:00
|
|
|
platform.getBranchStatus.mockReturnValueOnce('success');
|
|
|
|
platform.createPr.mockImplementationOnce(() => {
|
2017-09-03 08:02:48 +00:00
|
|
|
throw new Error('failed to create PR');
|
|
|
|
});
|
|
|
|
config.prCreation = 'status-success';
|
|
|
|
const pr = await prWorker.ensurePr(config);
|
2017-11-07 10:46:10 +00:00
|
|
|
expect(platform.deleteBranch.mock.calls).toHaveLength(1);
|
2017-09-03 08:02:48 +00:00
|
|
|
expect(pr).toBe(null);
|
|
|
|
});
|
2017-04-20 10:11:56 +00:00
|
|
|
it('should return null if waiting for not pending', async () => {
|
2017-11-07 10:46:10 +00:00
|
|
|
platform.getBranchStatus.mockReturnValueOnce('pending');
|
|
|
|
platform.getBranchLastCommitTime.mockImplementationOnce(() => new Date());
|
2017-04-20 10:11:56 +00:00
|
|
|
config.prCreation = 'not-pending';
|
2017-08-26 14:10:18 +00:00
|
|
|
const pr = await prWorker.ensurePr(config);
|
2017-04-20 10:11:56 +00:00
|
|
|
expect(pr).toBe(null);
|
|
|
|
});
|
2017-08-28 09:37:09 +00:00
|
|
|
it('should create PR if pending timeout hit', async () => {
|
2017-11-07 10:46:10 +00:00
|
|
|
platform.getBranchStatus.mockReturnValueOnce('pending');
|
|
|
|
platform.getBranchLastCommitTime.mockImplementationOnce(
|
2017-08-28 09:37:09 +00:00
|
|
|
() => new Date('2017-01-01')
|
|
|
|
);
|
|
|
|
config.prCreation = 'not-pending';
|
|
|
|
const pr = await prWorker.ensurePr(config);
|
|
|
|
expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
|
|
|
|
});
|
2017-04-20 10:11:56 +00:00
|
|
|
it('should create PR if no longer pending', async () => {
|
2017-11-07 10:46:10 +00:00
|
|
|
platform.getBranchStatus.mockReturnValueOnce('failed');
|
2017-04-20 10:11:56 +00:00
|
|
|
config.prCreation = 'not-pending';
|
2017-08-26 14:10:18 +00:00
|
|
|
const pr = await prWorker.ensurePr(config);
|
2017-04-20 10:11:56 +00:00
|
|
|
expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
|
|
|
|
});
|
2017-02-14 07:08:40 +00:00
|
|
|
it('should create new branch if none exists', async () => {
|
2017-08-26 14:10:18 +00:00
|
|
|
const pr = await prWorker.ensurePr(config);
|
2017-02-14 07:08:40 +00:00
|
|
|
expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
|
2017-11-07 10:46:10 +00:00
|
|
|
expect(platform.createPr.mock.calls[0][2].indexOf('Errors</h3>')).toEqual(
|
|
|
|
-1
|
|
|
|
);
|
2017-07-04 11:52:23 +00:00
|
|
|
expect(
|
2017-11-07 10:46:10 +00:00
|
|
|
platform.createPr.mock.calls[0][2].indexOf('Warnings</h3>')
|
2017-07-04 11:52:23 +00:00
|
|
|
).toEqual(-1);
|
2017-02-14 07:08:40 +00:00
|
|
|
});
|
|
|
|
it('should add assignees and reviewers to new PR', async () => {
|
2017-08-01 04:58:13 +00:00
|
|
|
config.assignees = ['@foo', 'bar'];
|
|
|
|
config.reviewers = ['baz', '@boo'];
|
2017-08-26 14:10:18 +00:00
|
|
|
const pr = await prWorker.ensurePr(config);
|
2017-02-14 07:08:40 +00:00
|
|
|
expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
|
2017-11-07 10:46:10 +00:00
|
|
|
expect(platform.addAssignees.mock.calls.length).toBe(1);
|
|
|
|
expect(platform.addAssignees.mock.calls).toMatchSnapshot();
|
|
|
|
expect(platform.addReviewers.mock.calls.length).toBe(1);
|
|
|
|
expect(platform.addReviewers.mock.calls).toMatchSnapshot();
|
2017-04-21 05:23:36 +00:00
|
|
|
});
|
2017-08-24 08:14:53 +00:00
|
|
|
it('should add reviewers even if assignees fails', async () => {
|
2017-11-07 10:46:10 +00:00
|
|
|
platform.addAssignees.mockImplementationOnce(() => {
|
2017-08-24 08:14:53 +00:00
|
|
|
throw new Error('some error');
|
|
|
|
});
|
|
|
|
config.assignees = ['@foo', 'bar'];
|
|
|
|
config.reviewers = ['baz', '@boo'];
|
2017-08-26 14:10:18 +00:00
|
|
|
const pr = await prWorker.ensurePr(config);
|
2017-08-24 08:14:53 +00:00
|
|
|
expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
|
2017-11-07 10:46:10 +00:00
|
|
|
expect(platform.addAssignees.mock.calls.length).toBe(1);
|
|
|
|
expect(platform.addReviewers.mock.calls.length).toBe(1);
|
2017-08-24 08:14:53 +00:00
|
|
|
});
|
|
|
|
it('should handled failed reviewers add', async () => {
|
2017-11-07 10:46:10 +00:00
|
|
|
platform.addReviewers.mockImplementationOnce(() => {
|
2017-08-24 08:14:53 +00:00
|
|
|
throw new Error('some error');
|
|
|
|
});
|
|
|
|
config.assignees = ['@foo', 'bar'];
|
|
|
|
config.reviewers = ['baz', '@boo'];
|
2017-08-26 14:10:18 +00:00
|
|
|
const pr = await prWorker.ensurePr(config);
|
2017-08-24 08:14:53 +00:00
|
|
|
expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
|
2017-11-07 10:46:10 +00:00
|
|
|
expect(platform.addAssignees.mock.calls.length).toBe(1);
|
|
|
|
expect(platform.addReviewers.mock.calls.length).toBe(1);
|
2017-08-24 08:14:53 +00:00
|
|
|
});
|
2017-07-04 11:52:23 +00:00
|
|
|
it('should display errors and warnings', async () => {
|
2017-08-26 14:10:18 +00:00
|
|
|
config.errors = [{}];
|
|
|
|
config.warnings = [{}];
|
|
|
|
const pr = await prWorker.ensurePr(config);
|
2017-07-04 11:52:23 +00:00
|
|
|
expect(
|
2017-11-08 10:09:26 +00:00
|
|
|
platform.createPr.mock.calls[0][2].indexOf('### Errors')
|
2017-07-04 11:52:23 +00:00
|
|
|
).not.toEqual(-1);
|
|
|
|
expect(
|
2017-11-08 10:09:26 +00:00
|
|
|
platform.createPr.mock.calls[0][2].indexOf('### Warnings')
|
2017-07-04 11:52:23 +00:00
|
|
|
).not.toEqual(-1);
|
|
|
|
expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
|
|
|
|
});
|
2017-06-08 04:18:21 +00:00
|
|
|
it('should not add assignees and reviewers to new PR if automerging enabled', async () => {
|
2017-04-21 05:23:36 +00:00
|
|
|
config.assignees = ['bar'];
|
|
|
|
config.reviewers = ['baz'];
|
2017-08-21 11:41:48 +00:00
|
|
|
config.automerge = true;
|
2017-08-26 14:10:18 +00:00
|
|
|
const pr = await prWorker.ensurePr(config);
|
2017-04-21 05:23:36 +00:00
|
|
|
expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
|
2017-11-07 10:46:10 +00:00
|
|
|
expect(platform.addAssignees.mock.calls.length).toBe(0);
|
|
|
|
expect(platform.addReviewers.mock.calls.length).toBe(0);
|
2017-04-21 05:23:36 +00:00
|
|
|
});
|
2017-10-13 08:56:18 +00:00
|
|
|
it('should add assignees and reviewers to existing PR', async () => {
|
|
|
|
config.assignees = ['bar'];
|
|
|
|
config.reviewers = ['baz'];
|
2017-11-08 10:09:26 +00:00
|
|
|
config.automerge = true;
|
2017-11-07 10:46:10 +00:00
|
|
|
platform.getBranchPr.mockReturnValueOnce(existingPr);
|
|
|
|
platform.getBranchStatus.mockReturnValueOnce('failure');
|
2017-10-13 08:56:18 +00:00
|
|
|
config.semanticPrefix = '';
|
|
|
|
const pr = await prWorker.ensurePr(config);
|
2017-11-07 10:46:10 +00:00
|
|
|
expect(platform.updatePr.mock.calls).toMatchSnapshot();
|
|
|
|
expect(platform.updatePr.mock.calls.length).toBe(0);
|
|
|
|
expect(platform.addAssignees.mock.calls.length).toBe(1);
|
|
|
|
expect(platform.addReviewers.mock.calls.length).toBe(1);
|
2017-10-13 08:56:18 +00:00
|
|
|
expect(pr).toMatchObject(existingPr);
|
|
|
|
});
|
2017-02-14 07:08:40 +00:00
|
|
|
it('should return unmodified existing PR', async () => {
|
2017-11-07 10:46:10 +00:00
|
|
|
platform.getBranchPr.mockReturnValueOnce(existingPr);
|
2017-06-29 17:50:26 +00:00
|
|
|
config.semanticPrefix = '';
|
2017-08-26 14:10:18 +00:00
|
|
|
const pr = await prWorker.ensurePr(config);
|
2017-11-07 10:46:10 +00:00
|
|
|
expect(platform.updatePr.mock.calls).toMatchSnapshot();
|
2017-11-08 10:09:26 +00:00
|
|
|
expect(platform.updatePr.mock.calls).toHaveLength(0);
|
2017-02-14 07:08:40 +00:00
|
|
|
expect(pr).toMatchObject(existingPr);
|
|
|
|
});
|
|
|
|
it('should return modified existing PR', async () => {
|
|
|
|
config.newVersion = '1.2.0';
|
2017-11-07 10:46:10 +00:00
|
|
|
platform.getBranchPr.mockReturnValueOnce(existingPr);
|
2017-08-26 14:10:18 +00:00
|
|
|
const pr = await prWorker.ensurePr(config);
|
2017-08-03 06:01:20 +00:00
|
|
|
expect(pr).toMatchSnapshot();
|
2017-02-14 07:08:40 +00:00
|
|
|
});
|
2017-10-05 07:31:10 +00:00
|
|
|
it('should create PR if branch tests failed', async () => {
|
2017-08-21 11:41:48 +00:00
|
|
|
config.automerge = true;
|
2017-06-08 04:18:21 +00:00
|
|
|
config.automergeType = 'branch-push';
|
2017-11-07 10:46:10 +00:00
|
|
|
platform.getBranchStatus.mockReturnValueOnce('failure');
|
2017-08-26 14:10:18 +00:00
|
|
|
const pr = await prWorker.ensurePr(config);
|
2017-06-08 04:18:21 +00:00
|
|
|
expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
|
|
|
|
});
|
2017-10-05 07:31:10 +00:00
|
|
|
it('should create PR if branch automerging failed', async () => {
|
|
|
|
config.automerge = true;
|
|
|
|
config.automergeType = 'branch-push';
|
2017-11-07 10:46:10 +00:00
|
|
|
platform.getBranchStatus.mockReturnValueOnce('success');
|
2017-10-05 07:31:10 +00:00
|
|
|
config.forcePr = true;
|
|
|
|
const pr = await prWorker.ensurePr(config);
|
|
|
|
expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
|
|
|
|
});
|
2017-06-08 04:18:21 +00:00
|
|
|
it('should return null if branch automerging not failed', async () => {
|
2017-08-21 11:41:48 +00:00
|
|
|
config.automerge = true;
|
2017-06-08 04:18:21 +00:00
|
|
|
config.automergeType = 'branch-push';
|
2017-11-07 10:46:10 +00:00
|
|
|
platform.getBranchStatus.mockReturnValueOnce('pending');
|
2017-08-26 14:10:18 +00:00
|
|
|
const pr = await prWorker.ensurePr(config);
|
2017-06-08 04:18:21 +00:00
|
|
|
expect(pr).toBe(null);
|
|
|
|
});
|
2017-06-22 19:35:32 +00:00
|
|
|
it('handles duplicate upgrades', async () => {
|
2017-07-07 09:45:48 +00:00
|
|
|
config.upgrades.push(config.upgrades[0]);
|
2017-08-26 14:10:18 +00:00
|
|
|
const pr = await prWorker.ensurePr(config);
|
2017-06-22 19:35:32 +00:00
|
|
|
expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
|
|
|
|
});
|
2017-02-14 07:08:40 +00:00
|
|
|
});
|
|
|
|
});
|