blob: 772782129456008aeea194fc4ec9488defdc35e5 [file] [log] [blame]
/**
* @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), '');
});
});
});