
The legacycid_in_change_table preference predates the change_table column preference and is thus persisted in separate field. With this change, a checkbox to drive this preference is added to the change table editor component as though it were a change_table preference. Feature: Issue 5333 Change-Id: Ia055ef23d7eec341455680b67bb6f3b0bdcbf531
482 lines
16 KiB
HTML
482 lines
16 KiB
HTML
<!DOCTYPE html>
|
|
<!--
|
|
Copyright (C) 2016 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-settings-view</title>
|
|
|
|
<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-settings-view.html">
|
|
|
|
<script>void(0);</script>
|
|
|
|
<test-fixture id="basic">
|
|
<template>
|
|
<gr-settings-view></gr-settings-view>
|
|
</template>
|
|
</test-fixture>
|
|
|
|
<test-fixture id="blank">
|
|
<template>
|
|
<div></div>
|
|
</template>
|
|
</test-fixture>
|
|
|
|
<script>
|
|
suite('gr-settings-view tests', () => {
|
|
let element;
|
|
let account;
|
|
let preferences;
|
|
let diffPreferences;
|
|
let config;
|
|
let sandbox;
|
|
|
|
function valueOf(title, fieldsetid) {
|
|
const sections = element.$[fieldsetid].querySelectorAll('section');
|
|
let titleEl;
|
|
for (let i = 0; i < sections.length; i++) {
|
|
titleEl = sections[i].querySelector('.title');
|
|
if (titleEl.textContent.trim() === title) {
|
|
return sections[i].querySelector('.value');
|
|
}
|
|
}
|
|
}
|
|
|
|
// Because deepEqual isn't behaving in Safari.
|
|
function assertMenusEqual(actual, expected) {
|
|
assert.equal(actual.length, expected.length);
|
|
for (let i = 0; i < actual.length; i++) {
|
|
assert.equal(actual[i].name, expected[i].name);
|
|
assert.equal(actual[i].url, expected[i].url);
|
|
}
|
|
}
|
|
|
|
function stubAddAccountEmail(statusCode) {
|
|
return sandbox.stub(element.$.restAPI, 'addAccountEmail',
|
|
() => { return Promise.resolve({status: statusCode}); });
|
|
}
|
|
|
|
setup(done => {
|
|
sandbox = sinon.sandbox.create();
|
|
account = {
|
|
_account_id: 123,
|
|
name: 'user name',
|
|
email: 'user@email',
|
|
username: 'user username',
|
|
registered: '2000-01-01 00:00:00.000000000',
|
|
};
|
|
preferences = {
|
|
changes_per_page: 25,
|
|
date_format: 'UK',
|
|
time_format: 'HHMM_12',
|
|
diff_view: 'UNIFIED_DIFF',
|
|
email_strategy: 'ENABLED',
|
|
email_format: 'HTML_PLAINTEXT',
|
|
|
|
my: [
|
|
{url: '/first/url', name: 'first name', target: '_blank'},
|
|
{url: '/second/url', name: 'second name', target: '_blank'},
|
|
],
|
|
change_table: [],
|
|
};
|
|
diffPreferences = {
|
|
context: 10,
|
|
tab_size: 8,
|
|
font_size: 12,
|
|
line_length: 100,
|
|
cursor_blink_rate: 0,
|
|
line_wrapping: false,
|
|
intraline_difference: true,
|
|
show_line_endings: true,
|
|
show_tabs: true,
|
|
show_whitespace_errors: true,
|
|
syntax_highlighting: true,
|
|
auto_hide_diff_table_header: true,
|
|
theme: 'DEFAULT',
|
|
ignore_whitespace: 'IGNORE_NONE',
|
|
};
|
|
config = {auth: {editable_account_fields: []}};
|
|
|
|
stub('gr-rest-api-interface', {
|
|
getLoggedIn() { return Promise.resolve(true); },
|
|
getAccount() { return Promise.resolve(account); },
|
|
getPreferences() { return Promise.resolve(preferences); },
|
|
getDiffPreferences() {
|
|
return Promise.resolve(diffPreferences);
|
|
},
|
|
getWatchedProjects() {
|
|
return Promise.resolve([]);
|
|
},
|
|
getAccountEmails() { return Promise.resolve(); },
|
|
getConfig() { return Promise.resolve(config); },
|
|
getAccountGroups() { return Promise.resolve([]); },
|
|
});
|
|
element = fixture('basic');
|
|
|
|
// Allow the element to render.
|
|
element._loadingPromise.then(done);
|
|
});
|
|
|
|
teardown(() => {
|
|
sandbox.restore();
|
|
});
|
|
|
|
test('calls the title-change event', () => {
|
|
const titleChangedStub = sandbox.stub();
|
|
|
|
// Create a new view.
|
|
const newElement = document.createElement('gr-settings-view');
|
|
newElement.addEventListener('title-change', titleChangedStub);
|
|
|
|
// Attach it to the fixture.
|
|
const blank = fixture('blank');
|
|
blank.appendChild(newElement);
|
|
|
|
Polymer.dom.flush();
|
|
|
|
assert.isTrue(titleChangedStub.called);
|
|
assert.equal(titleChangedStub.getCall(0).args[0].detail.title,
|
|
'Settings');
|
|
});
|
|
|
|
test('user preferences', done => {
|
|
// Rendered with the expected preferences selected.
|
|
assert.equal(valueOf('Changes per page', 'preferences')
|
|
.firstElementChild.bindValue, preferences.changes_per_page);
|
|
assert.equal(valueOf('Date/time format', 'preferences')
|
|
.firstElementChild.bindValue, preferences.date_format);
|
|
assert.equal(valueOf('Date/time format', 'preferences')
|
|
.lastElementChild.bindValue, preferences.time_format);
|
|
assert.equal(valueOf('Email notifications', 'preferences')
|
|
.firstElementChild.bindValue, preferences.email_strategy);
|
|
assert.equal(valueOf('Email format', 'preferences')
|
|
.firstElementChild.bindValue, preferences.email_format);
|
|
assert.equal(valueOf('Diff view', 'preferences')
|
|
.firstElementChild.bindValue, preferences.diff_view);
|
|
assert.equal(valueOf('Expand inline diffs', 'preferences')
|
|
.firstElementChild.checked, false);
|
|
assert.equal(valueOf('Publish comments on push', 'preferences')
|
|
.firstElementChild.checked, false);
|
|
assert.equal(valueOf(
|
|
'Insert Signed-off-by Footer For Inline Edit Changes', 'preferences')
|
|
.firstElementChild.checked, false);
|
|
|
|
assert.isFalse(element._prefsChanged);
|
|
assert.isFalse(element._menuChanged);
|
|
|
|
// Change the diff view element.
|
|
const diffSelect = valueOf('Diff view', 'preferences').firstElementChild;
|
|
diffSelect.bindValue = 'SIDE_BY_SIDE';
|
|
|
|
const expandInlineDiffs =
|
|
valueOf('Expand inline diffs', 'preferences').firstElementChild;
|
|
diffSelect.fire('change');
|
|
|
|
MockInteractions.tap(expandInlineDiffs);
|
|
|
|
assert.isTrue(element._prefsChanged);
|
|
assert.isFalse(element._menuChanged);
|
|
|
|
stub('gr-rest-api-interface', {
|
|
savePreferences(prefs) {
|
|
assert.equal(prefs.diff_view, 'SIDE_BY_SIDE');
|
|
assertMenusEqual(prefs.my, preferences.my);
|
|
assert.equal(prefs.expand_inline_diffs, true);
|
|
return Promise.resolve();
|
|
},
|
|
});
|
|
|
|
// Save the change.
|
|
element._handleSavePreferences().then(() => {
|
|
assert.isFalse(element._prefsChanged);
|
|
assert.isFalse(element._menuChanged);
|
|
done();
|
|
});
|
|
});
|
|
|
|
test('publish comments on push', done => {
|
|
const publishCommentsOnPush =
|
|
valueOf('Publish comments on push', 'preferences').firstElementChild;
|
|
MockInteractions.tap(publishCommentsOnPush);
|
|
|
|
assert.isFalse(element._menuChanged);
|
|
assert.isTrue(element._prefsChanged);
|
|
|
|
stub('gr-rest-api-interface', {
|
|
savePreferences(prefs) {
|
|
assert.equal(prefs.publish_comments_on_push, true);
|
|
return Promise.resolve();
|
|
},
|
|
});
|
|
|
|
// Save the change.
|
|
element._handleSavePreferences().then(() => {
|
|
assert.isFalse(element._prefsChanged);
|
|
assert.isFalse(element._menuChanged);
|
|
done();
|
|
});
|
|
});
|
|
|
|
test('diff preferences', done => {
|
|
// Rendered with the expected preferences selected.
|
|
assert.equal(valueOf('Context', 'diffPreferences')
|
|
.firstElementChild.bindValue, diffPreferences.context);
|
|
assert.equal(valueOf('Diff width', 'diffPreferences')
|
|
.firstElementChild.bindValue, diffPreferences.line_length);
|
|
assert.equal(valueOf('Tab width', 'diffPreferences')
|
|
.firstElementChild.bindValue, diffPreferences.tab_size);
|
|
assert.equal(valueOf('Font size', 'diffPreferences')
|
|
.firstElementChild.bindValue, diffPreferences.font_size);
|
|
assert.equal(valueOf('Show tabs', 'diffPreferences')
|
|
.firstElementChild.checked, diffPreferences.show_tabs);
|
|
assert.equal(valueOf('Show trailing whitespace', 'diffPreferences')
|
|
.firstElementChild.checked, diffPreferences.show_whitespace_errors);
|
|
assert.equal(valueOf('Fit to screen', 'diffPreferences')
|
|
.firstElementChild.checked, diffPreferences.line_wrapping);
|
|
|
|
assert.isFalse(element._diffPrefsChanged);
|
|
|
|
const showTabsCheckbox = valueOf('Show tabs', 'diffPreferences')
|
|
.firstElementChild;
|
|
showTabsCheckbox.checked = false;
|
|
element._handleShowTabsChanged();
|
|
|
|
assert.isTrue(element._diffPrefsChanged);
|
|
|
|
stub('gr-rest-api-interface', {
|
|
saveDiffPreferences(prefs) {
|
|
assert.equal(prefs.show_tabs, false);
|
|
return Promise.resolve();
|
|
},
|
|
});
|
|
|
|
// Save the change.
|
|
element._handleSaveDiffPreferences().then(() => {
|
|
assert.isFalse(element._diffPrefsChanged);
|
|
done();
|
|
});
|
|
});
|
|
|
|
test('columns input is hidden with fit to scsreen is selected', () => {
|
|
assert.isFalse(element.$.columnsPref.hidden);
|
|
|
|
MockInteractions.tap(element.$.lineWrapping);
|
|
assert.isTrue(element.$.columnsPref.hidden);
|
|
|
|
MockInteractions.tap(element.$.lineWrapping);
|
|
assert.isFalse(element.$.columnsPref.hidden);
|
|
});
|
|
|
|
test('menu', done => {
|
|
assert.isFalse(element._menuChanged);
|
|
assert.isFalse(element._prefsChanged);
|
|
|
|
assertMenusEqual(element._localMenu, preferences.my);
|
|
|
|
const menu = element.$.menu.firstElementChild;
|
|
let tableRows = Polymer.dom(menu.root).querySelectorAll('tbody tr');
|
|
assert.equal(tableRows.length, preferences.my.length);
|
|
|
|
// Add a menu item:
|
|
element.splice('_localMenu', 1, 0, {name: 'foo', url: 'bar', target: ''});
|
|
Polymer.dom.flush();
|
|
|
|
tableRows = Polymer.dom(menu.root).querySelectorAll('tbody tr');
|
|
assert.equal(tableRows.length, preferences.my.length + 1);
|
|
|
|
assert.isTrue(element._menuChanged);
|
|
assert.isFalse(element._prefsChanged);
|
|
|
|
stub('gr-rest-api-interface', {
|
|
savePreferences(prefs) {
|
|
assertMenusEqual(prefs.my, element._localMenu);
|
|
return Promise.resolve();
|
|
},
|
|
});
|
|
|
|
element._handleSaveMenu().then(() => {
|
|
assert.isFalse(element._menuChanged);
|
|
assert.isFalse(element._prefsChanged);
|
|
assertMenusEqual(element.prefs.my, element._localMenu);
|
|
done();
|
|
});
|
|
});
|
|
|
|
test('add email validation', () => {
|
|
assert.isFalse(element._isNewEmailValid('invalid email'));
|
|
assert.isTrue(element._isNewEmailValid('vaguely@valid.email'));
|
|
|
|
assert.isFalse(
|
|
element._computeAddEmailButtonEnabled('invalid email'), true);
|
|
assert.isFalse(
|
|
element._computeAddEmailButtonEnabled('vaguely@valid.email', true));
|
|
assert.isTrue(
|
|
element._computeAddEmailButtonEnabled('vaguely@valid.email', false));
|
|
});
|
|
|
|
test('add email does not save invalid', () => {
|
|
const addEmailStub = stubAddAccountEmail(201);
|
|
|
|
assert.isFalse(element._addingEmail);
|
|
assert.isNotOk(element._lastSentVerificationEmail);
|
|
element._newEmail = 'invalid email';
|
|
|
|
element._handleAddEmailButton();
|
|
|
|
assert.isFalse(element._addingEmail);
|
|
assert.isFalse(addEmailStub.called);
|
|
assert.isNotOk(element._lastSentVerificationEmail);
|
|
|
|
assert.isFalse(addEmailStub.called);
|
|
});
|
|
|
|
test('add email does save valid', done => {
|
|
const addEmailStub = stubAddAccountEmail(201);
|
|
|
|
assert.isFalse(element._addingEmail);
|
|
assert.isNotOk(element._lastSentVerificationEmail);
|
|
element._newEmail = 'valid@email.com';
|
|
|
|
element._handleAddEmailButton();
|
|
|
|
assert.isTrue(element._addingEmail);
|
|
assert.isTrue(addEmailStub.called);
|
|
|
|
assert.isTrue(addEmailStub.called);
|
|
addEmailStub.lastCall.returnValue.then(() => {
|
|
assert.isOk(element._lastSentVerificationEmail);
|
|
done();
|
|
});
|
|
});
|
|
|
|
test('add email does not set last-email if error', done => {
|
|
const addEmailStub = stubAddAccountEmail(500);
|
|
|
|
assert.isNotOk(element._lastSentVerificationEmail);
|
|
element._newEmail = 'valid@email.com';
|
|
|
|
element._handleAddEmailButton();
|
|
|
|
assert.isTrue(addEmailStub.called);
|
|
addEmailStub.lastCall.returnValue.then(() => {
|
|
assert.isNotOk(element._lastSentVerificationEmail);
|
|
done();
|
|
});
|
|
});
|
|
|
|
test('emails are loaded without emailToken', () => {
|
|
sandbox.stub(element.$.emailEditor, 'loadData');
|
|
element.params = {};
|
|
element.attached();
|
|
assert.isTrue(element.$.emailEditor.loadData.calledOnce);
|
|
});
|
|
|
|
test('_handleSaveChangeTable', () => {
|
|
let newColumns = ['Owner', 'Project', 'Branch'];
|
|
element._localChangeTableColumns = newColumns.slice(0);
|
|
element._showNumber = false;
|
|
const cloneStub = sandbox.stub(element, '_cloneChangeTableColumns');
|
|
element._handleSaveChangeTable();
|
|
assert.isTrue(cloneStub.calledOnce);
|
|
assert.deepEqual(element.prefs.change_table, newColumns);
|
|
assert.isNotOk(element.prefs.legacycid_in_change_table);
|
|
|
|
newColumns = ['Size'];
|
|
element._localChangeTableColumns = newColumns;
|
|
element._showNumber = true;
|
|
element._handleSaveChangeTable();
|
|
assert.isTrue(cloneStub.calledTwice);
|
|
assert.deepEqual(element.prefs.change_table, newColumns);
|
|
assert.isTrue(element.prefs.legacycid_in_change_table);
|
|
});
|
|
|
|
suite('_getFilterDocsLink', () => {
|
|
test('with http: docs base URL', () => {
|
|
const base = 'http://example.com/';
|
|
const result = element._getFilterDocsLink(base);
|
|
assert.equal(result, 'http://example.com/user-notify.html');
|
|
});
|
|
|
|
test('with http: docs base URL without slash', () => {
|
|
const base = 'http://example.com';
|
|
const result = element._getFilterDocsLink(base);
|
|
assert.equal(result, 'http://example.com/user-notify.html');
|
|
});
|
|
|
|
test('with https: docs base URL', () => {
|
|
const base = 'https://example.com/';
|
|
const result = element._getFilterDocsLink(base);
|
|
assert.equal(result, 'https://example.com/user-notify.html');
|
|
});
|
|
|
|
test('without docs base URL', () => {
|
|
const result = element._getFilterDocsLink(null);
|
|
assert.equal(result, 'https://gerrit-review.googlesource.com/' +
|
|
'Documentation/user-notify.html');
|
|
});
|
|
|
|
test('ignores non HTTP links', () => {
|
|
const base = 'javascript://alert("evil");';
|
|
const result = element._getFilterDocsLink(base);
|
|
assert.equal(result, 'https://gerrit-review.googlesource.com/' +
|
|
'Documentation/user-notify.html');
|
|
});
|
|
});
|
|
|
|
suite('when email verification token is provided', () => {
|
|
let resolveConfirm;
|
|
|
|
setup(() => {
|
|
sandbox.stub(element.$.emailEditor, 'loadData');
|
|
sandbox.stub(element.$.restAPI, 'confirmEmail', () => {
|
|
return new Promise(resolve => { resolveConfirm = resolve; });
|
|
});
|
|
element.params = {emailToken: 'foo'};
|
|
element.attached();
|
|
});
|
|
|
|
test('it is used to confirm email via rest API', () => {
|
|
assert.isTrue(element.$.restAPI.confirmEmail.calledOnce);
|
|
assert.isTrue(element.$.restAPI.confirmEmail.calledWith('foo'));
|
|
});
|
|
|
|
test('emails are not loaded initially', () => {
|
|
assert.isFalse(element.$.emailEditor.loadData.called);
|
|
});
|
|
|
|
test('user emails are loaded after email confirmed', done => {
|
|
element._loadingPromise.then(() => {
|
|
assert.isTrue(element.$.emailEditor.loadData.calledOnce);
|
|
done();
|
|
});
|
|
resolveConfirm();
|
|
});
|
|
|
|
test('show-alert is fired when email is confirmed', done => {
|
|
sandbox.spy(element, 'fire');
|
|
element._loadingPromise.then(() => {
|
|
assert.isTrue(
|
|
element.fire.calledWith('show-alert', {message: 'bar'}));
|
|
done();
|
|
});
|
|
resolveConfirm('bar');
|
|
});
|
|
});
|
|
});
|
|
</script>
|