| <!DOCTYPE html> |
| <!-- |
| @license |
| Copyright (C) 2019 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. |
| --> |
| <meta name='viewport' content='width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes'> |
| <title>gr-apply-fix-dialog</title> |
| <script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script> |
| |
| <script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script> |
| <script src="/components/wct-browser-legacy/browser.js"></script> |
| <script type="module"> |
| import '../../../test/common-test-setup.js'; |
| import '../../../test/common-test-setup.js'; |
| import './gr-apply-fix-dialog.js'; |
| void (0); |
| </script> |
| |
| <test-fixture id='basic'> |
| <template> |
| <gr-apply-fix-dialog></gr-apply-fix-dialog> |
| </template> |
| </test-fixture> |
| |
| <script type="module"> |
| import '../../../test/common-test-setup.js'; |
| import '../../../test/common-test-setup.js'; |
| import './gr-apply-fix-dialog.js'; |
| import {GerritNav} from '../../core/gr-navigation/gr-navigation.js'; |
| |
| suite('gr-apply-fix-dialog tests', () => { |
| let element; |
| let sandbox; |
| const ROBOT_COMMENT_WITH_TWO_FIXES = { |
| robot_id: 'robot_1', |
| fix_suggestions: [{fix_id: 'fix_1'}, {fix_id: 'fix_2'}], |
| }; |
| |
| const ROBOT_COMMENT_WITH_ONE_FIX = { |
| robot_id: 'robot_1', |
| fix_suggestions: [{fix_id: 'fix_1'}], |
| }; |
| |
| setup(() => { |
| sandbox = sinon.sandbox.create(); |
| element = fixture('basic'); |
| element.changeNum = '1'; |
| element._patchNum = 2; |
| element.change = { |
| _number: '1', |
| project: 'project', |
| revisions: { |
| abcd: {_number: 1}, |
| efgh: {_number: 2}, |
| }, |
| current_revision: 'efgh', |
| }; |
| element.prefs = { |
| font_size: 12, |
| line_length: 100, |
| tab_size: 4, |
| }; |
| }); |
| |
| teardown(() => { |
| sandbox.restore(); |
| }); |
| |
| suite('dialog open', () => { |
| setup(() => { |
| sandbox.stub(element.$.restAPI, 'getRobotCommentFixPreview') |
| .returns(Promise.resolve({ |
| f1: { |
| meta_a: {}, |
| meta_b: {}, |
| content: [ |
| { |
| ab: ['loqlwkqll'], |
| }, |
| { |
| b: ['qwqqsqw'], |
| }, |
| { |
| ab: ['qwqqsqw', 'qweqeqweqeq', 'qweqweq'], |
| }, |
| ], |
| }, |
| f2: { |
| meta_a: {}, |
| meta_b: {}, |
| content: [ |
| { |
| ab: ['eqweqweqwex'], |
| }, |
| { |
| b: ['zassdasd'], |
| }, |
| { |
| ab: ['zassdasd', 'dasdasda', 'asdasdad'], |
| }, |
| ], |
| }, |
| })); |
| sandbox.stub(element.$.applyFixOverlay, 'open') |
| .returns(Promise.resolve()); |
| }); |
| |
| test('dialog opens fetch and sets previews', done => { |
| element.open({detail: {patchNum: 2, |
| comment: ROBOT_COMMENT_WITH_TWO_FIXES}}) |
| .then(() => { |
| assert.equal(element._currentFix.fix_id, 'fix_1'); |
| assert.equal(element._currentPreviews.length, 2); |
| assert.equal(element._robotId, 'robot_1'); |
| const button = element.shadowRoot.querySelector( |
| '#applyFixDialog').shadowRoot.querySelector('#confirm'); |
| assert.isFalse(button.hasAttribute('disabled')); |
| assert.equal(button.getAttribute('title'), ''); |
| done(); |
| }); |
| }); |
| |
| test('tooltip is hidden if apply fix is loading', done => { |
| element.open({detail: {patchNum: 2, |
| comment: ROBOT_COMMENT_WITH_TWO_FIXES}}) |
| .then(() => { |
| element._isApplyFixLoading = true; |
| const button = element.shadowRoot.querySelector( |
| '#applyFixDialog').shadowRoot.querySelector('#confirm'); |
| assert.isTrue(button.hasAttribute('disabled')); |
| assert.equal(button.getAttribute('title'), ''); |
| done(); |
| }); |
| }); |
| |
| test('apply fix button is disabled on older patchset', done => { |
| element.change = { |
| _number: '1', |
| project: 'project', |
| revisions: { |
| abcd: {_number: 1}, |
| efgh: {_number: 2}, |
| }, |
| current_revision: 'abcd', |
| }; |
| element.open({detail: {patchNum: 2, |
| comment: ROBOT_COMMENT_WITH_ONE_FIX}}) |
| .then(() => { |
| flush(() => { |
| const button = element.shadowRoot.querySelector( |
| '#applyFixDialog').shadowRoot.querySelector('#confirm'); |
| assert.isTrue(button.hasAttribute('disabled')); |
| assert.equal(button.getAttribute('title'), |
| 'Fix can only be applied to the latest patchset'); |
| done(); |
| }); |
| }); |
| }); |
| }); |
| |
| test('next button state updated when suggestions changed', done => { |
| sandbox.stub(element.$.restAPI, 'getRobotCommentFixPreview') |
| .returns(Promise.resolve({})); |
| sandbox.stub(element.$.applyFixOverlay, 'open').returns(Promise.resolve()); |
| |
| element.open({detail: {patchNum: 2, comment: ROBOT_COMMENT_WITH_ONE_FIX}}) |
| .then(() => assert.isTrue(element.$.nextFix.disabled)) |
| .then(() => |
| element.open({detail: {patchNum: 2, |
| comment: ROBOT_COMMENT_WITH_TWO_FIXES}})) |
| .then(() => { |
| assert.isFalse(element.$.nextFix.disabled); |
| done(); |
| }); |
| }); |
| |
| test('preview endpoint throws error should reset dialog', done => { |
| sandbox.stub(window, 'fetch', (url => { |
| if (url.endsWith('/preview')) { |
| return Promise.reject(new Error('backend error')); |
| } |
| return Promise.resolve({ |
| ok: true, |
| text() { return Promise.resolve(''); }, |
| status: 200, |
| }); |
| })); |
| const errorStub = sinon.stub(); |
| document.addEventListener('network-error', errorStub); |
| element.open({detail: {patchNum: 2, |
| comment: ROBOT_COMMENT_WITH_TWO_FIXES}}); |
| flush(() => { |
| assert.isTrue(errorStub.called); |
| assert.deepEqual(element._currentFix, {}); |
| done(); |
| }); |
| }); |
| |
| test('apply fix button should call apply ' + |
| 'and navigate to change view', done => { |
| sandbox.stub(element.$.restAPI, 'applyFixSuggestion') |
| .returns(Promise.resolve({ok: true})); |
| sandbox.stub(GerritNav, 'navigateToChange'); |
| element._currentFix = {fix_id: '123'}; |
| |
| element._handleApplyFix().then(() => { |
| assert.isTrue(element.$.restAPI.applyFixSuggestion |
| .calledWithExactly('1', 2, '123')); |
| assert.isTrue(GerritNav.navigateToChange.calledWithExactly({ |
| _number: '1', |
| project: 'project', |
| revisions: { |
| abcd: {_number: 1}, |
| efgh: {_number: 2}, |
| }, |
| current_revision: 'efgh', |
| }, 'edit', 2)); |
| |
| // reset gr-apply-fix-dialog and close |
| assert.deepEqual(element._currentFix, {}); |
| assert.equal(element._currentPreviews.length, 0); |
| done(); |
| }); |
| }); |
| |
| test('should not navigate to change view if incorect reponse', done => { |
| sandbox.stub(element.$.restAPI, 'applyFixSuggestion') |
| .returns(Promise.resolve({})); |
| sandbox.stub(GerritNav, 'navigateToChange'); |
| element._currentFix = {fix_id: '123'}; |
| |
| element._handleApplyFix().then(() => { |
| assert.isTrue(element.$.restAPI.applyFixSuggestion |
| .calledWithExactly('1', 2, '123')); |
| assert.isTrue(GerritNav.navigateToChange.notCalled); |
| |
| assert.equal(element._isApplyFixLoading, false); |
| done(); |
| }); |
| }); |
| |
| test('select fix forward and back of multiple suggested fixes', done => { |
| sandbox.stub(element.$.restAPI, 'getRobotCommentFixPreview') |
| .returns(Promise.resolve({ |
| f1: { |
| meta_a: {}, |
| meta_b: {}, |
| content: [ |
| { |
| ab: ['loqlwkqll'], |
| }, |
| { |
| b: ['qwqqsqw'], |
| }, |
| { |
| ab: ['qwqqsqw', 'qweqeqweqeq', 'qweqweq'], |
| }, |
| ], |
| }, |
| f2: { |
| meta_a: {}, |
| meta_b: {}, |
| content: [ |
| { |
| ab: ['eqweqweqwex'], |
| }, |
| { |
| b: ['zassdasd'], |
| }, |
| { |
| ab: ['zassdasd', 'dasdasda', 'asdasdad'], |
| }, |
| ], |
| }, |
| })); |
| sandbox.stub(element.$.applyFixOverlay, 'open').returns(Promise.resolve()); |
| |
| element.open({detail: {patchNum: 2, comment: ROBOT_COMMENT_WITH_TWO_FIXES}}) |
| .then(() => { |
| element._onNextFixClick(); |
| assert.equal(element._currentFix.fix_id, 'fix_2'); |
| element._onPrevFixClick(); |
| assert.equal(element._currentFix.fix_id, 'fix_1'); |
| done(); |
| }); |
| }); |
| |
| test('server-error should throw for failed apply call', done => { |
| sandbox.stub(window, 'fetch', (url => { |
| if (url.endsWith('/apply')) { |
| return Promise.reject(new Error('backend error')); |
| } |
| return Promise.resolve({ |
| ok: true, |
| text() { return Promise.resolve(''); }, |
| status: 200, |
| }); |
| })); |
| const errorStub = sinon.stub(); |
| document.addEventListener('network-error', errorStub); |
| sandbox.stub(GerritNav, 'navigateToChange'); |
| element._currentFix = {fix_id: '123'}; |
| element._handleApplyFix(); |
| flush(() => { |
| assert.isFalse(GerritNav.navigateToChange.called); |
| assert.isTrue(errorStub.called); |
| done(); |
| }); |
| }); |
| }); |
| </script> |