445 lines
14 KiB
HTML
445 lines
14 KiB
HTML
<!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-repo-access</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-repo-access.html">
|
|
|
|
<script>void(0);</script>
|
|
|
|
<test-fixture id="basic">
|
|
<template>
|
|
<gr-repo-access></gr-repo-access>
|
|
</template>
|
|
</test-fixture>
|
|
|
|
<script>
|
|
suite('gr-repo-access tests', () => {
|
|
let element;
|
|
let sandbox;
|
|
|
|
const accessRes = {
|
|
local: {
|
|
'refs/*': {
|
|
permissions: {
|
|
owner: {
|
|
rules: {
|
|
234: {action: 'ALLOW'},
|
|
123: {action: 'DENY'},
|
|
},
|
|
},
|
|
read: {
|
|
rules: {
|
|
234: {action: 'ALLOW'},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
const accessRes2 = {
|
|
local: {
|
|
GLOBAL_CAPABILITIES: {
|
|
permissions: {
|
|
accessDatabase: {
|
|
rules: {
|
|
group1: {
|
|
action: 'ALLOW',
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
const repoRes = {
|
|
labels: {
|
|
'Code-Review': {},
|
|
},
|
|
};
|
|
setup(() => {
|
|
sandbox = sinon.sandbox.create();
|
|
element = fixture('basic');
|
|
});
|
|
|
|
teardown(() => {
|
|
sandbox.restore();
|
|
});
|
|
|
|
test('_repoChanged called when repo name changes', () => {
|
|
sandbox.stub(element, '_repoChanged');
|
|
element.repo = 'New Repo';
|
|
assert.isTrue(element._repoChanged.called);
|
|
});
|
|
|
|
test('_repoChanged', done => {
|
|
const capabilitiesRes = {
|
|
accessDatabase: {
|
|
id: 'accessDatabase',
|
|
name: 'Access Database',
|
|
},
|
|
createAccount: {
|
|
id: 'createAccount',
|
|
name: 'Create Account',
|
|
},
|
|
};
|
|
const accessStub = sandbox.stub(element.$.restAPI,
|
|
'getRepoAccessRights');
|
|
|
|
accessStub.withArgs('New Repo').returns(
|
|
Promise.resolve(JSON.parse(JSON.stringify(accessRes))));
|
|
accessStub.withArgs('Another New Repo')
|
|
.returns(Promise.resolve(JSON.parse(JSON.stringify(accessRes2))));
|
|
const capabilitiesStub = sandbox.stub(element.$.restAPI,
|
|
'getCapabilities');
|
|
capabilitiesStub.returns(Promise.resolve(capabilitiesRes));
|
|
const repoStub = sandbox.stub(element.$.restAPI, 'getRepo').returns(
|
|
Promise.resolve(repoRes));
|
|
const adminStub = sandbox.stub(element.$.restAPI, 'getIsAdmin').returns(
|
|
Promise.resolve(true));
|
|
|
|
element._repoChanged('New Repo').then(() => {
|
|
assert.isTrue(accessStub.called);
|
|
assert.isTrue(capabilitiesStub.called);
|
|
assert.isTrue(repoStub.called);
|
|
assert.isTrue(adminStub.called);
|
|
assert.isNotOk(element._inheritsFrom);
|
|
assert.deepEqual(element._local, accessRes.local);
|
|
assert.deepEqual(element._sections,
|
|
element.toSortedArray(accessRes.local));
|
|
assert.deepEqual(element._labels, repoRes.labels);
|
|
return element._repoChanged('Another New Repo');
|
|
})
|
|
.then(() => {
|
|
assert.deepEqual(element._sections,
|
|
element.toSortedArray(accessRes2.local));
|
|
done();
|
|
});
|
|
});
|
|
|
|
test('_repoChanged when repo changes to undefined returns', done => {
|
|
const capabilitiesRes = {
|
|
accessDatabase: {
|
|
id: 'accessDatabase',
|
|
name: 'Access Database',
|
|
},
|
|
};
|
|
const repoRes = {
|
|
labels: {
|
|
'Code-Review': {},
|
|
},
|
|
};
|
|
const accessStub = sandbox.stub(element.$.restAPI, 'getRepoAccessRights')
|
|
.returns(Promise.resolve(JSON.parse(JSON.stringify(accessRes2))));
|
|
const capabilitiesStub = sandbox.stub(element.$.restAPI,
|
|
'getCapabilities').returns(Promise.resolve(capabilitiesRes));
|
|
const repoStub = sandbox.stub(element.$.restAPI, 'getRepo').returns(
|
|
Promise.resolve(repoRes));
|
|
|
|
element._repoChanged().then(() => {
|
|
assert.isFalse(accessStub.called);
|
|
assert.isFalse(capabilitiesStub.called);
|
|
assert.isFalse(repoStub.called);
|
|
done();
|
|
});
|
|
});
|
|
|
|
test('_computeParentHref', () => {
|
|
const repoName = 'test-repo';
|
|
assert.equal(element._computeParentHref(repoName),
|
|
'/admin/repos/test-repo,access');
|
|
});
|
|
|
|
test('_computeAdminClass', () => {
|
|
let isAdmin = true;
|
|
assert.equal(element._computeAdminClass(isAdmin), 'admin');
|
|
isAdmin = false;
|
|
assert.equal(element._computeAdminClass(isAdmin), '');
|
|
});
|
|
|
|
test('inherit section', () => {
|
|
sandbox.stub(element, '_computeParentHref');
|
|
assert.isNotOk(Polymer.dom(element.root).querySelector('#inheritsFrom'));
|
|
assert.isFalse(element._computeParentHref.called);
|
|
element._inheritsFrom = {
|
|
name: 'another-repo',
|
|
};
|
|
flushAsynchronousOperations();
|
|
assert.isOk(Polymer.dom(element.root).querySelector('#inheritsFrom'));
|
|
assert.isTrue(element._computeParentHref.called);
|
|
});
|
|
|
|
suite('with defined sections', () => {
|
|
setup(() => {
|
|
element._sections =
|
|
element.toSortedArray(JSON.parse(JSON.stringify(accessRes.local)));
|
|
flushAsynchronousOperations();
|
|
});
|
|
|
|
test('button visibility for non admin', () => {
|
|
assert.equal(getComputedStyle(element.$.saveBtn).display, 'none');
|
|
assert.equal(getComputedStyle(element.$.editBtn).display, 'none');
|
|
});
|
|
|
|
test('button visibility for admin', () => {
|
|
element._isAdmin = true;
|
|
|
|
// Edit button is visible and Save button is hidden.
|
|
assert.equal(getComputedStyle(element.$.saveBtn).display, 'none');
|
|
assert.notEqual(getComputedStyle(element.$.editBtn).display, 'none');
|
|
assert.equal(element.$.editBtn.innerText, 'EDIT');
|
|
|
|
MockInteractions.tap(element.$.editBtn);
|
|
|
|
// Edit button changes to Cancel button, and Save button is visible but
|
|
// disabled.
|
|
assert.equal(element.$.editBtn.innerText, 'CANCEL');
|
|
assert.notEqual(getComputedStyle(element.$.saveBtn).display, 'none');
|
|
assert.isTrue(element.$.saveBtn.disabled);
|
|
|
|
// Save button should be enabled after access is modified
|
|
element.fire('access-modified');
|
|
assert.isFalse(element.$.saveBtn.disabled);
|
|
});
|
|
|
|
test('_handleAccessModified called with event fired', () => {
|
|
sandbox.spy(element, '_handleAccessModified');
|
|
element.fire('access-modified');
|
|
assert.isTrue(element._handleAccessModified.called);
|
|
});
|
|
|
|
test('_computeAddAndRemove rules', () => {
|
|
element._local = JSON.parse(JSON.stringify(accessRes.local));
|
|
assert.deepEqual(element._computeAddAndRemove(), {add: {}, remove: {}});
|
|
element._local['refs/*'].permissions.owner.rules[123].deleted = true;
|
|
let expectedInput = {
|
|
add: {},
|
|
remove: {
|
|
'refs/*': {
|
|
permissions: {
|
|
owner: {
|
|
rules: {
|
|
123: null,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
assert.deepEqual(element._computeAddAndRemove(), expectedInput);
|
|
delete element._local['refs/*'].permissions.owner.rules[123].deleted;
|
|
element._local['refs/*'].permissions.owner.rules[123].modified = true;
|
|
expectedInput = {
|
|
add: {
|
|
'refs/*': {
|
|
permissions: {
|
|
owner: {
|
|
rules: {
|
|
123: {action: 'DENY', modified: true},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
remove: {
|
|
'refs/*': {
|
|
permissions: {
|
|
owner: {
|
|
rules: {
|
|
123: null,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
assert.deepEqual(element._computeAddAndRemove(), expectedInput);
|
|
});
|
|
|
|
test('_computeAddAndRemove permissions', () => {
|
|
element._local = JSON.parse(JSON.stringify(accessRes.local));
|
|
assert.deepEqual(element._computeAddAndRemove(), {add: {}, remove: {}});
|
|
element._local['refs/*'].permissions.owner.deleted = true;
|
|
let expectedInput = {
|
|
add: {},
|
|
remove: {
|
|
'refs/*': {
|
|
permissions: {
|
|
owner: {rules: {}},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
assert.deepEqual(element._computeAddAndRemove(), expectedInput);
|
|
delete element._local['refs/*'].permissions.owner.deleted;
|
|
element._local['refs/*'].permissions.owner.modified = true;
|
|
expectedInput = {
|
|
add: {
|
|
'refs/*': {
|
|
permissions: {
|
|
owner: {
|
|
modified: true,
|
|
rules: {
|
|
234: {action: 'ALLOW'},
|
|
123: {action: 'DENY'},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
remove: {
|
|
'refs/*': {
|
|
permissions: {
|
|
owner: {rules: {}},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
assert.deepEqual(element._computeAddAndRemove(), expectedInput);
|
|
});
|
|
|
|
test('_computeAddAndRemove combinations', () => {
|
|
// Modify rule and delete permission that it is inside of.
|
|
element._local = JSON.parse(JSON.stringify(accessRes.local));
|
|
element._local['refs/*'].permissions.owner.rules[123].modified = true;
|
|
element._local['refs/*'].permissions.owner.deleted = true;
|
|
let expectedInput = {
|
|
add: {},
|
|
remove: {
|
|
'refs/*': {
|
|
permissions: {
|
|
owner: {rules: {}},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
assert.deepEqual(element._computeAddAndRemove(), expectedInput);
|
|
// Delete rule and delete permission that it is inside of.
|
|
element._local['refs/*'].permissions.owner.rules[123].modified = false;
|
|
element._local['refs/*'].permissions.owner.rules[123].deleted = true;
|
|
assert.deepEqual(element._computeAddAndRemove(), expectedInput);
|
|
|
|
// Also modify a different rule inside of another permission.
|
|
element._local['refs/*'].permissions.read.modified = true;
|
|
expectedInput = {
|
|
add: {
|
|
'refs/*': {
|
|
permissions: {
|
|
read: {
|
|
modified: true,
|
|
rules: {
|
|
234: {action: 'ALLOW'},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
remove: {
|
|
'refs/*': {
|
|
permissions: {
|
|
owner: {rules: {}},
|
|
read: {rules: {}},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
assert.deepEqual(element._computeAddAndRemove(), expectedInput);
|
|
// Modify both permissions with an exclusive bit. Owner is still
|
|
// deleted.
|
|
element._local['refs/*'].permissions.owner.exclusive = true;
|
|
element._local['refs/*'].permissions.owner.modified = true;
|
|
element._local['refs/*'].permissions.read.exclusive = true;
|
|
element._local['refs/*'].permissions.read.modified = true;
|
|
expectedInput = {
|
|
add: {
|
|
'refs/*': {
|
|
permissions: {
|
|
read: {
|
|
exclusive: true,
|
|
modified: true,
|
|
rules: {
|
|
234: {action: 'ALLOW'},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
remove: {
|
|
'refs/*': {
|
|
permissions: {
|
|
owner: {rules: {}},
|
|
read: {rules: {}},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
assert.deepEqual(element._computeAddAndRemove(), expectedInput);
|
|
});
|
|
|
|
test('_handleSaveForReview', done => {
|
|
const repoAccessInput = {
|
|
add: {
|
|
'refs/*': {
|
|
permissions: {
|
|
owner: {
|
|
rules: {
|
|
123: {action: 'DENY', modified: true},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
remove: {
|
|
'refs/*': {
|
|
permissions: {
|
|
owner: {
|
|
rules: {
|
|
123: null,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
sandbox.stub(element.$.restAPI, 'getRepoAccessRights').returns(
|
|
Promise.resolve(JSON.parse(JSON.stringify(accessRes))));
|
|
sandbox.stub(element.$.restAPI, 'getRepo')
|
|
.returns(Promise.resolve({}));
|
|
sandbox.stub(Gerrit.Nav, 'navigateToChange');
|
|
const saveForReviewStub = sandbox.stub(element.$.restAPI,
|
|
'setProjectAccessRightsForReview')
|
|
.returns(Promise.resolve({_number: 1}));
|
|
|
|
element.repo = 'test-repo';
|
|
sandbox.stub(element, '_computeAddAndRemove').returns(repoAccessInput);
|
|
|
|
element._handleSaveForReview().then(() => {
|
|
assert.isTrue(saveForReviewStub.called);
|
|
assert.isTrue(Gerrit.Nav.navigateToChange
|
|
.lastCall.calledWithExactly({_number: 1}));
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
</script>
|