| /** |
| * @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. |
| */ |
| |
| import '../../../test/common-test-setup-karma.js'; |
| import './gr-apply-fix-dialog.js'; |
| import {GerritNav} from '../../core/gr-navigation/gr-navigation.js'; |
| |
| const basicFixture = fixtureFromElement('gr-apply-fix-dialog'); |
| |
| suite('gr-apply-fix-dialog tests', () => { |
| let element; |
| |
| 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(() => { |
| element = basicFixture.instantiate(); |
| 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, |
| }; |
| }); |
| |
| suite('dialog open', () => { |
| setup(() => { |
| sinon.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'], |
| }, |
| ], |
| }, |
| })); |
| sinon.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 => { |
| sinon.stub(element.$.restAPI, 'getRobotCommentFixPreview') |
| .returns(Promise.resolve({})); |
| sinon.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 => { |
| sinon.stub(window, 'fetch').callsFake((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 => { |
| sinon.stub(element.$.restAPI, 'applyFixSuggestion') |
| .returns(Promise.resolve({ok: true})); |
| sinon.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 => { |
| sinon.stub(element.$.restAPI, 'applyFixSuggestion') |
| .returns(Promise.resolve({})); |
| sinon.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 => { |
| sinon.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'], |
| }, |
| ], |
| }, |
| })); |
| sinon.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 => { |
| sinon.stub(window, 'fetch').callsFake((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); |
| sinon.stub(GerritNav, 'navigateToChange'); |
| element._currentFix = {fix_id: '123'}; |
| element._handleApplyFix(); |
| flush(() => { |
| assert.isFalse(GerritNav.navigateToChange.called); |
| assert.isTrue(errorStub.called); |
| done(); |
| }); |
| }); |
| }); |
| |