Merge "Missing labels list in change metadata and long-label polish"
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/change/ChangeField.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/change/ChangeField.java
index 1f27d83..0f6e89e 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/index/change/ChangeField.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/change/ChangeField.java
@@ -299,13 +299,8 @@
return Sets.newHashSet(a.trackingFooters.extract(footers).values());
});
- /** List of labels on the current patch set. */
- @Deprecated
- public static final FieldDef<ChangeData, Iterable<String>> LABEL =
- exact(ChangeQueryBuilder.FIELD_LABEL).buildRepeatable(cd -> getLabels(cd, false));
-
/** List of labels on the current patch set including change owner votes. */
- public static final FieldDef<ChangeData, Iterable<String>> LABEL2 =
+ public static final FieldDef<ChangeData, Iterable<String>> LABEL =
exact("label2").buildRepeatable(cd -> getLabels(cd, true));
private static Iterable<String> getLabels(ChangeData cd, boolean owners) throws OrmException {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/change/ChangeSchemaDefinitions.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/change/ChangeSchemaDefinitions.java
index ba7c1ec..35d84b8 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/index/change/ChangeSchemaDefinitions.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/change/ChangeSchemaDefinitions.java
@@ -22,75 +22,53 @@
public class ChangeSchemaDefinitions extends SchemaDefinitions<ChangeData> {
@Deprecated
- static final Schema<ChangeData> V32 =
+ static final Schema<ChangeData> V39 =
schema(
- ChangeField.LEGACY_ID,
+ ChangeField.ADDED,
+ ChangeField.APPROVAL,
+ ChangeField.ASSIGNEE,
+ ChangeField.AUTHOR,
+ ChangeField.CHANGE,
+ ChangeField.COMMENT,
+ ChangeField.COMMENTBY,
+ ChangeField.COMMIT,
+ ChangeField.COMMITTER,
+ ChangeField.COMMIT_MESSAGE,
+ ChangeField.DELETED,
+ ChangeField.DELTA,
+ ChangeField.DRAFTBY,
+ ChangeField.EDITBY,
+ ChangeField.EXACT_COMMIT,
+ ChangeField.EXACT_TOPIC,
+ ChangeField.FILE_PART,
+ ChangeField.FUZZY_TOPIC,
+ ChangeField.GROUP,
+ ChangeField.HASHTAG,
+ ChangeField.HASHTAG_CASE_AWARE,
ChangeField.ID,
- ChangeField.STATUS,
+ ChangeField.LABEL,
+ ChangeField.LEGACY_ID,
+ ChangeField.MERGEABLE,
+ ChangeField.OWNER,
+ ChangeField.PATCH_SET,
+ ChangeField.PATH,
ChangeField.PROJECT,
ChangeField.PROJECTS,
ChangeField.REF,
- ChangeField.EXACT_TOPIC,
- ChangeField.FUZZY_TOPIC,
- ChangeField.UPDATED,
- ChangeField.FILE_PART,
- ChangeField.PATH,
- ChangeField.OWNER,
- ChangeField.COMMIT,
- ChangeField.TR,
- ChangeField.LABEL,
- ChangeField.COMMIT_MESSAGE,
- ChangeField.COMMENT,
- ChangeField.CHANGE,
- ChangeField.APPROVAL,
- ChangeField.MERGEABLE,
- ChangeField.ADDED,
- ChangeField.DELETED,
- ChangeField.DELTA,
- ChangeField.HASHTAG,
- ChangeField.COMMENTBY,
- ChangeField.PATCH_SET,
- ChangeField.GROUP,
- ChangeField.SUBMISSIONID,
- ChangeField.EDITBY,
+ ChangeField.REF_STATE,
+ ChangeField.REF_STATE_PATTERN,
ChangeField.REVIEWEDBY,
- ChangeField.EXACT_COMMIT,
- ChangeField.AUTHOR,
- ChangeField.COMMITTER,
- ChangeField.DRAFTBY,
- ChangeField.HASHTAG_CASE_AWARE,
+ ChangeField.REVIEWER,
ChangeField.STAR,
ChangeField.STARBY,
- ChangeField.REVIEWER);
-
- @Deprecated static final Schema<ChangeData> V33 = schema(V32, ChangeField.ASSIGNEE);
-
- @Deprecated
- static final Schema<ChangeData> V34 =
- new Schema.Builder<ChangeData>()
- .add(V33)
- .remove(ChangeField.LABEL)
- .add(ChangeField.LABEL2)
- .build();
-
- @Deprecated
- static final Schema<ChangeData> V35 =
- schema(
- V34,
- ChangeField.SUBMIT_RECORD,
+ ChangeField.STATUS,
ChangeField.STORED_SUBMIT_RECORD_LENIENT,
- ChangeField.STORED_SUBMIT_RECORD_STRICT);
-
- @Deprecated
- static final Schema<ChangeData> V36 =
- schema(V35, ChangeField.REF_STATE, ChangeField.REF_STATE_PATTERN);
-
- @Deprecated static final Schema<ChangeData> V37 = schema(V36);
-
- @Deprecated
- static final Schema<ChangeData> V38 = schema(V37, ChangeField.UNRESOLVED_COMMENT_COUNT);
-
- @Deprecated static final Schema<ChangeData> V39 = schema(V38);
+ ChangeField.STORED_SUBMIT_RECORD_STRICT,
+ ChangeField.SUBMISSIONID,
+ ChangeField.SUBMIT_RECORD,
+ ChangeField.TR,
+ ChangeField.UNRESOLVED_COMMENT_COUNT,
+ ChangeField.UPDATED);
@Deprecated static final Schema<ChangeData> V40 = schema(V39, ChangeField.PRIVATE);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/EqualsLabelPredicate.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/EqualsLabelPredicate.java
index 1189e87..bb251cb 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/EqualsLabelPredicate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/EqualsLabelPredicate.java
@@ -42,7 +42,7 @@
private final AccountGroup.UUID group;
EqualsLabelPredicate(LabelPredicate.Args args, String label, int expVal, Account.Id account) {
- super(args.field, ChangeField.formatLabel(label, expVal, account));
+ super(ChangeField.LABEL, ChangeField.formatLabel(label, expVal, account));
this.ccFactory = args.ccFactory;
this.projectCache = args.projectCache;
this.userFactory = args.userFactory;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/LabelPredicate.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/LabelPredicate.java
index 2fbaa1e..9fdbcef 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/LabelPredicate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/LabelPredicate.java
@@ -19,8 +19,6 @@
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.IdentifiedUser;
-import com.google.gerrit.server.index.FieldDef;
-import com.google.gerrit.server.index.change.ChangeField;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.query.OrPredicate;
@@ -37,7 +35,6 @@
private static final int MAX_LABEL_VALUE = 4;
static class Args {
- final FieldDef<ChangeData, ?> field;
final ProjectCache projectCache;
final ChangeControl.GenericFactory ccFactory;
final IdentifiedUser.GenericFactory userFactory;
@@ -47,7 +44,6 @@
final AccountGroup.UUID group;
private Args(
- FieldDef<ChangeData, ?> field,
ProjectCache projectCache,
ChangeControl.GenericFactory ccFactory,
IdentifiedUser.GenericFactory userFactory,
@@ -55,7 +51,6 @@
String value,
Set<Account.Id> accounts,
AccountGroup.UUID group) {
- this.field = field;
this.projectCache = projectCache;
this.ccFactory = ccFactory;
this.userFactory = userFactory;
@@ -80,7 +75,6 @@
private final String value;
- @SuppressWarnings("deprecation")
LabelPredicate(
ChangeQueryBuilder.Arguments a,
String value,
@@ -89,7 +83,6 @@
super(
predicates(
new Args(
- a.getSchema().getField(ChangeField.LABEL2, ChangeField.LABEL).get(),
a.projectCache,
a.changeControlGenericFactory,
a.userFactory,
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.html b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.html
index 8ad1ae2..5f11219 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.html
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.html
@@ -136,7 +136,7 @@
placeholder="Add assignee..."
accounts="{{_assignee}}"
change="[[change]]"
- readonly="[[!mutable]]"
+ readonly="[[_computeAssigneeReadOnly(mutable, change)]]"
allow-any-user></gr-account-list>
</span>
</section>
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
index f8c189a..6caed12 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
@@ -152,6 +152,12 @@
return !mutable || !change.actions.topic || !change.actions.topic.enabled;
},
+ _computeAssigneeReadOnly: function(mutable, change) {
+ return !mutable ||
+ !change.actions.assignee ||
+ !change.actions.assignee.enabled;
+ },
+
_computeTopicPlaceholder: function(_topicReadOnly) {
return _topicReadOnly ? 'No Topic' : 'Click to add topic';
},
@@ -239,8 +245,8 @@
status = this.change.status.toLowerCase();
}
return '/q/project:' + this.encodeURL(project, false) +
- ' branch:' + this.encodeURL(branch, false) +
- ' status:' + this.encodeURL(status, false);
+ ' branch:' + this.encodeURL(branch, false) +
+ ' status:' + this.encodeURL(status, false);
},
_computeTopicHref: function(topic) {
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.html b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.html
index c32f16b..e8e22f9 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.html
@@ -201,6 +201,7 @@
element.change = {
_number: 'the number',
change_id: 'the id',
+ actions: [],
topic: 'the topic',
status: 'NEW',
submit_type: 'CHERRY_PICK',
@@ -287,8 +288,15 @@
_account_id: 1,
name: 'bojack',
};
+ var change = {
+ actions: {
+ assignee: {enabled: false},
+ },
+ assignee: dummyAccount,
+ };
var deleteStub;
var setStub;
+
setup(function() {
deleteStub = sandbox.stub(element.$.restAPI, 'deleteAssignee');
setStub = sandbox.stub(element.$.restAPI, 'setAssignee');
@@ -315,6 +323,17 @@
element.set('_assignee', []);
assert.isTrue(deleteStub.calledOnce);
});
+
+ test('_computeAssigneeReadOnly', function() {
+ var mutable = false;
+ assert.isTrue(element._computeAssigneeReadOnly(mutable, change));
+ mutable = true;
+ assert.isTrue(element._computeAssigneeReadOnly(mutable, change));
+ change.actions.assignee.enabled = true;
+ assert.isFalse(element._computeAssigneeReadOnly(mutable, change));
+ mutable = false;
+ assert.isTrue(element._computeAssigneeReadOnly(mutable, change));
+ });
});
});
});
diff --git a/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.js b/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.js
index 870e7ea..1e609c9 100644
--- a/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.js
+++ b/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.js
@@ -20,6 +20,7 @@
var SIGN_IN_WIDTH_PX = 690;
var SIGN_IN_HEIGHT_PX = 500;
var TOO_MANY_FILES = 'too many files to find conflicts';
+ var AUTHENTICATION_REQUIRED = 'Authentication required\n';
Polymer({
is: 'gr-error-manager',
@@ -73,21 +74,21 @@
},
_handleServerError: function(e) {
- if (e.detail.response.status === 403) {
- this._getLoggedIn().then(function(loggedIn) {
- if (loggedIn) {
- // The app was logged at one point and is now getting auth errors.
- // This indicates the auth token is no longer valid.
- this._showAuthErrorAlert('Auth error', 'Refresh credentials.');
- }
- }.bind(this));
- } else {
- e.detail.response.text().then(function(text) {
- if (!this._shouldSuppressError(text)) {
- this._showAlert('Server error: ' + text);
- }
- }.bind(this));
- }
+ Promise.all([
+ e.detail.response.text(), this._getLoggedIn()
+ ]).then(function(values) {
+ var text = values[0];
+ var loggedIn = values[1];
+ if (e.detail.response.status === 403 &&
+ loggedIn &&
+ text === AUTHENTICATION_REQUIRED) {
+ // The app was logged at one point and is now getting auth errors.
+ // This indicates the auth token is no longer valid.
+ this._showAuthErrorAlert('Auth error', 'Refresh credentials.');
+ } else if (!this._shouldSuppressError(text)) {
+ this._showAlert('Server error: ' + text);
+ }
+ }.bind(this));
},
_handleShowAlert: function(e) {
diff --git a/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager_test.html b/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager_test.html
index 8bab82e..191d67a 100644
--- a/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager_test.html
+++ b/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager_test.html
@@ -49,10 +49,31 @@
sandbox.restore();
});
- test('show auth error', function(done) {
+ test('does not show auth error on 403 by default', function(done) {
var showAuthErrorStub = sandbox.stub(element, '_showAuthErrorAlert');
- element.fire('server-error', {response: {status: 403}});
- element.$.restAPI.getLoggedIn.lastCall.returnValue.then(function() {
+ var responseText = Promise.resolve('server says no.');
+ element.fire('server-error',
+ {response: {status: 403, text: function() { return responseText; }}}
+ );
+ Promise.all([
+ element.$.restAPI.getLoggedIn.lastCall.returnValue,
+ responseText,
+ ]).then(function() {
+ assert.isFalse(showAuthErrorStub.calledOnce);
+ done();
+ });
+ });
+
+ test('shows auth error on 403 and Authentication required', function(done) {
+ var showAuthErrorStub = sandbox.stub(element, '_showAuthErrorAlert');
+ var responseText = Promise.resolve('Authentication required\n');
+ element.fire('server-error',
+ {response: {status: 403, text: function() { return responseText; }}}
+ );
+ Promise.all([
+ element.$.restAPI.getLoggedIn.lastCall.returnValue,
+ responseText,
+ ]).then(function() {
assert.isTrue(showAuthErrorStub.calledOnce);
done();
});
@@ -71,7 +92,10 @@
element.fire('server-error', {response: {status: 500, text: textSpy}});
assert.isTrue(textSpy.called);
- textSpy.lastCall.returnValue.then(function() {
+ Promise.all([
+ element.$.restAPI.getLoggedIn.lastCall.returnValue,
+ textSpy.lastCall.returnValue,
+ ]).then(function() {
assert.isTrue(showAlertStub.calledOnce);
assert.isTrue(showAlertStub.lastCall.calledWithExactly(
'Server error: ZOMG'));
@@ -87,7 +111,10 @@
element.fire('server-error', {response: {status: 500, text: textSpy}});
assert.isTrue(textSpy.called);
- textSpy.lastCall.returnValue.then(function() {
+ Promise.all([
+ element.$.restAPI.getLoggedIn.lastCall.returnValue,
+ textSpy.lastCall.returnValue,
+ ]).then(function() {
assert.isFalse(showAlertStub.called);
done();
});
@@ -112,8 +139,14 @@
function() { return Promise.resolve(true); });
var toastSpy = sandbox.spy(element, '_createToastAlert');
var windowOpen = sandbox.stub(window, 'open');
- element.fire('server-error', {response: {status: 403}});
- element.$.restAPI.getLoggedIn.lastCall.returnValue.then(function() {
+ var responseText = Promise.resolve('Authentication required\n');
+ element.fire('server-error',
+ {response: {status: 403, text: function() { return responseText; }}}
+ );
+ Promise.all([
+ element.$.restAPI.getLoggedIn.lastCall.returnValue,
+ responseText,
+ ]).then(function() {
assert.isTrue(toastSpy.called);
var toast = toastSpy.lastCall.returnValue;
assert.isOk(toast);
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-image.js b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-image.js
index 838938b..368c613 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-image.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-image.js
@@ -45,7 +45,7 @@
tr.appendChild(this._createElement('td'));
tr.appendChild(this._createImageCell(
- this._revisionImage, 'right', section));
+ this._revisionImage, 'right', section));
section.appendChild(tr);
};
@@ -61,13 +61,13 @@
this._updateImageLabel(section, className, image);
}.bind(this);
imageEl.src = 'data:' + image.type + ';base64, ' + image.body;
- imageEl.addEventListener('error', function(e) {
+ imageEl.addEventListener('error', function() {
imageEl.remove();
td.textContent = '[Image failed to load]';
});
td.appendChild(imageEl);
- return td;
}
+ return td;
};
GrDiffBuilderImage.prototype._updateImageLabel =
@@ -86,7 +86,8 @@
var addNamesInLabel = false;
- if (this._baseImage._name !== this._revisionImage._name) {
+ if (this._baseImage && this._revisionImage &&
+ this._baseImage._name !== this._revisionImage._name) {
addNamesInLabel = true;
}
diff --git a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_test.html b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_test.html
index ad7a260..3db2295 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_test.html
@@ -338,7 +338,6 @@
function() { return Promise.resolve(mockComments); }));
element.patchRange = {basePatchNum: 'PARENT', patchNum: 1};
-
});
test('renders image diffs with same file name', function(done) {
@@ -500,6 +499,84 @@
element.reload();
});
});
+
+ test('renders added image', function(done) {
+ var mockDiff = {
+ meta_b: {name: 'carrot.jpg', content_type: 'image/jpeg',
+ lines: 560},
+ intraline_status: 'OK',
+ change_type: 'ADDED',
+ diff_header: [
+ 'diff --git a/carrot.jpg b/carrot.jpg',
+ 'index 0000000..f9c2f2c 100644',
+ '--- /dev/null',
+ '+++ b/carrot.jpg',
+ 'Binary files differ',
+ ],
+ content: [{skip: 66}],
+ binary: true,
+ };
+ stubs.push(sandbox.stub(element, '_getDiff',
+ function() { return Promise.resolve(mockDiff); }));
+
+ element.addEventListener('render', function() {
+ // Recognizes that it should be an image diff.
+ assert.isTrue(element.isImageDiff);
+ assert.instanceOf(
+ element.$.diffBuilder._builder, GrDiffBuilderImage);
+
+ var leftImage = element.$.diffTable.querySelector('td.left img');
+ var rightImage = element.$.diffTable.querySelector('td.right img');
+
+ assert.isNotOk(leftImage);
+ assert.isOk(rightImage);
+ done();
+ });
+
+ element.$.restAPI.getDiffPreferences().then(function(prefs) {
+ element.prefs = prefs;
+ element.reload();
+ });
+ });
+
+ test('renders removed image', function(done) {
+ var mockDiff = {
+ meta_a: {name: 'carrot.jpg', content_type: 'image/jpeg',
+ lines: 560},
+ intraline_status: 'OK',
+ change_type: 'DELETED',
+ diff_header: [
+ 'diff --git a/carrot.jpg b/carrot.jpg',
+ 'index f9c2f2c..0000000 100644',
+ '--- a/carrot.jpg',
+ '+++ /dev/null',
+ 'Binary files differ',
+ ],
+ content: [{skip: 66}],
+ binary: true,
+ };
+ stubs.push(sandbox.stub(element, '_getDiff',
+ function() { return Promise.resolve(mockDiff); }));
+
+ element.addEventListener('render', function() {
+ // Recognizes that it should be an image diff.
+ assert.isTrue(element.isImageDiff);
+ assert.instanceOf(
+ element.$.diffBuilder._builder, GrDiffBuilderImage);
+
+ var leftImage = element.$.diffTable.querySelector('td.left img');
+ var rightImage = element.$.diffTable.querySelector('td.right img');
+
+ assert.isOk(leftImage);
+ assert.isNotOk(rightImage);
+ done();
+ });
+
+ element.$.restAPI.getDiffPreferences().then(function(prefs) {
+ element.prefs = prefs;
+ element.reload();
+ });
+ });
});
test('_handleTap lineNum', function(done) {