blob: 45e13b2628de69ff6018895c69cb37fb1ba2599e [file] [log] [blame]
/**
* @license
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import '../../../test/common-test-setup-karma';
import './gr-confirm-cherrypick-dialog';
import {queryAll, queryAndAssert, stubRestApi} from '../../../test/test-utils';
import {GrConfirmCherrypickDialog} from './gr-confirm-cherrypick-dialog';
import {
BranchName,
ChangeId,
ChangeInfo,
ChangeInfoId,
ChangeStatus,
CommitId,
GitRef,
HttpMethod,
NumericChangeId,
RepoName,
TopicName,
} from '../../../api/rest-api';
import {createChange, createRevision} from '../../../test/test-data-generators';
import {GrDialog} from '../../shared/gr-dialog/gr-dialog.js';
import * as MockInteractions from '@polymer/iron-test-helpers/mock-interactions';
import {ProgressStatus} from '../../../constants/constants';
import {fixture, html} from '@open-wc/testing-helpers';
const CHERRY_PICK_TYPES = {
SINGLE_CHANGE: 1,
TOPIC: 2,
};
suite('gr-confirm-cherrypick-dialog tests', () => {
let element: GrConfirmCherrypickDialog;
setup(async () => {
stubRestApi('getRepoBranches').callsFake(input => {
if (input.startsWith('test')) {
return Promise.resolve([
{
ref: 'refs/heads/test-branch' as GitRef,
revision: '67ebf73496383c6777035e374d2d664009e2aa5c',
can_delete: true,
},
]);
} else {
return Promise.resolve([]);
}
});
element = await fixture(
html`<gr-confirm-cherrypick-dialog></gr-confirm-cherrypick-dialog>`
);
element.project = 'test-project' as RepoName;
});
test('with message missing newline', async () => {
element.changeStatus = ChangeStatus.MERGED;
element.commitMessage = 'message';
element.commitNum = '123' as CommitId;
element.branch = 'master' as BranchName;
await element.updateComplete;
const expectedMessage = 'message\n(cherry picked from commit 123)';
assert.equal(element.message, expectedMessage);
});
test('with merged change', async () => {
element.changeStatus = ChangeStatus.MERGED;
element.commitMessage = 'message\n';
element.commitNum = '123' as CommitId;
element.branch = 'master' as BranchName;
await element.updateComplete;
const expectedMessage = 'message\n(cherry picked from commit 123)';
assert.equal(element.message, expectedMessage);
});
test('with unmerged change', async () => {
element.changeStatus = ChangeStatus.NEW;
element.commitMessage = 'message\n';
element.commitNum = '123' as CommitId;
element.branch = 'master' as BranchName;
await element.updateComplete;
const expectedMessage = 'message\n';
assert.equal(element.message, expectedMessage);
});
test('with updated commit message', async () => {
element.changeStatus = ChangeStatus.NEW;
element.commitMessage = 'message\n';
element.commitNum = '123' as CommitId;
element.branch = 'master' as BranchName;
await element.updateComplete;
const myNewMessage = 'updated commit message';
element.message = myNewMessage;
await element.updateComplete;
assert.equal(element.message, myNewMessage);
});
test('getProjectBranchesSuggestions empty', async () => {
const branches = await element.getProjectBranchesSuggestions('asdf');
assert.isEmpty(branches);
});
suite('cherry pick topic', () => {
const changes: ChangeInfo[] = [
{
...createChange(),
id: '1234' as ChangeInfoId,
change_id: '12345678901234' as ChangeId,
topic: 'T' as TopicName,
subject: 'random',
project: 'A' as RepoName,
_number: 1 as NumericChangeId,
revisions: {
a: createRevision(),
},
current_revision: 'a' as CommitId,
},
{
...createChange(),
id: '5678' as ChangeInfoId,
change_id: '23456' as ChangeId,
topic: 'T' as TopicName,
subject: 'a'.repeat(100),
project: 'B' as RepoName,
_number: 2 as NumericChangeId,
revisions: {
a: createRevision(),
},
current_revision: 'a' as CommitId,
},
];
setup(async () => {
element.updateChanges(changes);
element.cherryPickType = CHERRY_PICK_TYPES.TOPIC;
await element.updateComplete;
});
test('cherry pick topic submit', async () => {
element.branch = 'master' as BranchName;
await element.updateComplete;
const executeChangeActionStub = stubRestApi(
'executeChangeAction'
).returns(Promise.resolve(new Response()));
queryAndAssert<GrDialog>(element, 'gr-dialog').confirmButton!.click();
await element.updateComplete;
const args = executeChangeActionStub.args[0];
assert.equal(args[0], 1);
assert.equal(args[1], 'POST' as HttpMethod);
assert.equal(args[2], '/cherrypick');
assert.equal((args[4] as any).destination, 'master');
assert.isTrue((args[4] as any).allow_conflicts);
assert.isTrue((args[4] as any).allow_empty);
});
test('deselecting a change removes it from being cherry picked', async () => {
const duplicateChangesStub = sinon.stub(
element,
'containsDuplicateProject'
);
element.branch = 'master' as BranchName;
await element.updateComplete;
const executeChangeActionStub = stubRestApi(
'executeChangeAction'
).returns(Promise.resolve(new Response()));
const checkboxes = queryAll<HTMLInputElement>(
element,
'input[type="checkbox"]'
);
assert.equal(checkboxes.length, 2);
assert.isTrue(checkboxes[0].checked);
MockInteractions.tap(checkboxes[0]);
queryAndAssert<GrDialog>(element, 'gr-dialog').confirmButton!.click();
await element.updateComplete;
assert.equal(executeChangeActionStub.callCount, 1);
assert.isTrue(duplicateChangesStub.called);
});
test('deselecting all change shows error message', async () => {
element.branch = 'master' as BranchName;
await element.updateComplete;
const executeChangeActionStub = stubRestApi(
'executeChangeAction'
).returns(Promise.resolve(new Response()));
const checkboxes = queryAll<HTMLInputElement>(
element,
'input[type="checkbox"]'
);
assert.equal(checkboxes.length, 2);
MockInteractions.tap(checkboxes[0]);
MockInteractions.tap(checkboxes[1]);
MockInteractions.tap(
queryAndAssert<GrDialog>(element, 'gr-dialog').confirmButton!
);
await element.updateComplete;
assert.equal(executeChangeActionStub.callCount, 0);
assert.equal(
queryAndAssert<HTMLElement>(element, '.error-message').innerText,
'No change selected'
);
});
test('computeStatusClass', async () => {
assert.equal(
element.computeStatusClass(
{...createChange(), id: '1' as ChangeInfoId},
{1: {status: ProgressStatus.RUNNING}}
),
''
);
assert.equal(
element.computeStatusClass(
{...createChange(), id: '1' as ChangeInfoId},
{1: {status: ProgressStatus.FAILED}}
),
'error'
);
});
test('submit button is blocked while cherry picks is running', async () => {
const confirmButton = queryAndAssert<GrDialog>(
element,
'gr-dialog'
).confirmButton;
assert.isTrue(confirmButton!.hasAttribute('disabled'));
element.branch = 'b' as BranchName;
await element.updateComplete;
assert.isFalse(confirmButton!.hasAttribute('disabled'));
element.updateStatus(changes[0], {status: ProgressStatus.RUNNING});
await element.updateComplete;
assert.isTrue(confirmButton!.hasAttribute('disabled'));
});
});
test('resetFocus', async () => {
const focusStub = sinon.stub(element.branchInput, 'focus');
element.resetFocus();
await element.updateComplete;
assert.isTrue(focusStub.called);
});
test('getProjectBranchesSuggestions non-empty', async () => {
const branches = await element.getProjectBranchesSuggestions('test-branch');
assert.equal(branches.length, 1);
assert.equal(branches[0].name, 'test-branch');
});
});