Convert polygerrit to es6-modules

This change replace all HTML imports with es6-modules. The only exceptions are:
* gr-app.html file, which can be deleted only after updating the
  gerrit/httpd/raw/PolyGerritIndexHtml.soy file.
* dark-theme.html which is loaded via importHref. Must be updated manually
  later in a separate change.

This change was produced automatically by ./es6-modules-converter.sh script.
No manual changes were made.

Change-Id: I0c447dd8c05757741e2c940720652d01d9fb7d67
This commit is contained in:
Dmitrii Filippov
2020-03-17 11:27:28 +01:00
parent dbe954539d
commit daf0ec9543
600 changed files with 99000 additions and 99742 deletions

View File

@@ -14,280 +14,300 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
'use strict';
import '../../../behaviors/base-url-behavior/base-url-behavior.js';
const SUGGESTIONS_LIMIT = 15;
const SAVING_ERROR_TEXT = 'Group may not exist, or you may not have '+
'permission to add it';
import '../../../behaviors/fire-behavior/fire-behavior.js';
import '../../../behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior.js';
import '../../../scripts/bundled-polymer.js';
import '@polymer/iron-autogrow-textarea/iron-autogrow-textarea.js';
import '../../../styles/gr-form-styles.js';
import '../../../styles/gr-subpage-styles.js';
import '../../../styles/gr-table-styles.js';
import '../../../styles/shared-styles.js';
import '../../shared/gr-account-link/gr-account-link.js';
import '../../shared/gr-autocomplete/gr-autocomplete.js';
import '../../shared/gr-button/gr-button.js';
import '../../shared/gr-overlay/gr-overlay.js';
import '../../shared/gr-rest-api-interface/gr-rest-api-interface.js';
import '../gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog.js';
import {mixinBehaviors} from '@polymer/polymer/lib/legacy/class.js';
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';
import {PolymerElement} from '@polymer/polymer/polymer-element.js';
import {htmlTemplate} from './gr-group-members_html.js';
const URL_REGEX = '^(?:[a-z]+:)?//';
const SUGGESTIONS_LIMIT = 15;
const SAVING_ERROR_TEXT = 'Group may not exist, or you may not have '+
'permission to add it';
/**
* @appliesMixin Gerrit.BaseUrlMixin
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.URLEncodingMixin
* @extends Polymer.Element
*/
class GrGroupMembers extends Polymer.mixinBehaviors( [
Gerrit.BaseUrlBehavior,
Gerrit.FireBehavior,
Gerrit.URLEncodingBehavior,
], Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element))) {
static get is() { return 'gr-group-members'; }
const URL_REGEX = '^(?:[a-z]+:)?//';
static get properties() {
return {
groupId: Number,
_groupMemberSearchId: String,
_groupMemberSearchName: String,
_includedGroupSearchId: String,
_includedGroupSearchName: String,
_loading: {
type: Boolean,
value: true,
/**
* @appliesMixin Gerrit.BaseUrlMixin
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.URLEncodingMixin
* @extends Polymer.Element
*/
class GrGroupMembers extends mixinBehaviors( [
Gerrit.BaseUrlBehavior,
Gerrit.FireBehavior,
Gerrit.URLEncodingBehavior,
], GestureEventListeners(
LegacyElementMixin(
PolymerElement))) {
static get template() { return htmlTemplate; }
static get is() { return 'gr-group-members'; }
static get properties() {
return {
groupId: Number,
_groupMemberSearchId: String,
_groupMemberSearchName: String,
_includedGroupSearchId: String,
_includedGroupSearchName: String,
_loading: {
type: Boolean,
value: true,
},
_groupName: String,
_groupMembers: Object,
_includedGroups: Object,
_itemName: String,
_itemType: String,
_queryMembers: {
type: Function,
value() {
return this._getAccountSuggestions.bind(this);
},
_groupName: String,
_groupMembers: Object,
_includedGroups: Object,
_itemName: String,
_itemType: String,
_queryMembers: {
type: Function,
value() {
return this._getAccountSuggestions.bind(this);
},
},
_queryIncludedGroup: {
type: Function,
value() {
return this._getGroupSuggestions.bind(this);
},
_queryIncludedGroup: {
type: Function,
value() {
return this._getGroupSuggestions.bind(this);
},
},
_groupOwner: {
type: Boolean,
value: false,
},
_isAdmin: {
type: Boolean,
value: false,
},
};
}
},
_groupOwner: {
type: Boolean,
value: false,
},
_isAdmin: {
type: Boolean,
value: false,
},
};
}
/** @override */
attached() {
super.attached();
this._loadGroupDetails();
/** @override */
attached() {
super.attached();
this._loadGroupDetails();
this.fire('title-change', {title: 'Members'});
}
this.fire('title-change', {title: 'Members'});
}
_loadGroupDetails() {
if (!this.groupId) { return; }
_loadGroupDetails() {
if (!this.groupId) { return; }
const promises = [];
const promises = [];
const errFn = response => {
this.fire('page-error', {response});
};
const errFn = response => {
this.fire('page-error', {response});
};
return this.$.restAPI.getGroupConfig(this.groupId, errFn)
.then(config => {
if (!config || !config.name) { return Promise.resolve(); }
return this.$.restAPI.getGroupConfig(this.groupId, errFn)
.then(config => {
if (!config || !config.name) { return Promise.resolve(); }
this._groupName = config.name;
this._groupName = config.name;
promises.push(this.$.restAPI.getIsAdmin().then(isAdmin => {
this._isAdmin = isAdmin ? true : false;
}));
promises.push(this.$.restAPI.getIsAdmin().then(isAdmin => {
this._isAdmin = isAdmin ? true : false;
}));
promises.push(this.$.restAPI.getIsGroupOwner(config.name)
.then(isOwner => {
this._groupOwner = isOwner ? true : false;
}));
promises.push(this.$.restAPI.getGroupMembers(config.name).then(
members => {
this._groupMembers = members;
}));
promises.push(this.$.restAPI.getIncludedGroup(config.name)
.then(includedGroup => {
this._includedGroups = includedGroup;
}));
return Promise.all(promises).then(() => {
this._loading = false;
});
});
}
_computeLoadingClass(loading) {
return loading ? 'loading' : '';
}
_isLoading() {
return this._loading || this._loading === undefined;
}
_computeGroupUrl(url) {
if (!url) { return; }
const r = new RegExp(URL_REGEX, 'i');
if (r.test(url)) {
return url;
}
// For GWT compatibility
if (url.startsWith('#')) {
return this.getBaseUrl() + url.slice(1);
}
return this.getBaseUrl() + url;
}
_handleSavingGroupMember() {
return this.$.restAPI.saveGroupMembers(this._groupName,
this._groupMemberSearchId).then(config => {
if (!config) {
return;
}
this.$.restAPI.getGroupMembers(this._groupName).then(members => {
this._groupMembers = members;
});
this._groupMemberSearchName = '';
this._groupMemberSearchId = '';
});
}
_handleDeleteConfirm() {
this.$.overlay.close();
if (this._itemType === 'member') {
return this.$.restAPI.deleteGroupMembers(this._groupName,
this._itemId)
.then(itemDeleted => {
if (itemDeleted.status === 204) {
this.$.restAPI.getGroupMembers(this._groupName)
.then(members => {
this._groupMembers = members;
});
}
});
} else if (this._itemType === 'includedGroup') {
return this.$.restAPI.deleteIncludedGroup(this._groupName,
this._itemId)
.then(itemDeleted => {
if (itemDeleted.status === 204 || itemDeleted.status === 205) {
this.$.restAPI.getIncludedGroup(this._groupName)
.then(includedGroup => {
this._includedGroups = includedGroup;
});
}
});
}
}
_handleConfirmDialogCancel() {
this.$.overlay.close();
}
_handleDeleteMember(e) {
const id = e.model.get('item._account_id');
const name = e.model.get('item.name');
const username = e.model.get('item.username');
const email = e.model.get('item.email');
const item = username || name || email || id;
if (!item) {
return '';
}
this._itemName = item;
this._itemId = id;
this._itemType = 'member';
this.$.overlay.open();
}
_handleSavingIncludedGroups() {
return this.$.restAPI.saveIncludedGroup(this._groupName,
this._includedGroupSearchId.replace(/\+/g, ' '), err => {
if (err.status === 404) {
this.dispatchEvent(new CustomEvent('show-alert', {
detail: {message: SAVING_ERROR_TEXT},
bubbles: true,
composed: true,
promises.push(this.$.restAPI.getIsGroupOwner(config.name)
.then(isOwner => {
this._groupOwner = isOwner ? true : false;
}));
return err;
}
throw Error(err.statusText);
})
.then(config => {
if (!config) {
return;
}
this.$.restAPI.getIncludedGroup(this._groupName)
.then(includedGroup => {
this._includedGroups = includedGroup;
});
this._includedGroupSearchName = '';
this._includedGroupSearchId = '';
promises.push(this.$.restAPI.getGroupMembers(config.name).then(
members => {
this._groupMembers = members;
}));
promises.push(this.$.restAPI.getIncludedGroup(config.name)
.then(includedGroup => {
this._includedGroups = includedGroup;
}));
return Promise.all(promises).then(() => {
this._loading = false;
});
});
}
_computeLoadingClass(loading) {
return loading ? 'loading' : '';
}
_isLoading() {
return this._loading || this._loading === undefined;
}
_computeGroupUrl(url) {
if (!url) { return; }
const r = new RegExp(URL_REGEX, 'i');
if (r.test(url)) {
return url;
}
_handleDeleteIncludedGroup(e) {
const id = decodeURIComponent(e.model.get('item.id')).replace(/\+/g, ' ');
const name = e.model.get('item.name');
const item = name || id;
if (!item) { return ''; }
this._itemName = item;
this._itemId = id;
this._itemType = 'includedGroup';
this.$.overlay.open();
// For GWT compatibility
if (url.startsWith('#')) {
return this.getBaseUrl() + url.slice(1);
}
return this.getBaseUrl() + url;
}
_getAccountSuggestions(input) {
if (input.length === 0) { return Promise.resolve([]); }
return this.$.restAPI.getSuggestedAccounts(
input, SUGGESTIONS_LIMIT).then(accounts => {
const accountSuggestions = [];
let nameAndEmail;
if (!accounts) { return []; }
for (const key in accounts) {
if (!accounts.hasOwnProperty(key)) { continue; }
if (accounts[key].email !== undefined) {
nameAndEmail = accounts[key].name +
' <' + accounts[key].email + '>';
} else {
nameAndEmail = accounts[key].name;
}
accountSuggestions.push({
name: nameAndEmail,
value: accounts[key]._account_id,
});
}
return accountSuggestions;
_handleSavingGroupMember() {
return this.$.restAPI.saveGroupMembers(this._groupName,
this._groupMemberSearchId).then(config => {
if (!config) {
return;
}
this.$.restAPI.getGroupMembers(this._groupName).then(members => {
this._groupMembers = members;
});
}
this._groupMemberSearchName = '';
this._groupMemberSearchId = '';
});
}
_getGroupSuggestions(input) {
return this.$.restAPI.getSuggestedGroups(input)
.then(response => {
const groups = [];
for (const key in response) {
if (!response.hasOwnProperty(key)) { continue; }
groups.push({
name: key,
value: decodeURIComponent(response[key].id),
});
_handleDeleteConfirm() {
this.$.overlay.close();
if (this._itemType === 'member') {
return this.$.restAPI.deleteGroupMembers(this._groupName,
this._itemId)
.then(itemDeleted => {
if (itemDeleted.status === 204) {
this.$.restAPI.getGroupMembers(this._groupName)
.then(members => {
this._groupMembers = members;
});
}
});
} else if (this._itemType === 'includedGroup') {
return this.$.restAPI.deleteIncludedGroup(this._groupName,
this._itemId)
.then(itemDeleted => {
if (itemDeleted.status === 204 || itemDeleted.status === 205) {
this.$.restAPI.getIncludedGroup(this._groupName)
.then(includedGroup => {
this._includedGroups = includedGroup;
});
}
return groups;
});
}
_computeHideItemClass(owner, admin) {
return admin || owner ? '' : 'canModify';
}
}
customElements.define(GrGroupMembers.is, GrGroupMembers);
})();
_handleConfirmDialogCancel() {
this.$.overlay.close();
}
_handleDeleteMember(e) {
const id = e.model.get('item._account_id');
const name = e.model.get('item.name');
const username = e.model.get('item.username');
const email = e.model.get('item.email');
const item = username || name || email || id;
if (!item) {
return '';
}
this._itemName = item;
this._itemId = id;
this._itemType = 'member';
this.$.overlay.open();
}
_handleSavingIncludedGroups() {
return this.$.restAPI.saveIncludedGroup(this._groupName,
this._includedGroupSearchId.replace(/\+/g, ' '), err => {
if (err.status === 404) {
this.dispatchEvent(new CustomEvent('show-alert', {
detail: {message: SAVING_ERROR_TEXT},
bubbles: true,
composed: true,
}));
return err;
}
throw Error(err.statusText);
})
.then(config => {
if (!config) {
return;
}
this.$.restAPI.getIncludedGroup(this._groupName)
.then(includedGroup => {
this._includedGroups = includedGroup;
});
this._includedGroupSearchName = '';
this._includedGroupSearchId = '';
});
}
_handleDeleteIncludedGroup(e) {
const id = decodeURIComponent(e.model.get('item.id')).replace(/\+/g, ' ');
const name = e.model.get('item.name');
const item = name || id;
if (!item) { return ''; }
this._itemName = item;
this._itemId = id;
this._itemType = 'includedGroup';
this.$.overlay.open();
}
_getAccountSuggestions(input) {
if (input.length === 0) { return Promise.resolve([]); }
return this.$.restAPI.getSuggestedAccounts(
input, SUGGESTIONS_LIMIT).then(accounts => {
const accountSuggestions = [];
let nameAndEmail;
if (!accounts) { return []; }
for (const key in accounts) {
if (!accounts.hasOwnProperty(key)) { continue; }
if (accounts[key].email !== undefined) {
nameAndEmail = accounts[key].name +
' <' + accounts[key].email + '>';
} else {
nameAndEmail = accounts[key].name;
}
accountSuggestions.push({
name: nameAndEmail,
value: accounts[key]._account_id,
});
}
return accountSuggestions;
});
}
_getGroupSuggestions(input) {
return this.$.restAPI.getSuggestedGroups(input)
.then(response => {
const groups = [];
for (const key in response) {
if (!response.hasOwnProperty(key)) { continue; }
groups.push({
name: key,
value: decodeURIComponent(response[key].id),
});
}
return groups;
});
}
_computeHideItemClass(owner, admin) {
return admin || owner ? '' : 'canModify';
}
}
customElements.define(GrGroupMembers.is, GrGroupMembers);

View File

@@ -1,38 +1,22 @@
<!--
@license
Copyright (C) 2017 The Android Open Source Project
/**
* @license
* Copyright (C) 2020 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 {html} from '@polymer/polymer/lib/utils/html-tag.js';
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.
-->
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../../../behaviors/fire-behavior/fire-behavior.html">
<link rel="import" href="../../../behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior.html">
<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="/bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
<link rel="import" href="../../../styles/gr-form-styles.html">
<link rel="import" href="../../../styles/gr-subpage-styles.html">
<link rel="import" href="../../../styles/gr-table-styles.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-account-link/gr-account-link.html">
<link rel="import" href="../../shared/gr-autocomplete/gr-autocomplete.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../../shared/gr-overlay/gr-overlay.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
<link rel="import" href="../gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog.html">
<dom-module id="gr-group-members">
<template>
export const htmlTemplate = html`
<style include="gr-form-styles">
/* Workaround for empty style block - see https://github.com/Polymer/tools/issues/408 */
</style>
@@ -72,37 +56,29 @@ limitations under the License.
display: none;
}
</style>
<main class$="gr-form-styles [[_computeHideItemClass(_groupOwner, _isAdmin)]]">
<div id="loading" class$="[[_computeLoadingClass(_loading)]]">
<main class\$="gr-form-styles [[_computeHideItemClass(_groupOwner, _isAdmin)]]">
<div id="loading" class\$="[[_computeLoadingClass(_loading)]]">
Loading...
</div>
<div id="loadedContent" class$="[[_computeLoadingClass(_loading)]]">
<div id="loadedContent" class\$="[[_computeLoadingClass(_loading)]]">
<h1 id="Title">[[_groupName]]</h1>
<div id="form">
<h3 id="members">Members</h3>
<fieldset>
<span class="value">
<gr-autocomplete
id="groupMemberSearchInput"
text="{{_groupMemberSearchName}}"
value="{{_groupMemberSearchId}}"
query="[[_queryMembers]]"
placeholder="Name Or Email">
<gr-autocomplete id="groupMemberSearchInput" text="{{_groupMemberSearchName}}" value="{{_groupMemberSearchId}}" query="[[_queryMembers]]" placeholder="Name Or Email">
</gr-autocomplete>
</span>
<gr-button
id="saveGroupMember"
on-click="_handleSavingGroupMember"
disabled="[[!_groupMemberSearchId]]">
<gr-button id="saveGroupMember" on-click="_handleSavingGroupMember" disabled="[[!_groupMemberSearchId]]">
Add
</gr-button>
<table id="groupMembers">
<tr class="headerRow">
<tbody><tr class="headerRow">
<th class="nameHeader">Name</th>
<th class="emailAddressHeader">Email Address</th>
<th class="deleteHeader">Delete Member</th>
</tr>
<tbody>
</tbody><tbody>
<template is="dom-repeat" items="[[_groupMembers]]">
<tr>
<td class="nameColumn">
@@ -110,9 +86,7 @@ limitations under the License.
</td>
<td>[[item.email]]</td>
<td class="deleteColumn">
<gr-button
class="deleteMembersButton"
on-click="_handleDeleteMember">
<gr-button class="deleteMembersButton" on-click="_handleDeleteMember">
Delete
</gr-button>
</td>
@@ -124,35 +98,26 @@ limitations under the License.
<h3 id="includedGroups">Included Groups</h3>
<fieldset>
<span class="value">
<gr-autocomplete
id="includedGroupSearchInput"
text="{{_includedGroupSearchName}}"
value="{{_includedGroupSearchId}}"
query="[[_queryIncludedGroup]]"
placeholder="Group Name">
<gr-autocomplete id="includedGroupSearchInput" text="{{_includedGroupSearchName}}" value="{{_includedGroupSearchId}}" query="[[_queryIncludedGroup]]" placeholder="Group Name">
</gr-autocomplete>
</span>
<gr-button
id="saveIncludedGroups"
on-click="_handleSavingIncludedGroups"
disabled="[[!_includedGroupSearchId]]">
<gr-button id="saveIncludedGroups" on-click="_handleSavingIncludedGroups" disabled="[[!_includedGroupSearchId]]">
Add
</gr-button>
<table id="includedGroups">
<tr class="headerRow">
<tbody><tr class="headerRow">
<th class="groupNameHeader">Group Name</th>
<th class="descriptionHeader">Description</th>
<th class="deleteIncludedHeader">
Delete Group
</th>
</tr>
<tbody>
</tbody><tbody>
<template is="dom-repeat" items="[[_includedGroups]]">
<tr>
<td class="nameColumn">
<template is="dom-if" if="[[item.url]]">
<a href$="[[_computeGroupUrl(item.url)]]"
rel="noopener">
<a href\$="[[_computeGroupUrl(item.url)]]" rel="noopener">
[[item.name]]
</a>
</template>
@@ -162,9 +127,7 @@ limitations under the License.
</td>
<td>[[item.description]]</td>
<td class="deleteColumn">
<gr-button
class="deleteIncludedGroupButton"
on-click="_handleDeleteIncludedGroup">
<gr-button class="deleteIncludedGroupButton" on-click="_handleDeleteIncludedGroup">
Delete
</gr-button>
</td>
@@ -176,15 +139,8 @@ limitations under the License.
</div>
</div>
</main>
<gr-overlay id="overlay" with-backdrop>
<gr-confirm-delete-item-dialog
class="confirmDialog"
on-confirm="_handleDeleteConfirm"
on-cancel="_handleConfirmDialogCancel"
item="[[_itemName]]"
item-type="[[_itemType]]"></gr-confirm-delete-item-dialog>
<gr-overlay id="overlay" with-backdrop="">
<gr-confirm-delete-item-dialog class="confirmDialog" on-confirm="_handleDeleteConfirm" on-cancel="_handleConfirmDialogCancel" item="[[_itemName]]" item-type="[[_itemType]]"></gr-confirm-delete-item-dialog>
</gr-overlay>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
</template>
<script src="gr-group-members.js"></script>
</dom-module>
`;

View File

@@ -19,15 +19,20 @@ limitations under the License.
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-group-members</title>
<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/bower_components/web-component-tester/browser.js"></script>
<script src="../../../test/test-pre-setup.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-group-members.html">
<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/components/wct-browser-legacy/browser.js"></script>
<script type="module" src="../../../test/test-pre-setup.js"></script>
<script type="module" src="../../../test/common-test-setup.js"></script>
<script type="module" src="./gr-group-members.js"></script>
<script>void(0);</script>
<script type="module">
import '../../../test/test-pre-setup.js';
import '../../../test/common-test-setup.js';
import './gr-group-members.js';
void(0);
</script>
<test-fixture id="basic">
<template>
@@ -35,342 +40,345 @@ limitations under the License.
</template>
</test-fixture>
<script>
suite('gr-group-members tests', async () => {
await readyToTest();
let element;
let sandbox;
let groups;
let groupMembers;
let includedGroups;
let groupStub;
<script type="module">
import '../../../test/test-pre-setup.js';
import '../../../test/common-test-setup.js';
import './gr-group-members.js';
import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
suite('gr-group-members tests', () => {
let element;
let sandbox;
let groups;
let groupMembers;
let includedGroups;
let groupStub;
setup(() => {
sandbox = sinon.sandbox.create();
setup(() => {
sandbox = sinon.sandbox.create();
groups = {
name: 'Administrators',
owner: 'Administrators',
group_id: 1,
};
groups = {
name: 'Administrators',
owner: 'Administrators',
group_id: 1,
};
groupMembers = [
{
_account_id: 1000097,
name: 'Jane Roe',
email: 'jane.roe@example.com',
username: 'jane',
},
{
_account_id: 1000096,
name: 'Test User',
email: 'john.doe@example.com',
},
{
_account_id: 1000095,
name: 'Gerrit',
},
{
_account_id: 1000098,
},
];
includedGroups = [{
url: 'https://group/url',
options: {},
id: 'testId',
name: 'testName',
groupMembers = [
{
_account_id: 1000097,
name: 'Jane Roe',
email: 'jane.roe@example.com',
username: 'jane',
},
{
url: '/group/url',
options: {},
id: 'testId2',
name: 'testName2',
_account_id: 1000096,
name: 'Test User',
email: 'john.doe@example.com',
},
{
url: '#/group/url',
options: {},
id: 'testId3',
name: 'testName3',
_account_id: 1000095,
name: 'Gerrit',
},
];
{
_account_id: 1000098,
},
];
stub('gr-rest-api-interface', {
getSuggestedAccounts(input) {
if (input.startsWith('test')) {
return Promise.resolve([
{
_account_id: 1000096,
name: 'test-account',
email: 'test.account@example.com',
username: 'test123',
},
{
_account_id: 1001439,
name: 'test-admin',
email: 'test.admin@example.com',
username: 'test_admin',
},
{
_account_id: 1001439,
name: 'test-git',
username: 'test_git',
},
]);
} else {
return Promise.resolve({});
}
},
getSuggestedGroups(input) {
if (input.startsWith('test')) {
return Promise.resolve({
'test-admin': {
id: '1ce023d3fb4e4260776fb92cd08b52bbd21ce70a',
},
'test/Administrator (admin)': {
id: 'test%3Aadmin',
},
});
} else {
return Promise.resolve({});
}
},
getLoggedIn() { return Promise.resolve(true); },
getConfig() {
return Promise.resolve();
},
getGroupMembers() {
return Promise.resolve(groupMembers);
},
getIsGroupOwner() {
return Promise.resolve(true);
},
getIncludedGroup() {
return Promise.resolve(includedGroups);
},
getAccountCapabilities() {
return Promise.resolve();
},
});
element = fixture('basic');
sandbox.stub(element, 'getBaseUrl').returns('https://test/site');
element.groupId = 1;
groupStub = sandbox.stub(
element.$.restAPI,
'getGroupConfig',
() => Promise.resolve(groups));
return element._loadGroupDetails();
includedGroups = [{
url: 'https://group/url',
options: {},
id: 'testId',
name: 'testName',
},
{
url: '/group/url',
options: {},
id: 'testId2',
name: 'testName2',
},
{
url: '#/group/url',
options: {},
id: 'testId3',
name: 'testName3',
},
];
stub('gr-rest-api-interface', {
getSuggestedAccounts(input) {
if (input.startsWith('test')) {
return Promise.resolve([
{
_account_id: 1000096,
name: 'test-account',
email: 'test.account@example.com',
username: 'test123',
},
{
_account_id: 1001439,
name: 'test-admin',
email: 'test.admin@example.com',
username: 'test_admin',
},
{
_account_id: 1001439,
name: 'test-git',
username: 'test_git',
},
]);
} else {
return Promise.resolve({});
}
},
getSuggestedGroups(input) {
if (input.startsWith('test')) {
return Promise.resolve({
'test-admin': {
id: '1ce023d3fb4e4260776fb92cd08b52bbd21ce70a',
},
'test/Administrator (admin)': {
id: 'test%3Aadmin',
},
});
} else {
return Promise.resolve({});
}
},
getLoggedIn() { return Promise.resolve(true); },
getConfig() {
return Promise.resolve();
},
getGroupMembers() {
return Promise.resolve(groupMembers);
},
getIsGroupOwner() {
return Promise.resolve(true);
},
getIncludedGroup() {
return Promise.resolve(includedGroups);
},
getAccountCapabilities() {
return Promise.resolve();
},
});
element = fixture('basic');
sandbox.stub(element, 'getBaseUrl').returns('https://test/site');
element.groupId = 1;
groupStub = sandbox.stub(
element.$.restAPI,
'getGroupConfig',
() => Promise.resolve(groups));
return element._loadGroupDetails();
});
teardown(() => {
sandbox.restore();
});
teardown(() => {
sandbox.restore();
});
test('_includedGroups', () => {
assert.equal(element._includedGroups.length, 3);
assert.equal(Polymer.dom(element.root)
.querySelectorAll('.nameColumn a')[0].href, includedGroups[0].url);
assert.equal(Polymer.dom(element.root)
.querySelectorAll('.nameColumn a')[1].href,
'https://test/site/group/url');
assert.equal(Polymer.dom(element.root)
.querySelectorAll('.nameColumn a')[2].href,
'https://test/site/group/url');
});
test('_includedGroups', () => {
assert.equal(element._includedGroups.length, 3);
assert.equal(dom(element.root)
.querySelectorAll('.nameColumn a')[0].href, includedGroups[0].url);
assert.equal(dom(element.root)
.querySelectorAll('.nameColumn a')[1].href,
'https://test/site/group/url');
assert.equal(dom(element.root)
.querySelectorAll('.nameColumn a')[2].href,
'https://test/site/group/url');
});
test('save members correctly', () => {
element._groupOwner = true;
test('save members correctly', () => {
element._groupOwner = true;
const memberName = 'test-admin';
const memberName = 'test-admin';
const saveStub = sandbox.stub(element.$.restAPI, 'saveGroupMembers',
() => Promise.resolve({}));
const saveStub = sandbox.stub(element.$.restAPI, 'saveGroupMembers',
() => Promise.resolve({}));
const button = element.$.saveGroupMember;
const button = element.$.saveGroupMember;
assert.isTrue(button.hasAttribute('disabled'));
element.$.groupMemberSearchInput.text = memberName;
element.$.groupMemberSearchInput.value = 1234;
assert.isFalse(button.hasAttribute('disabled'));
return element._handleSavingGroupMember().then(() => {
assert.isTrue(button.hasAttribute('disabled'));
element.$.groupMemberSearchInput.text = memberName;
element.$.groupMemberSearchInput.value = 1234;
assert.isFalse(button.hasAttribute('disabled'));
return element._handleSavingGroupMember().then(() => {
assert.isTrue(button.hasAttribute('disabled'));
assert.isFalse(element.$.Title.classList.contains('edited'));
assert.isTrue(saveStub.lastCall.calledWithExactly('Administrators',
1234));
});
});
test('save included groups correctly', () => {
element._groupOwner = true;
const includedGroupName = 'testName';
const saveIncludedGroupStub = sandbox.stub(
element.$.restAPI, 'saveIncludedGroup', () => Promise.resolve({}));
const button = element.$.saveIncludedGroups;
assert.isTrue(button.hasAttribute('disabled'));
element.$.includedGroupSearchInput.text = includedGroupName;
element.$.includedGroupSearchInput.value = 'testId';
assert.isFalse(button.hasAttribute('disabled'));
return element._handleSavingIncludedGroups().then(() => {
assert.isTrue(button.hasAttribute('disabled'));
assert.isFalse(element.$.Title.classList.contains('edited'));
assert.equal(saveIncludedGroupStub.lastCall.args[0], 'Administrators');
assert.equal(saveIncludedGroupStub.lastCall.args[1], 'testId');
});
});
test('add included group 404 shows helpful error text', () => {
element._groupOwner = true;
const memberName = 'bad-name';
const alertStub = sandbox.stub();
element.addEventListener('show-alert', alertStub);
const error = new Error('error');
error.status = 404;
sandbox.stub(element.$.restAPI, 'saveGroupMembers',
() => Promise.reject(error));
element.$.groupMemberSearchInput.text = memberName;
element.$.groupMemberSearchInput.value = 1234;
return element._handleSavingIncludedGroups().then(() => {
assert.isTrue(alertStub.called);
});
});
test('_getAccountSuggestions empty', done => {
element
._getAccountSuggestions('nonexistent').then(accounts => {
assert.equal(accounts.length, 0);
done();
});
});
test('_getAccountSuggestions non-empty', done => {
element
._getAccountSuggestions('test-').then(accounts => {
assert.equal(accounts.length, 3);
assert.equal(accounts[0].name,
'test-account <test.account@example.com>');
assert.equal(accounts[1].name, 'test-admin <test.admin@example.com>');
assert.equal(accounts[2].name, 'test-git');
done();
});
});
test('_getGroupSuggestions empty', done => {
element
._getGroupSuggestions('nonexistent').then(groups => {
assert.equal(groups.length, 0);
done();
});
});
test('_getGroupSuggestions non-empty', done => {
element
._getGroupSuggestions('test').then(groups => {
assert.equal(groups.length, 2);
assert.equal(groups[0].name, 'test-admin');
assert.equal(groups[1].name, 'test/Administrator (admin)');
done();
});
});
test('_computeHideItemClass returns string for admin', () => {
const admin = true;
const owner = false;
assert.equal(element._computeHideItemClass(owner, admin), '');
});
test('_computeHideItemClass returns hideItem for admin and owner', () => {
const admin = false;
const owner = false;
assert.equal(element._computeHideItemClass(owner, admin), 'canModify');
});
test('_computeHideItemClass returns string for owner', () => {
const admin = false;
const owner = true;
assert.equal(element._computeHideItemClass(owner, admin), '');
});
test('delete member', () => {
const deletelBtns = Polymer.dom(element.root)
.querySelectorAll('.deleteMembersButton');
MockInteractions.tap(deletelBtns[0]);
assert.equal(element._itemId, '1000097');
assert.equal(element._itemName, 'jane');
MockInteractions.tap(deletelBtns[1]);
assert.equal(element._itemId, '1000096');
assert.equal(element._itemName, 'Test User');
MockInteractions.tap(deletelBtns[2]);
assert.equal(element._itemId, '1000095');
assert.equal(element._itemName, 'Gerrit');
MockInteractions.tap(deletelBtns[3]);
assert.equal(element._itemId, '1000098');
assert.equal(element._itemName, '1000098');
});
test('delete included groups', () => {
const deletelBtns = Polymer.dom(element.root)
.querySelectorAll('.deleteIncludedGroupButton');
MockInteractions.tap(deletelBtns[0]);
assert.equal(element._itemId, 'testId');
assert.equal(element._itemName, 'testName');
MockInteractions.tap(deletelBtns[1]);
assert.equal(element._itemId, 'testId2');
assert.equal(element._itemName, 'testName2');
MockInteractions.tap(deletelBtns[2]);
assert.equal(element._itemId, 'testId3');
assert.equal(element._itemName, 'testName3');
});
test('_computeLoadingClass', () => {
assert.equal(element._computeLoadingClass(true), 'loading');
assert.equal(element._computeLoadingClass(false), '');
});
test('_computeGroupUrl', () => {
assert.isUndefined(element._computeGroupUrl(undefined));
assert.isUndefined(element._computeGroupUrl(false));
let url = '#/admin/groups/uuid-529b3c2605bb1029c8146f9de4a91c776fe64498';
assert.equal(element._computeGroupUrl(url),
'https://test/site/admin/groups/' +
'uuid-529b3c2605bb1029c8146f9de4a91c776fe64498');
url = 'https://gerrit.local/admin/groups/' +
'uuid-529b3c2605bb1029c8146f9de4a91c776fe64498';
assert.equal(element._computeGroupUrl(url), url);
});
test('fires page-error', done => {
groupStub.restore();
element.groupId = 1;
const response = {status: 404};
sandbox.stub(
element.$.restAPI, 'getGroupConfig', (group, errFn) => {
errFn(response);
});
element.addEventListener('page-error', e => {
assert.deepEqual(e.detail.response, response);
done();
});
element._loadGroupDetails();
assert.isFalse(element.$.Title.classList.contains('edited'));
assert.isTrue(saveStub.lastCall.calledWithExactly('Administrators',
1234));
});
});
test('save included groups correctly', () => {
element._groupOwner = true;
const includedGroupName = 'testName';
const saveIncludedGroupStub = sandbox.stub(
element.$.restAPI, 'saveIncludedGroup', () => Promise.resolve({}));
const button = element.$.saveIncludedGroups;
assert.isTrue(button.hasAttribute('disabled'));
element.$.includedGroupSearchInput.text = includedGroupName;
element.$.includedGroupSearchInput.value = 'testId';
assert.isFalse(button.hasAttribute('disabled'));
return element._handleSavingIncludedGroups().then(() => {
assert.isTrue(button.hasAttribute('disabled'));
assert.isFalse(element.$.Title.classList.contains('edited'));
assert.equal(saveIncludedGroupStub.lastCall.args[0], 'Administrators');
assert.equal(saveIncludedGroupStub.lastCall.args[1], 'testId');
});
});
test('add included group 404 shows helpful error text', () => {
element._groupOwner = true;
const memberName = 'bad-name';
const alertStub = sandbox.stub();
element.addEventListener('show-alert', alertStub);
const error = new Error('error');
error.status = 404;
sandbox.stub(element.$.restAPI, 'saveGroupMembers',
() => Promise.reject(error));
element.$.groupMemberSearchInput.text = memberName;
element.$.groupMemberSearchInput.value = 1234;
return element._handleSavingIncludedGroups().then(() => {
assert.isTrue(alertStub.called);
});
});
test('_getAccountSuggestions empty', done => {
element
._getAccountSuggestions('nonexistent').then(accounts => {
assert.equal(accounts.length, 0);
done();
});
});
test('_getAccountSuggestions non-empty', done => {
element
._getAccountSuggestions('test-').then(accounts => {
assert.equal(accounts.length, 3);
assert.equal(accounts[0].name,
'test-account <test.account@example.com>');
assert.equal(accounts[1].name, 'test-admin <test.admin@example.com>');
assert.equal(accounts[2].name, 'test-git');
done();
});
});
test('_getGroupSuggestions empty', done => {
element
._getGroupSuggestions('nonexistent').then(groups => {
assert.equal(groups.length, 0);
done();
});
});
test('_getGroupSuggestions non-empty', done => {
element
._getGroupSuggestions('test').then(groups => {
assert.equal(groups.length, 2);
assert.equal(groups[0].name, 'test-admin');
assert.equal(groups[1].name, 'test/Administrator (admin)');
done();
});
});
test('_computeHideItemClass returns string for admin', () => {
const admin = true;
const owner = false;
assert.equal(element._computeHideItemClass(owner, admin), '');
});
test('_computeHideItemClass returns hideItem for admin and owner', () => {
const admin = false;
const owner = false;
assert.equal(element._computeHideItemClass(owner, admin), 'canModify');
});
test('_computeHideItemClass returns string for owner', () => {
const admin = false;
const owner = true;
assert.equal(element._computeHideItemClass(owner, admin), '');
});
test('delete member', () => {
const deletelBtns = dom(element.root)
.querySelectorAll('.deleteMembersButton');
MockInteractions.tap(deletelBtns[0]);
assert.equal(element._itemId, '1000097');
assert.equal(element._itemName, 'jane');
MockInteractions.tap(deletelBtns[1]);
assert.equal(element._itemId, '1000096');
assert.equal(element._itemName, 'Test User');
MockInteractions.tap(deletelBtns[2]);
assert.equal(element._itemId, '1000095');
assert.equal(element._itemName, 'Gerrit');
MockInteractions.tap(deletelBtns[3]);
assert.equal(element._itemId, '1000098');
assert.equal(element._itemName, '1000098');
});
test('delete included groups', () => {
const deletelBtns = dom(element.root)
.querySelectorAll('.deleteIncludedGroupButton');
MockInteractions.tap(deletelBtns[0]);
assert.equal(element._itemId, 'testId');
assert.equal(element._itemName, 'testName');
MockInteractions.tap(deletelBtns[1]);
assert.equal(element._itemId, 'testId2');
assert.equal(element._itemName, 'testName2');
MockInteractions.tap(deletelBtns[2]);
assert.equal(element._itemId, 'testId3');
assert.equal(element._itemName, 'testName3');
});
test('_computeLoadingClass', () => {
assert.equal(element._computeLoadingClass(true), 'loading');
assert.equal(element._computeLoadingClass(false), '');
});
test('_computeGroupUrl', () => {
assert.isUndefined(element._computeGroupUrl(undefined));
assert.isUndefined(element._computeGroupUrl(false));
let url = '#/admin/groups/uuid-529b3c2605bb1029c8146f9de4a91c776fe64498';
assert.equal(element._computeGroupUrl(url),
'https://test/site/admin/groups/' +
'uuid-529b3c2605bb1029c8146f9de4a91c776fe64498');
url = 'https://gerrit.local/admin/groups/' +
'uuid-529b3c2605bb1029c8146f9de4a91c776fe64498';
assert.equal(element._computeGroupUrl(url), url);
});
test('fires page-error', done => {
groupStub.restore();
element.groupId = 1;
const response = {status: 404};
sandbox.stub(
element.$.restAPI, 'getGroupConfig', (group, errFn) => {
errFn(response);
});
element.addEventListener('page-error', e => {
assert.deepEqual(e.detail.response, response);
done();
});
element._loadGroupDetails();
});
});
</script>