| <!DOCTYPE html> |
| <!-- |
| Copyright (C) 2017 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-project-detail-list</title> |
| |
| <script src="../../../bower_components/page/page.js"></script> |
| <script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script> |
| <script src="../../../bower_components/web-component-tester/browser.js"></script> |
| <link rel="import" href="../../../test/common-test-setup.html"/> |
| <link rel="import" href="gr-project-detail-list.html"> |
| |
| <script>void(0);</script> |
| |
| <test-fixture id="basic"> |
| <template> |
| <gr-project-detail-list></gr-project-detail-list> |
| </template> |
| </test-fixture> |
| |
| <script> |
| let counter; |
| const branchGenerator = () => { |
| return { |
| ref: `refs/heads/test${++counter}`, |
| revision: '9c9d08a438e55e52f33b608415e6dddd9b18550d', |
| web_links: [ |
| { |
| name: 'diffusion', |
| url: `https://git.example.org/branch/test;refs/heads/test${counter}`, |
| }, |
| ], |
| }; |
| }; |
| const tagGenerator = () => { |
| return { |
| ref: `refs/tags/test${++counter}`, |
| revision: '9c9d08a438e55e52f33b608415e6dddd9b18550d', |
| web_links: [ |
| { |
| name: 'diffusion', |
| url: `https://git.example.org/tag/test;refs/tags/test${counter}`, |
| }, |
| ], |
| }; |
| }; |
| |
| suite('Branches', () => { |
| let element; |
| let branches; |
| let sandbox; |
| |
| setup(() => { |
| sandbox = sinon.sandbox.create(); |
| element = fixture('basic'); |
| element.detailType = 'branches'; |
| counter = 0; |
| sandbox.stub(page, 'show'); |
| }); |
| |
| teardown(() => { |
| sandbox.restore(); |
| }); |
| |
| suite('list of project branches', () => { |
| setup(done => { |
| branches = [{ |
| ref: 'HEAD', |
| revision: 'master', |
| }].concat(_.times(25, branchGenerator)); |
| |
| stub('gr-rest-api-interface', { |
| getProjectBranches(num, project, offset) { |
| return Promise.resolve(branches); |
| }, |
| }); |
| |
| const params = { |
| project: 'test', |
| detailType: 'branches', |
| }; |
| |
| element._paramsChanged(params).then(() => { flush(done); }); |
| }); |
| |
| test('test for branch in the list', done => { |
| flush(() => { |
| assert.equal(element._items[2].ref, 'refs/heads/test2'); |
| done(); |
| }); |
| }); |
| |
| test('test for web links in the branches list', done => { |
| flush(() => { |
| assert.equal(element._items[2].web_links[0].url, |
| 'https://git.example.org/branch/test;refs/heads/test2'); |
| done(); |
| }); |
| }); |
| |
| test('test for refs/heads/ being striped from ref', done => { |
| flush(() => { |
| assert.equal(element._stripRefs(element._items[2].ref, |
| element.detailType), 'test2'); |
| done(); |
| }); |
| }); |
| |
| test('_shownItems', () => { |
| assert.equal(element._shownItems.length, 25); |
| }); |
| |
| test('Edit HEAD button not admin', done => { |
| sandbox.stub(element, '_getLoggedIn').returns(Promise.resolve(true)); |
| sandbox.stub(element.$.restAPI, 'getProjectAccess').returns( |
| Promise.resolve({ |
| test: {is_owner: false}, |
| })); |
| element._determineIfOwner('test').then(() => { |
| assert.equal(element._isOwner, false); |
| assert.equal(getComputedStyle(Polymer.dom(element.root) |
| .querySelector('.revisionNoEditing')).display, 'inline'); |
| assert.equal(getComputedStyle(Polymer.dom(element.root) |
| .querySelector('.revisionEdit')).display, 'none'); |
| done(); |
| }); |
| }); |
| |
| test('Edit HEAD button admin', done => { |
| const saveBtn = Polymer.dom(element.root).querySelector('.saveBtn'); |
| const cancelBtn = Polymer.dom(element.root).querySelector('.cancelBtn'); |
| const editBtn = Polymer.dom(element.root).querySelector('.editBtn'); |
| const revisionNoEditing = Polymer.dom(element.root) |
| .querySelector('.revisionNoEditing'); |
| const revisionWithEditing = Polymer.dom(element.root) |
| .querySelector('.revisionWithEditing'); |
| |
| sandbox.stub(element, '_getLoggedIn').returns(Promise.resolve(true)); |
| sandbox.stub(element.$.restAPI, 'getProjectAccess').returns( |
| Promise.resolve({ |
| test: {is_owner: true}, |
| })); |
| sandbox.stub(element, '_handleSaveRevision'); |
| element._determineIfOwner('test').then(() => { |
| assert.equal(element._isOwner, true); |
| // The revision container for non-editing enabled row is not visible. |
| assert.equal(getComputedStyle(revisionNoEditing).display, 'none'); |
| |
| // The revision container for editing enabled row is visible. |
| assert.notEqual(getComputedStyle(Polymer.dom(element.root) |
| .querySelector('.revisionEdit')).display, 'none'); |
| |
| // The revision and edit button are visible. |
| assert.notEqual(getComputedStyle(revisionWithEditing).display, |
| 'none'); |
| assert.notEqual(getComputedStyle(editBtn).display, 'none'); |
| |
| // The input, cancel, and save buttons are not visible. |
| const hiddenElements = Polymer.dom(element.root) |
| .querySelectorAll('.canEdit .editItem'); |
| |
| for (const item of hiddenElements) { |
| assert.equal(getComputedStyle(item).display, 'none'); |
| } |
| |
| MockInteractions.tap(editBtn); |
| flushAsynchronousOperations(); |
| // The revision and edit button are not visible. |
| assert.equal(getComputedStyle(revisionWithEditing).display, 'none'); |
| assert.equal(getComputedStyle(editBtn).display, 'none'); |
| |
| // The input, cancel, and save buttons are not visible. |
| for (item of hiddenElements) { |
| assert.notEqual(getComputedStyle(item).display, 'none'); |
| } |
| |
| // The revised ref was set correctly |
| assert.equal(element._revisedRef, 'master'); |
| |
| assert.isFalse(saveBtn.disabled); |
| |
| // Delete the ref. |
| element._revisedRef = ''; |
| assert.isTrue(saveBtn.disabled); |
| |
| // Change the ref to something else |
| element._revisedRef = 'newRef'; |
| element._project = 'test'; |
| assert.isFalse(saveBtn.disabled); |
| |
| // Save button calls handleSave. since this is stubbed, the edit |
| // section remains open. |
| MockInteractions.tap(saveBtn); |
| assert.isTrue(element._handleSaveRevision.called); |
| |
| // When cancel is tapped, the edit secion closes. |
| MockInteractions.tap(cancelBtn); |
| flushAsynchronousOperations(); |
| |
| // The revision and edit button are visible. |
| assert.notEqual(getComputedStyle(revisionWithEditing).display, |
| 'none'); |
| assert.notEqual(getComputedStyle(editBtn).display, 'none'); |
| |
| // The input, cancel, and save buttons are not visible. |
| for (const item of hiddenElements) { |
| assert.equal(getComputedStyle(item).display, 'none'); |
| } |
| done(); |
| }); |
| }); |
| |
| test('_handleSaveRevision with invalid rev', done => { |
| const event = {model: {set: sandbox.stub()}}; |
| element._isEditing = true; |
| sandbox.stub(element.$.restAPI, 'setProjectHead').returns( |
| Promise.resolve({ |
| status: 400, |
| }) |
| ); |
| |
| element._setProjectHead('test', 'newRef', event).then(() => { |
| assert.isTrue(element._isEditing); |
| assert.isFalse(event.model.set.called); |
| done(); |
| }); |
| }); |
| |
| test('_handleSaveRevision with valid rev', done => { |
| const event = {model: {set: sandbox.stub()}}; |
| element._isEditing = true; |
| sandbox.stub(element.$.restAPI, 'setProjectHead').returns( |
| Promise.resolve({ |
| status: 200, |
| }) |
| ); |
| |
| element._setProjectHead('test', 'newRef', event).then(() => { |
| assert.isFalse(element._isEditing); |
| assert.isTrue(event.model.set.called); |
| done(); |
| }); |
| }); |
| |
| test('test _computeItemName', () => { |
| assert.deepEqual(element._computeItemName('branches'), 'Branch'); |
| assert.deepEqual(element._computeItemName('tags'), 'Tag'); |
| }); |
| }); |
| |
| suite('list with less then 25 branches', () => { |
| setup(done => { |
| branches = _.times(25, branchGenerator); |
| |
| stub('gr-rest-api-interface', { |
| getProjectBranches(num, project, offset) { |
| return Promise.resolve(branches); |
| }, |
| }); |
| |
| const params = { |
| project: 'test', |
| detailType: 'branches', |
| }; |
| |
| element._paramsChanged(params).then(() => { flush(done); }); |
| }); |
| |
| test('_shownProjectsBranches', () => { |
| assert.equal(element._shownItems.length, 25); |
| }); |
| }); |
| |
| suite('filter', () => { |
| test('_paramsChanged', done => { |
| sandbox.stub(element.$.restAPI, 'getProjectBranches', () => { |
| return Promise.resolve(branches); |
| }); |
| const params = { |
| detailType: 'branches', |
| project: 'test', |
| filter: 'test', |
| offset: 25, |
| }; |
| element._paramsChanged(params).then(() => { |
| assert.isTrue(element.$.restAPI.getProjectBranches.lastCall |
| .calledWithExactly('test', 'test', 25, 25)); |
| done(); |
| }); |
| }); |
| }); |
| }); |
| |
| suite('Tags', () => { |
| let element; |
| let tags; |
| let sandbox; |
| |
| setup(() => { |
| sandbox = sinon.sandbox.create(); |
| element = fixture('basic'); |
| element.detailType = 'tags'; |
| counter = 0; |
| sandbox.stub(page, 'show'); |
| }); |
| |
| teardown(() => { |
| sandbox.restore(); |
| }); |
| |
| suite('list of project tags', () => { |
| setup(done => { |
| tags = _.times(26, tagGenerator); |
| |
| stub('gr-rest-api-interface', { |
| getProjectTags(num, project, offset) { |
| return Promise.resolve(tags); |
| }, |
| }); |
| |
| const params = { |
| project: 'test', |
| detailType: 'tags', |
| }; |
| |
| element._paramsChanged(params).then(() => { flush(done); }); |
| }); |
| |
| test('test for tag in the list', done => { |
| flush(() => { |
| assert.equal(element._items[1].ref, 'refs/tags/test2'); |
| done(); |
| }); |
| }); |
| |
| test('test for web links in the tags list', done => { |
| flush(() => { |
| assert.equal(element._items[1].web_links[0].url, |
| 'https://git.example.org/tag/test;refs/tags/test2'); |
| done(); |
| }); |
| }); |
| |
| test('test for refs/tags/ being striped from ref', done => { |
| flush(() => { |
| assert.equal(element._stripRefs(element._items[1].ref, |
| element.detailType), 'test2'); |
| done(); |
| }); |
| }); |
| |
| test('_shownItems', () => { |
| assert.equal(element._shownItems.length, 25); |
| }); |
| }); |
| |
| suite('list with less then 25 tags', () => { |
| setup(done => { |
| tags = _.times(25, tagGenerator); |
| |
| stub('gr-rest-api-interface', { |
| getProjectTags(num, project, offset) { |
| return Promise.resolve(tags); |
| }, |
| }); |
| |
| const params = { |
| project: 'test', |
| detailType: 'tags', |
| }; |
| |
| element._paramsChanged(params).then(() => { flush(done); }); |
| }); |
| |
| test('_shownItems', () => { |
| assert.equal(element._shownItems.length, 25); |
| }); |
| }); |
| |
| suite('filter', () => { |
| test('_paramsChanged', done => { |
| sandbox.stub(element.$.restAPI, 'getProjectTags', () => { |
| return Promise.resolve(tags); |
| }); |
| const params = { |
| project: 'test', |
| detailType: 'tags', |
| filter: 'test', |
| offset: 25, |
| }; |
| element._paramsChanged(params).then(() => { |
| assert.isTrue(element.$.restAPI.getProjectTags.lastCall |
| .calledWithExactly('test', 'test', 25, 25)); |
| done(); |
| }); |
| }); |
| }); |
| |
| suite('create new', () => { |
| test('_handleCreateClicked called when create-click fired', () => { |
| sandbox.stub(element, '_handleCreateClicked'); |
| element.$$('gr-list-view').fire('create-clicked'); |
| assert.isTrue(element._handleCreateClicked.called); |
| }); |
| |
| test('_handleCreateClicked opens modal', () => { |
| const openStub = sandbox.stub(element.$.createOverlay, 'open'); |
| element._handleCreateClicked(); |
| assert.isTrue(openStub.called); |
| }); |
| |
| test('_handleCreateItem called when confirm fired', () => { |
| sandbox.stub(element, '_handleCreateItem'); |
| element.$.createDialog.fire('confirm'); |
| assert.isTrue(element._handleCreateItem.called); |
| }); |
| |
| test('_handleCloseCreate called when cancel fired', () => { |
| sandbox.stub(element, '_handleCloseCreate'); |
| element.$.createDialog.fire('cancel'); |
| assert.isTrue(element._handleCloseCreate.called); |
| }); |
| }); |
| }); |
| </script> |