2015-12-16 18:34:58 -05:00
|
|
|
<!DOCTYPE html>
|
|
|
|
<!--
|
2018-03-26 10:04:27 -04:00
|
|
|
@license
|
2015-12-16 18:34:58 -05:00
|
|
|
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">
|
|
|
|
<title>gr-patch-range-select</title>
|
|
|
|
|
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>
|
2015-12-16 18:34:58 -05:00
|
|
|
|
2017-11-09 11:37:09 -08:00
|
|
|
<link rel="import" href="../../diff/gr-comment-api/gr-comment-api.html">
|
|
|
|
<link rel="import" href="../../shared/gr-rest-api-interface/mock-diff-response_test.html">
|
2017-11-08 15:33:48 -08:00
|
|
|
<link rel="import" href="../../shared/revision-info/revision-info.html">
|
|
|
|
|
2016-03-04 17:48:22 -05:00
|
|
|
<link rel="import" href="gr-patch-range-select.html">
|
2015-12-16 18:34:58 -05:00
|
|
|
|
2017-03-28 17:02:44 -07:00
|
|
|
<script>void(0);</script>
|
|
|
|
|
2017-11-09 11:37:09 -08:00
|
|
|
<dom-module id="comment-api-mock">
|
|
|
|
<template>
|
|
|
|
<gr-patch-range-select id="patchRange" auto
|
|
|
|
change-comments="[[_changeComments]]"></gr-patch-range-select>
|
|
|
|
<gr-comment-api id="commentAPI"></gr-comment-api>
|
|
|
|
</template>
|
|
|
|
<script src="../../diff/gr-comment-api/gr-comment-api-mock.js"></script>
|
|
|
|
</dom-module>
|
|
|
|
|
2015-12-16 18:34:58 -05:00
|
|
|
<test-fixture id="basic">
|
|
|
|
<template>
|
2017-11-09 11:37:09 -08:00
|
|
|
<comment-api-mock></comment-api-mock>
|
2015-12-16 18:34:58 -05:00
|
|
|
</template>
|
|
|
|
</test-fixture>
|
|
|
|
|
|
|
|
<script>
|
2017-05-16 14:41:17 -07:00
|
|
|
suite('gr-patch-range-select tests', () => {
|
|
|
|
let element;
|
2017-04-25 23:48:05 +02:00
|
|
|
let sandbox;
|
2017-11-09 11:37:09 -08:00
|
|
|
let commentApiWrapper;
|
2015-12-16 18:34:58 -05:00
|
|
|
|
2017-11-08 15:33:48 -08:00
|
|
|
function getInfo(revisions) {
|
|
|
|
const revisionObj = {};
|
|
|
|
for (let i = 0; i < revisions.length; i++) {
|
|
|
|
revisionObj[i] = revisions[i];
|
|
|
|
}
|
|
|
|
return new Gerrit.RevisionInfo({revisions: revisionObj});
|
|
|
|
}
|
|
|
|
|
2017-05-16 14:41:17 -07:00
|
|
|
setup(() => {
|
2017-04-25 23:48:05 +02:00
|
|
|
sandbox = sinon.sandbox.create();
|
2017-11-09 11:37:09 -08:00
|
|
|
|
|
|
|
stub('gr-rest-api-interface', {
|
|
|
|
getDiffComments() { return Promise.resolve({}); },
|
|
|
|
getDiffRobotComments() { return Promise.resolve({}); },
|
|
|
|
getDiffDrafts() { return Promise.resolve({}); },
|
|
|
|
});
|
|
|
|
|
|
|
|
// Element must be wrapped in an element with direct access to the
|
|
|
|
// comment API.
|
|
|
|
commentApiWrapper = fixture('basic');
|
|
|
|
element = commentApiWrapper.$.patchRange;
|
|
|
|
|
|
|
|
// Stub methods on the changeComments object after changeComments has
|
|
|
|
// been initalized.
|
|
|
|
return commentApiWrapper.loadComments();
|
2015-12-16 18:34:58 -05:00
|
|
|
});
|
|
|
|
|
2017-04-25 23:48:05 +02:00
|
|
|
teardown(() => sandbox.restore());
|
|
|
|
|
2017-05-16 14:41:17 -07:00
|
|
|
test('enabled/disabled options', () => {
|
|
|
|
const patchRange = {
|
2015-12-16 18:34:58 -05:00
|
|
|
basePatchNum: 'PARENT',
|
|
|
|
patchNum: '3',
|
|
|
|
};
|
2017-09-12 16:54:19 -07:00
|
|
|
const sortedRevisions = [
|
2017-04-25 23:48:05 +02:00
|
|
|
{_number: 3},
|
2017-11-02 15:38:12 -07:00
|
|
|
{_number: element.EDIT_NAME, basePatchNum: 2},
|
|
|
|
{_number: 2},
|
|
|
|
{_number: 1},
|
2017-04-25 23:48:05 +02:00
|
|
|
];
|
2017-05-16 14:41:17 -07:00
|
|
|
for (const patchNum of ['1', '2', '3']) {
|
2017-11-02 15:38:12 -07:00
|
|
|
assert.isFalse(element._computeRightDisabled(patchRange.basePatchNum,
|
|
|
|
patchNum, sortedRevisions));
|
2017-05-16 14:41:17 -07:00
|
|
|
}
|
2017-11-02 15:38:12 -07:00
|
|
|
for (const basePatchNum of ['1', '2']) {
|
|
|
|
assert.isFalse(element._computeLeftDisabled(basePatchNum,
|
2017-09-12 16:54:19 -07:00
|
|
|
patchRange.patchNum, sortedRevisions));
|
2017-05-16 14:41:17 -07:00
|
|
|
}
|
2017-09-12 16:54:19 -07:00
|
|
|
assert.isTrue(element._computeLeftDisabled('3', patchRange.patchNum));
|
2015-12-16 18:34:58 -05:00
|
|
|
|
2017-04-25 23:48:05 +02:00
|
|
|
patchRange.basePatchNum = element.EDIT_NAME;
|
2017-09-12 16:54:19 -07:00
|
|
|
assert.isTrue(element._computeLeftDisabled('3', patchRange.patchNum,
|
|
|
|
sortedRevisions));
|
2017-11-02 15:38:12 -07:00
|
|
|
assert.isTrue(element._computeRightDisabled(patchRange.basePatchNum, '1',
|
2017-09-12 16:54:19 -07:00
|
|
|
sortedRevisions));
|
2017-11-02 15:38:12 -07:00
|
|
|
assert.isTrue(element._computeRightDisabled(patchRange.basePatchNum, '2',
|
2017-09-12 16:54:19 -07:00
|
|
|
sortedRevisions));
|
2017-11-02 15:38:12 -07:00
|
|
|
assert.isFalse(element._computeRightDisabled(patchRange.basePatchNum, '3',
|
2017-09-12 16:54:19 -07:00
|
|
|
sortedRevisions));
|
2017-11-02 15:38:12 -07:00
|
|
|
assert.isTrue(element._computeRightDisabled(patchRange.basePatchNum,
|
|
|
|
element.EDIT_NAME, sortedRevisions));
|
2015-12-16 18:34:58 -05:00
|
|
|
});
|
|
|
|
|
2017-09-26 09:59:33 -07:00
|
|
|
test('_computeBaseDropdownContent', () => {
|
|
|
|
const availablePatches = [
|
|
|
|
{num: 'edit'},
|
2017-11-02 15:38:12 -07:00
|
|
|
{num: 3},
|
|
|
|
{num: 2},
|
|
|
|
{num: 1},
|
2017-09-26 09:59:33 -07:00
|
|
|
];
|
2017-11-08 15:33:48 -08:00
|
|
|
const revisions = [
|
|
|
|
{
|
|
|
|
commit: {parents: []},
|
|
|
|
_number: 2,
|
|
|
|
description: 'description',
|
|
|
|
},
|
|
|
|
{commit: {parents: []}},
|
|
|
|
{commit: {parents: []}},
|
|
|
|
{commit: {parents: []}},
|
|
|
|
];
|
|
|
|
element.revisionInfo = getInfo(revisions);
|
2017-09-26 09:59:33 -07:00
|
|
|
const patchNum = 1;
|
|
|
|
const sortedRevisions = [
|
2017-11-23 00:20:32 -05:00
|
|
|
{_number: 3, created: 'Mon, 01 Jan 2001 00:00:00 GMT'},
|
2017-11-02 15:38:12 -07:00
|
|
|
{_number: element.EDIT_NAME, basePatchNum: 2},
|
2017-11-06 16:55:37 -08:00
|
|
|
{_number: 2, description: 'description'},
|
2017-11-02 15:38:12 -07:00
|
|
|
{_number: 1},
|
2017-09-26 09:59:33 -07:00
|
|
|
];
|
|
|
|
const expectedResult = [
|
|
|
|
{
|
2017-11-02 15:38:12 -07:00
|
|
|
disabled: true,
|
|
|
|
triggerText: 'Patchset edit',
|
|
|
|
text: 'Patchset edit',
|
|
|
|
mobileText: 'edit',
|
|
|
|
bottomText: '',
|
|
|
|
value: 'edit',
|
2017-09-26 09:59:33 -07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
disabled: true,
|
2017-11-02 15:38:12 -07:00
|
|
|
triggerText: 'Patchset 3',
|
|
|
|
text: 'Patchset 3',
|
|
|
|
mobileText: '3',
|
2017-09-26 09:59:33 -07:00
|
|
|
bottomText: '',
|
2017-11-02 15:38:12 -07:00
|
|
|
value: 3,
|
2017-11-23 00:20:32 -05:00
|
|
|
date: 'Mon, 01 Jan 2001 00:00:00 GMT',
|
2017-09-26 09:59:33 -07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
disabled: true,
|
|
|
|
triggerText: 'Patchset 2',
|
|
|
|
text: 'Patchset 2',
|
|
|
|
mobileText: '2 description',
|
|
|
|
bottomText: 'description',
|
|
|
|
value: 2,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
disabled: true,
|
2017-11-02 15:38:12 -07:00
|
|
|
triggerText: 'Patchset 1',
|
|
|
|
text: 'Patchset 1',
|
|
|
|
mobileText: '1',
|
2017-09-26 09:59:33 -07:00
|
|
|
bottomText: '',
|
2017-11-02 15:38:12 -07:00
|
|
|
value: 1,
|
2017-09-26 09:59:33 -07:00
|
|
|
},
|
|
|
|
{
|
2017-11-02 15:38:12 -07:00
|
|
|
text: 'Base',
|
|
|
|
value: 'PARENT',
|
2017-09-26 09:59:33 -07:00
|
|
|
},
|
|
|
|
];
|
|
|
|
assert.deepEqual(element._computeBaseDropdownContent(availablePatches,
|
2017-11-08 15:33:48 -08:00
|
|
|
patchNum, sortedRevisions, element.changeComments,
|
|
|
|
element.revisionInfo),
|
2017-11-09 11:37:09 -08:00
|
|
|
expectedResult);
|
2017-09-12 16:54:19 -07:00
|
|
|
});
|
|
|
|
|
2017-09-26 09:59:33 -07:00
|
|
|
test('_computeBaseDropdownContent called when patchNum updates', () => {
|
2017-09-12 16:54:19 -07:00
|
|
|
element.revisions = [
|
2017-11-08 15:33:48 -08:00
|
|
|
{commit: {parents: []}},
|
|
|
|
{commit: {parents: []}},
|
|
|
|
{commit: {parents: []}},
|
|
|
|
{commit: {parents: []}},
|
2017-09-12 16:54:19 -07:00
|
|
|
];
|
2017-11-08 15:33:48 -08:00
|
|
|
element.revisionInfo = getInfo(element.revisions);
|
2017-09-12 16:54:19 -07:00
|
|
|
element.availablePatches = [
|
|
|
|
{num: 1},
|
|
|
|
{num: 2},
|
|
|
|
{num: 3},
|
|
|
|
{num: 'edit'},
|
|
|
|
];
|
2017-09-26 09:59:33 -07:00
|
|
|
element.patchNum = 2;
|
|
|
|
element.basePatchNum = 'PARENT';
|
2017-09-12 16:54:19 -07:00
|
|
|
flushAsynchronousOperations();
|
|
|
|
|
2017-09-26 09:59:33 -07:00
|
|
|
sandbox.stub(element, '_computeBaseDropdownContent');
|
|
|
|
|
2017-09-12 16:54:19 -07:00
|
|
|
// Should be recomputed for each available patch
|
2017-09-26 09:59:33 -07:00
|
|
|
element.set('patchNum', 1);
|
|
|
|
assert.equal(element._computeBaseDropdownContent.callCount, 1);
|
2017-09-12 16:54:19 -07:00
|
|
|
});
|
|
|
|
|
2017-11-09 11:37:09 -08:00
|
|
|
test('_computeBaseDropdownContent called when changeComments update',
|
|
|
|
done => {
|
|
|
|
element.revisions = [
|
2017-11-08 15:33:48 -08:00
|
|
|
{commit: {parents: []}},
|
|
|
|
{commit: {parents: []}},
|
|
|
|
{commit: {parents: []}},
|
|
|
|
{commit: {parents: []}},
|
2017-11-09 11:37:09 -08:00
|
|
|
];
|
2017-11-08 15:33:48 -08:00
|
|
|
element.revisionInfo = getInfo(element.revisions);
|
2017-11-09 11:37:09 -08:00
|
|
|
element.availablePatches = [
|
2017-11-08 15:33:48 -08:00
|
|
|
{num: 'edit'},
|
|
|
|
{num: 3},
|
|
|
|
{num: 2},
|
|
|
|
{num: 1},
|
2017-11-09 11:37:09 -08:00
|
|
|
];
|
|
|
|
element.patchNum = 2;
|
|
|
|
element.basePatchNum = 'PARENT';
|
|
|
|
flushAsynchronousOperations();
|
|
|
|
|
|
|
|
// Should be recomputed for each available patch
|
|
|
|
sandbox.stub(element, '_computeBaseDropdownContent');
|
|
|
|
assert.equal(element._computeBaseDropdownContent.callCount, 0);
|
|
|
|
commentApiWrapper.loadComments().then().then(() => {
|
|
|
|
assert.equal(element._computeBaseDropdownContent.callCount, 1);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
2017-10-16 16:34:31 -07:00
|
|
|
|
2017-09-26 09:59:33 -07:00
|
|
|
test('_computePatchDropdownContent called when basePatchNum updates', () => {
|
2017-09-12 16:54:19 -07:00
|
|
|
element.revisions = [
|
2017-11-08 15:33:48 -08:00
|
|
|
{commit: {parents: []}},
|
|
|
|
{commit: {parents: []}},
|
|
|
|
{commit: {parents: []}},
|
|
|
|
{commit: {parents: []}},
|
2017-09-12 16:54:19 -07:00
|
|
|
];
|
2017-11-08 15:33:48 -08:00
|
|
|
element.revisionInfo = getInfo(element.revisions);
|
2017-09-12 16:54:19 -07:00
|
|
|
element.availablePatches = [
|
|
|
|
{num: 1},
|
|
|
|
{num: 2},
|
|
|
|
{num: 3},
|
|
|
|
{num: 'edit'},
|
|
|
|
];
|
2017-09-26 09:59:33 -07:00
|
|
|
element.patchNum = 2;
|
|
|
|
element.basePatchNum = 'PARENT';
|
2017-09-12 16:54:19 -07:00
|
|
|
flushAsynchronousOperations();
|
|
|
|
|
|
|
|
// Should be recomputed for each available patch
|
2017-09-26 09:59:33 -07:00
|
|
|
sandbox.stub(element, '_computePatchDropdownContent');
|
|
|
|
element.set('basePatchNum', 1);
|
|
|
|
assert.equal(element._computePatchDropdownContent.callCount, 1);
|
2017-09-12 16:54:19 -07:00
|
|
|
});
|
|
|
|
|
2017-11-09 11:37:09 -08:00
|
|
|
test('_computePatchDropdownContent called when comments update', done => {
|
2017-10-16 16:34:31 -07:00
|
|
|
element.revisions = [
|
2017-11-08 15:33:48 -08:00
|
|
|
{commit: {parents: []}},
|
|
|
|
{commit: {parents: []}},
|
|
|
|
{commit: {parents: []}},
|
|
|
|
{commit: {parents: []}},
|
2017-10-16 16:34:31 -07:00
|
|
|
];
|
2017-11-08 15:33:48 -08:00
|
|
|
element.revisionInfo = getInfo(element.revisions);
|
2017-10-16 16:34:31 -07:00
|
|
|
element.availablePatches = [
|
|
|
|
{num: 1},
|
|
|
|
{num: 2},
|
|
|
|
{num: 3},
|
|
|
|
{num: 'edit'},
|
|
|
|
];
|
|
|
|
element.patchNum = 2;
|
|
|
|
element.basePatchNum = 'PARENT';
|
|
|
|
flushAsynchronousOperations();
|
|
|
|
|
|
|
|
// Should be recomputed for each available patch
|
|
|
|
sandbox.stub(element, '_computePatchDropdownContent');
|
|
|
|
assert.equal(element._computePatchDropdownContent.callCount, 0);
|
2017-11-09 11:37:09 -08:00
|
|
|
commentApiWrapper.loadComments().then().then(() => {
|
|
|
|
done();
|
2017-10-16 16:34:31 -07:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2017-09-26 09:59:33 -07:00
|
|
|
test('_computePatchDropdownContent', () => {
|
|
|
|
const availablePatches = [
|
2017-09-12 16:54:19 -07:00
|
|
|
{num: 'edit'},
|
2017-11-02 15:38:12 -07:00
|
|
|
{num: 3},
|
|
|
|
{num: 2},
|
|
|
|
{num: 1},
|
2017-09-12 16:54:19 -07:00
|
|
|
];
|
2017-09-26 09:59:33 -07:00
|
|
|
const basePatchNum = 1;
|
|
|
|
const sortedRevisions = [
|
2017-11-23 00:20:32 -05:00
|
|
|
{_number: 3, created: 'Mon, 01 Jan 2001 00:00:00 GMT'},
|
2017-11-02 15:38:12 -07:00
|
|
|
{_number: element.EDIT_NAME, basePatchNum: 2},
|
2017-11-06 16:55:37 -08:00
|
|
|
{_number: 2, description: 'description'},
|
2017-11-02 15:38:12 -07:00
|
|
|
{_number: 1},
|
2017-09-26 09:59:33 -07:00
|
|
|
];
|
2017-09-12 16:54:19 -07:00
|
|
|
|
2017-09-26 09:59:33 -07:00
|
|
|
const expectedResult = [
|
|
|
|
{
|
|
|
|
disabled: false,
|
2017-11-02 15:38:12 -07:00
|
|
|
triggerText: 'edit',
|
|
|
|
text: 'edit',
|
|
|
|
mobileText: 'edit',
|
|
|
|
bottomText: '',
|
|
|
|
value: 'edit',
|
2017-09-26 09:59:33 -07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
disabled: false,
|
|
|
|
triggerText: 'Patchset 3',
|
|
|
|
text: 'Patchset 3',
|
|
|
|
mobileText: '3',
|
|
|
|
bottomText: '',
|
|
|
|
value: 3,
|
2017-11-23 00:20:32 -05:00
|
|
|
date: 'Mon, 01 Jan 2001 00:00:00 GMT',
|
2017-09-26 09:59:33 -07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
disabled: false,
|
2017-11-02 15:38:12 -07:00
|
|
|
triggerText: 'Patchset 2',
|
|
|
|
text: 'Patchset 2',
|
|
|
|
mobileText: '2 description',
|
|
|
|
bottomText: 'description',
|
|
|
|
value: 2,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
disabled: true,
|
|
|
|
triggerText: 'Patchset 1',
|
|
|
|
text: 'Patchset 1',
|
|
|
|
mobileText: '1',
|
2017-09-26 09:59:33 -07:00
|
|
|
bottomText: '',
|
2017-11-02 15:38:12 -07:00
|
|
|
value: 1,
|
2017-09-26 09:59:33 -07:00
|
|
|
},
|
|
|
|
];
|
2017-09-12 16:54:19 -07:00
|
|
|
|
2017-09-26 09:59:33 -07:00
|
|
|
assert.deepEqual(element._computePatchDropdownContent(availablePatches,
|
2017-11-09 11:37:09 -08:00
|
|
|
basePatchNum, sortedRevisions, element.changeComments),
|
|
|
|
expectedResult);
|
2017-09-12 16:54:19 -07:00
|
|
|
});
|
|
|
|
|
2017-05-16 14:41:17 -07:00
|
|
|
test('filesWeblinks', () => {
|
2016-08-03 13:16:36 -07:00
|
|
|
element.filesWeblinks = {
|
|
|
|
meta_a: [
|
|
|
|
{
|
|
|
|
name: 'foo',
|
|
|
|
url: 'f.oo',
|
2017-05-16 14:41:17 -07:00
|
|
|
},
|
2016-08-03 13:16:36 -07:00
|
|
|
],
|
|
|
|
meta_b: [
|
|
|
|
{
|
|
|
|
name: 'bar',
|
|
|
|
url: 'ba.r',
|
2017-05-16 14:41:17 -07:00
|
|
|
},
|
2016-08-03 13:16:36 -07:00
|
|
|
],
|
|
|
|
};
|
|
|
|
flushAsynchronousOperations();
|
2017-05-16 14:41:17 -07:00
|
|
|
const domApi = Polymer.dom(element.root);
|
2016-08-03 13:16:36 -07:00
|
|
|
assert.equal(
|
|
|
|
domApi.querySelector('a[href="f.oo"]').textContent, 'foo');
|
|
|
|
assert.equal(
|
|
|
|
domApi.querySelector('a[href="ba.r"]').textContent, 'bar');
|
|
|
|
});
|
2017-09-12 16:54:19 -07:00
|
|
|
|
|
|
|
test('_computePatchSetCommentsString', () => {
|
|
|
|
// Test string with unresolved comments.
|
2017-11-09 11:37:09 -08:00
|
|
|
element.changeComments._comments = {
|
2017-09-12 16:54:19 -07:00
|
|
|
foo: [{
|
|
|
|
id: '27dcee4d_f7b77cfa',
|
|
|
|
message: 'test',
|
|
|
|
patch_set: 1,
|
|
|
|
unresolved: true,
|
Count unresolved threads within thread groups rather than by leaves
Diff comments are threaded together based on the in_reply_to relation
(which potentially expresses a tree structure) but are always displayed
linearly in the UI. This means that some comments in the middle of a
linear thread may be actually stored as leaves of a tree.
For example, the following thread of comments can be created if comments
two and three are created at nearly the same time.
Comment 1: thread root, unresolved,
┣ Comment 2: in reply to comment 1, unresolved,
┗ Comment 3: also in reply to comment 1, unresolved,
┗ Comment 4: in reply to comment 3, resolved
Because the thread is flattened, the resolved state of the thread should
be determined by the state of the chronologically latest comment (#4),
resulting in this thread being considered as resolved.
However, in a couple of locations, the resolved state is counted
differently. Namely, it finds the "leaf" comments -- that is, the
comments that are not marked as the parent of any other comment -- and
the number of unresolved threads is determined as the number of
unresolved leaves.
This approach was used by:
- ChangeComments#computeUnresolvedNum in the UI, which determines
the string stating the number of unresolved threads in a file row.
- ChangeData#unresolvedCommentCount in the Java server code, which
determines, among other things, the value of the
unresolved_comment_count change detail property, as well as the Prolog
fact used by the Prolog recipe that requires all comments to be
resolved before a change can be submitted.
Instead, the unresolved thread logic is modified to group comments into
flat threads, and consider the resolved state of each one based on the
chronologically final comment, irregardless of the leaves.
Bug: Issue 8472
Change-Id: I2788fdb22ecfd56f0b3da763790a7732ec73be33
2018-03-01 14:25:06 -08:00
|
|
|
updated: '2017-10-11 20:48:40.000000000',
|
2017-09-12 16:54:19 -07:00
|
|
|
}],
|
|
|
|
bar: [{
|
|
|
|
id: '27dcee4d_f7b77cfa',
|
|
|
|
message: 'test',
|
|
|
|
patch_set: 1,
|
Count unresolved threads within thread groups rather than by leaves
Diff comments are threaded together based on the in_reply_to relation
(which potentially expresses a tree structure) but are always displayed
linearly in the UI. This means that some comments in the middle of a
linear thread may be actually stored as leaves of a tree.
For example, the following thread of comments can be created if comments
two and three are created at nearly the same time.
Comment 1: thread root, unresolved,
┣ Comment 2: in reply to comment 1, unresolved,
┗ Comment 3: also in reply to comment 1, unresolved,
┗ Comment 4: in reply to comment 3, resolved
Because the thread is flattened, the resolved state of the thread should
be determined by the state of the chronologically latest comment (#4),
resulting in this thread being considered as resolved.
However, in a couple of locations, the resolved state is counted
differently. Namely, it finds the "leaf" comments -- that is, the
comments that are not marked as the parent of any other comment -- and
the number of unresolved threads is determined as the number of
unresolved leaves.
This approach was used by:
- ChangeComments#computeUnresolvedNum in the UI, which determines
the string stating the number of unresolved threads in a file row.
- ChangeData#unresolvedCommentCount in the Java server code, which
determines, among other things, the value of the
unresolved_comment_count change detail property, as well as the Prolog
fact used by the Prolog recipe that requires all comments to be
resolved before a change can be submitted.
Instead, the unresolved thread logic is modified to group comments into
flat threads, and consider the resolved state of each one based on the
chronologically final comment, irregardless of the leaves.
Bug: Issue 8472
Change-Id: I2788fdb22ecfd56f0b3da763790a7732ec73be33
2018-03-01 14:25:06 -08:00
|
|
|
updated: '2017-10-12 20:48:40.000000000',
|
2017-09-12 16:54:19 -07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
id: '27dcee4d_f7b77cfa',
|
|
|
|
message: 'test',
|
|
|
|
patch_set: 1,
|
Count unresolved threads within thread groups rather than by leaves
Diff comments are threaded together based on the in_reply_to relation
(which potentially expresses a tree structure) but are always displayed
linearly in the UI. This means that some comments in the middle of a
linear thread may be actually stored as leaves of a tree.
For example, the following thread of comments can be created if comments
two and three are created at nearly the same time.
Comment 1: thread root, unresolved,
┣ Comment 2: in reply to comment 1, unresolved,
┗ Comment 3: also in reply to comment 1, unresolved,
┗ Comment 4: in reply to comment 3, resolved
Because the thread is flattened, the resolved state of the thread should
be determined by the state of the chronologically latest comment (#4),
resulting in this thread being considered as resolved.
However, in a couple of locations, the resolved state is counted
differently. Namely, it finds the "leaf" comments -- that is, the
comments that are not marked as the parent of any other comment -- and
the number of unresolved threads is determined as the number of
unresolved leaves.
This approach was used by:
- ChangeComments#computeUnresolvedNum in the UI, which determines
the string stating the number of unresolved threads in a file row.
- ChangeData#unresolvedCommentCount in the Java server code, which
determines, among other things, the value of the
unresolved_comment_count change detail property, as well as the Prolog
fact used by the Prolog recipe that requires all comments to be
resolved before a change can be submitted.
Instead, the unresolved thread logic is modified to group comments into
flat threads, and consider the resolved state of each one based on the
chronologically final comment, irregardless of the leaves.
Bug: Issue 8472
Change-Id: I2788fdb22ecfd56f0b3da763790a7732ec73be33
2018-03-01 14:25:06 -08:00
|
|
|
updated: '2017-10-13 20:48:40.000000000',
|
2017-09-12 16:54:19 -07:00
|
|
|
}],
|
|
|
|
abc: [],
|
|
|
|
};
|
|
|
|
|
2017-11-09 11:37:09 -08:00
|
|
|
assert.equal(element._computePatchSetCommentsString(
|
|
|
|
element.changeComments, 1), ' (3 comments, 1 unresolved)');
|
2017-09-12 16:54:19 -07:00
|
|
|
|
|
|
|
// Test string with no unresolved comments.
|
2017-11-09 11:37:09 -08:00
|
|
|
delete element.changeComments._comments['foo'];
|
|
|
|
assert.equal(element._computePatchSetCommentsString(
|
|
|
|
element.changeComments, 1), ' (2 comments)');
|
2017-09-12 16:54:19 -07:00
|
|
|
|
|
|
|
// Test string with no comments.
|
2017-11-09 11:37:09 -08:00
|
|
|
delete element.changeComments._comments['bar'];
|
|
|
|
assert.equal(element._computePatchSetCommentsString(
|
|
|
|
element.changeComments, 1), '');
|
2017-09-12 16:54:19 -07:00
|
|
|
});
|
2017-10-03 12:10:44 +01:00
|
|
|
|
|
|
|
test('patch-range-change fires', () => {
|
|
|
|
const handler = sandbox.stub();
|
|
|
|
element.basePatchNum = 1;
|
|
|
|
element.patchNum = 3;
|
|
|
|
element.addEventListener('patch-range-change', handler);
|
|
|
|
|
|
|
|
element.$.basePatchDropdown._handleValueChange(2, [{value: 2}]);
|
|
|
|
assert.isTrue(handler.calledOnce);
|
|
|
|
assert.deepEqual(handler.lastCall.args[0].detail,
|
|
|
|
{basePatchNum: 2, patchNum: 3});
|
|
|
|
|
|
|
|
// BasePatchNum should not have changed, due to one-way data binding.
|
|
|
|
element.$.patchNumDropdown._handleValueChange('edit', [{value: 'edit'}]);
|
|
|
|
assert.deepEqual(handler.lastCall.args[0].detail,
|
|
|
|
{basePatchNum: 1, patchNum: 'edit'});
|
|
|
|
});
|
2015-12-16 18:34:58 -05:00
|
|
|
});
|
|
|
|
</script>
|