| /** |
| * @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.js'; |
| import './gr-related-changes-list.js'; |
| import {GerritNav} from '../../core/gr-navigation/gr-navigation.js'; |
| import {getPluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader.js'; |
| import {_testOnly_initGerritPluginApi} from '../../shared/gr-js-api-interface/gr-gerrit.js'; |
| import {resetPlugins} from '../../../test/test-utils.js'; |
| import {stubRestApi} from '../../../test/test-utils.js'; |
| |
| const pluginApi = _testOnly_initGerritPluginApi(); |
| |
| const basicFixture = fixtureFromElement('gr-related-changes-list'); |
| |
| suite('gr-related-changes-list tests', () => { |
| let element; |
| |
| setup(() => { |
| element = basicFixture.instantiate(); |
| }); |
| |
| test('connected revisions', () => { |
| const change = { |
| revisions: { |
| 'e3c6d60783bfdec9ebae7dcfec4662360433449e': { |
| _number: 1, |
| }, |
| '26e5e4c9c7ae31cbd876271cca281ce22b413997': { |
| _number: 2, |
| }, |
| 'bf7884d695296ca0c91702ba3e2bc8df0f69a907': { |
| _number: 7, |
| }, |
| 'b5fc49f2e67d1889d5275cac04ad3648f2ec7fe3': { |
| _number: 5, |
| }, |
| 'd6bcee67570859ccb684873a85cf50b1f0e96fda': { |
| _number: 6, |
| }, |
| 'cc960918a7f90388f4a9e05753d0f7b90ad44546': { |
| _number: 3, |
| }, |
| '9e593f6dcc2c0785a2ad2c895a34ad2aa9a0d8b6': { |
| _number: 4, |
| }, |
| }, |
| }; |
| let patchNum = 7; |
| let relatedChanges = [ |
| { |
| commit: { |
| commit: '2cebeedfb1e80f4b872d0a13ade529e70652c0c8', |
| parents: [ |
| { |
| commit: '87ed20b241576b620bbaa3dfd47715ce6782b7dd', |
| }, |
| ], |
| }, |
| }, |
| { |
| commit: { |
| commit: '87ed20b241576b620bbaa3dfd47715ce6782b7dd', |
| parents: [ |
| { |
| commit: '6c71f9e86ba955a7e01e2088bce0050a90eb9fbb', |
| }, |
| ], |
| }, |
| }, |
| { |
| commit: { |
| commit: '6c71f9e86ba955a7e01e2088bce0050a90eb9fbb', |
| parents: [ |
| { |
| commit: 'b0ccb183494a8e340b8725a2dc553967d61e6dae', |
| }, |
| ], |
| }, |
| }, |
| { |
| commit: { |
| commit: 'b0ccb183494a8e340b8725a2dc553967d61e6dae', |
| parents: [ |
| { |
| commit: 'bf7884d695296ca0c91702ba3e2bc8df0f69a907', |
| }, |
| ], |
| }, |
| }, |
| { |
| commit: { |
| commit: 'bf7884d695296ca0c91702ba3e2bc8df0f69a907', |
| parents: [ |
| { |
| commit: '613bc4f81741a559c6667ac08d71dcc3348f73ce', |
| }, |
| ], |
| }, |
| }, |
| { |
| commit: { |
| commit: '613bc4f81741a559c6667ac08d71dcc3348f73ce', |
| parents: [ |
| { |
| commit: '455ed9cd27a16bf6991f04dcc57ef575dc4d5e75', |
| }, |
| ], |
| }, |
| }, |
| ]; |
| |
| let connectedChanges = |
| element._computeConnectedRevisions(change, patchNum, relatedChanges); |
| assert.deepEqual(connectedChanges, [ |
| '613bc4f81741a559c6667ac08d71dcc3348f73ce', |
| 'bf7884d695296ca0c91702ba3e2bc8df0f69a907', |
| 'bf7884d695296ca0c91702ba3e2bc8df0f69a907', |
| 'b0ccb183494a8e340b8725a2dc553967d61e6dae', |
| '6c71f9e86ba955a7e01e2088bce0050a90eb9fbb', |
| '87ed20b241576b620bbaa3dfd47715ce6782b7dd', |
| '2cebeedfb1e80f4b872d0a13ade529e70652c0c8', |
| ]); |
| |
| patchNum = 4; |
| relatedChanges = [ |
| { |
| commit: { |
| commit: '2cebeedfb1e80f4b872d0a13ade529e70652c0c8', |
| parents: [ |
| { |
| commit: '87ed20b241576b620bbaa3dfd47715ce6782b7dd', |
| }, |
| ], |
| }, |
| }, |
| { |
| commit: { |
| commit: '87ed20b241576b620bbaa3dfd47715ce6782b7dd', |
| parents: [ |
| { |
| commit: '6c71f9e86ba955a7e01e2088bce0050a90eb9fbb', |
| }, |
| ], |
| }, |
| }, |
| { |
| commit: { |
| commit: '6c71f9e86ba955a7e01e2088bce0050a90eb9fbb', |
| parents: [ |
| { |
| commit: 'b0ccb183494a8e340b8725a2dc553967d61e6dae', |
| }, |
| ], |
| }, |
| }, |
| { |
| commit: { |
| commit: 'a3e5d9d4902b915a39e2efba5577211b9b3ebe7b', |
| parents: [ |
| { |
| commit: '9e593f6dcc2c0785a2ad2c895a34ad2aa9a0d8b6', |
| }, |
| ], |
| }, |
| }, |
| { |
| commit: { |
| commit: '9e593f6dcc2c0785a2ad2c895a34ad2aa9a0d8b6', |
| parents: [ |
| { |
| commit: 'af815dac54318826b7f1fa468acc76349ffc588e', |
| }, |
| ], |
| }, |
| }, |
| { |
| commit: { |
| commit: 'af815dac54318826b7f1fa468acc76349ffc588e', |
| parents: [ |
| { |
| commit: '58f76e406e24cb8b0f5d64c7f5ac1e8616d0a22c', |
| }, |
| ], |
| }, |
| }, |
| ]; |
| |
| connectedChanges = |
| element._computeConnectedRevisions(change, patchNum, relatedChanges); |
| assert.deepEqual(connectedChanges, [ |
| 'af815dac54318826b7f1fa468acc76349ffc588e', |
| '9e593f6dcc2c0785a2ad2c895a34ad2aa9a0d8b6', |
| '9e593f6dcc2c0785a2ad2c895a34ad2aa9a0d8b6', |
| 'a3e5d9d4902b915a39e2efba5577211b9b3ebe7b', |
| ]); |
| }); |
| |
| test('_changesEqual', () => { |
| const change1 = {change_id: 123, _number: 0}; |
| const change2 = {change_id: 456, _number: 1}; |
| const change3 = {change_id: 123, _number: 2}; |
| const change4 = {change_id: 123, _change_number: 1}; |
| |
| assert.isTrue(element._changesEqual(change1, change1)); |
| assert.isFalse(element._changesEqual(change1, change2)); |
| assert.isFalse(element._changesEqual(change1, change3)); |
| assert.isTrue(element._changesEqual(change2, change4)); |
| }); |
| |
| test('_getChangeNumber', () => { |
| const change1 = {change_id: 123, _number: 0}; |
| const change2 = {change_id: 456, _change_number: 1}; |
| assert.equal(element._getChangeNumber(change1), 0); |
| assert.equal(element._getChangeNumber(change2), 1); |
| }); |
| |
| test('event for section loaded fires for each section ', () => { |
| const loadedStub = sinon.stub(); |
| element.patchNum = 7; |
| element.change = { |
| change_id: 123, |
| status: 'NEW', |
| }; |
| element.mergeable = true; |
| element.addEventListener('new-section-loaded', loadedStub); |
| stubRestApi('getRelatedChanges').returns(Promise.resolve({changes: []})); |
| stubRestApi('getChangesSubmittedTogether').returns(Promise.resolve()); |
| stubRestApi('getChangeCherryPicks').returns(Promise.resolve()); |
| stubRestApi('getChangeConflicts').returns(Promise.resolve()); |
| |
| return element.reload().then(() => { |
| assert.equal(loadedStub.callCount, 4); |
| }); |
| }); |
| |
| suite('getChangeConflicts resolves undefined', () => { |
| let element; |
| |
| setup(() => { |
| element = basicFixture.instantiate(); |
| |
| stubRestApi('getRelatedChanges').returns(Promise.resolve({changes: []})); |
| stubRestApi('getChangesSubmittedTogether').returns(Promise.resolve()); |
| stubRestApi('getChangeCherryPicks').returns(Promise.resolve()); |
| stubRestApi('getChangeConflicts').returns(Promise.resolve()); |
| }); |
| |
| test('_conflicts are an empty array', () => { |
| element.patchNum = 7; |
| element.change = { |
| change_id: 123, |
| status: 'NEW', |
| }; |
| element.mergeable = true; |
| element.reload(); |
| assert.equal(element._conflicts.length, 0); |
| }); |
| }); |
| |
| suite('get conflicts tests', () => { |
| let element; |
| let conflictsStub; |
| |
| setup(() => { |
| element = basicFixture.instantiate(); |
| |
| stubRestApi('getRelatedChanges').returns(Promise.resolve({changes: []})); |
| stubRestApi('getChangesSubmittedTogether').returns(Promise.resolve()); |
| stubRestApi('getChangeCherryPicks').returns(Promise.resolve()); |
| conflictsStub = stubRestApi('getChangeConflicts').returns( |
| Promise.resolve()); |
| }); |
| |
| test('request conflicts if open and mergeable', () => { |
| element.patchNum = 7; |
| element.change = { |
| change_id: 123, |
| status: 'NEW', |
| }; |
| element.mergeable = true; |
| element.reload(); |
| assert.isTrue(conflictsStub.called); |
| }); |
| |
| test('does not request conflicts if closed and mergeable', () => { |
| element.patchNum = 7; |
| element.change = { |
| change_id: 123, |
| status: 'MERGED', |
| }; |
| element.reload(); |
| assert.isFalse(conflictsStub.called); |
| }); |
| |
| test('does not request conflicts if open and not mergeable', () => { |
| element.patchNum = 7; |
| element.change = { |
| change_id: 123, |
| status: 'NEW', |
| }; |
| element.mergeable = false; |
| element.reload(); |
| assert.isFalse(conflictsStub.called); |
| }); |
| |
| test('doesnt request conflicts if closed and not mergeable', () => { |
| element.patchNum = 7; |
| element.change = { |
| change_id: 123, |
| status: 'MERGED', |
| }; |
| element.mergeable = false; |
| element.reload(); |
| assert.isFalse(conflictsStub.called); |
| }); |
| }); |
| |
| test('_calculateHasParent', () => { |
| const changeId = 123; |
| const relatedChanges = []; |
| |
| assert.equal(element._calculateHasParent(changeId, relatedChanges), |
| false); |
| |
| relatedChanges.push({change_id: 123}); |
| assert.equal(element._calculateHasParent(changeId, relatedChanges), |
| false); |
| |
| relatedChanges.push({change_id: 234}); |
| assert.equal(element._calculateHasParent(changeId, relatedChanges), |
| true); |
| }); |
| |
| suite('hidden attribute and update event', () => { |
| const changes = [{ |
| project: 'foo/bar', |
| change_id: 'Ideadbeef', |
| commit: { |
| commit: 'deadbeef', |
| parents: [{commit: 'abc123'}], |
| author: {}, |
| subject: 'do that thing', |
| }, |
| _change_number: 12345, |
| _revision_number: 1, |
| _current_revision_number: 1, |
| status: 'NEW', |
| }]; |
| |
| test('clear and empties', () => { |
| element._relatedResponse = {changes}; |
| element._submittedTogether = {changes}; |
| element._conflicts = changes; |
| element._cherryPicks = changes; |
| element._sameTopic = changes; |
| |
| element.hidden = false; |
| element.clear(); |
| assert.isTrue(element.hidden); |
| assert.equal(element._relatedResponse.changes.length, 0); |
| assert.equal(element._submittedTogether.changes.length, 0); |
| assert.equal(element._conflicts.length, 0); |
| assert.equal(element._cherryPicks.length, 0); |
| assert.equal(element._sameTopic.length, 0); |
| }); |
| |
| test('update fires', () => { |
| const updateHandler = sinon.stub(); |
| element.addEventListener('update', updateHandler); |
| |
| element._resultsChanged({}, {}, [], [], []); |
| assert.isTrue(element.hidden); |
| assert.isFalse(updateHandler.called); |
| |
| element._resultsChanged({}, {}, [], [], ['test']); |
| assert.isFalse(element.hidden); |
| assert.isTrue(updateHandler.called); |
| updateHandler.reset(); |
| |
| element._resultsChanged( |
| {}, {changes: [], non_visible_changes: 0}, [], [], []); |
| assert.isTrue(element.hidden); |
| assert.isFalse(updateHandler.called); |
| |
| element._resultsChanged( |
| {}, {changes: ['test'], non_visible_changes: 0}, [], [], []); |
| assert.isFalse(element.hidden); |
| assert.isTrue(updateHandler.called); |
| updateHandler.reset(); |
| |
| element._resultsChanged( |
| {}, {changes: [], non_visible_changes: 1}, [], [], []); |
| assert.isFalse(element.hidden); |
| assert.isTrue(updateHandler.called); |
| }); |
| |
| suite('hiding and unhiding', () => { |
| test('related response', () => { |
| assert.isTrue(element.hidden); |
| element._resultsChanged({changes}, {}, [], [], []); |
| assert.isFalse(element.hidden); |
| }); |
| |
| test('submitted together', () => { |
| assert.isTrue(element.hidden); |
| element._resultsChanged({}, {changes}, [], [], []); |
| assert.isFalse(element.hidden); |
| }); |
| |
| test('conflicts', () => { |
| assert.isTrue(element.hidden); |
| element._resultsChanged({}, {}, changes, [], []); |
| assert.isFalse(element.hidden); |
| }); |
| |
| test('cherrypicks', () => { |
| assert.isTrue(element.hidden); |
| element._resultsChanged({}, {}, [], changes, []); |
| assert.isFalse(element.hidden); |
| }); |
| |
| test('same topic', () => { |
| assert.isTrue(element.hidden); |
| element._resultsChanged({}, {}, [], [], changes); |
| assert.isFalse(element.hidden); |
| }); |
| }); |
| }); |
| |
| test('_computeChangeURL uses GerritNav', () => { |
| const getUrlStub = sinon.stub(GerritNav, 'getUrlForChangeById'); |
| element._computeChangeURL(123, 'abc/def', 12); |
| assert.isTrue(getUrlStub.called); |
| }); |
| |
| suite('submitted together changes', () => { |
| const change = { |
| project: 'foo/bar', |
| change_id: 'Ideadbeef', |
| commit: { |
| commit: 'deadbeef', |
| parents: [{commit: 'abc123'}], |
| author: {}, |
| subject: 'do that thing', |
| }, |
| _change_number: 12345, |
| _revision_number: 1, |
| _current_revision_number: 1, |
| status: 'NEW', |
| }; |
| |
| test('_computeSubmittedTogetherClass', () => { |
| assert.strictEqual( |
| element._computeSubmittedTogetherClass(undefined), |
| 'hidden'); |
| assert.strictEqual( |
| element._computeSubmittedTogetherClass({changes: []}), |
| 'hidden'); |
| assert.strictEqual( |
| element._computeSubmittedTogetherClass({changes: [{}]}), |
| ''); |
| assert.strictEqual( |
| element._computeSubmittedTogetherClass({ |
| changes: [], |
| non_visible_changes: 0, |
| }), |
| 'hidden'); |
| assert.strictEqual( |
| element._computeSubmittedTogetherClass({ |
| changes: [], |
| non_visible_changes: 1, |
| }), |
| ''); |
| assert.strictEqual( |
| element._computeSubmittedTogetherClass({ |
| changes: [{}], |
| non_visible_changes: 1, |
| }), |
| ''); |
| }); |
| |
| test('no submitted together changes', () => { |
| flush(); |
| assert.include(element.$.submittedTogether.className, 'hidden'); |
| }); |
| |
| test('no non-visible submitted together changes', () => { |
| element._submittedTogether = {changes: [change]}; |
| flush(); |
| assert.notInclude(element.$.submittedTogether.className, 'hidden'); |
| assert.isNull(element.shadowRoot |
| .querySelector('.note')); |
| }); |
| |
| test('no visible submitted together changes', () => { |
| // Technically this should never happen, but worth asserting the logic. |
| element._submittedTogether = {changes: [], non_visible_changes: 1}; |
| flush(); |
| assert.notInclude(element.$.submittedTogether.className, 'hidden'); |
| assert.isNotNull(element.shadowRoot |
| .querySelector('.note')); |
| assert.strictEqual( |
| element.shadowRoot |
| .querySelector('.note').innerText.trim(), |
| '(+ 1 non-visible change)'); |
| }); |
| |
| test('visible and non-visible submitted together changes', () => { |
| element._submittedTogether = {changes: [change], non_visible_changes: 2}; |
| flush(); |
| assert.notInclude(element.$.submittedTogether.className, 'hidden'); |
| assert.isNotNull(element.shadowRoot |
| .querySelector('.note')); |
| assert.strictEqual( |
| element.shadowRoot |
| .querySelector('.note').innerText.trim(), |
| '(+ 2 non-visible changes)'); |
| }); |
| }); |
| }); |
| |
| suite('gr-related-changes-list plugin tests', () => { |
| let element; |
| |
| setup(() => { |
| resetPlugins(); |
| element = basicFixture.instantiate(); |
| }); |
| |
| teardown(() => { |
| resetPlugins(); |
| }); |
| |
| test('endpoint params', done => { |
| element.change = {labels: {}}; |
| let hookEl; |
| let plugin; |
| pluginApi.install( |
| p => { |
| plugin = p; |
| plugin.hook('related-changes-section').getLastAttached() |
| .then(el => hookEl = el); |
| }, |
| '0.1', |
| 'http://some/plugins/url1.html'); |
| getPluginLoader().loadPlugins([]); |
| flush(() => { |
| assert.strictEqual(hookEl.plugin, plugin); |
| assert.strictEqual(hookEl.change, element.change); |
| done(); |
| }); |
| }); |
| |
| test('hiding and unhiding', done => { |
| element.change = {labels: {}}; |
| let hookEl; |
| let plugin; |
| |
| // No changes, and no plugin. The element is still hidden. |
| element._resultsChanged({}, {}, [], [], []); |
| assert.isTrue(element.hidden); |
| pluginApi.install( |
| p => { |
| plugin = p; |
| plugin.hook('related-changes-section').getLastAttached() |
| .then(el => hookEl = el); |
| }, |
| '0.1', |
| 'http://some/plugins/url2.html'); |
| getPluginLoader().loadPlugins([]); |
| flush(() => { |
| // No changes, and plugin without hidden attribute. So it's visible. |
| element._resultsChanged({}, {}, [], [], []); |
| assert.isFalse(element.hidden); |
| |
| // No changes, but plugin with true hidden attribute. So it's invisible. |
| hookEl.hidden = true; |
| |
| element._resultsChanged({}, {}, [], [], []); |
| assert.isTrue(element.hidden); |
| |
| // No changes, and plugin with false hidden attribute. So it's visible. |
| hookEl.hidden = false; |
| element._resultsChanged({}, {}, [], [], []); |
| assert.isFalse(element.hidden); |
| |
| // Hiding triggered by plugin itself |
| hookEl.hidden = true; |
| hookEl.dispatchEvent(new CustomEvent('new-section-loaded', { |
| composed: true, bubbles: true, |
| })); |
| assert.isTrue(element.hidden); |
| |
| // Unhiding triggered by plugin itself |
| hookEl.hidden = false; |
| hookEl.dispatchEvent(new CustomEvent('new-section-loaded', { |
| composed: true, bubbles: true, |
| })); |
| assert.isFalse(element.hidden); |
| |
| // Hiding plugin keeps list visible, if there are changes |
| hookEl.hidden = false; |
| element._sameTopic = ['test']; |
| element._resultsChanged({}, {}, [], [], ['test']); |
| assert.isFalse(element.hidden); |
| hookEl.hidden = true; |
| hookEl.dispatchEvent(new CustomEvent('new-section-loaded', { |
| composed: true, bubbles: true, |
| })); |
| assert.isFalse(element.hidden); |
| |
| done(); |
| }); |
| }); |
| }); |
| |