Wait for revert or cherrypick changes to be reachable before redirecting
Bug: Issue 6969 Change-Id: I60c27dcf3446eec0afa07b2d5ef45cbfd080a3d7
This commit is contained in:
@@ -118,6 +118,9 @@
|
|||||||
__type: 'revision',
|
__type: 'revision',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const AWAIT_CHANGE_ATTEMPTS = 5;
|
||||||
|
const AWAIT_CHANGE_TIMEOUT_MS = 1000;
|
||||||
|
|
||||||
Polymer({
|
Polymer({
|
||||||
is: 'gr-change-actions',
|
is: 'gr-change-actions',
|
||||||
|
|
||||||
@@ -824,10 +827,9 @@
|
|||||||
// https://bugs.chromium.org/p/gerrit/issues/detail?id=4671 is resolved.
|
// https://bugs.chromium.org/p/gerrit/issues/detail?id=4671 is resolved.
|
||||||
_setLabelValuesOnRevert(newChangeId) {
|
_setLabelValuesOnRevert(newChangeId) {
|
||||||
const labels = this.$.jsAPI.getLabelValuesPostRevert(this.change);
|
const labels = this.$.jsAPI.getLabelValuesPostRevert(this.change);
|
||||||
if (labels) {
|
if (!labels) { return Promise.resolve(); }
|
||||||
this.$.restAPI.getChangeURLAndSend(newChangeId,
|
return this.$.restAPI.getChangeURLAndSend(newChangeId,
|
||||||
this.actions.revert.method, 'current', '/review', {labels});
|
this.actions.revert.method, 'current', '/review', {labels});
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_handleResponse(action, response) {
|
_handleResponse(action, response) {
|
||||||
@@ -835,10 +837,16 @@
|
|||||||
return this.$.restAPI.getResponseObject(response).then(obj => {
|
return this.$.restAPI.getResponseObject(response).then(obj => {
|
||||||
switch (action.__key) {
|
switch (action.__key) {
|
||||||
case ChangeActions.REVERT:
|
case ChangeActions.REVERT:
|
||||||
this._setLabelValuesOnRevert(obj.change_id);
|
this._waitForChangeReachable(obj._number)
|
||||||
/* falls through */
|
.then(() => this._setLabelValuesOnRevert(obj._number))
|
||||||
|
.then(() => {
|
||||||
|
Gerrit.Nav.navigateToChange(obj);
|
||||||
|
});
|
||||||
|
break;
|
||||||
case RevisionActions.CHERRYPICK:
|
case RevisionActions.CHERRYPICK:
|
||||||
page.show(this.changePath(obj._number));
|
this._waitForChangeReachable(obj._number).then(() => {
|
||||||
|
Gerrit.Nav.navigateToChange(obj);
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case ChangeActions.DELETE:
|
case ChangeActions.DELETE:
|
||||||
case RevisionActions.DELETE:
|
case RevisionActions.DELETE:
|
||||||
@@ -1015,5 +1023,39 @@
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Occasionally, a change created by a change action is not yet knwon to the
|
||||||
|
* API for a brief time. Wait for the given change number to be recognized.
|
||||||
|
*
|
||||||
|
* Returns a promise that resolves with true if a request is recognized, or
|
||||||
|
* false if the change was never recognized after all attempts.
|
||||||
|
*
|
||||||
|
* @param {number} changeNum
|
||||||
|
* @return {Promise<boolean>}
|
||||||
|
*/
|
||||||
|
_waitForChangeReachable(changeNum) {
|
||||||
|
let attempsRemaining = AWAIT_CHANGE_ATTEMPTS;
|
||||||
|
return new Promise(resolve => {
|
||||||
|
const check = () => {
|
||||||
|
attempsRemaining--;
|
||||||
|
// Pass a no-op error handler to avoid the "not found" error toast.
|
||||||
|
this.$.restAPI.getChange(changeNum, () => {}).then(response => {
|
||||||
|
// If the response is 404, the response will be undefined.
|
||||||
|
if (response) {
|
||||||
|
resolve(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attempsRemaining) {
|
||||||
|
this.async(check, AWAIT_CHANGE_TIMEOUT_MS);
|
||||||
|
} else {
|
||||||
|
resolve(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
check();
|
||||||
|
});
|
||||||
|
},
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1038,6 +1038,37 @@ limitations under the License.
|
|||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
element.$.moreActions.items[4].id, 'submit-revision');
|
element.$.moreActions.items[4].id, 'submit-revision');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
suite('_waitForChangeReachable', () => {
|
||||||
|
setup(() => {
|
||||||
|
sandbox.stub(element, 'async', fn => fn());
|
||||||
|
});
|
||||||
|
|
||||||
|
const makeGetChange = numTries => {
|
||||||
|
return () => {
|
||||||
|
if (numTries === 1) {
|
||||||
|
return Promise.resolve({_number: 123});
|
||||||
|
} else {
|
||||||
|
numTries--;
|
||||||
|
return Promise.resolve(undefined);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
test('succeed', () => {
|
||||||
|
sandbox.stub(element.$.restAPI, 'getChange', makeGetChange(5));
|
||||||
|
return element._waitForChangeReachable(123).then(success => {
|
||||||
|
assert.isTrue(success);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('fail', () => {
|
||||||
|
sandbox.stub(element.$.restAPI, 'getChange', makeGetChange(6));
|
||||||
|
return element._waitForChangeReachable(123).then(success => {
|
||||||
|
assert.isFalse(success);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1738,11 +1738,12 @@
|
|||||||
* Given a changeNum, gets the change.
|
* Given a changeNum, gets the change.
|
||||||
*
|
*
|
||||||
* @param {number|string} changeNum
|
* @param {number|string} changeNum
|
||||||
|
* @param {function(?Response, string=)=} opt_errFn
|
||||||
* @return {!Promise<?Object>} The change
|
* @return {!Promise<?Object>} The change
|
||||||
*/
|
*/
|
||||||
getChange(changeNum) {
|
getChange(changeNum, opt_errFn) {
|
||||||
// Cannot use _changeBaseURL, as this function is used by _projectLookup.
|
// Cannot use _changeBaseURL, as this function is used by _projectLookup.
|
||||||
return this.fetchJSON(`/changes/${changeNum}`);
|
return this.fetchJSON(`/changes/${changeNum}`, opt_errFn);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user