blob: 5cf71f8be5ed239c332c2cb6b74767e79be4dcd8 [file] [log] [blame]
/**
* @license
* Copyright 2017 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import '../../../test/common-test-setup';
import './gr-group';
import {GrGroup} from './gr-group';
import {
addListenerForTest,
mockPromise,
queryAndAssert,
stubRestApi,
waitUntil,
} from '../../../test/test-utils';
import {createGroupInfo} from '../../../test/test-data-generators';
import {GroupId, GroupInfo, GroupName} from '../../../types/common';
import {GrAutocomplete} from '../../shared/gr-autocomplete/gr-autocomplete';
import {GrButton} from '../../shared/gr-button/gr-button';
import {GrCopyClipboard} from '../../shared/gr-copy-clipboard/gr-copy-clipboard';
import {GrSelect} from '../../shared/gr-select/gr-select';
import {fixture, html, assert} from '@open-wc/testing';
suite('gr-group tests', () => {
let element: GrGroup;
let groupStub: sinon.SinonStub;
const group: GroupInfo = {
...createGroupInfo('6a1e70e1a88782771a91808c8af9bbb7a9871389'),
url: '#/admin/groups/uuid-6a1e70e1a88782771a91808c8af9bbb7a9871389',
options: {
visible_to_all: false,
},
description: 'Gerrit Site Administrators',
group_id: 1,
owner: 'Administrators',
owner_id: '6a1e70e1a88782771a91808c8af9bbb7a9871389',
name: 'Administrators' as GroupName,
};
setup(async () => {
element = await fixture(html`<gr-group></gr-group>`);
groupStub = stubRestApi('getGroupConfig').returns(Promise.resolve(group));
});
test('render', () => {
assert.shadowDom.equal(
element,
/* HTML */ `
<div class="gr-form-styles main read-only">
<div class="loading" id="loading">Loading...</div>
<div class="loading" id="loadedContent">
<h1 class="heading-1" id="Title"></h1>
<h2 class="heading-2" id="configurations">General</h2>
<div id="form">
<fieldset>
<h3 class="heading-3" id="groupUUID">Group UUID</h3>
<fieldset>
<gr-copy-clipboard id="uuid"> </gr-copy-clipboard>
</fieldset>
<h3 class="heading-3" id="groupName">Group Name</h3>
<fieldset>
<span class="value">
<gr-autocomplete disabled="" id="groupNameInput">
</gr-autocomplete>
</span>
<span class="value">
<gr-button
aria-disabled="true"
disabled=""
id="inputUpdateNameBtn"
role="button"
tabindex="-1"
>
Rename Group
</gr-button>
</span>
</fieldset>
<h3 class="heading-3" id="groupOwner">Owners</h3>
<fieldset>
<span class="value">
<gr-autocomplete disabled="" id="groupOwnerInput">
</gr-autocomplete>
</span>
<span class="value">
<gr-button
aria-disabled="true"
disabled=""
id="inputUpdateOwnerBtn"
role="button"
tabindex="-1"
>
Change Owners
</gr-button>
</span>
</fieldset>
<h3 class="heading-3">Description</h3>
<fieldset>
<div>
<gr-suggestion-textarea
autocomplete="on"
class="description monospace"
disabled=""
monospace=""
rows="4"
>
</gr-suggestion-textarea>
</div>
<span class="value">
<gr-button
aria-disabled="true"
disabled=""
role="button"
tabindex="-1"
>
Save Description
</gr-button>
</span>
</fieldset>
<h3 class="heading-3" id="options">Group Options</h3>
<fieldset>
<section>
<span class="title">
Make group visible to all registered users
</span>
<span class="value">
<gr-select id="visibleToAll">
<select disabled="">
<option value="false">False</option>
<option value="true">True</option>
</select>
</gr-select>
</span>
</section>
<span class="value">
<gr-button
aria-disabled="true"
disabled=""
role="button"
tabindex="-1"
>
Save Group Options
</gr-button>
</span>
</fieldset>
</fieldset>
</div>
</div>
</div>
`
);
});
test('loading displays before group config is loaded', () => {
assert.isTrue(
queryAndAssert<HTMLDivElement>(element, '#loading').classList.contains(
'loading'
)
);
assert.isFalse(
getComputedStyle(queryAndAssert<HTMLDivElement>(element, '#loading'))
.display === 'none'
);
assert.isTrue(
queryAndAssert<HTMLDivElement>(
element,
'#loadedContent'
).classList.contains('loading')
);
assert.isTrue(
getComputedStyle(
queryAndAssert<HTMLDivElement>(element, '#loadedContent')
).display === 'none'
);
});
test('default values are populated with internal group', async () => {
stubRestApi('getIsGroupOwner').returns(Promise.resolve(true));
element.groupId = '1' as GroupId;
await element.loadGroup();
assert.isTrue(element.groupIsInternal);
// The value returned is a boolean in a string
// thus we have to check with the string.
assert.equal(
queryAndAssert<GrSelect>(element, '#visibleToAll').bindValue,
'false'
);
});
test('default values with external group', async () => {
const groupExternal = {...group};
groupExternal.id = 'external-group-id' as GroupId;
groupStub.restore();
groupStub = stubRestApi('getGroupConfig').returns(
Promise.resolve(groupExternal)
);
stubRestApi('getIsGroupOwner').returns(Promise.resolve(true));
element.groupId = '1' as GroupId;
await element.loadGroup();
assert.isFalse(element.groupIsInternal);
// The value returned is a boolean in a string
// thus we have to check with the string.
assert.equal(
queryAndAssert<GrSelect>(element, '#visibleToAll').bindValue,
'false'
);
});
test('rename group', async () => {
const groupName = 'test-group';
const groupName2 = 'test-group2';
element.groupId = '1' as GroupId;
element.groupConfig = {
name: groupName as GroupName,
id: '1' as GroupId,
};
element.originalName = groupName as GroupName;
stubRestApi('getIsGroupOwner').returns(Promise.resolve(true));
stubRestApi('saveGroupName').returns(
Promise.resolve({...new Response(), status: 200})
);
const button = queryAndAssert<GrButton>(element, '#inputUpdateNameBtn');
await element.loadGroup();
assert.isTrue(button.hasAttribute('disabled'));
assert.isFalse(
queryAndAssert<HTMLHeadingElement>(element, '#Title').classList.contains(
'edited'
)
);
queryAndAssert<GrAutocomplete>(element, '#groupNameInput').text =
groupName2;
await waitUntil(() => button.hasAttribute('disabled') === false);
assert.isTrue(
queryAndAssert<HTMLHeadingElement>(
element,
'#groupName'
).classList.contains('edited')
);
await element.handleSaveName();
assert.isTrue(button.disabled);
assert.isFalse(
queryAndAssert<HTMLHeadingElement>(element, '#Title').classList.contains(
'edited'
)
);
assert.equal(element.originalName, groupName2);
});
test('rename group owner', async () => {
const groupName = 'test-group';
element.groupId = '1' as GroupId;
element.groupConfig = {
name: groupName as GroupName,
id: '1' as GroupId,
};
element.groupConfigOwner = 'testId';
element.groupOwner = true;
stubRestApi('getIsGroupOwner').returns(Promise.resolve(true));
const button = queryAndAssert<GrButton>(element, '#inputUpdateOwnerBtn');
await element.loadGroup();
assert.isTrue(button.disabled);
assert.isFalse(
queryAndAssert<HTMLHeadingElement>(element, '#Title').classList.contains(
'edited'
)
);
queryAndAssert<GrAutocomplete>(element, '#groupOwnerInput').text =
'testId2';
await waitUntil(() => button.disabled === false);
assert.isTrue(
queryAndAssert<HTMLHeadingElement>(
element,
'#groupOwner'
).classList.contains('edited')
);
await element.handleSaveOwner();
assert.isTrue(button.disabled);
assert.isFalse(
queryAndAssert<HTMLHeadingElement>(element, '#Title').classList.contains(
'edited'
)
);
});
test('test for undefined group name', async () => {
groupStub.restore();
stubRestApi('getGroupConfig').returns(Promise.resolve(undefined));
assert.isUndefined(element.groupId);
element.groupId = '1' as GroupId;
assert.isDefined(element.groupId);
// Test that loading shows instead of filling
// in group details
await element.loadGroup();
assert.isTrue(
queryAndAssert<HTMLDivElement>(element, '#loading').classList.contains(
'loading'
)
);
assert.isTrue(element.loading);
});
test('test fire event', async () => {
element.groupConfig = {
name: 'test-group' as GroupName,
id: '1' as GroupId,
};
element.groupId = 'gg' as GroupId;
stubRestApi('saveGroupName').returns(
Promise.resolve({...new Response(), status: 200})
);
const showStub = sinon.stub(element, 'dispatchEvent');
await element.handleSaveName();
assert.isTrue(showStub.called);
});
test('computeGroupDisabled', () => {
element.isAdmin = true;
element.groupOwner = false;
element.groupIsInternal = true;
assert.equal(element.computeGroupDisabled(), false);
element.isAdmin = false;
assert.equal(element.computeGroupDisabled(), true);
element.groupOwner = true;
assert.equal(element.computeGroupDisabled(), false);
element.groupOwner = false;
assert.equal(element.computeGroupDisabled(), true);
element.groupIsInternal = false;
assert.equal(element.computeGroupDisabled(), true);
element.isAdmin = true;
assert.equal(element.computeGroupDisabled(), true);
});
test('computeLoadingClass', () => {
element.loading = true;
assert.equal(element.computeLoadingClass(), 'loading');
element.loading = false;
assert.equal(element.computeLoadingClass(), '');
});
test('fires page-error', async () => {
groupStub.restore();
element.groupId = '1' as GroupId;
const response = {...new Response(), status: 404};
stubRestApi('getGroupConfig').callsFake((_, errFn) => {
if (errFn !== undefined) {
errFn(response);
} else {
assert.fail('errFn is undefined');
}
return Promise.resolve(undefined);
});
const promise = mockPromise();
addListenerForTest(document, 'page-error', e => {
assert.deepEqual((e as CustomEvent).detail.response, response);
promise.resolve();
});
await element.loadGroup();
await promise;
});
test('uuid', async () => {
element.groupConfig = {
id: '6a1e70e1a88782771a91808c8af9bbb7a9871389' as GroupId,
};
await element.updateComplete;
assert.equal(
element.groupConfig.id,
queryAndAssert<GrCopyClipboard>(element, '#uuid').text
);
element.groupConfig = {
id: 'user%2Fgroup' as GroupId,
};
await element.updateComplete;
assert.equal(
'user/group',
queryAndAssert<GrCopyClipboard>(element, '#uuid').text
);
});
});