Use project lookup
Specifying the project as part of the change ID when the /changes endpoint is used can help reduce latency significantly. This change modifies _changeBaseUrl to return a URL that specifies both the project and the change number. As a portion of this, there may be an API call made to get the project number (this is unlikely, but possible). Due to that fact, _changeBaseUrl now returns a promise. Bug: Issue 6708 Change-Id: I630e521cf6226e579e99aa3dc08cc17239d4dbd4
This commit is contained in:
@@ -817,8 +817,8 @@
|
||||
_setLabelValuesOnRevert(newChangeId) {
|
||||
const labels = this.$.jsAPI.getLabelValuesPostRevert(this.change);
|
||||
if (labels) {
|
||||
const url = `/changes/${newChangeId}/revisions/current/review`;
|
||||
this.$.restAPI.send(this.actions.revert.method, url, {labels});
|
||||
this.$.restAPI.getChangeURLAndSend(newChangeId,
|
||||
this.actions.revert.method, 'current', '/review', {labels});
|
||||
}
|
||||
},
|
||||
|
||||
@@ -878,11 +878,10 @@
|
||||
cleanupFn();
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
const url = this.$.restAPI.getChangeActionURL(this.changeNum,
|
||||
revisionAction ? this.patchNum : null, actionEndpoint);
|
||||
return this.$.restAPI.send(method, url, payload,
|
||||
this._handleResponseError, this).then(response => {
|
||||
const patchNum = revisionAction ? this.patchNum : null;
|
||||
return this.$.restAPI.getChangeURLAndSend(this.changeNum, method,
|
||||
patchNum, actionEndpoint, payload, this._handleResponseError,
|
||||
this).then(response => {
|
||||
cleanupFn.call(this);
|
||||
return response;
|
||||
});
|
||||
|
||||
@@ -71,12 +71,12 @@ limitations under the License.
|
||||
send(method, url, payload) {
|
||||
if (method !== 'POST') { return Promise.reject('bad method'); }
|
||||
|
||||
if (url === '/changes/42/revisions/2/submit') {
|
||||
if (url === '/changes/test~42/revisions/2/submit') {
|
||||
return Promise.resolve({
|
||||
ok: true,
|
||||
text() { return Promise.resolve(')]}\'\n{}'); },
|
||||
});
|
||||
} else if (url === '/changes/42/revisions/2/rebase') {
|
||||
} else if (url === '/changes/test~42/revisions/2/rebase') {
|
||||
return Promise.resolve({
|
||||
ok: true,
|
||||
text() { return Promise.resolve(')]}\'\n{}'); },
|
||||
@@ -228,6 +228,8 @@ limitations under the License.
|
||||
});
|
||||
|
||||
test('submit change', done => {
|
||||
sandbox.stub(element.$.restAPI, '_getFromProjectLookup')
|
||||
.returns(Promise.resolve('test'));
|
||||
sandbox.stub(element, 'fetchIsLatestKnown',
|
||||
() => { return Promise.resolve(true); });
|
||||
element.change = {
|
||||
|
||||
@@ -596,7 +596,8 @@
|
||||
},
|
||||
|
||||
getChangeActionURL(changeNum, opt_patchNum, endpoint) {
|
||||
return this._changeBaseURL(changeNum, opt_patchNum) + endpoint;
|
||||
return this._changeBaseURL(changeNum, opt_patchNum)
|
||||
.then(url => url + endpoint);
|
||||
},
|
||||
|
||||
getChangeDetail(changeNum, opt_errFn, opt_cancelCondition) {
|
||||
@@ -624,34 +625,34 @@
|
||||
|
||||
_getChangeDetail(changeNum, params, opt_errFn,
|
||||
opt_cancelCondition) {
|
||||
const url = this.getChangeActionURL(changeNum, null, '/detail');
|
||||
const urlWithParams = this._urlWithParams(url, params);
|
||||
return this._fetchRawJSON(
|
||||
url,
|
||||
opt_errFn,
|
||||
opt_cancelCondition,
|
||||
{O: params},
|
||||
this._etags.getOptions(urlWithParams))
|
||||
.then(response => {
|
||||
if (response && response.status === 304) {
|
||||
return Promise.resolve(
|
||||
this._etags.getCachedPayload(urlWithParams));
|
||||
} else {
|
||||
const payloadPromise = response ?
|
||||
this.getResponseObject(response) :
|
||||
Promise.resolve();
|
||||
payloadPromise.then(payload => {
|
||||
this._etags.collect(urlWithParams, response, payload);
|
||||
this._maybeInsertInLookup(payload);
|
||||
});
|
||||
return payloadPromise;
|
||||
}
|
||||
});
|
||||
return this.getChangeActionURL(changeNum, null, '/detail').then(url => {
|
||||
const urlWithParams = this._urlWithParams(url, params);
|
||||
return this._fetchRawJSON(
|
||||
url,
|
||||
opt_errFn,
|
||||
opt_cancelCondition,
|
||||
{O: params},
|
||||
this._etags.getOptions(urlWithParams))
|
||||
.then(response => {
|
||||
if (response && response.status === 304) {
|
||||
return Promise.resolve(
|
||||
this._etags.getCachedPayload(urlWithParams));
|
||||
} else {
|
||||
const payloadPromise = response ?
|
||||
this.getResponseObject(response) :
|
||||
Promise.resolve();
|
||||
payloadPromise.then(payload => {
|
||||
this._etags.collect(urlWithParams, response, payload);
|
||||
this._maybeInsertInLookup(payload);
|
||||
});
|
||||
return payloadPromise;
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
getChangeCommitInfo(changeNum, patchNum) {
|
||||
return this.fetchJSON(
|
||||
this.getChangeActionURL(changeNum, patchNum, '/commit?links'));
|
||||
return this._getChangeURLAndFetch(changeNum, '/commit?links', patchNum);
|
||||
},
|
||||
|
||||
getChangeFiles(changeNum, patchRange) {
|
||||
@@ -659,8 +660,8 @@
|
||||
if (patchRange.basePatchNum !== 'PARENT') {
|
||||
endpoint += '?base=' + encodeURIComponent(patchRange.basePatchNum);
|
||||
}
|
||||
return this.fetchJSON(
|
||||
this.getChangeActionURL(changeNum, patchRange.patchNum, endpoint));
|
||||
return this._getChangeURLAndFetch(changeNum, endpoint,
|
||||
patchRange.patchNum);
|
||||
},
|
||||
|
||||
getChangeFilesAsSpeciallySortedArray(changeNum, patchRange) {
|
||||
@@ -689,9 +690,8 @@
|
||||
},
|
||||
|
||||
getChangeRevisionActions(changeNum, patchNum) {
|
||||
return this.fetchJSON(
|
||||
this.getChangeActionURL(changeNum, patchNum, '/actions')).then(
|
||||
revisionActions => {
|
||||
return this._getChangeURLAndFetch(changeNum, '/actions', patchNum)
|
||||
.then(revisionActions => {
|
||||
// The rebase button on change screen is always enabled.
|
||||
if (revisionActions.rebase) {
|
||||
revisionActions.rebase.rebaseOnCurrent =
|
||||
@@ -702,13 +702,11 @@
|
||||
});
|
||||
},
|
||||
|
||||
getChangeSuggestedReviewers(changeNum, inputVal, opt_errFn,
|
||||
opt_ctx) {
|
||||
const url =
|
||||
this.getChangeActionURL(changeNum, null, '/suggest_reviewers');
|
||||
const req = {n: 10};
|
||||
if (inputVal) { req.q = inputVal; }
|
||||
return this.fetchJSON(url, opt_errFn, opt_ctx, req);
|
||||
getChangeSuggestedReviewers(changeNum, inputVal, opt_errFn) {
|
||||
const params = {n: 10};
|
||||
if (inputVal) { params.q = inputVal; }
|
||||
return this._getChangeURLAndFetch(changeNum, '/suggest_reviewers', null,
|
||||
opt_errFn, null, params);
|
||||
},
|
||||
|
||||
_computeFilter(filter) {
|
||||
@@ -808,30 +806,30 @@
|
||||
},
|
||||
|
||||
_sendChangeReviewerRequest(method, changeNum, reviewerID) {
|
||||
let url = this.getChangeActionURL(changeNum, null, '/reviewers');
|
||||
let body;
|
||||
switch (method) {
|
||||
case 'POST':
|
||||
body = {reviewer: reviewerID};
|
||||
break;
|
||||
case 'DELETE':
|
||||
url += '/' + encodeURIComponent(reviewerID);
|
||||
break;
|
||||
default:
|
||||
throw Error('Unsupported HTTP method: ' + method);
|
||||
}
|
||||
return this.getChangeActionURL(changeNum, null, '/reviewers')
|
||||
.then(url => {
|
||||
let body;
|
||||
switch (method) {
|
||||
case 'POST':
|
||||
body = {reviewer: reviewerID};
|
||||
break;
|
||||
case 'DELETE':
|
||||
url += '/' + encodeURIComponent(reviewerID);
|
||||
break;
|
||||
default:
|
||||
throw Error('Unsupported HTTP method: ' + method);
|
||||
}
|
||||
|
||||
return this.send(method, url, body);
|
||||
return this.send(method, url, body);
|
||||
});
|
||||
},
|
||||
|
||||
getRelatedChanges(changeNum, patchNum) {
|
||||
return this.fetchJSON(
|
||||
this.getChangeActionURL(changeNum, patchNum, '/related'));
|
||||
return this._getChangeURLAndFetch(changeNum, '/related', patchNum);
|
||||
},
|
||||
|
||||
getChangesSubmittedTogether(changeNum) {
|
||||
return this.fetchJSON(
|
||||
this.getChangeActionURL(changeNum, null, '/submitted_together'));
|
||||
return this._getChangeURLAndFetch(changeNum, '/submitted_together', null);
|
||||
},
|
||||
|
||||
getChangeConflicts(changeNum) {
|
||||
@@ -879,100 +877,84 @@
|
||||
},
|
||||
|
||||
getReviewedFiles(changeNum, patchNum) {
|
||||
return this.fetchJSON(
|
||||
this.getChangeActionURL(changeNum, patchNum, '/files?reviewed'));
|
||||
return this._getChangeURLAndFetch(changeNum, '/files?reviewed', patchNum);
|
||||
},
|
||||
|
||||
saveFileReviewed(changeNum, patchNum, path, reviewed, opt_errFn, opt_ctx) {
|
||||
const method = reviewed ? 'PUT' : 'DELETE';
|
||||
const url = this.getChangeActionURL(changeNum, patchNum,
|
||||
'/files/' + encodeURIComponent(path) + '/reviewed');
|
||||
|
||||
return this.send(method, url, null, opt_errFn, opt_ctx);
|
||||
const e = `/files/${encodeURIComponent(path)}/reviewed`;
|
||||
return this.getChangeURLAndSend(changeNum, method, patchNum, e, null,
|
||||
opt_errFn, opt_ctx);
|
||||
},
|
||||
|
||||
saveChangeReview(changeNum, patchNum, review, opt_errFn, opt_ctx) {
|
||||
const url = this.getChangeActionURL(changeNum, patchNum, '/review');
|
||||
return this.awaitPendingDiffDrafts()
|
||||
.then(() => this.send('POST', url, review, opt_errFn, opt_ctx));
|
||||
const promises = [
|
||||
this.awaitPendingDiffDrafts(),
|
||||
this.getChangeActionURL(changeNum, patchNum, '/review'),
|
||||
];
|
||||
return Promise.all(promises).then(([, url]) => {
|
||||
return this.send('POST', url, review, opt_errFn, opt_ctx);
|
||||
});
|
||||
},
|
||||
|
||||
getChangeEdit(changeNum, opt_download_commands) {
|
||||
const params = opt_download_commands ? {'download-commands': true} : null;
|
||||
return this.getLoggedIn().then(loggedIn => {
|
||||
return loggedIn ?
|
||||
this.fetchJSON(
|
||||
this.getChangeActionURL(changeNum, null, '/edit/'), null, null,
|
||||
opt_download_commands ? {'download-commands': true} : null) :
|
||||
false;
|
||||
this._getChangeURLAndFetch(changeNum, '/edit/', null, null, null,
|
||||
params) :
|
||||
false;
|
||||
});
|
||||
},
|
||||
|
||||
getFileInChangeEdit(changeNum, path) {
|
||||
return this.send('GET',
|
||||
this.getChangeActionURL(changeNum, null,
|
||||
'/edit/' + encodeURIComponent(path)
|
||||
));
|
||||
const e = '/edit/' + encodeURIComponent(path);
|
||||
return this.getChangeURLAndSend(changeNum, 'GET', null, e);
|
||||
},
|
||||
|
||||
rebaseChangeEdit(changeNum) {
|
||||
return this.send('POST',
|
||||
this.getChangeActionURL(changeNum, null,
|
||||
'/edit:rebase'
|
||||
));
|
||||
return this.getChangeURLAndSend(changeNum, 'POST', null, '/edit:rebase');
|
||||
},
|
||||
|
||||
deleteChangeEdit(changeNum) {
|
||||
return this.send('DELETE',
|
||||
this.getChangeActionURL(changeNum, null,
|
||||
'/edit'
|
||||
));
|
||||
return this.getChangeURLAndSend(changeNum, 'DELETE', null, '/edit');
|
||||
},
|
||||
|
||||
restoreFileInChangeEdit(changeNum, restore_path) {
|
||||
return this.send('POST',
|
||||
this.getChangeActionURL(changeNum, null, '/edit'),
|
||||
{restore_path}
|
||||
);
|
||||
const p = {restore_path};
|
||||
return this.getChangeURLAndSend(changeNum, 'POST', null, '/edit', p);
|
||||
},
|
||||
|
||||
renameFileInChangeEdit(changeNum, old_path, new_path) {
|
||||
return this.send('POST',
|
||||
this.getChangeActionURL(changeNum, null, '/edit'),
|
||||
{old_path},
|
||||
{new_path}
|
||||
);
|
||||
const p = {old_path, new_path};
|
||||
return this.getChangeURLAndSend(changeNum, 'POST', null, '/edit', p);
|
||||
},
|
||||
|
||||
deleteFileInChangeEdit(changeNum, path) {
|
||||
return this.send('DELETE',
|
||||
this.getChangeActionURL(changeNum, null,
|
||||
'/edit/' + encodeURIComponent(path)
|
||||
));
|
||||
const e = '/edit/' + encodeURIComponent(path);
|
||||
return this.getChangeURLAndSend(changeNum, 'DELETE', null, e);
|
||||
},
|
||||
|
||||
saveChangeEdit(changeNum, path, contents) {
|
||||
return this.send('PUT',
|
||||
this.getChangeActionURL(changeNum, null,
|
||||
'/edit/' + encodeURIComponent(path)
|
||||
),
|
||||
contents
|
||||
);
|
||||
const e = '/edit/' + encodeURIComponent(path);
|
||||
return this.getChangeURLAndSend(changeNum, 'PUT', null, e, contents);
|
||||
},
|
||||
|
||||
// Deprecated, prefer to use putChangeCommitMessage instead.
|
||||
saveChangeCommitMessageEdit(changeNum, message) {
|
||||
const url = this.getChangeActionURL(changeNum, null, '/edit:message');
|
||||
return this.send('PUT', url, {message});
|
||||
const p = {message};
|
||||
return this.getChangeURLAndSend(changeNum, 'PUT', null, '/edit:message',
|
||||
p);
|
||||
},
|
||||
|
||||
publishChangeEdit(changeNum) {
|
||||
return this.send('POST',
|
||||
this.getChangeActionURL(changeNum, null, '/edit:publish'));
|
||||
return this.getChangeURLAndSend(changeNum, 'POST', null,
|
||||
'/edit:publish');
|
||||
},
|
||||
|
||||
putChangeCommitMessage(changeNum, message) {
|
||||
const url = this.getChangeActionURL(changeNum, null, '/message');
|
||||
return this.send('PUT', url, {message});
|
||||
const p = {message};
|
||||
return this.getChangeURLAndSend(changeNum, 'PUT', null, '/message', p);
|
||||
},
|
||||
|
||||
saveChangeStarred(changeNum, starred) {
|
||||
@@ -1014,7 +996,6 @@
|
||||
|
||||
getDiff(changeNum, basePatchNum, patchNum, path,
|
||||
opt_errFn, opt_cancelCondition) {
|
||||
const url = this._getDiffFetchURL(changeNum, patchNum, path);
|
||||
const params = {
|
||||
context: 'ALL',
|
||||
intraline: null,
|
||||
@@ -1023,13 +1004,10 @@
|
||||
if (basePatchNum != PARENT_PATCH_NUM) {
|
||||
params.base = basePatchNum;
|
||||
}
|
||||
const endpoint = `/files/${encodeURIComponent(path)}/diff`;
|
||||
|
||||
return this.fetchJSON(url, opt_errFn, opt_cancelCondition, params);
|
||||
},
|
||||
|
||||
_getDiffFetchURL(changeNum, patchNum, path) {
|
||||
return this._changeBaseURL(changeNum, patchNum) + '/files/' +
|
||||
encodeURIComponent(path) + '/diff';
|
||||
return this._getChangeURLAndFetch(changeNum, endpoint, patchNum,
|
||||
opt_errFn, opt_cancelCondition, params);
|
||||
},
|
||||
|
||||
getDiffComments(changeNum, opt_basePatchNum, opt_patchNum, opt_path) {
|
||||
@@ -1086,11 +1064,20 @@
|
||||
|
||||
_getDiffComments(changeNum, endpoint, opt_basePatchNum,
|
||||
opt_patchNum, opt_path) {
|
||||
if (!opt_basePatchNum && !opt_patchNum && !opt_path) {
|
||||
return this.fetchJSON(
|
||||
this._getDiffCommentsFetchURL(changeNum, endpoint));
|
||||
}
|
||||
/**
|
||||
* Fetches the comments for a given patchNum.
|
||||
* Helper function to make promises more legible.
|
||||
*
|
||||
* @param {string|number} patchNum
|
||||
* @return {!Object} Diff comments response.
|
||||
*/
|
||||
const fetchComments = patchNum => {
|
||||
return this._getChangeURLAndFetch(changeNum, endpoint, patchNum);
|
||||
};
|
||||
|
||||
if (!opt_basePatchNum && !opt_patchNum && !opt_path) {
|
||||
return fetchComments();
|
||||
}
|
||||
function onlyParent(c) { return c.side == PARENT_PATCH_NUM; }
|
||||
function withoutParent(c) { return c.side != PARENT_PATCH_NUM; }
|
||||
function setPath(c) { c.path = opt_path; }
|
||||
@@ -1098,16 +1085,13 @@
|
||||
const promises = [];
|
||||
let comments;
|
||||
let baseComments;
|
||||
const url =
|
||||
this._getDiffCommentsFetchURL(changeNum, endpoint, opt_patchNum);
|
||||
promises.push(this.fetchJSON(url).then(response => {
|
||||
let fetchPromise;
|
||||
fetchPromise = fetchComments(opt_patchNum).then(response => {
|
||||
comments = response[opt_path] || [];
|
||||
|
||||
// TODO(kaspern): Implement this on in the backend so this can be
|
||||
// removed.
|
||||
|
||||
// Sort comments by date so that parent ranges can be propagated in a
|
||||
// single pass.
|
||||
// TODO(kaspern): Implement this on in the backend so this can
|
||||
// be removed.
|
||||
// Sort comments by date so that parent ranges can be propagated
|
||||
// in a single pass.
|
||||
comments = this._setRanges(comments);
|
||||
|
||||
if (opt_basePatchNum == PARENT_PATCH_NUM) {
|
||||
@@ -1117,18 +1101,17 @@
|
||||
comments = comments.filter(withoutParent);
|
||||
|
||||
comments.forEach(setPath);
|
||||
}));
|
||||
});
|
||||
promises.push(fetchPromise);
|
||||
|
||||
if (opt_basePatchNum != PARENT_PATCH_NUM) {
|
||||
const baseURL = this._getDiffCommentsFetchURL(changeNum, endpoint,
|
||||
opt_basePatchNum);
|
||||
promises.push(this.fetchJSON(baseURL).then(response => {
|
||||
baseComments = (response[opt_path] || []).filter(withoutParent);
|
||||
|
||||
fetchPromise = fetchComments(opt_basePatchNum).then(response => {
|
||||
baseComments = (response[opt_path] || [])
|
||||
.filter(withoutParent);
|
||||
baseComments = this._setRanges(baseComments);
|
||||
|
||||
baseComments.forEach(setPath);
|
||||
}));
|
||||
});
|
||||
promises.push(fetchPromise);
|
||||
}
|
||||
|
||||
return Promise.all(promises).then(() => {
|
||||
@@ -1140,7 +1123,8 @@
|
||||
},
|
||||
|
||||
_getDiffCommentsFetchURL(changeNum, endpoint, opt_patchNum) {
|
||||
return this._changeBaseURL(changeNum, opt_patchNum) + endpoint;
|
||||
return this._changeBaseURL(changeNum, opt_patchNum)
|
||||
.then(url => url + endpoint);
|
||||
},
|
||||
|
||||
saveDiffDraft(changeNum, patchNum, draft) {
|
||||
@@ -1171,9 +1155,9 @@
|
||||
},
|
||||
|
||||
_sendDiffDraftRequest(method, changeNum, patchNum, draft) {
|
||||
let url = this.getChangeActionURL(changeNum, patchNum, '/drafts');
|
||||
let endpoint = '/drafts';
|
||||
if (draft.id) {
|
||||
url += '/' + draft.id;
|
||||
endpoint += '/' + draft.id;
|
||||
}
|
||||
let body;
|
||||
if (method === 'PUT') {
|
||||
@@ -1184,7 +1168,8 @@
|
||||
this._pendingRequests[Requests.SEND_DIFF_DRAFT] = [];
|
||||
}
|
||||
|
||||
const promise = this.send(method, url, body);
|
||||
const promise = this.getChangeURLAndSend(changeNum, method, patchNum,
|
||||
endpoint, body);
|
||||
this._pendingRequests[Requests.SEND_DIFF_DRAFT].push(promise);
|
||||
return promise;
|
||||
},
|
||||
@@ -1210,11 +1195,10 @@
|
||||
getChangeFileContents(changeId, patchNum, path, opt_parentIndex) {
|
||||
const parent = typeof opt_parentIndex === 'number' ?
|
||||
'?parent=' + opt_parentIndex : '';
|
||||
return this._fetchB64File(
|
||||
'/changes/' + encodeURIComponent(changeId) +
|
||||
'/revisions/' + encodeURIComponent(patchNum) +
|
||||
'/files/' + encodeURIComponent(path) +
|
||||
'/content' + parent);
|
||||
return this._changeBaseUrl(changeId, patchNum).then(url => {
|
||||
url = `${url}/files/${encodeURIComponent(path)}/content${parent}`;
|
||||
return this._fetchB64File(url);
|
||||
});
|
||||
},
|
||||
|
||||
getImagesForDiff(changeNum, diff, patchRange) {
|
||||
@@ -1259,22 +1243,36 @@
|
||||
});
|
||||
},
|
||||
|
||||
_changeBaseURL(changeNum, opt_patchNum) {
|
||||
let v = '/changes/' + changeNum;
|
||||
if (opt_patchNum) {
|
||||
v += '/revisions/' + opt_patchNum;
|
||||
}
|
||||
return v;
|
||||
/**
|
||||
* @param {string} changeNum
|
||||
* @param {number|string=} opt_patchNum
|
||||
* @param {string=} opt_project
|
||||
* @return {!Promise<string>}
|
||||
*/
|
||||
_changeBaseURL(changeNum, opt_patchNum, opt_project) {
|
||||
// TODO(kaspern): For full slicer migration, app should warn with a call
|
||||
// stack every time _changeBaseURL is called without a project.
|
||||
const projectPromise = opt_project ?
|
||||
Promise.resolve(opt_project) :
|
||||
this._getFromProjectLookup(changeNum);
|
||||
return projectPromise.then(project => {
|
||||
let url = `/changes/${encodeURIComponent(project)}~${changeNum}`;
|
||||
if (opt_patchNum) {
|
||||
url += `/revisions/${opt_patchNum}`;
|
||||
}
|
||||
return url;
|
||||
});
|
||||
},
|
||||
|
||||
setChangeTopic(changeNum, topic) {
|
||||
return this.send('PUT', '/changes/' + encodeURIComponent(changeNum) +
|
||||
'/topic', {topic}).then(this.getResponseObject);
|
||||
const p = {topic};
|
||||
return this.getChangeURLAndSend(changeNum, 'PUT', null, '/topic', p)
|
||||
.then(this.getResponseObject);
|
||||
},
|
||||
|
||||
setChangeHashtag(changeNum, hashtag) {
|
||||
return this.send('POST', '/changes/' + encodeURIComponent(changeNum) +
|
||||
'/hashtags', hashtag).then(this.getResponseObject);
|
||||
return this.getChangeURLAndSend(changeNum, 'POST', null, '/hashtags',
|
||||
hashtag).then(this.getResponseObject);
|
||||
},
|
||||
|
||||
deleteAccountHttpPassword() {
|
||||
@@ -1309,15 +1307,15 @@
|
||||
return this.send('DELETE', '/accounts/self/sshkeys/' + id);
|
||||
},
|
||||
|
||||
deleteVote(changeID, account, label) {
|
||||
return this.send('DELETE', '/changes/' + changeID +
|
||||
'/reviewers/' + account + '/votes/' + encodeURIComponent(label));
|
||||
deleteVote(changeNum, account, label) {
|
||||
const e = `/reviewers/${account}/votes/${encodeURIComponent(label)}`;
|
||||
return this.getChangeURLAndSend(changeNum, 'DELETE', null, e);
|
||||
},
|
||||
|
||||
setDescription(changeNum, patchNum, desc) {
|
||||
return this.send('PUT',
|
||||
this.getChangeActionURL(changeNum, patchNum, '/description'),
|
||||
{description: desc});
|
||||
const p = {description: desc};
|
||||
return this.getChangeURLAndSend(changeNum, 'PUT', patchNum,
|
||||
'/description', p);
|
||||
},
|
||||
|
||||
confirmEmail(token) {
|
||||
@@ -1331,14 +1329,12 @@
|
||||
},
|
||||
|
||||
setAssignee(changeNum, assignee) {
|
||||
return this.send('PUT',
|
||||
this.getChangeActionURL(changeNum, null, '/assignee'),
|
||||
{assignee});
|
||||
const p = {assignee};
|
||||
return this.getChangeURLAndSend(changeNum, 'PUT', null, '/assignee', p);
|
||||
},
|
||||
|
||||
deleteAssignee(changeNum) {
|
||||
return this.send('DELETE',
|
||||
this.getChangeActionURL(changeNum, null, '/assignee'));
|
||||
return this.getChangeURLAndSend(changeNum, 'DELETE', null, '/assignee');
|
||||
},
|
||||
|
||||
probePath(path) {
|
||||
@@ -1353,8 +1349,7 @@
|
||||
if (opt_message) {
|
||||
payload.message = opt_message;
|
||||
}
|
||||
const url = this.getChangeActionURL(changeNum, null, '/wip');
|
||||
return this.send('POST', url, payload)
|
||||
return this.getChangeURLAndSend(changeNum, 'POST', null, '/wip', payload)
|
||||
.then(response => {
|
||||
if (response.status === 204) {
|
||||
return 'Change marked as Work In Progress.';
|
||||
@@ -1363,16 +1358,15 @@
|
||||
},
|
||||
|
||||
startReview(changeNum, opt_body, opt_errFn) {
|
||||
return this.send(
|
||||
'POST', this.getChangeActionURL(changeNum, null, '/ready'),
|
||||
return this.getChangeURLAndSend(changeNum, 'POST', null, '/ready',
|
||||
opt_body, opt_errFn);
|
||||
},
|
||||
|
||||
deleteComment(changeNum, patchNum, commentID, reason) {
|
||||
const url = this.changeBaseURL(changeNum, patchNum) +
|
||||
'/comments/' + commentID + '/delete';
|
||||
return this.send('POST', url, {reason}).then(response =>
|
||||
this.getResponseObject(response));
|
||||
const endpoint = `/comments/${commentID}/delete`;
|
||||
const payload = {reason};
|
||||
return this.getChangeURLAndSend(changeNum, 'POST', patchNum, endpoint,
|
||||
payload).then(this.getResponseObject);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1382,6 +1376,7 @@
|
||||
* @return {Promise<Object>} The change
|
||||
*/
|
||||
getChange(changeNum) {
|
||||
// Cannot use _changeBaseURL, as this function is used by _projectLookup.
|
||||
return this.fetchJSON(`/changes/${changeNum}`);
|
||||
},
|
||||
|
||||
@@ -1415,5 +1410,44 @@
|
||||
return change.project;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Alias for _changeBaseURL.then(send).
|
||||
*
|
||||
* @param {string|number} changeNum
|
||||
* @param {string} method
|
||||
* @param {string} endpoint
|
||||
* @param {string|number=} opt_patchNum
|
||||
* @param {!Object=} opt_payload
|
||||
* @param {function(?Response, string)=} opt_errFn
|
||||
* @return {!Promise<!Object>}
|
||||
*/
|
||||
getChangeURLAndSend(changeNum, method, opt_patchNum, endpoint, opt_payload,
|
||||
opt_errFn, opt_ctx, opt_contentType) {
|
||||
return this._changeBaseURL(changeNum, opt_patchNum).then(url => {
|
||||
return this.send(method, url + endpoint, opt_payload, opt_errFn,
|
||||
opt_ctx, opt_contentType);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Alias for _changeBaseURL.then(fetchJSON).
|
||||
*
|
||||
* @param {string|number} changeNum
|
||||
* @param {string} endpoint
|
||||
* @param {string|number=} opt_patchNum
|
||||
* @param {function(?Response, string)=} opt_errFn
|
||||
* @param {!function()=} opt_cancelCondition
|
||||
* @param {!Object=} opt_params
|
||||
* @param {!Object=} opt_options
|
||||
* @return {!Promise<!Object>}
|
||||
*/
|
||||
_getChangeURLAndFetch(changeNum, endpoint, opt_patchNum, opt_errFn,
|
||||
opt_cancelCondition, opt_params, opt_options) {
|
||||
return this._changeBaseURL(changeNum, opt_patchNum).then(url => {
|
||||
return this.fetchJSON(url + endpoint, opt_errFn, opt_cancelCondition,
|
||||
opt_params, opt_options);
|
||||
});
|
||||
},
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -269,8 +269,10 @@ limitations under the License.
|
||||
});
|
||||
|
||||
test('differing patch diff comments are properly grouped', done => {
|
||||
sandbox.stub(element, '_getFromProjectLookup')
|
||||
.returns(Promise.resolve('test'));
|
||||
sandbox.stub(element, 'fetchJSON', url => {
|
||||
if (url == '/changes/42/revisions/1') {
|
||||
if (url === '/changes/test~42/revisions/1') {
|
||||
return Promise.resolve({
|
||||
'/COMMIT_MSG': [],
|
||||
'sieve.go': [
|
||||
@@ -285,7 +287,7 @@ limitations under the License.
|
||||
},
|
||||
],
|
||||
});
|
||||
} else if (url == '/changes/42/revisions/2') {
|
||||
} else if (url === '/changes/test~42/revisions/2') {
|
||||
return Promise.resolve({
|
||||
'/COMMIT_MSG': [],
|
||||
'sieve.go': [
|
||||
@@ -606,8 +608,7 @@ limitations under the License.
|
||||
|
||||
test('_sendDiffDraft pending requests tracked', () => {
|
||||
const obj = element._pendingRequests;
|
||||
sandbox.stub(element, 'send', () => mockPromise());
|
||||
sandbox.stub(element, 'getChangeActionURL');
|
||||
sandbox.stub(element, 'getChangeURLAndSend', () => mockPromise());
|
||||
assert.notOk(element.hasPendingDiffDrafts());
|
||||
|
||||
element._sendDiffDraftRequest(null, null, null, {});
|
||||
@@ -627,6 +628,7 @@ limitations under the License.
|
||||
});
|
||||
|
||||
test('saveChangeEdit', done => {
|
||||
element._projectLookup = {1: 'test'};
|
||||
const change_num = '1';
|
||||
const file_name = 'index.php';
|
||||
const file_contents = '<?php';
|
||||
@@ -636,17 +638,16 @@ limitations under the License.
|
||||
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();
|
||||
}
|
||||
);
|
||||
element.saveChangeEdit(change_num, file_name, file_contents).then(() => {
|
||||
assert.isTrue(element.send.calledWith('PUT',
|
||||
'/changes/test~1/edit/' + file_name,
|
||||
file_contents));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('putChangeCommitMessage', done => {
|
||||
element._projectLookup = {1: 'test'};
|
||||
const change_num = '1';
|
||||
const message = 'this is a commit message';
|
||||
sandbox.stub(element, 'send').returns(
|
||||
@@ -655,42 +656,42 @@ limitations under the License.
|
||||
sandbox.stub(element, 'getResponseObject')
|
||||
.returns(Promise.resolve([change_num, message]));
|
||||
element._cache['/changes/' + change_num + '/message'] = {};
|
||||
element.putChangeCommitMessage(change_num, message).then(
|
||||
() => {
|
||||
assert.isTrue(element.send.calledWith('PUT',
|
||||
'/changes/' + change_num + '/message', {message}));
|
||||
done();
|
||||
}
|
||||
);
|
||||
element.putChangeCommitMessage(change_num, message).then(() => {
|
||||
assert.isTrue(element.send.calledWith('PUT',
|
||||
'/changes/test~1/message', {message}));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('startWorkInProgress', () => {
|
||||
sandbox.stub(element, 'send').returns(Promise.resolve('ok'));
|
||||
sandbox.stub(element, 'getChangeURLAndSend')
|
||||
.returns(Promise.resolve('ok'));
|
||||
element.startWorkInProgress('42');
|
||||
assert.isTrue(element.send.calledWith(
|
||||
'POST', '/changes/42/wip', {}));
|
||||
assert.isTrue(element.getChangeURLAndSend.calledWith(
|
||||
'42', 'POST', null, '/wip', {}));
|
||||
element.startWorkInProgress('42', 'revising...');
|
||||
assert.isTrue(element.send.calledWith(
|
||||
'POST', '/changes/42/wip', {message: 'revising...'}));
|
||||
assert.isTrue(element.getChangeURLAndSend.calledWith(
|
||||
'42', 'POST', null, '/wip', {message: 'revising...'}));
|
||||
});
|
||||
|
||||
test('startReview', () => {
|
||||
sandbox.stub(element, 'send').returns(Promise.resolve({}));
|
||||
sandbox.stub(element, 'getChangeURLAndSend')
|
||||
.returns(Promise.resolve({}));
|
||||
element.startReview('42', {message: 'Please review.'});
|
||||
assert.isTrue(element.send.calledWith(
|
||||
'POST', '/changes/42/ready', {message: 'Please review.'}));
|
||||
assert.isTrue(element.getChangeURLAndSend.calledWith(
|
||||
'42', 'POST', null, '/ready', {message: 'Please review.'}));
|
||||
});
|
||||
|
||||
test('deleteComment', done => {
|
||||
sandbox.stub(element, 'send').returns(Promise.resolve());
|
||||
sandbox.stub(element, 'getChangeURLAndSend').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',
|
||||
assert.isTrue(element.getChangeURLAndSend.calledWith(
|
||||
'foo', 'POST', 'bar', '/comments/01234/delete',
|
||||
{reason: 'removal reason'}));
|
||||
});
|
||||
|
||||
@@ -763,10 +764,9 @@ limitations under the License.
|
||||
|
||||
test('_getChangeDetail passes params to ETags decorator', () => {
|
||||
const changeNum = 4321;
|
||||
element._projectLookup[changeNum] = 'test';
|
||||
const params = {foo: 'bar'};
|
||||
const expectedUrl = element._urlWithParams(
|
||||
element.getChangeActionURL(changeNum, null, '/detail'),
|
||||
params);
|
||||
const expectedUrl = '/changes/test~4321/detail?foo=bar';
|
||||
sandbox.stub(element._etags, 'getOptions');
|
||||
sandbox.stub(element._etags, 'collect');
|
||||
return element._getChangeDetail(changeNum, params).then(() => {
|
||||
@@ -858,5 +858,23 @@ limitations under the License.
|
||||
assert.equal(element._projectLookup[1], 'test');
|
||||
});
|
||||
});
|
||||
|
||||
test('_getChangeURLAndFetch', () => {
|
||||
element._projectLookup = {1: 'test'};
|
||||
const fetchStub = sandbox.stub(element, 'fetchJSON')
|
||||
.returns(Promise.resolve());
|
||||
return element._getChangeURLAndFetch(1, '/test', 1).then(() => {
|
||||
assert.isTrue(fetchStub.calledWith('/changes/test~1/revisions/1/test'));
|
||||
});
|
||||
});
|
||||
|
||||
test('getChangeURLAndSend', () => {
|
||||
element._projectLookup = {1: 'test'};
|
||||
const sendStub = sandbox.stub(element, 'send').returns(Promise.resolve());
|
||||
return element.getChangeURLAndSend(1, 'POST', 1, '/test').then(() => {
|
||||
assert.isTrue(sendStub.calledWith('POST',
|
||||
'/changes/test~1/revisions/1/test'));
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user