Add patchset navigator for checks table
Change-Id: I6d29739a68f9b49a98e76017f8ad8aad001fc01c
diff --git a/gr-checks/gr-checks-view.html b/gr-checks/gr-checks-view.html
index 205dbe6..b7c658d 100644
--- a/gr-checks/gr-checks-view.html
+++ b/gr-checks/gr-checks-view.html
@@ -48,6 +48,7 @@
header {
display: flex;
margin: 1rem 1rem 0;
+ justify-content: space-between;
}
table {
@@ -96,9 +97,20 @@
}
</style>
- <template is="dom-if" if="[[_createCheckerCapability]]">
- <gr-button class="configure-button" on-click="_handleConfigureClicked"> Configure </gr-button>
- </template>
+ <header>
+ <template is="dom-if" if="[[_patchSetDropdownItems.length]]">
+ <gr-dropdown-list
+ class="patch-set-dropdown"
+ items="[[_patchSetDropdownItems]]"
+ on-value-change="_handlePatchSetChanged"
+ value="[[_currentPatchSet]]">
+ </gr-dropdown-list>
+ </template>
+ <template is="dom-if" if="[[_createCheckerCapability]]">
+ <gr-button class="configure-button" on-click="_handleConfigureClicked"> Configure </gr-button>
+ </template>
+ </header>
+
<template is="dom-if" if="[[_isLoading(_status)]]">
<div class="no-content">
@@ -121,10 +133,6 @@
</template>
<template is="dom-if" if="[[_hasResults(_status)]]">
- <header>
- <h3>Latest checks for Patchset [[revision._number]]</h3>
- </header>
-
<table>
<thead>
<tr class="headerRow">
diff --git a/gr-checks/gr-checks-view.js b/gr-checks/gr-checks-view.js
index 41d4054..af2d11c 100644
--- a/gr-checks/gr-checks-view.js
+++ b/gr-checks/gr-checks-view.js
@@ -39,7 +39,10 @@
is: 'gr-checks-view',
properties: {
- revision: Object,
+ revision: {
+ type: Object,
+ observer: '_computeCurrentPatchSet',
+ },
change: Object,
/** @type {function(number, number): !Promise<!Object>} */
getChecks: Function,
@@ -61,15 +64,32 @@
type: Boolean,
value: false,
},
+ _patchSetDropdownItems: {
+ type: Array,
+ value() { return []; },
+ },
+ _currentPatchSet: {
+ type: Number,
+ },
},
observers: [
- '_pollChecksRegularly(change, revision, getChecks)',
+ '_pollChecksRegularly(change, _currentPatchSet, getChecks)',
],
attached() {
this.pluginRestApi = this.plugin.restApi();
this._initCreateCheckerCapability();
+ this._patchSetDropdownItems = Object.values(this.change.revisions)
+ .filter(patch => patch._number !== 'edit')
+ .map(patch => {
+ return {
+ text: 'Patchset ' + patch._number,
+ value: patch._number,
+ };
+ })
+ .sort((a, b) => b.value - a.value);
+ this._currentPatchSet = this.revision._number;
},
detached() {
@@ -77,6 +97,16 @@
this.unlisten(document, 'visibilitychange', '_onVisibililityChange');
},
+ _computeCurrentPatchSet(revision) {
+ this._currentPatchSet = revision._number;
+ },
+
+ _handlePatchSetChanged(e) {
+ const patchSet = e.detail.value;
+ if (patchSet === this._currentPatchSet) return;
+ this._currentPatchSet = patchSet;
+ },
+
_handleCheckersListResize() {
// Force polymer to recalculate position of overlay when length of
// checkers changes
@@ -160,10 +190,11 @@
* @param {!Defs.Revision} revision
* @param {function(number, number): !Promise<!Object>} getChecks
*/
- _fetchChecks(change, revision, getChecks) {
- if (!getChecks || !change || !revision) return;
+ _fetchChecks(change, revisionNumber, getChecks) {
+ if (!getChecks || !change || !revisionNumber) return;
- getChecks(change._number, revision._number).then(checks => {
+ getChecks(change._number, revisionNumber).then(checks => {
+ if (revisionNumber !== this._currentPatchSet) return;
if (checks && checks.length) {
checks.sort((a, b) => this._orderChecks(a, b));
if (!this._checks) {
@@ -186,7 +217,8 @@
clearInterval(this.pollChecksInterval);
return;
}
- this._pollChecksRegularly(this.change, this.revision, this.getChecks);
+ this._pollChecksRegularly(this.change, this._currentPatchSet,
+ this.getChecks);
},
_toggleCheckMessage(e) {
@@ -205,11 +237,12 @@
!this._checks[idx].showCheckMessage);
},
- _pollChecksRegularly(change, revision, getChecks) {
+ _pollChecksRegularly(change, revisionNumber, getChecks) {
+ if (!change || !revisionNumber || !getChecks) return;
if (this.pollChecksInterval) {
clearInterval(this.pollChecksInterval);
}
- const poll = () => this._fetchChecks(change, revision, getChecks);
+ const poll = () => this._fetchChecks(change, revisionNumber, getChecks);
poll();
this.pollChecksInterval = setInterval(poll, CHECKS_POLL_INTERVAL_MS);
if (!this.visibilityChangeListenerAdded) {
diff --git a/gr-checks/gr-checks-view_test.html b/gr-checks/gr-checks-view_test.html
index a801b9f..2ad1b3d 100644
--- a/gr-checks/gr-checks-view_test.html
+++ b/gr-checks/gr-checks-view_test.html
@@ -8,7 +8,6 @@
<title>gr-checks-item</title>
<link rel="import" href="gr-checks-view.html">
-
<!-- Gr-overlay does not exist in the test framework
It is expected to be provided by Gerrit core -->
<dom-module id="gr-overlay">
@@ -30,7 +29,7 @@
get-checks="[[getChecks]]"
is-configured="[[isConfigured]]"
plugin="[[plugin]]"
- retry-check="[[retryCheck]]">
+ retry-check="[[retryCheck]]"
</gr-checks-view>
</template>
</test-fixture>
@@ -79,6 +78,23 @@
commit: '1c9a1dfd38ea51dc7880f3ddf669100710f0c91b',
},
};
+ const REVISION2 = {
+ kind: 'REWORK',
+ _number: 2,
+ created: '2018-05-15 21:56:13.000000000',
+ uploader: {
+ _account_id: 1000000,
+ },
+ ref: 'refs/changes/00/1000/2',
+ commit: {
+ parents: [],
+ subject: '',
+ message: '\n\nChange-Id: I8df212a28ae23cc239afd10ee4f506887e03ab70\n',
+ commit: '1c9a1dfd38ea51dc6880f3ddf669100710f0c91b',
+ },
+ };
+
+ const CHECKS_POLL_INTERVAL_MS = 60 * 1000;
suite('gr-checks-view tests', () => {
let element;
@@ -143,7 +159,7 @@
project: 'test-repository',
_number: 2,
revisions: {
- 'first-sha': 'test-revision',
+ 'first-sha': REVISION2,
'second-sha': REVISION,
},
},
@@ -198,6 +214,7 @@
getAccountCapabilitiesResolve({'checks-administrateCheckers': false});
flush(done);
});
+
test('checker button does not render', () => {
assert(!element.$$('gr-button'));
});
@@ -301,11 +318,6 @@
assert.isFalse(isConfiguredSpy.called);
});
- test('renders the header', () => {
- const header = element.$$('header > h3');
- assert.equal(header.textContent.trim(), 'Latest checks for Patchset 3');
- });
-
test('renders a table of all the checks', () => {
const tbody = element.$$('table > tbody');
assert.lengthOf(tbody.querySelectorAll('gr-checks-item'), 3);
@@ -328,10 +340,43 @@
getAccountCapabilitiesResolve({'checks-administrateCheckers': true});
flush(done);
});
+
test('checker button renders', () => {
assert(element.$$('gr-button'));
});
});
+
+ suite('patchset navigation', () => {
+ test('renders the dropdown', () => {
+ assert.isNotNull(element.querySelector('gr-dropdown-list'));
+ });
+
+ test('when patchset updated it fetches new checks', done => {
+ const clock = sinon.useFakeTimers();
+ const fetchChecksStub = sandbox.stub(element,
+ '_fetchChecks');
+ assert.equal(element._currentPatchSet, 3);
+ element._currentPatchSet = 2;
+ const firstCallArgs = fetchChecksStub.args[0];
+ assert.equal(firstCallArgs[1], element._currentPatchSet);
+ clock.tick(CHECKS_POLL_INTERVAL_MS + 1000);
+ flush(() => {
+ assert(fetchChecksStub.callCount === 2);
+ const secondCallArgs = fetchChecksStub.args[1];
+ assert.equal(secondCallArgs[1], element._currentPatchSet);
+ done();
+ });
+ });
+
+ test('update to revision updatesd currentPatchset', done => {
+ assert.equal(element._currentPatchSet, 3);
+ element.revision = REVISION2;
+ flush(() => {
+ assert.equal(element._currentPatchSet, 2);
+ done();
+ });
+ });
+ });
});
});