2015-11-14 15:40:47 -05:00
|
|
|
<!DOCTYPE html>
|
|
|
|
<!--
|
|
|
|
Copyright (C) 2015 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">
|
2015-11-18 16:31:18 -05:00
|
|
|
<title>gr-diff-view</title>
|
2015-11-14 15:40:47 -05:00
|
|
|
|
2017-03-28 17:02:44 -07:00
|
|
|
<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
|
2016-03-04 17:48:22 -05:00
|
|
|
<script src="../../../bower_components/web-component-tester/browser.js"></script>
|
2017-06-02 13:08:19 -04:00
|
|
|
<link rel="import" href="../../../test/common-test-setup.html"/>
|
2016-03-04 17:48:22 -05:00
|
|
|
<script src="../../../bower_components/page/page.js"></script>
|
|
|
|
<script src="../../../scripts/util.js"></script>
|
2015-11-25 19:08:45 -05:00
|
|
|
|
2016-03-04 17:48:22 -05:00
|
|
|
<link rel="import" href="gr-diff-view.html">
|
2015-11-14 15:40:47 -05:00
|
|
|
|
2017-03-28 17:02:44 -07:00
|
|
|
<script>void(0);</script>
|
|
|
|
|
2015-11-14 15:40:47 -05:00
|
|
|
<test-fixture id="basic">
|
2015-12-02 13:17:35 -05:00
|
|
|
<template>
|
|
|
|
<gr-diff-view></gr-diff-view>
|
|
|
|
</template>
|
|
|
|
</test-fixture>
|
|
|
|
|
2016-08-25 12:35:50 -07:00
|
|
|
<test-fixture id="blank">
|
|
|
|
<template>
|
|
|
|
<div></div>
|
|
|
|
</template>
|
2016-09-16 10:44:37 -07:00
|
|
|
</test-fixture>
|
2016-08-25 12:35:50 -07:00
|
|
|
|
2015-11-14 15:40:47 -05:00
|
|
|
<script>
|
2017-05-16 14:38:48 -07:00
|
|
|
suite('gr-diff-view tests', () => {
|
|
|
|
let element;
|
|
|
|
let sandbox;
|
2015-12-02 13:17:35 -05:00
|
|
|
|
2017-07-05 21:26:33 -07:00
|
|
|
const PARENT = 'PARENT';
|
|
|
|
|
2018-01-23 10:33:44 -08:00
|
|
|
setup(() => {
|
2016-10-26 17:11:50 -07:00
|
|
|
sandbox = sinon.sandbox.create();
|
|
|
|
|
2016-03-29 14:06:39 -04:00
|
|
|
stub('gr-rest-api-interface', {
|
Weblinks API for embedded scenario using Gerrit.Nav interface
Gerrit.Nav.setup() now takes a weblinks generator function as a third
parameter. Here's the function signature:
``` js
Gerrit.Nav.setup(navigate, generateUrl, generateWeblinks)
```
Weblinks generator function takes single payload parameter with
`type` property that determines which part of the UI is the consumer of
the weblinks. `type` property can be one of `file`, `change`, or
`patchset`.
For `file` type, payload will also contain string properties:
`repo`, `commit`, `file`.
For `pachset` type, payload will also contain string properties:
`repo`, `commit`.
For `change` type, payload will also contain string properties:
`repo`, `commit`.
If server provides weblinks, those will be passed as `options.weblinks`
property on the main payload object.
Change-Id: I0d9de3a295435304e2b6aad551112440075cf098
2017-11-10 16:03:13 -08:00
|
|
|
getConfig() { return Promise.resolve({change: {}}); },
|
2017-05-16 14:38:48 -07:00
|
|
|
getLoggedIn() { return Promise.resolve(false); },
|
|
|
|
getProjectConfig() { return Promise.resolve({}); },
|
2018-01-23 10:33:44 -08:00
|
|
|
getDiffChangeDetail() { return Promise.resolve({}); },
|
2017-05-16 14:38:48 -07:00
|
|
|
getChangeFiles() { return Promise.resolve({}); },
|
|
|
|
saveFileReviewed() { return Promise.resolve(); },
|
Update gr-comment-api
Previously, nested components (that are never standalone) were making
their own requests for comments, creating unecessary duplicate API
requests.
Some requests were made to the rest API directly (for example,
gr-change-view requested comments this way), and some were through the
gr-comment-api, which also helped handle comment manipulation and
reorganization.
Instead of ad-hoc comment requesting, move all comment requests to the
top level (standalone) component, and use an object prototype to
generate _changeComments as a property on gr-comment-api. This is an
immutable object that can be passed to the inner components
(file list, etc), and includes the methods needed to manipulate
comments into the forms
necessary.
When a child component needs to trigger a refresh of the comments, fire
an event that the parent event handles (see gr-file-list l.867).
Bug: Issue 6953
Change-Id: Ic4b6cf16520baae65d8cf956c311a60f2a70a2e1
2017-11-02 16:07:13 -07:00
|
|
|
getDiffComments() { return Promise.resolve({}); },
|
2017-07-26 09:32:03 -07:00
|
|
|
getDiffRobotComments() { return Promise.resolve({}); },
|
Update gr-comment-api
Previously, nested components (that are never standalone) were making
their own requests for comments, creating unecessary duplicate API
requests.
Some requests were made to the rest API directly (for example,
gr-change-view requested comments this way), and some were through the
gr-comment-api, which also helped handle comment manipulation and
reorganization.
Instead of ad-hoc comment requesting, move all comment requests to the
top level (standalone) component, and use an object prototype to
generate _changeComments as a property on gr-comment-api. This is an
immutable object that can be passed to the inner components
(file list, etc), and includes the methods needed to manipulate
comments into the forms
necessary.
When a child component needs to trigger a refresh of the comments, fire
an event that the parent event handles (see gr-file-list l.867).
Bug: Issue 6953
Change-Id: Ic4b6cf16520baae65d8cf956c311a60f2a70a2e1
2017-11-02 16:07:13 -07:00
|
|
|
getDiffDrafts() { return Promise.resolve({}); },
|
2016-03-29 14:06:39 -04:00
|
|
|
});
|
2015-11-14 15:40:47 -05:00
|
|
|
element = fixture('basic');
|
2018-01-23 10:33:44 -08:00
|
|
|
return element._loadComments();
|
2015-12-02 13:17:35 -05:00
|
|
|
});
|
2015-11-14 15:40:47 -05:00
|
|
|
|
2017-05-16 14:38:48 -07:00
|
|
|
teardown(() => {
|
2016-10-26 17:11:50 -07:00
|
|
|
sandbox.restore();
|
|
|
|
});
|
|
|
|
|
2017-05-16 14:38:48 -07:00
|
|
|
test('toggle left diff with a hotkey', () => {
|
|
|
|
const toggleLeftDiffStub = sandbox.stub(element.$.diff, 'toggleLeftDiff');
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 65, 'shift', 'a');
|
2016-08-10 11:53:12 -07:00
|
|
|
assert.isTrue(toggleLeftDiffStub.calledOnce);
|
|
|
|
});
|
|
|
|
|
2017-05-16 14:38:48 -07:00
|
|
|
test('keyboard shortcuts', () => {
|
2015-12-01 01:02:00 -05:00
|
|
|
element._changeNum = '42';
|
2015-12-11 12:02:57 -05:00
|
|
|
element._patchRange = {
|
2017-07-05 21:26:33 -07:00
|
|
|
basePatchNum: PARENT,
|
2015-12-11 12:02:57 -05:00
|
|
|
patchNum: '10',
|
|
|
|
};
|
2016-02-25 11:51:15 -05:00
|
|
|
element._change = {
|
2017-07-05 21:26:33 -07:00
|
|
|
_number: 42,
|
2016-02-25 11:51:15 -05:00
|
|
|
revisions: {
|
2017-11-08 15:33:48 -08:00
|
|
|
a: {_number: 10, commit: {parents: []}},
|
2016-02-25 11:51:15 -05:00
|
|
|
},
|
|
|
|
};
|
2015-12-01 01:02:00 -05:00
|
|
|
element._fileList = ['chell.go', 'glados.txt', 'wheatley.md'];
|
|
|
|
element._path = 'glados.txt';
|
2016-02-03 20:40:36 -08:00
|
|
|
element.changeViewState.selectedFileIndex = 1;
|
2015-12-01 01:02:00 -05:00
|
|
|
|
2017-07-05 21:26:33 -07:00
|
|
|
const diffNavStub = sandbox.stub(Gerrit.Nav, 'navigateToDiff');
|
|
|
|
const changeNavStub = sandbox.stub(Gerrit.Nav, 'navigateToChange');
|
|
|
|
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 85, null, 'u');
|
2017-07-05 21:26:33 -07:00
|
|
|
assert(changeNavStub.lastCall.calledWith(element._change),
|
2016-02-25 11:51:15 -05:00
|
|
|
'Should navigate to /c/42/');
|
2015-12-01 01:02:00 -05:00
|
|
|
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 221, null, ']');
|
2017-07-05 21:26:33 -07:00
|
|
|
assert(diffNavStub.lastCall.calledWith(element._change, 'wheatley.md',
|
|
|
|
'10', PARENT), 'Should navigate to /c/42/10/wheatley.md');
|
2015-12-01 01:02:00 -05:00
|
|
|
element._path = 'wheatley.md';
|
2016-02-03 20:40:36 -08:00
|
|
|
assert.equal(element.changeViewState.selectedFileIndex, 2);
|
2017-10-09 11:36:19 -07:00
|
|
|
assert.isTrue(element._loading);
|
2015-12-01 01:02:00 -05:00
|
|
|
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
|
2017-07-05 21:26:33 -07:00
|
|
|
assert(diffNavStub.lastCall.calledWith(element._change, 'glados.txt',
|
|
|
|
'10', PARENT), 'Should navigate to /c/42/10/glados.txt');
|
2015-12-01 01:02:00 -05:00
|
|
|
element._path = 'glados.txt';
|
2016-02-03 20:40:36 -08:00
|
|
|
assert.equal(element.changeViewState.selectedFileIndex, 1);
|
2017-10-09 11:36:19 -07:00
|
|
|
assert.isTrue(element._loading);
|
2015-12-01 01:02:00 -05:00
|
|
|
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
|
2017-07-05 21:26:33 -07:00
|
|
|
assert(diffNavStub.lastCall.calledWith(element._change, 'chell.go', '10',
|
|
|
|
PARENT), 'Should navigate to /c/42/10/chell.go');
|
2015-12-01 01:02:00 -05:00
|
|
|
element._path = 'chell.go';
|
2016-02-03 20:40:36 -08:00
|
|
|
assert.equal(element.changeViewState.selectedFileIndex, 0);
|
2017-10-09 11:36:19 -07:00
|
|
|
assert.isTrue(element._loading);
|
2015-12-01 01:02:00 -05:00
|
|
|
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
|
2017-07-05 21:26:33 -07:00
|
|
|
assert(changeNavStub.lastCall.calledWith(element._change),
|
2016-02-25 11:51:15 -05:00
|
|
|
'Should navigate to /c/42/');
|
2016-02-03 20:40:36 -08:00
|
|
|
assert.equal(element.changeViewState.selectedFileIndex, 0);
|
2017-10-09 11:36:19 -07:00
|
|
|
assert.isTrue(element._loading);
|
2015-12-01 01:02:00 -05:00
|
|
|
|
2017-05-16 14:38:48 -07:00
|
|
|
const showPrefsStub =
|
|
|
|
sandbox.stub(element.$.diffPreferences.$.prefsOverlay, 'open',
|
|
|
|
() => Promise.resolve());
|
2016-09-16 10:44:37 -07:00
|
|
|
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 188, null, ',');
|
2016-01-26 16:30:02 -05:00
|
|
|
assert(showPrefsStub.calledOnce);
|
|
|
|
|
2017-05-16 14:38:48 -07:00
|
|
|
let scrollStub = sandbox.stub(element.$.cursor, 'moveToNextChunk');
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 78, null, 'n');
|
2016-02-25 18:19:51 -05:00
|
|
|
assert(scrollStub.calledOnce);
|
|
|
|
|
2016-10-26 17:11:50 -07:00
|
|
|
scrollStub = sandbox.stub(element.$.cursor, 'moveToPreviousChunk');
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 80, null, 'p');
|
2016-02-25 18:19:51 -05:00
|
|
|
assert(scrollStub.calledOnce);
|
|
|
|
|
2016-10-26 17:11:50 -07:00
|
|
|
scrollStub = sandbox.stub(element.$.cursor, 'moveToNextCommentThread');
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 78, 'shift', 'n');
|
2016-02-25 18:19:51 -05:00
|
|
|
assert(scrollStub.calledOnce);
|
|
|
|
|
2016-10-26 17:11:50 -07:00
|
|
|
scrollStub = sandbox.stub(element.$.cursor,
|
|
|
|
'moveToPreviousCommentThread');
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 80, 'shift', 'p');
|
2016-02-25 18:19:51 -05:00
|
|
|
assert(scrollStub.calledOnce);
|
2016-11-02 16:25:53 -07:00
|
|
|
|
2017-05-16 14:38:48 -07:00
|
|
|
const computeContainerClassStub = sandbox.stub(element.$.diff,
|
2016-11-02 16:25:53 -07:00
|
|
|
'_computeContainerClass');
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 74, null, 'j');
|
2016-11-02 16:25:53 -07:00
|
|
|
assert(computeContainerClassStub.lastCall.calledWithExactly(
|
|
|
|
false, 'SIDE_BY_SIDE', true));
|
|
|
|
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 27, null, 'esc');
|
2016-11-02 16:25:53 -07:00
|
|
|
assert(computeContainerClassStub.lastCall.calledWithExactly(
|
|
|
|
false, 'SIDE_BY_SIDE', false));
|
2016-01-08 10:13:54 -05:00
|
|
|
});
|
2015-12-01 01:02:00 -05:00
|
|
|
|
2017-05-16 14:38:48 -07:00
|
|
|
test('keyboard shortcuts with patch range', () => {
|
2016-01-08 10:13:54 -05:00
|
|
|
element._changeNum = '42';
|
|
|
|
element._patchRange = {
|
|
|
|
basePatchNum: '5',
|
|
|
|
patchNum: '10',
|
|
|
|
};
|
2016-02-25 11:51:15 -05:00
|
|
|
element._change = {
|
2017-07-05 21:26:33 -07:00
|
|
|
_number: 42,
|
2016-02-25 11:51:15 -05:00
|
|
|
revisions: {
|
2017-11-08 15:33:48 -08:00
|
|
|
a: {_number: 10, commit: {parents: []}},
|
|
|
|
b: {_number: 5, commit: {parents: []}},
|
2016-02-25 11:51:15 -05:00
|
|
|
},
|
|
|
|
};
|
2016-01-08 10:13:54 -05:00
|
|
|
element._fileList = ['chell.go', 'glados.txt', 'wheatley.md'];
|
|
|
|
element._path = 'glados.txt';
|
2015-12-01 01:02:00 -05:00
|
|
|
|
2017-07-05 21:26:33 -07:00
|
|
|
const diffNavStub = sandbox.stub(Gerrit.Nav, 'navigateToDiff');
|
|
|
|
const changeNavStub = sandbox.stub(Gerrit.Nav, 'navigateToChange');
|
2015-12-01 01:02:00 -05:00
|
|
|
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 65, null, 'a');
|
2017-07-05 21:26:33 -07:00
|
|
|
assert.isTrue(changeNavStub.notCalled, 'The `a` keyboard shortcut ' +
|
|
|
|
'should only work when the user is logged in.');
|
2016-01-28 14:58:04 -05:00
|
|
|
assert.isNull(window.sessionStorage.getItem(
|
2016-02-22 18:12:27 -05:00
|
|
|
'changeView.showReplyDialog'));
|
2016-01-28 14:58:04 -05:00
|
|
|
|
|
|
|
element._loggedIn = true;
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 65, null, 'a');
|
2016-02-22 18:12:27 -05:00
|
|
|
assert.isTrue(element.changeViewState.showReplyDialog);
|
2016-02-03 20:40:36 -08:00
|
|
|
|
2017-07-05 21:26:33 -07:00
|
|
|
assert(changeNavStub.lastCall.calledWithExactly(element._change, '10',
|
|
|
|
'5'), 'Should navigate to /c/42/5..10');
|
2016-01-28 14:58:04 -05:00
|
|
|
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 85, null, 'u');
|
2017-07-05 21:26:33 -07:00
|
|
|
assert(changeNavStub.lastCall.calledWithExactly(element._change, '10',
|
|
|
|
'5'), 'Should navigate to /c/42/5..10');
|
2015-12-01 01:02:00 -05:00
|
|
|
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 221, null, ']');
|
2017-10-09 11:36:19 -07:00
|
|
|
assert.isTrue(element._loading);
|
2017-07-05 21:26:33 -07:00
|
|
|
assert(diffNavStub.lastCall.calledWithExactly(element._change,
|
|
|
|
'wheatley.md', '10', '5'),
|
2016-01-08 10:13:54 -05:00
|
|
|
'Should navigate to /c/42/5..10/wheatley.md');
|
|
|
|
element._path = 'wheatley.md';
|
2015-12-01 01:02:00 -05:00
|
|
|
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
|
2017-10-09 11:36:19 -07:00
|
|
|
assert.isTrue(element._loading);
|
2017-07-05 21:26:33 -07:00
|
|
|
assert(diffNavStub.lastCall.calledWithExactly(element._change,
|
|
|
|
'glados.txt', '10', '5'),
|
2016-01-08 10:13:54 -05:00
|
|
|
'Should navigate to /c/42/5..10/glados.txt');
|
|
|
|
element._path = 'glados.txt';
|
2015-12-01 01:02:00 -05:00
|
|
|
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
|
2017-10-09 11:36:19 -07:00
|
|
|
assert.isTrue(element._loading);
|
2017-07-05 21:26:33 -07:00
|
|
|
assert(diffNavStub.lastCall.calledWithExactly(element._change, 'chell.go',
|
|
|
|
'10', '5'),
|
2016-01-08 10:13:54 -05:00
|
|
|
'Should navigate to /c/42/5..10/chell.go');
|
|
|
|
element._path = 'chell.go';
|
2015-12-01 01:02:00 -05:00
|
|
|
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
|
2017-10-09 11:36:19 -07:00
|
|
|
assert.isTrue(element._loading);
|
2017-07-05 21:26:33 -07:00
|
|
|
assert(changeNavStub.lastCall.calledWithExactly(element._change, '10',
|
|
|
|
'5'),
|
2016-05-11 14:31:49 -04:00
|
|
|
'Should navigate to /c/42/5..10');
|
2016-02-25 11:51:15 -05:00
|
|
|
});
|
|
|
|
|
2017-05-16 14:38:48 -07:00
|
|
|
test('keyboard shortcuts with old patch number', () => {
|
2016-02-25 11:51:15 -05:00
|
|
|
element._changeNum = '42';
|
|
|
|
element._patchRange = {
|
2017-07-05 21:26:33 -07:00
|
|
|
basePatchNum: PARENT,
|
2016-02-25 11:51:15 -05:00
|
|
|
patchNum: '1',
|
|
|
|
};
|
|
|
|
element._change = {
|
2017-07-05 21:26:33 -07:00
|
|
|
_number: 42,
|
2016-02-25 11:51:15 -05:00
|
|
|
revisions: {
|
2017-11-08 15:33:48 -08:00
|
|
|
a: {_number: 1, commit: {parents: []}},
|
|
|
|
b: {_number: 2, commit: {parents: []}},
|
2016-02-25 11:51:15 -05:00
|
|
|
},
|
|
|
|
};
|
|
|
|
element._fileList = ['chell.go', 'glados.txt', 'wheatley.md'];
|
|
|
|
element._path = 'glados.txt';
|
|
|
|
|
2017-07-05 21:26:33 -07:00
|
|
|
const diffNavStub = sandbox.stub(Gerrit.Nav, 'navigateToDiff');
|
|
|
|
const changeNavStub = sandbox.stub(Gerrit.Nav, 'navigateToChange');
|
2016-02-25 11:51:15 -05:00
|
|
|
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 65, null, 'a');
|
2017-07-05 21:26:33 -07:00
|
|
|
assert.isTrue(changeNavStub.notCalled, 'The `a` keyboard shortcut ' +
|
|
|
|
'should only work when the user is logged in.');
|
2016-02-25 11:51:15 -05:00
|
|
|
assert.isNull(window.sessionStorage.getItem(
|
|
|
|
'changeView.showReplyDialog'));
|
|
|
|
|
|
|
|
element._loggedIn = true;
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 65, null, 'a');
|
2016-02-25 11:51:15 -05:00
|
|
|
assert.isTrue(element.changeViewState.showReplyDialog);
|
|
|
|
|
2017-07-05 21:26:33 -07:00
|
|
|
assert(changeNavStub.lastCall.calledWithExactly(element._change, '1',
|
|
|
|
PARENT), 'Should navigate to /c/42/1');
|
2016-02-25 11:51:15 -05:00
|
|
|
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 85, null, 'u');
|
2017-07-05 21:26:33 -07:00
|
|
|
assert(changeNavStub.lastCall.calledWithExactly(element._change, '1',
|
|
|
|
PARENT), 'Should navigate to /c/42/1');
|
2016-02-25 11:51:15 -05:00
|
|
|
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 221, null, ']');
|
2017-07-05 21:26:33 -07:00
|
|
|
assert(diffNavStub.lastCall.calledWithExactly(element._change,
|
|
|
|
'wheatley.md', '1', PARENT),
|
2016-02-25 11:51:15 -05:00
|
|
|
'Should navigate to /c/42/1/wheatley.md');
|
|
|
|
element._path = 'wheatley.md';
|
|
|
|
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
|
2017-07-05 21:26:33 -07:00
|
|
|
assert(diffNavStub.lastCall.calledWithExactly(element._change,
|
|
|
|
'glados.txt', '1', PARENT),
|
2016-02-25 11:51:15 -05:00
|
|
|
'Should navigate to /c/42/1/glados.txt');
|
|
|
|
element._path = 'glados.txt';
|
|
|
|
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
|
2017-07-05 21:26:33 -07:00
|
|
|
assert(diffNavStub.lastCall.calledWithExactly(element._change, 'chell.go',
|
|
|
|
'1', PARENT), 'Should navigate to /c/42/1/chell.go');
|
2016-02-25 11:51:15 -05:00
|
|
|
element._path = 'chell.go';
|
|
|
|
|
2016-11-15 17:01:15 -08:00
|
|
|
MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
|
2017-07-05 21:26:33 -07:00
|
|
|
assert(changeNavStub.lastCall.calledWithExactly(element._change, '1',
|
|
|
|
PARENT), 'Should navigate to /c/42/1');
|
2016-02-25 11:51:15 -05:00
|
|
|
});
|
|
|
|
|
2017-05-16 14:38:48 -07:00
|
|
|
test('Diff preferences hidden when no prefs or logged out', () => {
|
2017-05-08 14:41:57 -07:00
|
|
|
element._loggedIn = false;
|
|
|
|
flushAsynchronousOperations();
|
|
|
|
assert.isTrue(element.$.diffPrefsContainer.hidden);
|
|
|
|
|
|
|
|
element._loggedIn = true;
|
|
|
|
flushAsynchronousOperations();
|
|
|
|
assert.isTrue(element.$.diffPrefsContainer.hidden);
|
|
|
|
|
|
|
|
element._loggedIn = false;
|
2017-05-16 14:38:48 -07:00
|
|
|
element._prefs = {font_size: '12'};
|
2017-05-08 14:41:57 -07:00
|
|
|
flushAsynchronousOperations();
|
|
|
|
assert.isTrue(element.$.diffPrefsContainer.hidden);
|
|
|
|
|
|
|
|
element._loggedIn = true;
|
|
|
|
flushAsynchronousOperations();
|
|
|
|
assert.isFalse(element.$.diffPrefsContainer.hidden);
|
|
|
|
});
|
|
|
|
|
2017-05-16 14:38:48 -07:00
|
|
|
test('prefsButton opens gr-diff-preferences', () => {
|
|
|
|
const handlePrefsTapSpy = sandbox.spy(element, '_handlePrefsTap');
|
|
|
|
const overlayOpenStub = sandbox.stub(element.$.diffPreferences,
|
2017-05-08 14:41:57 -07:00
|
|
|
'open');
|
2017-05-16 14:38:48 -07:00
|
|
|
const prefsButton =
|
|
|
|
Polymer.dom(element.root).querySelector('.prefsButton');
|
2017-05-08 14:41:57 -07:00
|
|
|
|
|
|
|
MockInteractions.tap(prefsButton);
|
|
|
|
|
|
|
|
assert.isTrue(handlePrefsTapSpy.called);
|
|
|
|
assert.isTrue(overlayOpenStub.called);
|
|
|
|
});
|
|
|
|
|
2017-11-09 11:53:33 -08:00
|
|
|
test('_computeCommentString', done => {
|
|
|
|
loadCommentSpy = sandbox.spy(element.$.commentAPI, 'loadAll');
|
|
|
|
const path = '/test';
|
|
|
|
element.$.commentAPI.loadAll().then(comments => {
|
|
|
|
const commentCountStub =
|
|
|
|
sandbox.stub(comments, 'computeCommentCount');
|
|
|
|
const unresolvedCountStub =
|
|
|
|
sandbox.stub(comments, 'computeUnresolvedNum');
|
|
|
|
commentCountStub.withArgs(1, path).returns(0);
|
|
|
|
commentCountStub.withArgs(2, path).returns(1);
|
|
|
|
commentCountStub.withArgs(3, path).returns(2);
|
|
|
|
commentCountStub.withArgs(4, path).returns(0);
|
|
|
|
unresolvedCountStub.withArgs(1, path).returns(1);
|
|
|
|
unresolvedCountStub.withArgs(2, path).returns(0);
|
|
|
|
unresolvedCountStub.withArgs(3, path).returns(2);
|
|
|
|
unresolvedCountStub.withArgs(4, path).returns(0);
|
|
|
|
|
|
|
|
assert.equal(element._computeCommentString(comments, 1, path),
|
|
|
|
'1 unresolved');
|
|
|
|
assert.equal(element._computeCommentString(comments, 2, path),
|
|
|
|
'1 comment');
|
|
|
|
assert.equal(element._computeCommentString(comments, 3, path),
|
|
|
|
'2 comments, 2 unresolved');
|
|
|
|
assert.equal(element._computeCommentString(comments, 4, path), '');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2017-07-05 21:26:33 -07:00
|
|
|
suite('url params', () => {
|
|
|
|
setup(() => {
|
|
|
|
sandbox.stub(Gerrit.Nav, 'getUrlForDiff', (c, p, pn, bpn) => {
|
|
|
|
return `${c._number}-${p}-${pn}-${bpn}`;
|
|
|
|
});
|
|
|
|
sandbox.stub(Gerrit.Nav, 'getUrlForChange', (c, pn, bpn) => {
|
|
|
|
return `${c._number}-${pn}-${bpn}`;
|
|
|
|
});
|
|
|
|
});
|
2016-02-25 11:51:15 -05:00
|
|
|
|
2017-11-07 15:49:55 -08:00
|
|
|
test('_formattedFiles', () => {
|
2017-07-05 21:26:33 -07:00
|
|
|
element._changeNum = '42';
|
|
|
|
element._patchRange = {
|
|
|
|
basePatchNum: PARENT,
|
|
|
|
patchNum: '10',
|
|
|
|
};
|
|
|
|
element._change = {_number: 42};
|
2017-11-13 16:23:08 -08:00
|
|
|
element._fileList = ['chell.go', 'glados.txt', 'wheatley.md',
|
|
|
|
'/COMMIT_MSG', '/MERGE_LIST'];
|
2017-07-05 21:26:33 -07:00
|
|
|
element._path = 'glados.txt';
|
2017-11-07 15:49:55 -08:00
|
|
|
const expectedFormattedFiles = [
|
|
|
|
{
|
|
|
|
text: 'chell.go',
|
|
|
|
mobileText: 'chell.go',
|
|
|
|
value: 'chell.go',
|
2017-11-09 11:53:33 -08:00
|
|
|
bottomText: '',
|
2017-11-07 15:49:55 -08:00
|
|
|
}, {
|
|
|
|
text: 'glados.txt',
|
|
|
|
mobileText: 'glados.txt',
|
|
|
|
value: 'glados.txt',
|
2017-11-09 11:53:33 -08:00
|
|
|
bottomText: '',
|
2017-11-07 15:49:55 -08:00
|
|
|
}, {
|
|
|
|
text: 'wheatley.md',
|
|
|
|
mobileText: 'wheatley.md',
|
|
|
|
value: 'wheatley.md',
|
2017-11-09 11:53:33 -08:00
|
|
|
bottomText: '',
|
2017-11-07 15:49:55 -08:00
|
|
|
},
|
2017-11-13 16:23:08 -08:00
|
|
|
{
|
|
|
|
text: 'Commit message',
|
|
|
|
mobileText: 'Commit message',
|
|
|
|
value: '/COMMIT_MSG',
|
2017-11-09 11:53:33 -08:00
|
|
|
bottomText: '',
|
2017-11-13 16:23:08 -08:00
|
|
|
},
|
|
|
|
{
|
|
|
|
text: 'Merge list',
|
|
|
|
mobileText: 'Merge list',
|
|
|
|
value: '/MERGE_LIST',
|
2017-11-09 11:53:33 -08:00
|
|
|
bottomText: '',
|
2017-11-13 16:23:08 -08:00
|
|
|
},
|
2017-11-07 15:49:55 -08:00
|
|
|
];
|
2015-12-11 12:02:57 -05:00
|
|
|
|
2017-11-07 15:49:55 -08:00
|
|
|
assert.deepEqual(element._formattedFiles, expectedFormattedFiles);
|
|
|
|
assert.equal(element._formattedFiles[1].value, element._path);
|
2017-07-05 21:26:33 -07:00
|
|
|
});
|
2015-12-28 12:40:03 -05:00
|
|
|
|
2017-07-05 21:26:33 -07:00
|
|
|
test('prev/up/next links', () => {
|
|
|
|
element._changeNum = '42';
|
|
|
|
element._patchRange = {
|
|
|
|
basePatchNum: PARENT,
|
|
|
|
patchNum: '10',
|
|
|
|
};
|
|
|
|
element._change = {
|
|
|
|
_number: 42,
|
|
|
|
revisions: {
|
2017-11-08 15:33:48 -08:00
|
|
|
a: {_number: 10, commit: {parents: []}},
|
2017-07-05 21:26:33 -07:00
|
|
|
},
|
|
|
|
};
|
|
|
|
element._fileList = ['chell.go', 'glados.txt', 'wheatley.md'];
|
|
|
|
element._path = 'glados.txt';
|
|
|
|
flushAsynchronousOperations();
|
|
|
|
const linkEls = Polymer.dom(element.root).querySelectorAll('.navLink');
|
|
|
|
assert.equal(linkEls.length, 3);
|
|
|
|
assert.equal(linkEls[0].getAttribute('href'), '42-chell.go-10-PARENT');
|
|
|
|
assert.equal(linkEls[1].getAttribute('href'), '42-undefined-undefined');
|
|
|
|
assert.equal(linkEls[2].getAttribute('href'),
|
|
|
|
'42-wheatley.md-10-PARENT');
|
|
|
|
element._path = 'wheatley.md';
|
|
|
|
flushAsynchronousOperations();
|
|
|
|
assert.equal(linkEls[0].getAttribute('href'),
|
|
|
|
'42-glados.txt-10-PARENT');
|
|
|
|
assert.equal(linkEls[1].getAttribute('href'), '42-undefined-undefined');
|
|
|
|
assert.isFalse(linkEls[2].hasAttribute('href'));
|
|
|
|
element._path = 'chell.go';
|
|
|
|
flushAsynchronousOperations();
|
|
|
|
assert.isFalse(linkEls[0].hasAttribute('href'));
|
|
|
|
assert.equal(linkEls[1].getAttribute('href'), '42-undefined-undefined');
|
|
|
|
assert.equal(linkEls[2].getAttribute('href'),
|
|
|
|
'42-glados.txt-10-PARENT');
|
|
|
|
element._path = 'not_a_real_file';
|
|
|
|
flushAsynchronousOperations();
|
|
|
|
assert.equal(linkEls[0].getAttribute('href'),
|
|
|
|
'42-wheatley.md-10-PARENT');
|
|
|
|
assert.equal(linkEls[1].getAttribute('href'), '42-undefined-undefined');
|
|
|
|
assert.equal(linkEls[2].getAttribute('href'), '42-chell.go-10-PARENT');
|
|
|
|
});
|
2016-02-10 21:59:20 +01:00
|
|
|
|
2017-07-05 21:26:33 -07:00
|
|
|
test('prev/up/next links with patch range', () => {
|
|
|
|
element._changeNum = '42';
|
|
|
|
element._patchRange = {
|
|
|
|
basePatchNum: '5',
|
|
|
|
patchNum: '10',
|
|
|
|
};
|
|
|
|
element._change = {
|
|
|
|
_number: 42,
|
|
|
|
revisions: {
|
2017-11-08 15:33:48 -08:00
|
|
|
a: {_number: 5, commit: {parents: []}},
|
|
|
|
b: {_number: 10, commit: {parents: []}},
|
2017-07-05 21:26:33 -07:00
|
|
|
},
|
|
|
|
};
|
|
|
|
element._fileList = ['chell.go', 'glados.txt', 'wheatley.md'];
|
|
|
|
element._path = 'glados.txt';
|
|
|
|
flushAsynchronousOperations();
|
|
|
|
const linkEls = Polymer.dom(element.root).querySelectorAll('.navLink');
|
|
|
|
assert.equal(linkEls.length, 3);
|
|
|
|
assert.equal(linkEls[0].getAttribute('href'), '42-chell.go-10-5');
|
|
|
|
assert.equal(linkEls[1].getAttribute('href'), '42-10-5');
|
|
|
|
assert.equal(linkEls[2].getAttribute('href'), '42-wheatley.md-10-5');
|
|
|
|
element._path = 'wheatley.md';
|
|
|
|
flushAsynchronousOperations();
|
|
|
|
assert.equal(linkEls[0].getAttribute('href'), '42-glados.txt-10-5');
|
|
|
|
assert.equal(linkEls[1].getAttribute('href'), '42-10-5');
|
|
|
|
assert.isFalse(linkEls[2].hasAttribute('href'));
|
|
|
|
element._path = 'chell.go';
|
|
|
|
flushAsynchronousOperations();
|
|
|
|
assert.isFalse(linkEls[0].hasAttribute('href'));
|
|
|
|
assert.equal(linkEls[1].getAttribute('href'), '42-10-5');
|
|
|
|
assert.equal(linkEls[2].getAttribute('href'), '42-glados.txt-10-5');
|
|
|
|
});
|
2016-09-07 17:34:41 -04:00
|
|
|
});
|
|
|
|
|
2017-09-12 16:54:19 -07:00
|
|
|
test('_handlePatchChange calls navigateToDiff correctly', () => {
|
|
|
|
const navigateStub = sandbox.stub(Gerrit.Nav, 'navigateToDiff');
|
|
|
|
element._change = {_number: 321, project: 'foo/bar'};
|
|
|
|
element._path = 'path/to/file.txt';
|
2017-09-26 09:59:33 -07:00
|
|
|
|
|
|
|
element._patchRange = {
|
|
|
|
basePatchNum: 'PARENT',
|
|
|
|
patchNum: '3',
|
|
|
|
};
|
|
|
|
|
2017-10-12 11:35:18 -07:00
|
|
|
const detail = {
|
|
|
|
basePatchNum: 'PARENT',
|
|
|
|
patchNum: '1',
|
|
|
|
};
|
2017-09-26 09:59:33 -07:00
|
|
|
|
2017-10-12 11:35:18 -07:00
|
|
|
element.$.rangeSelect.dispatchEvent(
|
|
|
|
new CustomEvent('patch-range-change', {detail, bubbles: false}));
|
2017-09-12 16:54:19 -07:00
|
|
|
|
|
|
|
assert(navigateStub.lastCall.calledWithExactly(element._change,
|
2017-09-26 09:59:33 -07:00
|
|
|
element._path, '1', 'PARENT'));
|
2017-09-12 16:54:19 -07:00
|
|
|
});
|
|
|
|
|
2017-05-16 14:38:48 -07:00
|
|
|
test('download link', () => {
|
2016-10-21 11:01:08 -07:00
|
|
|
element._changeNum = '42';
|
|
|
|
element._patchRange = {
|
2017-07-05 21:26:33 -07:00
|
|
|
basePatchNum: PARENT,
|
2016-10-21 11:01:08 -07:00
|
|
|
patchNum: '10',
|
|
|
|
};
|
|
|
|
element._fileList = ['chell.go', 'glados.txt', 'wheatley.md'];
|
|
|
|
element._path = 'glados.txt';
|
|
|
|
flushAsynchronousOperations();
|
2017-09-07 10:39:15 -07:00
|
|
|
const link = element.$$('.downloadLink');
|
|
|
|
assert.equal(link.getAttribute('href'),
|
2016-10-21 11:01:08 -07:00
|
|
|
'/changes/42/revisions/10/patch?zip&path=glados.txt');
|
2017-09-07 10:39:15 -07:00
|
|
|
assert.isTrue(link.hasAttribute('download'));
|
2016-10-21 11:01:08 -07:00
|
|
|
});
|
|
|
|
|
2018-01-23 10:33:44 -08:00
|
|
|
test('file review status', () => {
|
2017-06-26 15:13:03 -07:00
|
|
|
const saveReviewedStub = sandbox.stub(element, '_saveReviewedState',
|
|
|
|
() => Promise.resolve());
|
|
|
|
sandbox.stub(element.$.diff, 'reload');
|
|
|
|
|
2016-02-10 21:59:20 +01:00
|
|
|
element._loggedIn = true;
|
2017-06-26 15:13:03 -07:00
|
|
|
element.params = {
|
2017-07-17 14:12:16 -07:00
|
|
|
view: Gerrit.Nav.View.DIFF,
|
2017-06-26 15:13:03 -07:00
|
|
|
changeNum: '42',
|
2016-02-10 21:59:20 +01:00
|
|
|
patchNum: '2',
|
2017-06-26 15:13:03 -07:00
|
|
|
basePatchNum: '1',
|
|
|
|
path: '/COMMIT_MSG',
|
2016-02-10 21:59:20 +01:00
|
|
|
};
|
2018-01-23 10:33:44 -08:00
|
|
|
flushAsynchronousOperations();
|
2016-02-10 21:59:20 +01:00
|
|
|
|
2018-01-23 10:33:44 -08:00
|
|
|
const commitMsg = Polymer.dom(element.root).querySelector(
|
|
|
|
'input[type="checkbox"]');
|
2016-02-10 21:59:20 +01:00
|
|
|
|
2018-01-23 10:33:44 -08:00
|
|
|
assert.isTrue(commitMsg.checked);
|
|
|
|
MockInteractions.tap(commitMsg);
|
|
|
|
assert.isFalse(commitMsg.checked);
|
|
|
|
assert.isTrue(saveReviewedStub.lastCall.calledWithExactly(false));
|
2016-02-10 21:59:20 +01:00
|
|
|
|
2018-01-23 10:33:44 -08:00
|
|
|
MockInteractions.tap(commitMsg);
|
|
|
|
assert.isTrue(commitMsg.checked);
|
|
|
|
assert.isTrue(saveReviewedStub.lastCall.calledWithExactly(true));
|
|
|
|
const callCount = saveReviewedStub.callCount;
|
2016-04-05 16:06:57 -04:00
|
|
|
|
2018-01-23 10:33:44 -08:00
|
|
|
element.set('params.view', Gerrit.Nav.View.CHANGE);
|
|
|
|
flushAsynchronousOperations();
|
|
|
|
|
|
|
|
// saveReviewedState observer observes params, but should not fire when
|
|
|
|
// view !== Gerrit.Nav.View.DIFF.
|
|
|
|
assert.equal(saveReviewedStub.callCount, callCount);
|
2016-02-10 21:59:20 +01:00
|
|
|
});
|
2016-05-05 16:53:38 -07:00
|
|
|
|
2017-08-08 14:04:54 -07:00
|
|
|
test('file review status with edit loaded', () => {
|
|
|
|
const saveReviewedStub = sandbox.stub(element, '_saveReviewedState');
|
|
|
|
|
|
|
|
element._patchRange = {patchNum: element.EDIT_NAME};
|
|
|
|
flushAsynchronousOperations();
|
|
|
|
|
2018-01-23 17:15:38 -08:00
|
|
|
assert.isTrue(element._editMode);
|
2017-08-08 14:04:54 -07:00
|
|
|
element._setReviewed();
|
|
|
|
assert.isFalse(saveReviewedStub.called);
|
|
|
|
});
|
|
|
|
|
2017-07-17 14:12:16 -07:00
|
|
|
test('hash is determined from params', done => {
|
2017-07-18 16:59:04 -07:00
|
|
|
sandbox.stub(element.$.diff, 'reload');
|
2017-08-28 16:42:40 -07:00
|
|
|
sandbox.stub(element, '_initCursor');
|
2017-07-18 16:59:04 -07:00
|
|
|
|
|
|
|
element._loggedIn = true;
|
|
|
|
element.params = {
|
2017-07-17 14:12:16 -07:00
|
|
|
view: Gerrit.Nav.View.DIFF,
|
2017-07-18 16:59:04 -07:00
|
|
|
changeNum: '42',
|
|
|
|
patchNum: '2',
|
|
|
|
basePatchNum: '1',
|
|
|
|
path: '/COMMIT_MSG',
|
|
|
|
hash: 10,
|
|
|
|
};
|
|
|
|
|
|
|
|
flush(() => {
|
2017-08-28 16:42:40 -07:00
|
|
|
assert.isTrue(element._initCursor.calledOnce);
|
2017-07-18 16:59:04 -07:00
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2017-05-16 14:38:48 -07:00
|
|
|
test('diff mode selector correctly toggles the diff', () => {
|
|
|
|
const select = element.$.modeSelect;
|
|
|
|
const diffDisplay = element.$.diff;
|
2016-12-09 16:58:31 -08:00
|
|
|
element._userPrefs = {default_diff_view: 'SIDE_BY_SIDE'};
|
2016-05-05 16:53:38 -07:00
|
|
|
|
|
|
|
// The mode selected in the view state reflects the selected option.
|
2017-07-05 14:12:44 -07:00
|
|
|
assert.equal(element._getDiffViewMode(), select.nativeSelect.value);
|
2016-05-05 16:53:38 -07:00
|
|
|
|
|
|
|
// The mode selected in the view state reflects the view rednered in the
|
|
|
|
// diff.
|
2017-07-05 14:12:44 -07:00
|
|
|
assert.equal(select.nativeSelect.value, diffDisplay.viewMode);
|
2016-05-05 16:53:38 -07:00
|
|
|
|
|
|
|
// We will simulate a user change of the selected mode.
|
2017-05-16 14:38:48 -07:00
|
|
|
const newMode = 'UNIFIED_DIFF';
|
2016-05-05 16:53:38 -07:00
|
|
|
// Set the actual value of the select, and simulate the change event.
|
2017-07-05 14:12:44 -07:00
|
|
|
select.nativeSelect.value = newMode;
|
|
|
|
element.fire('change', {}, {node: select.nativeSelect});
|
2016-05-05 16:53:38 -07:00
|
|
|
|
|
|
|
// Make sure the handler was called and the state is still coherent.
|
|
|
|
assert.equal(element._getDiffViewMode(), newMode);
|
2017-07-05 14:12:44 -07:00
|
|
|
assert.equal(element._getDiffViewMode(), select.nativeSelect.value);
|
2016-05-05 16:53:38 -07:00
|
|
|
assert.equal(element._getDiffViewMode(), diffDisplay.viewMode);
|
|
|
|
});
|
2016-06-20 14:38:33 -07:00
|
|
|
|
2017-05-16 14:38:48 -07:00
|
|
|
test('diff mode selector initializes from preferences', () => {
|
|
|
|
let resolvePrefs;
|
|
|
|
const prefsPromise = new Promise(resolve => {
|
2016-08-25 12:35:50 -07:00
|
|
|
resolvePrefs = resolve;
|
|
|
|
});
|
2017-05-16 14:38:48 -07:00
|
|
|
sandbox.stub(element.$.restAPI, 'getPreferences', () => prefsPromise);
|
2016-08-25 12:35:50 -07:00
|
|
|
|
|
|
|
// Attach a new gr-diff-view so we can intercept the preferences fetch.
|
2017-05-16 14:38:48 -07:00
|
|
|
const view = document.createElement('gr-diff-view');
|
|
|
|
const select = view.$.modeSelect;
|
2016-08-25 12:35:50 -07:00
|
|
|
fixture('blank').appendChild(view);
|
|
|
|
flushAsynchronousOperations();
|
|
|
|
|
|
|
|
// At this point the diff mode doesn't yet have the user's preference.
|
2017-07-05 14:12:44 -07:00
|
|
|
assert.equal(select.nativeSelect.value, 'SIDE_BY_SIDE');
|
2016-08-25 12:35:50 -07:00
|
|
|
|
|
|
|
// Receive the overriding preference.
|
2016-12-09 16:58:31 -08:00
|
|
|
resolvePrefs({default_diff_view: 'UNIFIED'});
|
2016-08-25 12:35:50 -07:00
|
|
|
flushAsynchronousOperations();
|
2017-07-05 14:12:44 -07:00
|
|
|
assert.equal(select.nativeSelect.value, 'SIDE_BY_SIDE');
|
2016-08-25 12:35:50 -07:00
|
|
|
});
|
|
|
|
|
2017-08-28 16:42:40 -07:00
|
|
|
test('_initCursor', () => {
|
2016-06-20 14:38:33 -07:00
|
|
|
assert.isNotOk(element.$.cursor.initialLineNumber);
|
|
|
|
|
2017-08-28 16:42:40 -07:00
|
|
|
// Does nothing when params specify no cursor address:
|
|
|
|
element._initCursor({});
|
2016-06-20 14:38:33 -07:00
|
|
|
assert.isNotOk(element.$.cursor.initialLineNumber);
|
|
|
|
|
2017-08-28 16:42:40 -07:00
|
|
|
// Does nothing when params specify side but no number:
|
|
|
|
element._initCursor({leftSide: true});
|
2017-07-18 16:59:04 -07:00
|
|
|
assert.isNotOk(element.$.cursor.initialLineNumber);
|
|
|
|
|
2017-08-28 16:42:40 -07:00
|
|
|
// Revision hash: specifies lineNum but not side.
|
|
|
|
element._initCursor({lineNum: 234});
|
2016-06-20 14:38:33 -07:00
|
|
|
assert.equal(element.$.cursor.initialLineNumber, 234);
|
|
|
|
assert.equal(element.$.cursor.side, 'right');
|
|
|
|
|
2017-08-28 16:42:40 -07:00
|
|
|
// Base hash: specifies lineNum and side.
|
|
|
|
element._initCursor({leftSide: true, lineNum: 345});
|
2016-06-20 14:38:33 -07:00
|
|
|
assert.equal(element.$.cursor.initialLineNumber, 345);
|
|
|
|
assert.equal(element.$.cursor.side, 'left');
|
2016-10-19 15:03:18 -07:00
|
|
|
|
2017-08-28 16:42:40 -07:00
|
|
|
// Specifies right side:
|
|
|
|
element._initCursor({leftSide: false, lineNum: 123});
|
2016-10-19 15:03:18 -07:00
|
|
|
assert.equal(element.$.cursor.initialLineNumber, 123);
|
2017-08-28 16:42:40 -07:00
|
|
|
assert.equal(element.$.cursor.side, 'right');
|
2016-06-20 14:38:33 -07:00
|
|
|
});
|
2016-09-27 15:57:56 -07:00
|
|
|
|
2018-01-19 17:54:50 -08:00
|
|
|
test('_getLineOfInterest', () => {
|
|
|
|
assert.isNull(element._getLineOfInterest({}));
|
|
|
|
|
|
|
|
let result = element._getLineOfInterest({lineNum: 12});
|
|
|
|
assert.equal(result.number, 12);
|
|
|
|
assert.isNotOk(result.leftSide);
|
|
|
|
|
|
|
|
result = element._getLineOfInterest({lineNum: 12, leftSide: true});
|
|
|
|
assert.equal(result.number, 12);
|
|
|
|
assert.isOk(result.leftSide);
|
|
|
|
});
|
|
|
|
|
2017-05-16 14:38:48 -07:00
|
|
|
test('_onLineSelected', () => {
|
2017-08-22 13:37:13 -07:00
|
|
|
const getUrlStub = sandbox.stub(Gerrit.Nav, 'getUrlForDiffById');
|
2017-05-16 14:38:48 -07:00
|
|
|
const replaceStateStub = sandbox.stub(history, 'replaceState');
|
|
|
|
const moveStub = sandbox.stub(element.$.cursor, 'moveToLineNumber');
|
2017-08-22 13:37:13 -07:00
|
|
|
sandbox.stub(element.$.cursor, 'getAddress')
|
|
|
|
.returns({number: 123, isLeftSide: false});
|
2016-10-26 17:11:50 -07:00
|
|
|
|
2017-08-22 13:37:13 -07:00
|
|
|
element._changeNum = 321;
|
|
|
|
element._change = {_number: 321, project: 'foo/bar'};
|
|
|
|
element._patchRange = {
|
|
|
|
basePatchNum: '3',
|
|
|
|
patchNum: '5',
|
|
|
|
};
|
2017-05-16 14:38:48 -07:00
|
|
|
const e = {};
|
|
|
|
const detail = {number: 123, side: 'right'};
|
2016-10-26 17:11:50 -07:00
|
|
|
|
|
|
|
element._onLineSelected(e, detail);
|
|
|
|
|
|
|
|
assert.isTrue(moveStub.called);
|
|
|
|
assert.equal(moveStub.lastCall.args[0], detail.number);
|
|
|
|
assert.equal(moveStub.lastCall.args[1], detail.side);
|
|
|
|
|
|
|
|
assert.isTrue(replaceStateStub.called);
|
2017-08-22 13:37:13 -07:00
|
|
|
assert.isTrue(getUrlStub.called);
|
2016-10-26 17:11:50 -07:00
|
|
|
});
|
2016-11-01 16:11:07 -07:00
|
|
|
|
2017-09-15 11:55:35 -07:00
|
|
|
test('_onLineSelected w/o line address', () => {
|
|
|
|
const getUrlStub = sandbox.stub(Gerrit.Nav, 'getUrlForDiffById');
|
|
|
|
sandbox.stub(history, 'replaceState');
|
|
|
|
sandbox.stub(element.$.cursor, 'moveToLineNumber');
|
|
|
|
sandbox.stub(element.$.cursor, 'getAddress').returns(null);
|
|
|
|
element._changeNum = 321;
|
|
|
|
element._change = {_number: 321, project: 'foo/bar'};
|
|
|
|
element._patchRange = {basePatchNum: '3', patchNum: '5'};
|
|
|
|
element._onLineSelected({}, {number: 123, side: 'right'});
|
|
|
|
assert.isTrue(getUrlStub.calledOnce);
|
|
|
|
assert.isUndefined(getUrlStub.lastCall.args[5]);
|
|
|
|
assert.isUndefined(getUrlStub.lastCall.args[6]);
|
|
|
|
});
|
|
|
|
|
2017-05-16 14:38:48 -07:00
|
|
|
test('_getDiffViewMode', () => {
|
2016-12-09 16:58:31 -08:00
|
|
|
// No user prefs or change view state set.
|
|
|
|
assert.equal(element._getDiffViewMode(), 'SIDE_BY_SIDE');
|
|
|
|
|
|
|
|
// User prefs but no change view state set.
|
|
|
|
element._userPrefs = {default_diff_view: 'UNIFIED_DIFF'};
|
|
|
|
assert.equal(element._getDiffViewMode(), 'UNIFIED_DIFF');
|
|
|
|
|
|
|
|
// User prefs and change view state set.
|
|
|
|
element.changeViewState = {diffMode: 'SIDE_BY_SIDE'};
|
|
|
|
assert.equal(element._getDiffViewMode(), 'SIDE_BY_SIDE');
|
|
|
|
});
|
2017-01-18 17:10:51 -08:00
|
|
|
|
2017-07-26 09:32:03 -07:00
|
|
|
suite('_loadComments', () => {
|
2017-05-16 14:38:48 -07:00
|
|
|
test('empty', done => {
|
2017-07-26 09:32:03 -07:00
|
|
|
element._loadComments().then(() => {
|
|
|
|
assert.equal(Object.keys(element._commentMap).length, 0);
|
2017-01-18 17:10:51 -08:00
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2017-07-26 09:32:03 -07:00
|
|
|
test('has paths', done => {
|
Update gr-comment-api
Previously, nested components (that are never standalone) were making
their own requests for comments, creating unecessary duplicate API
requests.
Some requests were made to the rest API directly (for example,
gr-change-view requested comments this way), and some were through the
gr-comment-api, which also helped handle comment manipulation and
reorganization.
Instead of ad-hoc comment requesting, move all comment requests to the
top level (standalone) component, and use an object prototype to
generate _changeComments as a property on gr-comment-api. This is an
immutable object that can be passed to the inner components
(file list, etc), and includes the methods needed to manipulate
comments into the forms
necessary.
When a child component needs to trigger a refresh of the comments, fire
an event that the parent event handles (see gr-file-list l.867).
Bug: Issue 6953
Change-Id: Ic4b6cf16520baae65d8cf956c311a60f2a70a2e1
2017-11-02 16:07:13 -07:00
|
|
|
sandbox.stub(element, '_getPaths').returns({
|
|
|
|
'path/to/file/one.cpp': [{patch_set: 3, message: 'lorem'}],
|
|
|
|
'path-to/file/two.py': [{patch_set: 5, message: 'ipsum'}],
|
2017-01-18 17:10:51 -08:00
|
|
|
});
|
Update gr-comment-api
Previously, nested components (that are never standalone) were making
their own requests for comments, creating unecessary duplicate API
requests.
Some requests were made to the rest API directly (for example,
gr-change-view requested comments this way), and some were through the
gr-comment-api, which also helped handle comment manipulation and
reorganization.
Instead of ad-hoc comment requesting, move all comment requests to the
top level (standalone) component, and use an object prototype to
generate _changeComments as a property on gr-comment-api. This is an
immutable object that can be passed to the inner components
(file list, etc), and includes the methods needed to manipulate
comments into the forms
necessary.
When a child component needs to trigger a refresh of the comments, fire
an event that the parent event handles (see gr-file-list l.867).
Bug: Issue 6953
Change-Id: Ic4b6cf16520baae65d8cf956c311a60f2a70a2e1
2017-11-02 16:07:13 -07:00
|
|
|
sandbox.stub(element, '_getCommentsForPath').returns({meta: {}});
|
2017-01-18 17:10:51 -08:00
|
|
|
element._changeNum = '42';
|
|
|
|
element._patchRange = {
|
|
|
|
basePatchNum: '3',
|
|
|
|
patchNum: '5',
|
|
|
|
};
|
2017-07-26 09:32:03 -07:00
|
|
|
element._loadComments().then(() => {
|
|
|
|
assert.deepEqual(Object.keys(element._commentMap),
|
2017-01-18 17:10:51 -08:00
|
|
|
['path/to/file/one.cpp', 'path-to/file/two.py']);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2017-05-16 14:38:48 -07:00
|
|
|
suite('_computeCommentSkips', () => {
|
|
|
|
test('empty file list', () => {
|
|
|
|
const commentMap = {
|
2017-01-18 17:10:51 -08:00
|
|
|
'path/one.jpg': true,
|
|
|
|
'path/three.wav': true,
|
|
|
|
};
|
2017-05-16 14:38:48 -07:00
|
|
|
const path = 'path/two.m4v';
|
|
|
|
const fileList = [];
|
|
|
|
const result = element._computeCommentSkips(commentMap, fileList, path);
|
2017-01-18 17:10:51 -08:00
|
|
|
assert.isNull(result.previous);
|
|
|
|
assert.isNull(result.next);
|
|
|
|
});
|
|
|
|
|
2017-05-16 14:38:48 -07:00
|
|
|
test('finds skips', () => {
|
|
|
|
const fileList = ['path/one.jpg', 'path/two.m4v', 'path/three.wav'];
|
|
|
|
let path = fileList[1];
|
|
|
|
const commentMap = {};
|
2017-01-18 17:10:51 -08:00
|
|
|
commentMap[fileList[0]] = true;
|
|
|
|
commentMap[fileList[1]] = false;
|
|
|
|
commentMap[fileList[2]] = true;
|
|
|
|
|
2017-05-16 14:38:48 -07:00
|
|
|
let result = element._computeCommentSkips(commentMap, fileList, path);
|
2017-01-18 17:10:51 -08:00
|
|
|
assert.equal(result.previous, fileList[0]);
|
|
|
|
assert.equal(result.next, fileList[2]);
|
|
|
|
|
|
|
|
commentMap[fileList[1]] = true;
|
|
|
|
|
|
|
|
result = element._computeCommentSkips(commentMap, fileList, path);
|
|
|
|
assert.equal(result.previous, fileList[0]);
|
|
|
|
assert.equal(result.next, fileList[2]);
|
|
|
|
|
|
|
|
path = fileList[0];
|
|
|
|
|
|
|
|
result = element._computeCommentSkips(commentMap, fileList, path);
|
|
|
|
assert.isNull(result.previous);
|
|
|
|
assert.equal(result.next, fileList[1]);
|
|
|
|
|
|
|
|
path = fileList[2];
|
|
|
|
|
|
|
|
result = element._computeCommentSkips(commentMap, fileList, path);
|
|
|
|
assert.equal(result.previous, fileList[1]);
|
|
|
|
assert.isNull(result.next);
|
|
|
|
});
|
2018-01-10 15:18:32 -08:00
|
|
|
|
|
|
|
suite('skip next/previous', () => {
|
|
|
|
let navToChangeStub;
|
|
|
|
let navToDiffStub;
|
|
|
|
|
|
|
|
setup(() => {
|
|
|
|
navToChangeStub = sandbox.stub(element, '_navToChangeView');
|
|
|
|
navToDiffStub = sandbox.stub(Gerrit.Nav, 'navigateToDiff');
|
|
|
|
element._fileList = [
|
|
|
|
'path/one.jpg', 'path/two.m4v', 'path/three.wav',
|
|
|
|
];
|
|
|
|
element._patchRange = {patchNum: '2', basePatchNum: '1'};
|
|
|
|
});
|
|
|
|
|
|
|
|
suite('_moveToPreviousFileWithComment', () => {
|
|
|
|
test('no skips', () => {
|
|
|
|
element._moveToPreviousFileWithComment();
|
|
|
|
assert.isFalse(navToChangeStub.called);
|
|
|
|
assert.isFalse(navToDiffStub.called);
|
|
|
|
});
|
|
|
|
|
|
|
|
test('no previous', () => {
|
|
|
|
const commentMap = {};
|
|
|
|
commentMap[element._fileList[0]] = false;
|
|
|
|
commentMap[element._fileList[1]] = false;
|
|
|
|
commentMap[element._fileList[2]] = true;
|
|
|
|
element._commentMap = commentMap;
|
|
|
|
element._path = element._fileList[1];
|
|
|
|
|
|
|
|
element._moveToPreviousFileWithComment();
|
|
|
|
assert.isTrue(navToChangeStub.calledOnce);
|
|
|
|
assert.isFalse(navToDiffStub.called);
|
|
|
|
});
|
|
|
|
|
|
|
|
test('w/ previous', () => {
|
|
|
|
const commentMap = {};
|
|
|
|
commentMap[element._fileList[0]] = true;
|
|
|
|
commentMap[element._fileList[1]] = false;
|
|
|
|
commentMap[element._fileList[2]] = true;
|
|
|
|
element._commentMap = commentMap;
|
|
|
|
element._path = element._fileList[1];
|
|
|
|
|
|
|
|
element._moveToPreviousFileWithComment();
|
|
|
|
assert.isFalse(navToChangeStub.called);
|
|
|
|
assert.isTrue(navToDiffStub.calledOnce);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
suite('_moveToNextFileWithComment', () => {
|
|
|
|
test('no skips', () => {
|
|
|
|
element._moveToNextFileWithComment();
|
|
|
|
assert.isFalse(navToChangeStub.called);
|
|
|
|
assert.isFalse(navToDiffStub.called);
|
|
|
|
});
|
|
|
|
|
|
|
|
test('no previous', () => {
|
|
|
|
const commentMap = {};
|
|
|
|
commentMap[element._fileList[0]] = true;
|
|
|
|
commentMap[element._fileList[1]] = false;
|
|
|
|
commentMap[element._fileList[2]] = false;
|
|
|
|
element._commentMap = commentMap;
|
|
|
|
element._path = element._fileList[1];
|
|
|
|
|
|
|
|
element._moveToNextFileWithComment();
|
|
|
|
assert.isTrue(navToChangeStub.calledOnce);
|
|
|
|
assert.isFalse(navToDiffStub.called);
|
|
|
|
});
|
|
|
|
|
|
|
|
test('w/ previous', () => {
|
|
|
|
const commentMap = {};
|
|
|
|
commentMap[element._fileList[0]] = true;
|
|
|
|
commentMap[element._fileList[1]] = false;
|
|
|
|
commentMap[element._fileList[2]] = true;
|
|
|
|
element._commentMap = commentMap;
|
|
|
|
element._path = element._fileList[1];
|
|
|
|
|
|
|
|
element._moveToNextFileWithComment();
|
|
|
|
assert.isFalse(navToChangeStub.called);
|
|
|
|
assert.isTrue(navToDiffStub.calledOnce);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2017-07-24 15:06:07 -07:00
|
|
|
});
|
2017-08-08 14:04:54 -07:00
|
|
|
|
2018-01-23 17:15:38 -08:00
|
|
|
test('_computeEditMode', () => {
|
|
|
|
const callCompute = range => element._computeEditMode({base: range});
|
2017-08-08 14:04:54 -07:00
|
|
|
assert.isFalse(callCompute({}));
|
|
|
|
assert.isFalse(callCompute({basePatchNum: 'PARENT', patchNum: 1}));
|
|
|
|
assert.isFalse(callCompute({basePatchNum: 'edit', patchNum: 1}));
|
|
|
|
assert.isTrue(callCompute({basePatchNum: 1, patchNum: 'edit'}));
|
|
|
|
});
|
|
|
|
|
2018-01-23 17:15:38 -08:00
|
|
|
suite('editMode behavior', () => {
|
2017-08-08 14:04:54 -07:00
|
|
|
setup(() => {
|
|
|
|
element._loggedIn = true;
|
|
|
|
});
|
|
|
|
|
|
|
|
const isVisible = el => {
|
|
|
|
assert.ok(el);
|
|
|
|
return getComputedStyle(el).getPropertyValue('display') !== 'none';
|
|
|
|
};
|
|
|
|
|
|
|
|
test('reviewed checkbox', () => {
|
2017-09-26 09:59:33 -07:00
|
|
|
sandbox.stub(element, '_handlePatchChange');
|
2017-08-08 14:04:54 -07:00
|
|
|
element._patchRange = {patchNum: '1'};
|
|
|
|
// Reviewed checkbox should be shown.
|
|
|
|
assert.isTrue(isVisible(element.$.reviewed));
|
|
|
|
element.set('_patchRange.patchNum', element.EDIT_NAME);
|
|
|
|
flushAsynchronousOperations();
|
|
|
|
|
|
|
|
assert.isFalse(isVisible(element.$.reviewed));
|
|
|
|
});
|
|
|
|
});
|
2015-11-14 15:40:47 -05:00
|
|
|
});
|
|
|
|
</script>
|