| /** |
| * @license |
| * 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. |
| */ |
| |
| import '../../../test/common-test-setup-karma.js'; |
| import './gr-repo-detail-list.js'; |
| import 'lodash/lodash.js'; |
| import {page} from '../../../utils/page-wrapper-utils.js'; |
| import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js'; |
| |
| const basicFixture = fixtureFromElement('gr-repo-detail-list'); |
| |
| 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}`, |
| }, |
| ], |
| message: 'Annotated tag', |
| tagger: { |
| name: 'Test User', |
| email: 'test.user@gmail.com', |
| date: '2017-09-19 14:54:00.000000000', |
| tz: 540, |
| }, |
| }; |
| }; |
| |
| suite('gr-repo-detail-list', () => { |
| suite('Branches', () => { |
| let element; |
| let branches; |
| |
| setup(() => { |
| element = basicFixture.instantiate(); |
| element.detailType = 'branches'; |
| counter = 0; |
| sinon.stub(page, 'show'); |
| }); |
| |
| suite('list of repo branches', () => { |
| setup(done => { |
| branches = [{ |
| ref: 'HEAD', |
| revision: 'master', |
| }].concat(_.times(25, branchGenerator)); |
| |
| stub('gr-rest-api-interface', { |
| getRepoBranches(num, project, offset) { |
| return Promise.resolve(branches); |
| }, |
| }); |
| |
| const params = { |
| repo: 'test', |
| detail: '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 => { |
| sinon.stub(element, '_getLoggedIn').returns(Promise.resolve(true)); |
| sinon.stub(element.$.restAPI, 'getRepoAccess').returns( |
| Promise.resolve({ |
| test: {is_owner: false}, |
| })); |
| element._determineIfOwner('test').then(() => { |
| assert.equal(element._isOwner, false); |
| assert.equal(getComputedStyle(dom(element.root) |
| .querySelector('.revisionNoEditing')).display, 'inline'); |
| assert.equal(getComputedStyle(dom(element.root) |
| .querySelector('.revisionEdit')).display, 'none'); |
| done(); |
| }); |
| }); |
| |
| test('Edit HEAD button admin', done => { |
| const saveBtn = element.root.querySelector('.saveBtn'); |
| const cancelBtn = element.root.querySelector('.cancelBtn'); |
| const editBtn = element.root.querySelector('.editBtn'); |
| const revisionNoEditing = dom(element.root) |
| .querySelector('.revisionNoEditing'); |
| const revisionWithEditing = dom(element.root) |
| .querySelector('.revisionWithEditing'); |
| |
| sinon.stub(element, '_getLoggedIn').returns(Promise.resolve(true)); |
| sinon.stub(element.$.restAPI, 'getRepoAccess').returns( |
| Promise.resolve({ |
| test: {is_owner: true}, |
| })); |
| sinon.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(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 = dom(element.root) |
| .querySelectorAll('.canEdit .editItem'); |
| |
| for (const item of hiddenElements) { |
| assert.equal(getComputedStyle(item).display, 'none'); |
| } |
| |
| MockInteractions.tap(editBtn); |
| flush(); |
| // 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 (const 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._repo = '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); |
| flush(); |
| |
| // 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: sinon.stub()}}; |
| element._isEditing = true; |
| sinon.stub(element.$.restAPI, 'setRepoHead').returns( |
| Promise.resolve({ |
| status: 400, |
| }) |
| ); |
| |
| element._setRepoHead('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: sinon.stub()}}; |
| element._isEditing = true; |
| sinon.stub(element.$.restAPI, 'setRepoHead').returns( |
| Promise.resolve({ |
| status: 200, |
| }) |
| ); |
| |
| element._setRepoHead('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', { |
| getRepoBranches(num, repo, offset) { |
| return Promise.resolve(branches); |
| }, |
| }); |
| |
| const params = { |
| repo: 'test', |
| detail: 'branches', |
| }; |
| |
| element._paramsChanged(params).then(() => { flush(done); }); |
| }); |
| |
| test('_shownItems', () => { |
| assert.equal(element._shownItems.length, 25); |
| }); |
| }); |
| |
| suite('filter', () => { |
| test('_paramsChanged', done => { |
| sinon.stub( |
| element.$.restAPI, |
| 'getRepoBranches') |
| .callsFake(() => Promise.resolve(branches)); |
| const params = { |
| detail: 'branches', |
| repo: 'test', |
| filter: 'test', |
| offset: 25, |
| }; |
| element._paramsChanged(params).then(() => { |
| assert.equal(element.$.restAPI.getRepoBranches.lastCall.args[0], |
| 'test'); |
| assert.equal(element.$.restAPI.getRepoBranches.lastCall.args[1], |
| 'test'); |
| assert.equal(element.$.restAPI.getRepoBranches.lastCall.args[2], |
| 25); |
| assert.equal(element.$.restAPI.getRepoBranches.lastCall.args[3], |
| 25); |
| done(); |
| }); |
| }); |
| }); |
| |
| suite('404', () => { |
| test('fires page-error', done => { |
| const response = {status: 404}; |
| sinon.stub(element.$.restAPI, 'getRepoBranches').callsFake( |
| (filter, repo, reposBranchesPerPage, opt_offset, errFn) => { |
| errFn(response); |
| }); |
| |
| element.addEventListener('page-error', e => { |
| assert.deepEqual(e.detail.response, response); |
| done(); |
| }); |
| |
| const params = { |
| detail: 'branches', |
| repo: 'test', |
| filter: 'test', |
| offset: 25, |
| }; |
| element._paramsChanged(params); |
| }); |
| }); |
| }); |
| |
| suite('Tags', () => { |
| let element; |
| let tags; |
| |
| setup(() => { |
| element = basicFixture.instantiate(); |
| element.detailType = 'tags'; |
| counter = 0; |
| sinon.stub(page, 'show'); |
| }); |
| |
| test('_computeMessage', () => { |
| let message = 'v2.15-rc1↵-----BEGIN PGP SIGNATURE-----↵Version: GnuPG v' + |
| '1↵↵iQIcBAABAgAGBQJZ27O7AAoJEF/XxZqaEoiMy6kQAMoQCpGr3J6JITI4BVWsr7QM↵xy' + |
| 'EcWH5YPUko5EPTbkABHmaVyFmKGkuIQdn6c+NIbqJOk+5XT4oUyRSo1T569HPJ↵3kyxEJi' + |
| 'T1ryvp5BIHwdvHx58fjw1+YkiWLZuZq1FFkUYqnWTYCrkv7Fok98pdOmV↵CL1Hgugi5uK8' + |
| '/kxf1M7+Nv6piaZ140pwSb1h6QdAjaZVfaBCnoxlG4LRUqHvEYay↵f4QYgFT67auHIGkZ4' + |
| 'moUcsp2Du/1jSsCWL/CPwjPFGbbckVAjLCMT9yD3NKwpEZF↵pfsiZyHI9dL0M+QjVrM+RD' + |
| 'HwIIJwra8R0IMkDlQ6MDrFlKNqNBbo588S6UPrm71L↵YuiwWlcrK9ZIybxT6LzbR65Rvez' + |
| 'DSitQ+xeIfpZE19/X6BCnvlARLE8k/tC2JksI↵lEZi7Lf3FQdIcwwyt98tJkS9HX9v9jbC' + |
| '5QXifnoj3Li8tHSLuQ1dJCxHQiis6ojI↵OWUFkm0IHBXVNHA2dqYBdM+pL12mlI3wp6Ica' + |
| '4cdEVDwzu+j1xnVSFUa+d+Y2xJF↵7mytuyhHiKG4hm+zbhMv6WD8Q3FoDsJZeLY99l0hYQ' + |
| 'SnnkMduFVroIs45pAs8gUA↵RvYla8mm9w/543IJAPzzFarPVLSsSyQ7tJl3UBzjKRNH/rX' + |
| 'W+F22qyWD1zyHPUIR↵C00ItmwlAvveImYKpQAH↵=L+K9↵-----END PGP SIGNATURE---' + |
| '--'; |
| assert.equal(element._computeMessage(message), 'v2.15-rc1↵'); |
| message = 'v2.15-rc1'; |
| assert.equal(element._computeMessage(message), 'v2.15-rc1'); |
| }); |
| |
| suite('list of repo tags', () => { |
| setup(done => { |
| tags = _.times(26, tagGenerator); |
| |
| stub('gr-rest-api-interface', { |
| getRepoTags(num, repo, offset) { |
| return Promise.resolve(tags); |
| }, |
| }); |
| |
| const params = { |
| repo: 'test', |
| detail: '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 tag message in the list', done => { |
| flush(() => { |
| assert.equal(element._items[1].message, 'Annotated tag'); |
| done(); |
| }); |
| }); |
| |
| test('test for tagger in the tag list', done => { |
| const tagger = { |
| name: 'Test User', |
| email: 'test.user@gmail.com', |
| date: '2017-09-19 14:54:00.000000000', |
| tz: 540, |
| }; |
| flush(() => { |
| assert.deepEqual(element._items[1].tagger, tagger); |
| 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); |
| }); |
| |
| test('_computeHideTagger', () => { |
| const testObject1 = { |
| tagger: 'test', |
| }; |
| assert.equal(element._computeHideTagger(testObject1), ''); |
| |
| assert.equal(element._computeHideTagger(undefined), 'hide'); |
| }); |
| }); |
| |
| suite('list with less then 25 tags', () => { |
| setup(done => { |
| tags = _.times(25, tagGenerator); |
| |
| stub('gr-rest-api-interface', { |
| getRepoTags(num, project, offset) { |
| return Promise.resolve(tags); |
| }, |
| }); |
| |
| const params = { |
| repo: 'test', |
| detail: 'tags', |
| }; |
| |
| element._paramsChanged(params).then(() => { flush(done); }); |
| }); |
| |
| test('_shownItems', () => { |
| assert.equal(element._shownItems.length, 25); |
| }); |
| }); |
| |
| suite('filter', () => { |
| test('_paramsChanged', done => { |
| sinon.stub( |
| element.$.restAPI, |
| 'getRepoTags') |
| .callsFake(() => Promise.resolve(tags)); |
| const params = { |
| repo: 'test', |
| detail: 'tags', |
| filter: 'test', |
| offset: 25, |
| }; |
| element._paramsChanged(params).then(() => { |
| assert.equal(element.$.restAPI.getRepoTags.lastCall.args[0], |
| 'test'); |
| assert.equal(element.$.restAPI.getRepoTags.lastCall.args[1], |
| 'test'); |
| assert.equal(element.$.restAPI.getRepoTags.lastCall.args[2], |
| 25); |
| assert.equal(element.$.restAPI.getRepoTags.lastCall.args[3], |
| 25); |
| done(); |
| }); |
| }); |
| }); |
| |
| suite('create new', () => { |
| test('_handleCreateClicked called when create-click fired', () => { |
| sinon.stub(element, '_handleCreateClicked'); |
| element.shadowRoot |
| .querySelector('gr-list-view').dispatchEvent( |
| new CustomEvent('create-clicked', { |
| composed: true, bubbles: true, |
| })); |
| assert.isTrue(element._handleCreateClicked.called); |
| }); |
| |
| test('_handleCreateClicked opens modal', () => { |
| const openStub = sinon.stub(element.$.createOverlay, 'open'); |
| element._handleCreateClicked(); |
| assert.isTrue(openStub.called); |
| }); |
| |
| test('_handleCreateItem called when confirm fired', () => { |
| sinon.stub(element, '_handleCreateItem'); |
| element.$.createDialog.dispatchEvent( |
| new CustomEvent('confirm', { |
| composed: true, bubbles: true, |
| })); |
| assert.isTrue(element._handleCreateItem.called); |
| }); |
| |
| test('_handleCloseCreate called when cancel fired', () => { |
| sinon.stub(element, '_handleCloseCreate'); |
| element.$.createDialog.dispatchEvent( |
| new CustomEvent('cancel', { |
| composed: true, bubbles: true, |
| })); |
| assert.isTrue(element._handleCloseCreate.called); |
| }); |
| }); |
| |
| suite('404', () => { |
| test('fires page-error', done => { |
| const response = {status: 404}; |
| sinon.stub(element.$.restAPI, 'getRepoTags').callsFake( |
| (filter, repo, reposTagsPerPage, opt_offset, errFn) => { |
| errFn(response); |
| }); |
| |
| element.addEventListener('page-error', e => { |
| assert.deepEqual(e.detail.response, response); |
| done(); |
| }); |
| |
| const params = { |
| repo: 'test', |
| detail: 'tags', |
| filter: 'test', |
| offset: 25, |
| }; |
| element._paramsChanged(params); |
| }); |
| }); |
| |
| test('test _computeHideDeleteClass', () => { |
| assert.deepEqual(element._computeHideDeleteClass(true, false), 'show'); |
| assert.deepEqual(element._computeHideDeleteClass(false, true), 'show'); |
| assert.deepEqual(element._computeHideDeleteClass(false, false), ''); |
| }); |
| }); |
| }); |
| |