blob: bc000af940d5fd850b43da1a822e3ef63f4b518c [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-rebase-dialog';
import {GrConfirmRebaseDialog, RebaseChange} from './gr-confirm-rebase-dialog';
import {queryAndAssert, stubRestApi, waitUntil} from '../../../test/test-utils';
import * as MockInteractions from '@polymer/iron-test-helpers/mock-interactions';
import {NumericChangeId, BranchName} from '../../../types/common';
import {createChangeViewChange} from '../../../test/test-data-generators';
import {fixture, html} from '@open-wc/testing-helpers';
suite('gr-confirm-rebase-dialog tests', () => {
let element: GrConfirmRebaseDialog;
setup(async () => {
element = await fixture(
html`<gr-confirm-rebase-dialog></gr-confirm-rebase-dialog>`
);
});
test('render', async () => {
element.branch = 'test' as BranchName;
await element.updateComplete;
expect(element).shadowDom.to.equal(/* HTML */ `<gr-dialog
confirm-label="Rebase"
id="confirmDialog"
role="dialog"
>
<div class="header" slot="header">Confirm rebase</div>
<div class="main" slot="main">
<div class="rebaseOption" hidden="" id="rebaseOnParent">
<input id="rebaseOnParentInput" name="rebaseOptions" type="radio" />
<label for="rebaseOnParentInput" id="rebaseOnParentLabel">
Rebase on parent change
</label>
</div>
<div class="message" hidden="" id="parentUpToDateMsg">
This change is up to date with its parent.
</div>
<div class="rebaseOption" hidden="" id="rebaseOnTip">
<input
disabled=""
id="rebaseOnTipInput"
name="rebaseOptions"
type="radio"
/>
<label for="rebaseOnTipInput" id="rebaseOnTipLabel">
Rebase on top of the test branch
<span hidden=""> (breaks relation chain) </span>
</label>
</div>
<div class="message" id="tipUpToDateMsg">
Change is up to date with the target branch already (test)
</div>
<div class="rebaseOption" id="rebaseOnOther">
<input id="rebaseOnOtherInput" name="rebaseOptions" type="radio" />
<label for="rebaseOnOtherInput" id="rebaseOnOtherLabel">
Rebase on a specific change, ref, or commit
<span hidden=""> (breaks relation chain) </span>
</label>
</div>
<div class="parentRevisionContainer">
<gr-autocomplete
allow-non-suggested-values=""
id="parentInput"
no-debounce=""
placeholder="Change number, ref, or commit hash"
>
</gr-autocomplete>
</div>
</div>
</gr-dialog> `);
});
test('controls with parent and rebase on current available', async () => {
element.rebaseOnCurrent = true;
element.hasParent = true;
await element.updateComplete;
assert.isTrue(
queryAndAssert<HTMLInputElement>(element, '#rebaseOnParentInput').checked
);
assert.isFalse(
queryAndAssert(element, '#rebaseOnParent').hasAttribute('hidden')
);
assert.isTrue(
queryAndAssert(element, '#parentUpToDateMsg').hasAttribute('hidden')
);
assert.isFalse(
queryAndAssert(element, '#rebaseOnTip').hasAttribute('hidden')
);
assert.isTrue(
queryAndAssert(element, '#tipUpToDateMsg').hasAttribute('hidden')
);
});
test('controls with parent rebase on current not available', async () => {
element.rebaseOnCurrent = false;
element.hasParent = true;
await element.updateComplete;
assert.isTrue(
queryAndAssert<HTMLInputElement>(element, '#rebaseOnTipInput').checked
);
assert.isTrue(
queryAndAssert(element, '#rebaseOnParent').hasAttribute('hidden')
);
assert.isFalse(
queryAndAssert(element, '#parentUpToDateMsg').hasAttribute('hidden')
);
assert.isFalse(
queryAndAssert(element, '#rebaseOnTip').hasAttribute('hidden')
);
assert.isTrue(
queryAndAssert(element, '#tipUpToDateMsg').hasAttribute('hidden')
);
});
test('controls without parent and rebase on current available', async () => {
element.rebaseOnCurrent = true;
element.hasParent = false;
await element.updateComplete;
assert.isTrue(
queryAndAssert<HTMLInputElement>(element, '#rebaseOnTipInput').checked
);
assert.isTrue(
queryAndAssert(element, '#rebaseOnParent').hasAttribute('hidden')
);
assert.isTrue(
queryAndAssert(element, '#parentUpToDateMsg').hasAttribute('hidden')
);
assert.isFalse(
queryAndAssert(element, '#rebaseOnTip').hasAttribute('hidden')
);
assert.isTrue(
queryAndAssert(element, '#tipUpToDateMsg').hasAttribute('hidden')
);
});
test('controls without parent rebase on current not available', async () => {
element.rebaseOnCurrent = false;
element.hasParent = false;
await element.updateComplete;
assert.isTrue(element.rebaseOnOtherInput.checked);
assert.isTrue(
queryAndAssert(element, '#rebaseOnParent').hasAttribute('hidden')
);
assert.isTrue(
queryAndAssert(element, '#parentUpToDateMsg').hasAttribute('hidden')
);
assert.isTrue(
queryAndAssert(element, '#rebaseOnTip').hasAttribute('hidden')
);
assert.isFalse(
queryAndAssert(element, '#tipUpToDateMsg').hasAttribute('hidden')
);
});
test('input cleared on cancel or submit', async () => {
element.text = '123';
await element.updateComplete;
queryAndAssert(element, '#confirmDialog').dispatchEvent(
new CustomEvent('confirm', {
composed: true,
bubbles: true,
})
);
assert.equal(element.text, '');
element.text = '123';
await element.updateComplete;
queryAndAssert(element, '#confirmDialog').dispatchEvent(
new CustomEvent('cancel', {
composed: true,
bubbles: true,
})
);
assert.equal(element.text, '');
});
test('_getSelectedBase', async () => {
element.text = '5fab321c';
await element.updateComplete;
queryAndAssert<HTMLInputElement>(element, '#rebaseOnParentInput').checked =
true;
assert.equal(element.getSelectedBase(), null);
queryAndAssert<HTMLInputElement>(element, '#rebaseOnParentInput').checked =
false;
queryAndAssert<HTMLInputElement>(element, '#rebaseOnTipInput').checked =
true;
assert.equal(element.getSelectedBase(), '');
queryAndAssert<HTMLInputElement>(element, '#rebaseOnTipInput').checked =
false;
assert.equal(element.getSelectedBase(), element.text);
element.text = '101: Test';
await element.updateComplete;
assert.equal(element.getSelectedBase(), '101');
});
suite('parent suggestions', () => {
let recentChanges: RebaseChange[];
let getChangesStub: sinon.SinonStub;
setup(() => {
recentChanges = [
{
name: '123: my first awesome change',
value: 123 as NumericChangeId,
},
{
name: '124: my second awesome change',
value: 124 as NumericChangeId,
},
{
name: '245: my third awesome change',
value: 245 as NumericChangeId,
},
];
getChangesStub = stubRestApi('getChanges').returns(
Promise.resolve([
{
...createChangeViewChange(),
_number: 123 as NumericChangeId,
subject: 'my first awesome change',
},
{
...createChangeViewChange(),
_number: 124 as NumericChangeId,
subject: 'my second awesome change',
},
{
...createChangeViewChange(),
_number: 245 as NumericChangeId,
subject: 'my third awesome change',
},
])
);
});
test('_getRecentChanges', async () => {
const recentChangesSpy = sinon.spy(element, 'getRecentChanges');
await element.getRecentChanges();
await element.updateComplete;
assert.deepEqual(element.recentChanges, recentChanges);
assert.equal(getChangesStub.callCount, 1);
// When called a second time, should not re-request recent changes.
await element.getRecentChanges();
await element.updateComplete;
assert.equal(recentChangesSpy.callCount, 2);
assert.equal(getChangesStub.callCount, 1);
});
test('_filterChanges', async () => {
assert.equal(element.filterChanges('123', recentChanges).length, 1);
assert.equal(element.filterChanges('12', recentChanges).length, 2);
assert.equal(element.filterChanges('awesome', recentChanges).length, 3);
assert.equal(element.filterChanges('third', recentChanges).length, 1);
element.changeNumber = 123 as NumericChangeId;
await element.updateComplete;
assert.equal(element.filterChanges('123', recentChanges).length, 0);
assert.equal(element.filterChanges('124', recentChanges).length, 1);
assert.equal(element.filterChanges('awesome', recentChanges).length, 2);
});
test('input text change triggers function', async () => {
const recentChangesSpy = sinon.spy(element, 'getRecentChanges');
element.parentInput.noDebounce = true;
MockInteractions.pressAndReleaseKeyOn(
queryAndAssert(queryAndAssert(element, '#parentInput'), '#input'),
13,
null,
'enter'
);
await element.updateComplete;
element.text = '1';
await waitUntil(() => recentChangesSpy.calledOnce);
element.text = '12';
await waitUntil(() => recentChangesSpy.calledTwice);
});
});
});