648 lines
20 KiB
HTML
648 lines
20 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-rest-api-interface</title>
|
||
|
||
<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
|
||
<script src="../../../bower_components/web-component-tester/browser.js"></script>
|
||
<script src="../../../scripts/util.js"></script>
|
||
|
||
<link rel="import" href="../../../bower_components/iron-test-helpers/iron-test-helpers.html">
|
||
<link rel="import" href="gr-rest-api-interface.html">
|
||
|
||
<script>void(0);</script>
|
||
|
||
<test-fixture id="basic">
|
||
<template>
|
||
<gr-rest-api-interface></gr-rest-api-interface>
|
||
</template>
|
||
</test-fixture>
|
||
|
||
<script>
|
||
suite('gr-rest-api-interface tests', () => {
|
||
let element;
|
||
let sandbox;
|
||
|
||
setup(() => {
|
||
sandbox = sinon.sandbox.create();
|
||
element = fixture('basic');
|
||
const testJSON = ')]}\'\n{"hello": "bonjour"}';
|
||
sandbox.stub(window, 'fetch').returns(Promise.resolve({
|
||
ok: true,
|
||
text() {
|
||
return Promise.resolve(testJSON);
|
||
},
|
||
}));
|
||
});
|
||
|
||
teardown(() => {
|
||
sandbox.restore();
|
||
});
|
||
|
||
test('JSON prefix is properly removed', done => {
|
||
element.fetchJSON('/dummy/url').then(obj => {
|
||
assert.deepEqual(obj, {hello: 'bonjour'});
|
||
done();
|
||
});
|
||
});
|
||
|
||
test('cached results', done => {
|
||
let n = 0;
|
||
sandbox.stub(element, 'fetchJSON', () => {
|
||
return Promise.resolve(++n);
|
||
});
|
||
const promises = [];
|
||
promises.push(element._fetchSharedCacheURL('/foo'));
|
||
promises.push(element._fetchSharedCacheURL('/foo'));
|
||
promises.push(element._fetchSharedCacheURL('/foo'));
|
||
|
||
Promise.all(promises).then(results => {
|
||
assert.deepEqual(results, [1, 1, 1]);
|
||
element._fetchSharedCacheURL('/foo').then(foo => {
|
||
assert.equal(foo, 1);
|
||
done();
|
||
});
|
||
});
|
||
});
|
||
|
||
test('cached promise', done => {
|
||
const promise = Promise.reject('foo');
|
||
element._cache['/foo'] = promise;
|
||
element._fetchSharedCacheURL('/foo').catch(p => {
|
||
assert.equal(p, 'foo');
|
||
done();
|
||
});
|
||
});
|
||
|
||
test('params are properly encoded', () => {
|
||
let url = element._urlWithParams('/path/', {
|
||
sp: 'hola',
|
||
gr: 'guten tag',
|
||
noval: null,
|
||
});
|
||
assert.equal(url, '/path/?sp=hola&gr=guten%20tag&noval');
|
||
|
||
url = element._urlWithParams('/path/', {
|
||
sp: 'hola',
|
||
en: ['hey', 'hi'],
|
||
});
|
||
assert.equal(url, '/path/?sp=hola&en=hey&en=hi');
|
||
|
||
// Order must be maintained with array params.
|
||
url = element._urlWithParams('/path/', {
|
||
l: ['c', 'b', 'a'],
|
||
});
|
||
assert.equal(url, '/path/?l=c&l=b&l=a');
|
||
});
|
||
|
||
test('request callbacks can be canceled', done => {
|
||
let cancelCalled = false;
|
||
window.fetch.returns(Promise.resolve({
|
||
body: {
|
||
cancel() { cancelCalled = true; },
|
||
},
|
||
}));
|
||
element.fetchJSON('/dummy/url', null, () => { return true; }).then(
|
||
obj => {
|
||
assert.isUndefined(obj);
|
||
assert.isTrue(cancelCalled);
|
||
done();
|
||
});
|
||
});
|
||
|
||
test('parent diff comments are properly grouped', done => {
|
||
sandbox.stub(element, 'fetchJSON', () => {
|
||
return Promise.resolve({
|
||
'/COMMIT_MSG': [],
|
||
'sieve.go': [
|
||
{
|
||
updated: '2017-02-03 22:32:28.000000000',
|
||
message: 'this isn’t quite right',
|
||
},
|
||
{
|
||
side: 'PARENT',
|
||
message: 'how did this work in the first place?',
|
||
updated: '2017-02-03 22:33:28.000000000',
|
||
},
|
||
],
|
||
});
|
||
});
|
||
element._getDiffComments('42', '', 'PARENT', 1, 'sieve.go').then(
|
||
obj => {
|
||
assert.equal(obj.baseComments.length, 1);
|
||
assert.deepEqual(obj.baseComments[0], {
|
||
side: 'PARENT',
|
||
message: 'how did this work in the first place?',
|
||
path: 'sieve.go',
|
||
updated: '2017-02-03 22:33:28.000000000',
|
||
});
|
||
assert.equal(obj.comments.length, 1);
|
||
assert.deepEqual(obj.comments[0], {
|
||
message: 'this isn’t quite right',
|
||
path: 'sieve.go',
|
||
updated: '2017-02-03 22:32:28.000000000',
|
||
});
|
||
done();
|
||
});
|
||
});
|
||
|
||
test('_setRange', () => {
|
||
const comments = [
|
||
{
|
||
id: 1,
|
||
side: 'PARENT',
|
||
message: 'how did this work in the first place?',
|
||
updated: '2017-02-03 22:32:28.000000000',
|
||
range: {
|
||
start_line: 1,
|
||
start_character: 1,
|
||
end_line: 2,
|
||
end_character: 1,
|
||
},
|
||
},
|
||
{
|
||
id: 2,
|
||
in_reply_to: 1,
|
||
message: 'this isn’t quite right',
|
||
updated: '2017-02-03 22:33:28.000000000',
|
||
},
|
||
];
|
||
const expectedResult = {
|
||
id: 2,
|
||
in_reply_to: 1,
|
||
message: 'this isn’t quite right',
|
||
updated: '2017-02-03 22:33:28.000000000',
|
||
range: {
|
||
start_line: 1,
|
||
start_character: 1,
|
||
end_line: 2,
|
||
end_character: 1,
|
||
},
|
||
};
|
||
const comment = comments[1];
|
||
assert.deepEqual(element._setRange(comments, comment), expectedResult);
|
||
});
|
||
|
||
test('_setRanges', () => {
|
||
const comments = [
|
||
{
|
||
id: 3,
|
||
in_reply_to: 2,
|
||
message: 'this isn’t quite right either',
|
||
updated: '2017-02-03 22:34:28.000000000',
|
||
},
|
||
{
|
||
id: 2,
|
||
in_reply_to: 1,
|
||
message: 'this isn’t quite right',
|
||
updated: '2017-02-03 22:33:28.000000000',
|
||
},
|
||
{
|
||
id: 1,
|
||
side: 'PARENT',
|
||
message: 'how did this work in the first place?',
|
||
updated: '2017-02-03 22:32:28.000000000',
|
||
range: {
|
||
start_line: 1,
|
||
start_character: 1,
|
||
end_line: 2,
|
||
end_character: 1,
|
||
},
|
||
},
|
||
];
|
||
const expectedResult = [
|
||
{
|
||
id: 1,
|
||
side: 'PARENT',
|
||
message: 'how did this work in the first place?',
|
||
updated: '2017-02-03 22:32:28.000000000',
|
||
range: {
|
||
start_line: 1,
|
||
start_character: 1,
|
||
end_line: 2,
|
||
end_character: 1,
|
||
},
|
||
},
|
||
{
|
||
id: 2,
|
||
in_reply_to: 1,
|
||
message: 'this isn’t quite right',
|
||
updated: '2017-02-03 22:33:28.000000000',
|
||
range: {
|
||
start_line: 1,
|
||
start_character: 1,
|
||
end_line: 2,
|
||
end_character: 1,
|
||
},
|
||
},
|
||
{
|
||
id: 3,
|
||
in_reply_to: 2,
|
||
message: 'this isn’t quite right either',
|
||
updated: '2017-02-03 22:34:28.000000000',
|
||
range: {
|
||
start_line: 1,
|
||
start_character: 1,
|
||
end_line: 2,
|
||
end_character: 1,
|
||
},
|
||
},
|
||
];
|
||
assert.deepEqual(element._setRanges(comments), expectedResult);
|
||
});
|
||
|
||
test('differing patch diff comments are properly grouped', done => {
|
||
sandbox.stub(element, 'fetchJSON', url => {
|
||
if (url == '/changes/42/revisions/1') {
|
||
return Promise.resolve({
|
||
'/COMMIT_MSG': [],
|
||
'sieve.go': [
|
||
{
|
||
message: 'this isn’t quite right',
|
||
updated: '2017-02-03 22:32:28.000000000',
|
||
},
|
||
{
|
||
side: 'PARENT',
|
||
message: 'how did this work in the first place?',
|
||
updated: '2017-02-03 22:33:28.000000000',
|
||
},
|
||
],
|
||
});
|
||
} else if (url == '/changes/42/revisions/2') {
|
||
return Promise.resolve({
|
||
'/COMMIT_MSG': [],
|
||
'sieve.go': [
|
||
{
|
||
message: 'What on earth are you thinking, here?',
|
||
updated: '2017-02-03 22:32:28.000000000',
|
||
},
|
||
{
|
||
side: 'PARENT',
|
||
message: 'Yeah not sure how this worked either?',
|
||
updated: '2017-02-03 22:33:28.000000000',
|
||
},
|
||
{
|
||
message: '¯\\_(ツ)_/¯',
|
||
updated: '2017-02-04 22:33:28.000000000',
|
||
},
|
||
],
|
||
});
|
||
}
|
||
});
|
||
element._getDiffComments('42', '', 1, 2, 'sieve.go').then(
|
||
obj => {
|
||
assert.equal(obj.baseComments.length, 1);
|
||
assert.deepEqual(obj.baseComments[0], {
|
||
message: 'this isn’t quite right',
|
||
path: 'sieve.go',
|
||
updated: '2017-02-03 22:32:28.000000000',
|
||
});
|
||
assert.equal(obj.comments.length, 2);
|
||
assert.deepEqual(obj.comments[0], {
|
||
message: 'What on earth are you thinking, here?',
|
||
path: 'sieve.go',
|
||
updated: '2017-02-03 22:32:28.000000000',
|
||
});
|
||
assert.deepEqual(obj.comments[1], {
|
||
message: '¯\\_(ツ)_/¯',
|
||
path: 'sieve.go',
|
||
updated: '2017-02-04 22:33:28.000000000',
|
||
});
|
||
done();
|
||
});
|
||
});
|
||
|
||
test('special file path sorting', () => {
|
||
assert.deepEqual(
|
||
['.b', '/COMMIT_MSG', '.a', 'file'].sort(
|
||
element.specialFilePathCompare),
|
||
['/COMMIT_MSG', '.a', '.b', 'file']);
|
||
|
||
assert.deepEqual(
|
||
['.b', '/COMMIT_MSG', 'foo/bar/baz.cc', 'foo/bar/baz.h'].sort(
|
||
element.specialFilePathCompare),
|
||
['/COMMIT_MSG', '.b', 'foo/bar/baz.h', 'foo/bar/baz.cc']);
|
||
|
||
assert.deepEqual(
|
||
['.b', '/COMMIT_MSG', 'foo/bar/baz.cc', 'foo/bar/baz.hpp'].sort(
|
||
element.specialFilePathCompare),
|
||
['/COMMIT_MSG', '.b', 'foo/bar/baz.hpp', 'foo/bar/baz.cc']);
|
||
|
||
assert.deepEqual(
|
||
['.b', '/COMMIT_MSG', 'foo/bar/baz.cc', 'foo/bar/baz.hxx'].sort(
|
||
element.specialFilePathCompare),
|
||
['/COMMIT_MSG', '.b', 'foo/bar/baz.hxx', 'foo/bar/baz.cc']);
|
||
|
||
assert.deepEqual(
|
||
['foo/bar.h', 'foo/bar.hxx', 'foo/bar.hpp'].sort(
|
||
element.specialFilePathCompare),
|
||
['foo/bar.h', 'foo/bar.hpp', 'foo/bar.hxx']);
|
||
|
||
// Regression test for Issue 4448.
|
||
assert.deepEqual(
|
||
[
|
||
'minidump/minidump_memory_writer.cc',
|
||
'minidump/minidump_memory_writer.h',
|
||
'minidump/minidump_thread_writer.cc',
|
||
'minidump/minidump_thread_writer.h',
|
||
].sort(element.specialFilePathCompare),
|
||
[
|
||
'minidump/minidump_memory_writer.h',
|
||
'minidump/minidump_memory_writer.cc',
|
||
'minidump/minidump_thread_writer.h',
|
||
'minidump/minidump_thread_writer.cc',
|
||
]);
|
||
|
||
// Regression test for Issue 4545.
|
||
assert.deepEqual(
|
||
[
|
||
'task_test.go',
|
||
'task.go',
|
||
].sort(element.specialFilePathCompare),
|
||
[
|
||
'task.go',
|
||
'task_test.go',
|
||
]);
|
||
});
|
||
|
||
suite('rebase action', () => {
|
||
let resolveFetchJSON;
|
||
setup(() => {
|
||
sandbox.stub(element, 'fetchJSON').returns(
|
||
new Promise(resolve => {
|
||
resolveFetchJSON = resolve;
|
||
}));
|
||
});
|
||
|
||
test('no rebase on current', done => {
|
||
element.getChangeRevisionActions('42', '1337').then(
|
||
response => {
|
||
assert.isTrue(response.rebase.enabled);
|
||
assert.isFalse(response.rebase.rebaseOnCurrent);
|
||
done();
|
||
});
|
||
resolveFetchJSON({rebase: {}});
|
||
});
|
||
|
||
test('rebase on current', done => {
|
||
element.getChangeRevisionActions('42', '1337').then(
|
||
response => {
|
||
assert.isTrue(response.rebase.enabled);
|
||
assert.isTrue(response.rebase.rebaseOnCurrent);
|
||
done();
|
||
});
|
||
resolveFetchJSON({rebase: {enabled: true}});
|
||
});
|
||
});
|
||
|
||
|
||
test('server error', done => {
|
||
const getResponseObjectStub = sandbox.stub(element, 'getResponseObject');
|
||
window.fetch.returns(Promise.resolve({ok: false}));
|
||
const serverErrorEventPromise = new Promise(resolve => {
|
||
element.addEventListener('server-error', () => { resolve(); });
|
||
});
|
||
|
||
element.fetchJSON().then(
|
||
response => {
|
||
assert.isUndefined(response);
|
||
assert.isTrue(getResponseObjectStub.notCalled);
|
||
serverErrorEventPromise.then(() => {
|
||
done();
|
||
});
|
||
});
|
||
});
|
||
|
||
test('checkCredentials', done => {
|
||
const responses = [
|
||
{
|
||
ok: false,
|
||
status: 403,
|
||
text() { return Promise.resolve(); },
|
||
},
|
||
{
|
||
ok: true,
|
||
status: 200,
|
||
text() { return Promise.resolve(')]}\'{}'); },
|
||
},
|
||
];
|
||
window.fetch.restore();
|
||
sandbox.stub(window, 'fetch', url => {
|
||
if (url === '/accounts/self/detail') {
|
||
return Promise.resolve(responses.shift());
|
||
}
|
||
});
|
||
|
||
element.getLoggedIn().then(account => {
|
||
assert.isNotOk(account);
|
||
element.checkCredentials().then(account => {
|
||
assert.isOk(account);
|
||
done();
|
||
});
|
||
});
|
||
});
|
||
|
||
test('legacy n,z key in change url is replaced', () => {
|
||
const stub = sandbox.stub(element, 'fetchJSON');
|
||
element.getChanges(1, null, 'n,z');
|
||
assert.equal(stub.args[0][3].S, 0);
|
||
});
|
||
|
||
test('saveDiffPreferences invalidates cache line', () => {
|
||
const cacheKey = '/accounts/self/preferences.diff';
|
||
sandbox.stub(element, 'send');
|
||
element._cache[cacheKey] = {tab_size: 4};
|
||
element.saveDiffPreferences({tab_size: 8});
|
||
assert.isTrue(element.send.called);
|
||
assert.notOk(element._cache[cacheKey]);
|
||
});
|
||
|
||
const preferenceSetup = function(testJSON, loggedIn, smallScreen) {
|
||
sandbox.stub(element, 'getLoggedIn', () => {
|
||
return Promise.resolve(loggedIn);
|
||
});
|
||
sandbox.stub(element, '_isNarrowScreen', () => {
|
||
return smallScreen;
|
||
});
|
||
sandbox.stub(element, '_fetchSharedCacheURL', () => {
|
||
return Promise.resolve(testJSON);
|
||
});
|
||
};
|
||
|
||
test('getPreferences returns correctly on small screens logged in',
|
||
done => {
|
||
const testJSON = {diff_view: 'SIDE_BY_SIDE'};
|
||
const loggedIn = true;
|
||
const smallScreen = true;
|
||
|
||
preferenceSetup(testJSON, loggedIn, smallScreen);
|
||
|
||
element.getPreferences().then(obj => {
|
||
assert.equal(obj.default_diff_view, 'UNIFIED_DIFF');
|
||
assert.equal(obj.diff_view, 'SIDE_BY_SIDE');
|
||
done();
|
||
});
|
||
});
|
||
|
||
test('getPreferences returns correctly on small screens not logged in',
|
||
done => {
|
||
const testJSON = {diff_view: 'SIDE_BY_SIDE'};
|
||
const loggedIn = false;
|
||
const smallScreen = true;
|
||
|
||
preferenceSetup(testJSON, loggedIn, smallScreen);
|
||
element.getPreferences().then(obj => {
|
||
assert.equal(obj.default_diff_view, 'UNIFIED_DIFF');
|
||
assert.equal(obj.diff_view, 'SIDE_BY_SIDE');
|
||
done();
|
||
});
|
||
});
|
||
|
||
test('getPreferences returns correctly on larger screens logged in',
|
||
done => {
|
||
const testJSON = {diff_view: 'UNIFIED_DIFF'};
|
||
const loggedIn = true;
|
||
const smallScreen = false;
|
||
|
||
preferenceSetup(testJSON, loggedIn, smallScreen);
|
||
|
||
element.getPreferences().then(obj => {
|
||
assert.equal(obj.default_diff_view, 'UNIFIED_DIFF');
|
||
assert.equal(obj.diff_view, 'UNIFIED_DIFF');
|
||
done();
|
||
});
|
||
});
|
||
|
||
test('getPreferences returns correctly on larger screens not logged in',
|
||
done => {
|
||
const testJSON = {diff_view: 'UNIFIED_DIFF'};
|
||
const loggedIn = false;
|
||
const smallScreen = false;
|
||
|
||
preferenceSetup(testJSON, loggedIn, smallScreen);
|
||
|
||
element.getPreferences().then(obj => {
|
||
assert.equal(obj.default_diff_view, 'SIDE_BY_SIDE');
|
||
assert.equal(obj.diff_view, 'SIDE_BY_SIDE');
|
||
done();
|
||
});
|
||
});
|
||
|
||
test('savPreferences normalizes download scheme', () => {
|
||
sandbox.stub(element, 'send');
|
||
element.savePreferences({download_scheme: 'HTTP'});
|
||
assert.isTrue(element.send.called);
|
||
assert.equal(element.send.lastCall.args[2].download_scheme, 'http');
|
||
});
|
||
|
||
test('confirmEmail', () => {
|
||
sandbox.spy(element, 'send');
|
||
element.confirmEmail('foo');
|
||
assert.isTrue(element.send.calledWith(
|
||
'PUT', '/config/server/email.confirm', {token: 'foo'}));
|
||
});
|
||
|
||
test('GrReviewerUpdatesParser.parse is used', () => {
|
||
sandbox.stub(GrReviewerUpdatesParser, 'parse').returns(
|
||
Promise.resolve('foo'));
|
||
return element.getChangeDetail(42).then(result => {
|
||
assert.isTrue(GrReviewerUpdatesParser.parse.calledOnce);
|
||
assert.equal(result, 'foo');
|
||
});
|
||
});
|
||
|
||
test('setAccountStatus', done => {
|
||
sandbox.stub(element, 'send').returns(Promise.resolve('OOO'));
|
||
sandbox.stub(element, 'getResponseObject')
|
||
.returns(Promise.resolve('OOO'));
|
||
element._cache['/accounts/self/detail'] = {};
|
||
element.setAccountStatus('OOO').then(() => {
|
||
assert.isTrue(element.send.calledWith('PUT', '/accounts/self/status',
|
||
{status: 'OOO'}));
|
||
assert.deepEqual(element._cache['/accounts/self/detail'],
|
||
{status: 'OOO'});
|
||
done();
|
||
});
|
||
});
|
||
|
||
test('_sendDiffDraft pending requests tracked', done => {
|
||
sandbox.stub(element, 'send', () => {
|
||
assert.equal(element._pendingRequests.sendDiffDraft, 1);
|
||
return Promise.resolve([]);
|
||
});
|
||
element.saveDiffDraft('', 1, 1).then(() => {
|
||
assert.equal(element._pendingRequests.sendDiffDraft, 0);
|
||
element.deleteDiffDraft('', 1, 1).then(() => {
|
||
assert.equal(element._pendingRequests.sendDiffDraft, 0);
|
||
done();
|
||
});
|
||
});
|
||
});
|
||
|
||
test('saveChangeEdit', done => {
|
||
const change_num = '1';
|
||
const file_name = 'index.php';
|
||
const file_contents = '<?php';
|
||
sandbox.stub(element, 'send').returns(
|
||
Promise.resolve([change_num, file_name, file_contents])
|
||
);
|
||
sandbox.stub(element, 'getResponseObject')
|
||
.returns(Promise.resolve([change_num, file_name, file_contents]));
|
||
element._cache['/changes/' + change_num + '/edit/' + file_name] = {};
|
||
element.saveChangeEdit(change_num, file_name, file_contents).then(
|
||
() => {
|
||
assert.isTrue(element.send.calledWith('PUT',
|
||
'/changes/' + change_num + '/edit/' + file_name,
|
||
file_contents));
|
||
done();
|
||
}
|
||
);
|
||
});
|
||
|
||
test('startWorkInProgress', () => {
|
||
sandbox.stub(element, 'send').returns(Promise.resolve('ok'));
|
||
element.startWorkInProgress('42');
|
||
assert.isTrue(element.send.calledWith(
|
||
'POST', '/changes/42/wip', {}));
|
||
element.startWorkInProgress('42', 'revising...');
|
||
assert.isTrue(element.send.calledWith(
|
||
'POST', '/changes/42/wip', {message: 'revising...'}));
|
||
});
|
||
|
||
test('startReview', () => {
|
||
sandbox.stub(element, 'send').returns(Promise.resolve({}));
|
||
element.startReview('42', {message: 'Please review.'});
|
||
assert.isTrue(element.send.calledWith(
|
||
'POST', '/changes/42/ready', {message: 'Please review.'}));
|
||
});
|
||
|
||
test('deleteComment', done => {
|
||
sandbox.stub(element, 'send').returns(Promise.resolve());
|
||
sandbox.stub(element, 'getResponseObject').returns('some response');
|
||
element.deleteComment('foo', 'bar', '01234', 'removal reason')
|
||
.then(response => {
|
||
assert.equal(response, 'some response');
|
||
done();
|
||
});
|
||
assert.isTrue(element.send.calledWith(
|
||
'POST', '/changes/foo/revisions/bar/comments/01234/delete',
|
||
{reason: 'removal reason'}));
|
||
});
|
||
});
|
||
</script>
|