Merge "Move diffViewMode into model"
diff --git a/java/com/google/gerrit/entities/SubmitRequirementExpressionResult.java b/java/com/google/gerrit/entities/SubmitRequirementExpressionResult.java
index 900b2e2..9e4416b 100644
--- a/java/com/google/gerrit/entities/SubmitRequirementExpressionResult.java
+++ b/java/com/google/gerrit/entities/SubmitRequirementExpressionResult.java
@@ -39,17 +39,17 @@
/**
* List leaf predicates that are fulfilled, for example the expression
*
- * <p><i>label:code-review=+2 and branch:refs/heads/master</i>
+ * <p><i>label:Code-Review=+2 and branch:refs/heads/master</i>
*
* <p>has two leaf predicates:
*
* <ul>
- * <li>label:code-review=+2
+ * <li>label:Code-Review=+2
* <li>branch:refs/heads/master
* </ul>
*
* This method will return the leaf predicates that were fulfilled, for example if only the first
- * predicate was fulfilled, the returned list will be equal to ["label:code-review=+2"].
+ * predicate was fulfilled, the returned list will be equal to ["label:Code-Review=+2"].
*/
public abstract ImmutableList<String> passingAtoms();
diff --git a/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java b/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
index 0d7210f..74407c0 100644
--- a/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
@@ -225,7 +225,6 @@
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.PushResult;
-import org.junit.Ignore;
import org.junit.Test;
@NoHttpd
@@ -4059,7 +4058,7 @@
assertThat(testLabel.status).isEqualTo(SubmitRecordInfo.Label.Status.OK);
assertThat(testLabel.appliedBy).isNull();
- voteLabel(changeId, "code-review", 2);
+ voteLabel(changeId, "Code-Review", 2);
// Code review record is satisfied after voting +2
change = gApi.changes().id(changeId).get();
assertThat(change.submitRecords).hasSize(2);
@@ -4166,9 +4165,9 @@
configSubmitRequirement(
project,
SubmitRequirement.builder()
- .setName("code-review")
+ .setName("Code-Review")
.setSubmittabilityExpression(
- SubmitRequirementExpression.create("label:code-review=MAX"))
+ SubmitRequirementExpression.create("label:Code-Review=MAX"))
.setAllowOverrideInChildProjects(false)
.build());
@@ -4178,13 +4177,13 @@
ChangeInfo change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).hasSize(1);
assertSubmitRequirementStatus(
- change.submitRequirements, "code-review", Status.UNSATISFIED, /* isLegacy= */ false);
+ change.submitRequirements, "Code-Review", Status.UNSATISFIED, /* isLegacy= */ false);
- voteLabel(changeId, "code-review", 2);
+ voteLabel(changeId, "Code-Review", 2);
change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).hasSize(1);
assertSubmitRequirementStatus(
- change.submitRequirements, "code-review", Status.SATISFIED, /* isLegacy= */ false);
+ change.submitRequirements, "Code-Review", Status.SATISFIED, /* isLegacy= */ false);
}
@Test
@@ -4239,9 +4238,9 @@
configSubmitRequirement(
project,
SubmitRequirement.builder()
- .setName("code-review")
+ .setName("Code-Review")
.setSubmittabilityExpression(
- SubmitRequirementExpression.create("-label:code-review=MIN"))
+ SubmitRequirementExpression.create("-label:Code-Review=MIN"))
.setAllowOverrideInChildProjects(false)
.build());
@@ -4252,27 +4251,27 @@
assertThat(change.submitRequirements).hasSize(2);
// Requirement is satisfied because there are no votes
assertSubmitRequirementStatus(
- change.submitRequirements, "code-review", Status.SATISFIED, /* isLegacy= */ false);
+ change.submitRequirements, "Code-Review", Status.SATISFIED, /* isLegacy= */ false);
// Legacy requirement (coming from the label function definition) is not satisfied. We return
// both legacy and non-legacy requirements in this case since their statuses are not identical.
assertSubmitRequirementStatus(
change.submitRequirements, "Code-Review", Status.UNSATISFIED, /* isLegacy= */ true);
- voteLabel(changeId, "code-review", -1);
+ voteLabel(changeId, "Code-Review", -1);
change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).hasSize(2);
// Requirement is still satisfied because -1 is not the max negative value
assertSubmitRequirementStatus(
- change.submitRequirements, "code-review", Status.SATISFIED, /* isLegacy= */ false);
+ change.submitRequirements, "Code-Review", Status.SATISFIED, /* isLegacy= */ false);
assertSubmitRequirementStatus(
change.submitRequirements, "Code-Review", Status.UNSATISFIED, /* isLegacy= */ true);
- voteLabel(changeId, "code-review", -2);
+ voteLabel(changeId, "Code-Review", -2);
change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).hasSize(1);
// Requirement is now unsatisfied because -2 is the max negative value
assertSubmitRequirementStatus(
- change.submitRequirements, "code-review", Status.UNSATISFIED, /* isLegacy= */ false);
+ change.submitRequirements, "Code-Review", Status.UNSATISFIED, /* isLegacy= */ false);
}
@Test
@@ -4335,9 +4334,9 @@
configSubmitRequirement(
project,
SubmitRequirement.builder()
- .setName("code-review")
+ .setName("Code-Review")
.setSubmittabilityExpression(
- SubmitRequirementExpression.create("label:code-review=ANY"))
+ SubmitRequirementExpression.create("label:Code-Review=ANY"))
.setAllowOverrideInChildProjects(false)
.build());
@@ -4347,14 +4346,14 @@
ChangeInfo change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).hasSize(1);
assertSubmitRequirementStatus(
- change.submitRequirements, "code-review", Status.UNSATISFIED, /* isLegacy= */ false);
+ change.submitRequirements, "Code-Review", Status.UNSATISFIED, /* isLegacy= */ false);
- voteLabel(changeId, "code-review", 1);
+ voteLabel(changeId, "Code-Review", 1);
change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).hasSize(2);
// Legacy and non-legacy requirements have mismatching status. Both are returned from the API.
assertSubmitRequirementStatus(
- change.submitRequirements, "code-review", Status.SATISFIED, /* isLegacy= */ false);
+ change.submitRequirements, "Code-Review", Status.SATISFIED, /* isLegacy= */ false);
assertSubmitRequirementStatus(
change.submitRequirements, "Code-Review", Status.UNSATISFIED, /* isLegacy= */ true);
}
@@ -4368,15 +4367,15 @@
configSubmitRequirement(
project,
SubmitRequirement.builder()
- .setName("code-review")
- .setSubmittabilityExpression(SubmitRequirementExpression.create("label:code-review=+2"))
+ .setName("Code-Review")
+ .setSubmittabilityExpression(SubmitRequirementExpression.create("label:Code-Review=+2"))
.setAllowOverrideInChildProjects(false)
.build());
configSubmitRequirement(
project,
SubmitRequirement.builder()
- .setName("verified")
- .setSubmittabilityExpression(SubmitRequirementExpression.create("label:verified=+1"))
+ .setName("Verified")
+ .setSubmittabilityExpression(SubmitRequirementExpression.create("label:Verified=+1"))
.setAllowOverrideInChildProjects(false)
.build());
@@ -4386,18 +4385,18 @@
ChangeInfo change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).hasSize(2);
assertSubmitRequirementStatus(
- change.submitRequirements, "code-review", Status.UNSATISFIED, /* isLegacy= */ false);
+ change.submitRequirements, "Code-Review", Status.UNSATISFIED, /* isLegacy= */ false);
assertSubmitRequirementStatus(
- change.submitRequirements, "verified", Status.UNSATISFIED, /* isLegacy= */ false);
+ change.submitRequirements, "Verified", Status.UNSATISFIED, /* isLegacy= */ false);
- voteLabel(changeId, "code-review", 2);
+ voteLabel(changeId, "Code-Review", 2);
change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).hasSize(2);
assertSubmitRequirementStatus(
- change.submitRequirements, "code-review", Status.SATISFIED, /* isLegacy= */ false);
+ change.submitRequirements, "Code-Review", Status.SATISFIED, /* isLegacy= */ false);
assertSubmitRequirementStatus(
- change.submitRequirements, "verified", Status.UNSATISFIED, /* isLegacy= */ false);
+ change.submitRequirements, "Verified", Status.UNSATISFIED, /* isLegacy= */ false);
}
@Test
@@ -4409,9 +4408,9 @@
configSubmitRequirement(
project,
SubmitRequirement.builder()
- .setName("code-review")
+ .setName("Code-Review")
.setApplicabilityExpression(SubmitRequirementExpression.of("project:foo"))
- .setSubmittabilityExpression(SubmitRequirementExpression.create("label:code-review=+2"))
+ .setSubmittabilityExpression(SubmitRequirementExpression.create("label:Code-Review=+2"))
.setAllowOverrideInChildProjects(false)
.build());
@@ -4421,7 +4420,7 @@
ChangeInfo change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).hasSize(2);
assertSubmitRequirementStatus(
- change.submitRequirements, "code-review", Status.NOT_APPLICABLE, /* isLegacy= */ false);
+ change.submitRequirements, "Code-Review", Status.NOT_APPLICABLE, /* isLegacy= */ false);
assertSubmitRequirementStatus(
change.submitRequirements, "Code-Review", Status.UNSATISFIED, /* isLegacy= */ true);
}
@@ -4445,8 +4444,8 @@
configSubmitRequirement(
project,
SubmitRequirement.builder()
- .setName("code-review")
- .setSubmittabilityExpression(SubmitRequirementExpression.create("label:code-review=+2"))
+ .setName("Code-Review")
+ .setSubmittabilityExpression(SubmitRequirementExpression.create("label:Code-Review=+2"))
.setOverrideExpression(SubmitRequirementExpression.of("label:build-cop-override=+1"))
.setAllowOverrideInChildProjects(false)
.build());
@@ -4456,36 +4455,38 @@
ChangeInfo change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).hasSize(1);
assertSubmitRequirementStatus(
- change.submitRequirements, "code-review", Status.UNSATISFIED, /* isLegacy= */ false);
+ change.submitRequirements, "Code-Review", Status.UNSATISFIED, /* isLegacy= */ false);
voteLabel(changeId, "build-cop-override", 1);
change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).hasSize(2);
assertSubmitRequirementStatus(
- change.submitRequirements, "code-review", Status.OVERRIDDEN, /* isLegacy= */ false);
+ change.submitRequirements, "Code-Review", Status.OVERRIDDEN, /* isLegacy= */ false);
assertSubmitRequirementStatus(
change.submitRequirements, "Code-Review", Status.UNSATISFIED, /* isLegacy= */ true);
}
@Test
- @Ignore("Test is flaky")
+ @GerritConfig(
+ name = "experiments.enabled",
+ value = ExperimentFeaturesConstants.GERRIT_BACKEND_REQUEST_FEATURE_ENABLE_SUBMIT_REQUIREMENTS)
public void submitRequirement_overriddenInChildProject() throws Exception {
configSubmitRequirement(
allProjects,
SubmitRequirement.builder()
- .setName("code-review")
- .setSubmittabilityExpression(SubmitRequirementExpression.create("label:code-review=+1"))
+ .setName("Code-Review")
+ .setSubmittabilityExpression(SubmitRequirementExpression.create("label:Code-Review=+1"))
.setOverrideExpression(SubmitRequirementExpression.of("label:build-cop-override=+1"))
.setAllowOverrideInChildProjects(true)
.build());
- // Override submit requirement in child project (requires code-review=+2 instead of +1)
+ // Override submit requirement in child project (requires Code-Review=+2 instead of +1)
configSubmitRequirement(
project,
SubmitRequirement.builder()
- .setName("code-review")
- .setSubmittabilityExpression(SubmitRequirementExpression.create("label:code-review=+2"))
+ .setName("Code-Review")
+ .setSubmittabilityExpression(SubmitRequirementExpression.create("label:Code-Review=+2"))
.setOverrideExpression(SubmitRequirementExpression.of("label:build-cop-override=+1"))
.setAllowOverrideInChildProjects(false)
.build());
@@ -4495,19 +4496,19 @@
ChangeInfo change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).hasSize(1);
assertSubmitRequirementStatus(
- change.submitRequirements, "code-review", Status.UNSATISFIED, /* isLegacy= */ false);
+ change.submitRequirements, "Code-Review", Status.UNSATISFIED, /* isLegacy= */ false);
- voteLabel(changeId, "code-review", 1);
+ voteLabel(changeId, "Code-Review", 1);
change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).hasSize(1);
assertSubmitRequirementStatus(
- change.submitRequirements, "code-review", Status.UNSATISFIED, /* isLegacy= */ false);
+ change.submitRequirements, "Code-Review", Status.UNSATISFIED, /* isLegacy= */ false);
- voteLabel(changeId, "code-review", 2);
+ voteLabel(changeId, "Code-Review", 2);
change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).hasSize(1);
assertSubmitRequirementStatus(
- change.submitRequirements, "code-review", Status.SATISFIED, /* isLegacy= */ false);
+ change.submitRequirements, "Code-Review", Status.SATISFIED, /* isLegacy= */ false);
}
@Test
@@ -4518,8 +4519,8 @@
configSubmitRequirement(
allProjects,
SubmitRequirement.builder()
- .setName("code-review")
- .setSubmittabilityExpression(SubmitRequirementExpression.create("label:code-review=+1"))
+ .setName("Code-Review")
+ .setSubmittabilityExpression(SubmitRequirementExpression.create("label:Code-Review=+1"))
.setOverrideExpression(SubmitRequirementExpression.of("label:build-cop-override=+1"))
.setAllowOverrideInChildProjects(false)
.build());
@@ -4529,13 +4530,13 @@
ChangeInfo change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).hasSize(1);
assertSubmitRequirementStatus(
- change.submitRequirements, "code-review", Status.UNSATISFIED, /* isLegacy= */ false);
+ change.submitRequirements, "Code-Review", Status.UNSATISFIED, /* isLegacy= */ false);
- voteLabel(changeId, "code-review", 1);
+ voteLabel(changeId, "Code-Review", 1);
change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).hasSize(2);
assertSubmitRequirementStatus(
- change.submitRequirements, "code-review", Status.SATISFIED, /* isLegacy= */ false);
+ change.submitRequirements, "Code-Review", Status.SATISFIED, /* isLegacy= */ false);
// Legacy requirement is coming from the label MaxWithBlock function. Still unsatisfied.
assertSubmitRequirementStatus(
change.submitRequirements, "Code-Review", Status.UNSATISFIED, /* isLegacy= */ true);
@@ -4550,19 +4551,19 @@
configSubmitRequirement(
allProjects,
SubmitRequirement.builder()
- .setName("code-review")
- .setSubmittabilityExpression(SubmitRequirementExpression.create("label:code-review=+1"))
+ .setName("Code-Review")
+ .setSubmittabilityExpression(SubmitRequirementExpression.create("label:Code-Review=+1"))
.setOverrideExpression(SubmitRequirementExpression.of("label:build-cop-override=+1"))
.setAllowOverrideInChildProjects(false)
.build());
- // Override submit requirement in child project (requires code-review=+2 instead of +1).
+ // Override submit requirement in child project (requires Code-Review=+2 instead of +1).
// Will have no effect since parent does not allow override.
configSubmitRequirement(
project,
SubmitRequirement.builder()
- .setName("code-review")
- .setSubmittabilityExpression(SubmitRequirementExpression.create("label:code-review=+2"))
+ .setName("Code-Review")
+ .setSubmittabilityExpression(SubmitRequirementExpression.create("label:Code-Review=+2"))
.setOverrideExpression(SubmitRequirementExpression.of("label:build-cop-override=+1"))
.setAllowOverrideInChildProjects(false)
.build());
@@ -4572,14 +4573,14 @@
ChangeInfo change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).hasSize(1);
assertSubmitRequirementStatus(
- change.submitRequirements, "code-review", Status.UNSATISFIED, /* isLegacy= */ false);
+ change.submitRequirements, "Code-Review", Status.UNSATISFIED, /* isLegacy= */ false);
- voteLabel(changeId, "code-review", 1);
+ voteLabel(changeId, "Code-Review", 1);
change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).hasSize(2);
// +1 was enough to fulfill the requirement: override in child project was ignored
assertSubmitRequirementStatus(
- change.submitRequirements, "code-review", Status.SATISFIED, /* isLegacy= */ false);
+ change.submitRequirements, "Code-Review", Status.SATISFIED, /* isLegacy= */ false);
// Legacy requirement is coming from the label MaxWithBlock function. Still unsatisfied.
assertSubmitRequirementStatus(
change.submitRequirements, "Code-Review", Status.UNSATISFIED, /* isLegacy= */ true);
@@ -4600,9 +4601,9 @@
configSubmitRequirement(
project,
SubmitRequirement.builder()
- .setName("code-review")
+ .setName("Code-Review")
.setSubmittabilityExpression(
- SubmitRequirementExpression.create("label:code-review=+2"))
+ SubmitRequirementExpression.create("label:Code-Review=+2"))
.setAllowOverrideInChildProjects(false)
.build());
@@ -4610,12 +4611,12 @@
createChange(repo, "master", "Add a file", "foo", "content", "topic");
String changeId = r.getChangeId();
- voteLabel(changeId, "code-review", 2);
+ voteLabel(changeId, "Code-Review", 2);
ChangeInfo change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).hasSize(1);
assertSubmitRequirementStatus(
- change.submitRequirements, "code-review", Status.SATISFIED, /* isLegacy= */ false);
+ change.submitRequirements, "Code-Review", Status.SATISFIED, /* isLegacy= */ false);
RevisionApi revision = gApi.changes().id(r.getChangeId()).current();
revision.review(ReviewInput.approve());
@@ -4629,7 +4630,7 @@
assertThat(result.submittabilityExpressionResult().status())
.isEqualTo(SubmitRequirementExpressionResult.Status.PASS);
assertThat(result.submittabilityExpressionResult().expression().expressionString())
- .isEqualTo("label:code-review=+2");
+ .isEqualTo("label:Code-Review=+2");
}
}
@@ -4645,8 +4646,8 @@
configSubmitRequirement(
project,
SubmitRequirement.builder()
- .setName("code-review")
- .setSubmittabilityExpression(SubmitRequirementExpression.create("label:code-review=+2"))
+ .setName("Code-Review")
+ .setSubmittabilityExpression(SubmitRequirementExpression.create("label:Code-Review=+2"))
.setAllowOverrideInChildProjects(false)
.build());
@@ -4656,14 +4657,14 @@
ChangeInfo change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).hasSize(1);
assertSubmitRequirementStatus(
- change.submitRequirements, "code-review", Status.UNSATISFIED, /* isLegacy= */ false);
+ change.submitRequirements, "Code-Review", Status.UNSATISFIED, /* isLegacy= */ false);
- voteLabel(changeId, "code-review", 2);
+ voteLabel(changeId, "Code-Review", 2);
change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).hasSize(1);
assertSubmitRequirementStatus(
- change.submitRequirements, "code-review", Status.SATISFIED, /* isLegacy= */ false);
+ change.submitRequirements, "Code-Review", Status.SATISFIED, /* isLegacy= */ false);
gApi.changes().id(changeId).current().submit();
@@ -4671,16 +4672,16 @@
configSubmitRequirement(
project,
SubmitRequirement.builder()
- .setName("verified")
- .setSubmittabilityExpression(SubmitRequirementExpression.create("label:verified=+1"))
+ .setName("Verified")
+ .setSubmittabilityExpression(SubmitRequirementExpression.create("label:Verified=+1"))
.setAllowOverrideInChildProjects(false)
.build());
- // The new "verified" submit requirement is not returned, since this change is closed
+ // The new "Verified" submit requirement is not returned, since this change is closed
change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).hasSize(1);
assertSubmitRequirementStatus(
- change.submitRequirements, "code-review", Status.SATISFIED, /* isLegacy= */ false);
+ change.submitRequirements, "Code-Review", Status.SATISFIED, /* isLegacy= */ false);
}
@Test
@@ -4869,15 +4870,15 @@
configSubmitRequirement(
project,
SubmitRequirement.builder()
- .setName("code-review")
- .setSubmittabilityExpression(SubmitRequirementExpression.create("label:code-review=+2"))
+ .setName("Code-Review")
+ .setSubmittabilityExpression(SubmitRequirementExpression.create("label:Code-Review=+2"))
.setAllowOverrideInChildProjects(false)
.build());
PushOneCommit.Result r = createChange();
String changeId = r.getChangeId();
- voteLabel(changeId, "code-review", 2);
+ voteLabel(changeId, "Code-Review", 2);
// Query the change. ChangeInfo is back-filled from the change index.
List<ChangeInfo> changeInfos =
@@ -4889,7 +4890,7 @@
assertThat(changeInfos).hasSize(1);
assertSubmitRequirementStatus(
changeInfos.get(0).submitRequirements,
- "code-review",
+ "Code-Review",
Status.SATISFIED,
/* isLegacy= */ false);
}
@@ -4906,15 +4907,15 @@
configSubmitRequirement(
project,
SubmitRequirement.builder()
- .setName("code-review")
- .setSubmittabilityExpression(SubmitRequirementExpression.create("label:code-review=+2"))
+ .setName("Code-Review")
+ .setSubmittabilityExpression(SubmitRequirementExpression.create("label:Code-Review=+2"))
.setAllowOverrideInChildProjects(false)
.build());
PushOneCommit.Result r = createChange();
String changeId = r.getChangeId();
- voteLabel(changeId, "code-review", 2);
+ voteLabel(changeId, "Code-Review", 2);
gApi.changes().id(changeId).current().submit();
// Query the change. ChangeInfo is back-filled from the change index.
@@ -4927,7 +4928,7 @@
assertThat(changeInfos).hasSize(1);
assertSubmitRequirementStatus(
changeInfos.get(0).submitRequirements,
- "code-review",
+ "Code-Review",
Status.SATISFIED,
/* isLegacy= */ false);
}
@@ -4937,8 +4938,8 @@
configSubmitRequirement(
project,
SubmitRequirement.builder()
- .setName("code-review")
- .setSubmittabilityExpression(SubmitRequirementExpression.create("label:code-review=+2"))
+ .setName("Code-Review")
+ .setSubmittabilityExpression(SubmitRequirementExpression.create("label:Code-Review=+2"))
.setAllowOverrideInChildProjects(false)
.build());
@@ -4948,11 +4949,11 @@
ChangeInfo change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).isEmpty();
- voteLabel(changeId, "code-review", -1);
+ voteLabel(changeId, "Code-Review", -1);
change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).isEmpty();
- voteLabel(changeId, "code-review", 2);
+ voteLabel(changeId, "Code-Review", 2);
change = gApi.changes().id(changeId).get();
assertThat(change.submitRequirements).isEmpty();
diff --git a/javatests/com/google/gerrit/acceptance/server/project/SubmitRequirementsEvaluatorIT.java b/javatests/com/google/gerrit/acceptance/server/project/SubmitRequirementsEvaluatorIT.java
index 6e19c39..f511683 100644
--- a/javatests/com/google/gerrit/acceptance/server/project/SubmitRequirementsEvaluatorIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/project/SubmitRequirementsEvaluatorIT.java
@@ -138,13 +138,13 @@
SubmitRequirement sr =
createSubmitRequirement(
/* applicabilityExpr= */ "project:" + project.get(),
- /* submittabilityExpr= */ "label:\"code-review=+2\"",
+ /* submittabilityExpr= */ "label:\"Code-Review=+2\"",
/* overrideExpr= */ "");
SubmitRequirementResult result = evaluator.evaluateRequirement(sr, changeData);
assertThat(result.status()).isEqualTo(SubmitRequirementResult.Status.UNSATISFIED);
assertThat(result.submittabilityExpressionResult().failingAtoms())
- .containsExactly("label:\"code-review=+2\"");
+ .containsExactly("label:\"Code-Review=+2\"");
}
@Test
@@ -160,7 +160,7 @@
SubmitRequirement sr =
createSubmitRequirement(
/* applicabilityExpr= */ "project:" + project.get(),
- /* submittabilityExpr= */ "label:\"code-review=+2\"",
+ /* submittabilityExpr= */ "label:\"Code-Review=+2\"",
/* overrideExpr= */ "label:\"build-cop-override=+1\"");
SubmitRequirementResult result = evaluator.evaluateRequirement(sr, changeData);
@@ -175,7 +175,7 @@
SubmitRequirement sr =
createSubmitRequirement(
/* applicabilityExpr= */ "invalid_field:invalid_value",
- /* submittabilityExpr= */ "label:\"code-review=+2\"",
+ /* submittabilityExpr= */ "label:\"Code-Review=+2\"",
/* overrideExpr= */ "label:\"build-cop-override=+1\"");
SubmitRequirementResult result = evaluator.evaluateRequirement(sr, changeData);
@@ -206,7 +206,7 @@
SubmitRequirement sr =
createSubmitRequirement(
/* applicabilityExpr= */ "project:" + project.get(),
- /* submittabilityExpr= */ "label:\"code-review=+2\"",
+ /* submittabilityExpr= */ "label:\"Code-Review=+2\"",
/* overrideExpr= */ "invalid_field:invalid_value");
SubmitRequirementResult result = evaluator.evaluateRequirement(sr, changeData);
diff --git a/javatests/com/google/gerrit/acceptance/server/project/SubmitRequirementsValidationIT.java b/javatests/com/google/gerrit/acceptance/server/project/SubmitRequirementsValidationIT.java
index 85dfd4d..d8aa789 100644
--- a/javatests/com/google/gerrit/acceptance/server/project/SubmitRequirementsValidationIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/project/SubmitRequirementsValidationIT.java
@@ -50,7 +50,7 @@
ProjectConfig.SUBMIT_REQUIREMENT,
/* subsection= */ submitRequirementName,
/* name= */ ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION,
- /* value= */ "label:\"code-review=+2\""));
+ /* value= */ "label:\"Code-Review=+2\""));
PushResult r = pushRefsMetaConfig();
assertOkStatus(r);
@@ -77,7 +77,7 @@
ProjectConfig.SUBMIT_REQUIREMENT,
/* subsection= */ submitRequirementName,
/* name= */ ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION,
- /* value= */ "label:\"code-review=+2\"");
+ /* value= */ "label:\"Code-Review=+2\"");
projectConfig.setString(
ProjectConfig.SUBMIT_REQUIREMENT,
/* subsection= */ submitRequirementName,
@@ -109,7 +109,7 @@
ProjectConfig.SUBMIT_REQUIREMENT,
/* subsection= */ null,
/* name= */ ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION,
- /* value= */ "label:\"code-review=+2\"");
+ /* value= */ "label:\"Code-Review=+2\"");
});
PushResult r = pushRefsMetaConfig();
@@ -177,12 +177,12 @@
ProjectConfig.SUBMIT_REQUIREMENT,
/* subsection= */ submitRequirementName,
/* name= */ ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION,
- /* value= */ "label:\"code-review=+2\"");
+ /* value= */ "label:\"Code-Review=+2\"");
projectConfig.setString(
ProjectConfig.SUBMIT_REQUIREMENT,
/* subsection= */ submitRequirementName.toLowerCase(Locale.US),
/* name= */ ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION,
- /* value= */ "label:\"code-review=+2\"");
+ /* value= */ "label:\"Code-Review=+2\"");
});
PushResult r = pushRefsMetaConfig();
@@ -204,7 +204,7 @@
ProjectConfig.SUBMIT_REQUIREMENT,
/* subsection= */ submitRequirementName,
/* name= */ ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION,
- /* value= */ "label:\"code-review=+2\""));
+ /* value= */ "label:\"Code-Review=+2\""));
PushResult r = pushRefsMetaConfig();
assertOkStatus(r);
@@ -214,7 +214,7 @@
ProjectConfig.SUBMIT_REQUIREMENT,
/* subsection= */ submitRequirementName.toLowerCase(Locale.US),
/* name= */ ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION,
- /* value= */ "label:\"code-review=+2\""));
+ /* value= */ "label:\"Code-Review=+2\""));
r = pushRefsMetaConfig();
assertErrorStatus(
r,
@@ -291,7 +291,7 @@
ProjectConfig.SUBMIT_REQUIREMENT,
/* subsection= */ submitRequirementName,
/* name= */ ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION,
- /* value= */ "label:\"code-review=+2\"");
+ /* value= */ "label:\"Code-Review=+2\"");
projectConfig.setString(
ProjectConfig.SUBMIT_REQUIREMENT,
/* subsection= */ submitRequirementName,
@@ -326,7 +326,7 @@
ProjectConfig.SUBMIT_REQUIREMENT,
/* subsection= */ submitRequirementName,
/* name= */ ProjectConfig.KEY_SR_SUBMITTABILITY_EXPRESSION,
- /* value= */ "label:\"code-review=+2\"");
+ /* value= */ "label:\"Code-Review=+2\"");
projectConfig.setString(
ProjectConfig.SUBMIT_REQUIREMENT,
/* subsection= */ submitRequirementName,
diff --git a/javatests/com/google/gerrit/server/cache/serialize/entities/SubmitRequirementSerializerTest.java b/javatests/com/google/gerrit/server/cache/serialize/entities/SubmitRequirementSerializerTest.java
index a1dee1a..6993dfe 100644
--- a/javatests/com/google/gerrit/server/cache/serialize/entities/SubmitRequirementSerializerTest.java
+++ b/javatests/com/google/gerrit/server/cache/serialize/entities/SubmitRequirementSerializerTest.java
@@ -26,7 +26,7 @@
public class SubmitRequirementSerializerTest {
private static final SubmitRequirement submitReq =
SubmitRequirement.builder()
- .setName("code-review")
+ .setName("Code-Review")
.setDescription(Optional.of("require code review +2"))
.setApplicabilityExpression(SubmitRequirementExpression.of("branch(refs/heads/master)"))
.setSubmittabilityExpression(SubmitRequirementExpression.create("label(code-review, 2+)"))
diff --git a/javatests/com/google/gerrit/server/notedb/ChangeNotesStateTest.java b/javatests/com/google/gerrit/server/notedb/ChangeNotesStateTest.java
index 61002f9..0c26f1a 100644
--- a/javatests/com/google/gerrit/server/notedb/ChangeNotesStateTest.java
+++ b/javatests/com/google/gerrit/server/notedb/ChangeNotesStateTest.java
@@ -696,7 +696,7 @@
.setApplicabilityExpression(
SubmitRequirementExpression.of("project:foo"))
.setSubmittabilityExpression(
- SubmitRequirementExpression.create("label:code-review=+2"))
+ SubmitRequirementExpression.create("label:Code-Review=+2"))
.setAllowOverrideInChildProjects(false)
.build())
.applicabilityExpressionResult(
@@ -708,10 +708,10 @@
ImmutableList.of())))
.submittabilityExpressionResult(
SubmitRequirementExpressionResult.create(
- SubmitRequirementExpression.create("label:code-review=+2"),
+ SubmitRequirementExpression.create("label:Code-Review=+2"),
SubmitRequirementExpressionResult.Status.FAIL,
ImmutableList.of(),
- ImmutableList.of("label:code-review=+2")))
+ ImmutableList.of("label:Code-Review=+2")))
.build()))
.build(),
newProtoBuilder()
@@ -726,7 +726,7 @@
SubmitRequirementProto.newBuilder()
.setName("Code-Review")
.setApplicabilityExpression("project:foo")
- .setSubmittabilityExpression("label:code-review=+2")
+ .setSubmittabilityExpression("label:Code-Review=+2")
.setAllowOverrideInChildProjects(false)
.build())
.setApplicabilityExpressionResult(
@@ -737,9 +737,9 @@
.build())
.setSubmittabilityExpressionResult(
SubmitRequirementExpressionResultProto.newBuilder()
- .setExpression("label:code-review=+2")
+ .setExpression("label:Code-Review=+2")
.setStatus("FAIL")
- .addFailingAtoms("label:code-review=+2")
+ .addFailingAtoms("label:Code-Review=+2")
.build())
.build())
.build());
diff --git a/javatests/com/google/gerrit/server/project/ProjectConfigTest.java b/javatests/com/google/gerrit/server/project/ProjectConfigTest.java
index 48ef85d8..aed1648 100644
--- a/javatests/com/google/gerrit/server/project/ProjectConfigTest.java
+++ b/javatests/com/google/gerrit/server/project/ProjectConfigTest.java
@@ -217,7 +217,7 @@
"[submit-requirement \"Code-review\"]\n"
+ " description = At least one Code Review +2\n"
+ " applicableIf =branch(refs/heads/master)\n"
- + " submittableIf = label(code-review, +2)\n"
+ + " submittableIf = label(Code-Review, +2)\n"
+ "[submit-requirement \"api-review\"]\n"
+ " description = Additional review required for API modifications\n"
+ " applicableIf =commit_filepath_contains(\\\"/api/.*\\\")\n"
@@ -237,7 +237,7 @@
.setApplicabilityExpression(
SubmitRequirementExpression.of("branch(refs/heads/master)"))
.setSubmittabilityExpression(
- SubmitRequirementExpression.create("label(code-review, +2)"))
+ SubmitRequirementExpression.create("label(Code-Review, +2)"))
.setOverrideExpression(Optional.empty())
.setAllowOverrideInChildProjects(false)
.build(),
@@ -262,19 +262,19 @@
.add("groups", group(developers))
.add(
"project.config",
- "[submit-requirement \"code-review\"]\n"
- + " submittableIf = label(code-review, +2)\n")
+ "[submit-requirement \"Code-Review\"]\n"
+ + " submittableIf = label(Code-Review, +2)\n")
.create();
ProjectConfig cfg = read(rev);
Map<String, SubmitRequirement> submitRequirements = cfg.getSubmitRequirementSections();
assertThat(submitRequirements)
.containsExactly(
- "code-review",
+ "Code-Review",
SubmitRequirement.builder()
- .setName("code-review")
+ .setName("Code-Review")
.setSubmittabilityExpression(
- SubmitRequirementExpression.create("label(code-review, +2)"))
+ SubmitRequirementExpression.create("label(Code-Review, +2)"))
.setAllowOverrideInChildProjects(false)
.build());
}
@@ -320,8 +320,8 @@
.add("groups", group(developers))
.add(
"project.config",
- "[submit-requirement \"code-review\"]\n"
- + " applicableIf =label(code-review, +2)\n")
+ "[submit-requirement \"Code-Review\"]\n"
+ + " applicableIf =label(Code-Review, +2)\n")
.create();
ProjectConfig cfg = read(rev);
@@ -331,8 +331,8 @@
assertThat(Iterables.getOnlyElement(cfg.getValidationErrors()).getMessage())
.isEqualTo(
"project.config: Setting a submittability expression for submit requirement"
- + " 'code-review' is required: Missing"
- + " submit-requirement.code-review.submittableIf");
+ + " 'Code-Review' is required: Missing"
+ + " submit-requirement.Code-Review.submittableIf");
}
@Test
@@ -953,10 +953,10 @@
tr.commit()
.add(
"project.config",
- "[submit-requirement \"code-review\"]\n"
+ "[submit-requirement \"Code-Review\"]\n"
+ " description = At least one Code Review +2\n"
+ " applicableIf =branch(refs/heads/master)\n"
- + " submittableIf = label(code-review, +2)\n"
+ + " submittableIf = label(Code-Review, +2)\n"
+ "[notify \"name\"]\n"
+ " email = example@example.com\n")
.create();
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-column/gr-change-list-column.ts b/polygerrit-ui/app/elements/change-list/gr-change-list-column/gr-change-list-column.ts
index 480f502..2b9abfd 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-column/gr-change-list-column.ts
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-column/gr-change-list-column.ts
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+import '../../change/gr-submit-requirement-dashboard-hovercard/gr-submit-requirement-dashboard-hovercard';
import {LitElement, css, html} from 'lit';
import {customElement, property} from 'lit/decorators';
import {ChangeInfo, SubmitRequirementStatus} from '../../../api/rest-api';
@@ -71,7 +72,9 @@
renderState(icon: string, message: string) {
return html`<span class="${icon}"
- ><iron-icon class="${icon}" icon="gr-icons:${icon}" role="img"></iron-icon
+ ><gr-submit-requirement-dashboard-hovercard .change=${this.change}>
+ </gr-submit-requirement-dashboard-hovercard>
+ <iron-icon class="${icon}" icon="gr-icons:${icon}" role="img"></iron-icon
>${message}</span
>`;
}
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.ts b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.ts
index 050e86d..5506bc7 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.ts
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.ts
@@ -426,7 +426,9 @@
});
this.cleanups.push(
addGlobalShortcut({key: Key.ESC}, _ => this._handleEscKey()),
- addShortcut(this, {key: Key.ENTER}, _ => this.handleOpenFile())
+ addShortcut(this, {key: Key.ENTER}, _ => this.handleOpenFile(), {
+ shouldSuppress: true,
+ })
);
}
diff --git a/polygerrit-ui/app/elements/change/gr-submit-requirement-dashboard-hovercard/gr-submit-requirement-dashboard-hovercard.ts b/polygerrit-ui/app/elements/change/gr-submit-requirement-dashboard-hovercard/gr-submit-requirement-dashboard-hovercard.ts
new file mode 100644
index 0000000..94dcbef
--- /dev/null
+++ b/polygerrit-ui/app/elements/change/gr-submit-requirement-dashboard-hovercard/gr-submit-requirement-dashboard-hovercard.ts
@@ -0,0 +1,57 @@
+/**
+ * @license
+ * Copyright (C) 2021 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.
+ */
+import '../gr-submit-requirements/gr-submit-requirements';
+import {customElement, property} from 'lit/decorators';
+import {css, html, LitElement} from 'lit';
+import {HovercardMixin} from '../../../mixins/hovercard-mixin/hovercard-mixin';
+import {ParsedChangeInfo} from '../../../types/types';
+
+// This avoids JSC_DYNAMIC_EXTENDS_WITHOUT_JSDOC closure compiler error.
+const base = HovercardMixin(LitElement);
+
+@customElement('gr-submit-requirement-dashboard-hovercard')
+export class GrSubmitRequirementDashboardHovercard extends base {
+ @property({type: Object})
+ change?: ParsedChangeInfo;
+
+ static override get styles() {
+ return [
+ base.styles || [],
+ css`
+ #container {
+ padding: var(--spacing-xl);
+ padding-left: var(--spacing-s);
+ }
+ `,
+ ];
+ }
+
+ override render() {
+ return html`<div id="container" role="tooltip" tabindex="-1">
+ <gr-submit-requirements
+ .change=${this.change}
+ inHovercard
+ ></gr-submit-requirements>
+ </div>`;
+ }
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ 'gr-submit-requirement-dashboard-hovercard': GrSubmitRequirementDashboardHovercard;
+ }
+}
diff --git a/polygerrit-ui/app/elements/change/gr-submit-requirements/gr-submit-requirements.ts b/polygerrit-ui/app/elements/change/gr-submit-requirements/gr-submit-requirements.ts
index e8859fd..f9d5803 100644
--- a/polygerrit-ui/app/elements/change/gr-submit-requirements/gr-submit-requirements.ts
+++ b/polygerrit-ui/app/elements/change/gr-submit-requirements/gr-submit-requirements.ts
@@ -67,6 +67,9 @@
return [
fontStyles,
css`
+ :host([inHovercard]) .metadata-title {
+ display: none;
+ }
.metadata-title {
color: var(--deemphasized-text-color);
padding-left: var(--metadata-horizontal-padding);
@@ -108,6 +111,7 @@
}
td {
padding: var(--spacing-s);
+ white-space: nowrap;
}
.votes-cell {
display: flex;
diff --git a/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search.ts b/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search.ts
index 3adb0f3..173a27e 100644
--- a/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search.ts
+++ b/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search.ts
@@ -14,28 +14,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import '../../../styles/gr-table-styles';
-import '../../../styles/shared-styles';
import '../../shared/gr-list-view/gr-list-view';
-import {PolymerElement} from '@polymer/polymer/polymer-element';
-import {htmlTemplate} from './gr-documentation-search_html';
import {getBaseUrl} from '../../../utils/url-util';
-import {customElement, property} from '@polymer/decorators';
import {DocResult} from '../../../types/common';
import {fireTitleChange} from '../../../utils/event-util';
import {appContext} from '../../../services/app-context';
import {ListViewParams} from '../../gr-app-types';
+import {sharedStyles} from '../../../styles/shared-styles';
+import {tableStyles} from '../../../styles/gr-table-styles';
+import {LitElement, PropertyValues, html} from 'lit';
+import {customElement, property} from 'lit/decorators';
@customElement('gr-documentation-search')
-export class GrDocumentationSearch extends PolymerElement {
- static get template() {
- return htmlTemplate;
- }
-
+export class GrDocumentationSearch extends LitElement {
/**
* URL params passed from the router.
*/
- @property({type: Object, observer: '_paramsChanged'})
+ @property({type: Object})
params?: ListViewParams;
@property({type: Array})
@@ -54,7 +49,57 @@
fireTitleChange(this, 'Documentation Search');
}
- _paramsChanged(params: ListViewParams) {
+ static override get styles() {
+ return [sharedStyles, tableStyles];
+ }
+
+ override render() {
+ return html` <gr-list-view
+ .filter="${this._filter}"
+ .offset="${0}"
+ .loading="${this._loading}"
+ .path="/Documentation"
+ >
+ <table id="list" class="genericList">
+ <tbody>
+ <tr class="headerRow">
+ <th class="name topHeader">Name</th>
+ <th class="name topHeader"></th>
+ <th class="name topHeader"></th>
+ </tr>
+ <tr
+ id="loading"
+ class="loadingMsg ${this.computeLoadingClass(this._loading)}"
+ >
+ <td>Loading...</td>
+ </tr>
+ </tbody>
+ <tbody class="${this.computeLoadingClass(this._loading)}">
+ ${this._documentationSearches?.map(
+ search => html`
+ <tr class="table">
+ <td class="name">
+ <a href="${this._computeSearchUrl(search.url)}"
+ >${search.title}</a
+ >
+ </td>
+ <td></td>
+ <td></td>
+ </tr>
+ `
+ )}
+ </tbody>
+ </table>
+ </gr-list-view>`;
+ }
+
+ override updated(changedProperties: PropertyValues) {
+ if (changedProperties.has('params')) {
+ this._paramsChanged(this.params);
+ }
+ }
+
+ _paramsChanged(params?: ListViewParams) {
this._loading = true;
this._filter = params?.filter ?? '';
diff --git a/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search_html.ts b/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search_html.ts
deleted file mode 100644
index 95ce1ec..0000000
--- a/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search_html.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * @license
- * Copyright (C) 2020 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.
- */
-import {html} from '@polymer/polymer/lib/utils/html-tag';
-
-export const htmlTemplate = html`
- <style include="shared-styles">
- /* Workaround for empty style block - see https://github.com/Polymer/tools/issues/408 */
- </style>
- <style include="gr-table-styles">
- /* Workaround for empty style block - see https://github.com/Polymer/tools/issues/408 */
- </style>
- <gr-list-view
- filter="[[_filter]]"
- offset="0"
- loading="[[_loading]]"
- path="/Documentation"
- >
- <table id="list" class="genericList">
- <tbody>
- <tr class="headerRow">
- <th class="name topHeader">Name</th>
- <th class="name topHeader"></th>
- <th class="name topHeader"></th>
- </tr>
- <tr id="loading" class$="loadingMsg [[computeLoadingClass(_loading)]]">
- <td>Loading...</td>
- </tr>
- </tbody>
- <tbody class$="[[computeLoadingClass(_loading)]]">
- <template is="dom-repeat" items="[[_documentationSearches]]">
- <tr class="table">
- <td class="name">
- <a href$="[[_computeSearchUrl(item.url)]]">[[item.title]]</a>
- </td>
- <td></td>
- <td></td>
- </tr>
- </template>
- </tbody>
- </table>
- </gr-list-view>
-`;
diff --git a/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search_test.ts b/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search_test.ts
index bf6a0d5..47c83da 100644
--- a/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search_test.ts
+++ b/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search_test.ts
@@ -20,7 +20,7 @@
import {GrDocumentationSearch} from './gr-documentation-search';
import {page} from '../../../utils/page-wrapper-utils';
import 'lodash/lodash';
-import {stubRestApi} from '../../../test/test-utils';
+import {queryAndAssert, stubRestApi} from '../../../test/test-utils';
import {DocResult} from '../../../types/common';
import {ListViewParams} from '../../gr-app-types';
@@ -40,10 +40,11 @@
let value: ListViewParams;
- setup(() => {
+ setup(async () => {
sinon.stub(page, 'show');
element = basicFixture.instantiate();
counter = 0;
+ await flush();
});
suite('list with searches for documentation', () => {
@@ -87,13 +88,19 @@
test('correct contents are displayed', async () => {
assert.isTrue(element._loading);
assert.equal(element.computeLoadingClass(element._loading), 'loading');
- assert.equal(getComputedStyle(element.$.loading).display, 'block');
+ assert.equal(
+ getComputedStyle(queryAndAssert(element, '#loading')).display,
+ 'block'
+ );
element._loading = false;
await flush();
assert.equal(element.computeLoadingClass(element._loading), '');
- assert.equal(getComputedStyle(element.$.loading).display, 'none');
+ assert.equal(
+ getComputedStyle(queryAndAssert(element, '#loading')).display,
+ 'none'
+ );
});
});
});
diff --git a/polygerrit-ui/app/services/shortcuts/shortcuts-service.ts b/polygerrit-ui/app/services/shortcuts/shortcuts-service.ts
index 19f12c5..a26fa08 100644
--- a/polygerrit-ui/app/services/shortcuts/shortcuts-service.ts
+++ b/polygerrit-ui/app/services/shortcuts/shortcuts-service.ts
@@ -28,6 +28,7 @@
Key,
Modifier,
Binding,
+ shouldSuppress,
} from '../../utils/dom-util';
import {ReportingService} from '../gr-reporting/gr-reporting';
@@ -154,34 +155,8 @@
shouldSuppress(e: KeyboardEvent) {
if (this.shortcutsDisabled) return true;
+ if (shouldSuppress(e)) return true;
- // Note that when you listen on document, then `e.currentTarget` will be the
- // document and `e.target` will be `<gr-app>` due to shadow dom, but by
- // using the composedPath() you can actually find the true origin of the
- // event.
- const rootTarget = e.composedPath()[0];
- if (!isElementTarget(rootTarget)) return false;
- const tagName = rootTarget.tagName;
- const type = rootTarget.getAttribute('type');
-
- if (
- // Suppress shortcuts on <input> and <textarea>, but not on
- // checkboxes, because we want to enable workflows like 'click
- // mark-reviewed and then press ] to go to the next file'.
- (tagName === 'INPUT' && type !== 'checkbox') ||
- tagName === 'TEXTAREA' ||
- // Suppress shortcuts if the key is 'enter'
- // and target is an anchor or button or paper-tab.
- (e.keyCode === 13 &&
- (tagName === 'A' || tagName === 'BUTTON' || tagName === 'PAPER-TAB'))
- ) {
- return true;
- }
- const path: EventTarget[] = e.composedPath() ?? [];
- for (const el of path) {
- if (!isElementTarget(el)) continue;
- if (el.tagName === 'GR-OVERLAY') return true;
- }
// eg: {key: "k:keydown", ..., from: "gr-diff-view"}
let key = `${e.key}:${e.type}`;
if (this.isInSpecificComboKeyMode(ComboKey.G)) key = 'g+' + key;
diff --git a/polygerrit-ui/app/utils/dom-util.ts b/polygerrit-ui/app/utils/dom-util.ts
index b6dece0..e2fa8fe 100644
--- a/polygerrit-ui/app/utils/dom-util.ts
+++ b/polygerrit-ui/app/utils/dom-util.ts
@@ -398,10 +398,16 @@
export function addShortcut(
element: HTMLElement,
shortcut: Binding,
- listener: (e: KeyboardEvent) => void
+ listener: (e: KeyboardEvent) => void,
+ options: {
+ shouldSuppress: boolean;
+ } = {
+ shouldSuppress: false,
+ }
) {
const wrappedListener = (e: KeyboardEvent) => {
if (e.repeat) return;
+ if (options.shouldSuppress && shouldSuppress(e)) return;
if (eventMatchesShortcut(e, shortcut)) {
listener(e);
}
@@ -417,3 +423,43 @@
export function shiftPressed(e: KeyboardEvent) {
return e.shiftKey;
}
+
+/**
+ * When you listen on keyboard events, then within Gerrit's web app you may want
+ * to avoid firing in certain common scenarios such as key strokes from <input>
+ * elements. But this can also be undesirable, for example Ctrl-Enter from
+ * <input> should trigger a save event.
+ *
+ * The shortcuts-service has a stateful method `shouldSuppress()` with
+ * reporting functionality, which delegates to here.
+ */
+export function shouldSuppress(e: KeyboardEvent): boolean {
+ // Note that when you listen on document, then `e.currentTarget` will be the
+ // document and `e.target` will be `<gr-app>` due to shadow dom, but by
+ // using the composedPath() you can actually find the true origin of the
+ // event.
+ const rootTarget = e.composedPath()[0];
+ if (!isElementTarget(rootTarget)) return false;
+ const tagName = rootTarget.tagName;
+ const type = rootTarget.getAttribute('type');
+
+ if (
+ // Suppress shortcuts on <input> and <textarea>, but not on
+ // checkboxes, because we want to enable workflows like 'click
+ // mark-reviewed and then press ] to go to the next file'.
+ (tagName === 'INPUT' && type !== 'checkbox') ||
+ tagName === 'TEXTAREA' ||
+ // Suppress shortcuts if the key is 'enter'
+ // and target is an anchor or button or paper-tab.
+ (e.keyCode === 13 &&
+ (tagName === 'A' || tagName === 'BUTTON' || tagName === 'PAPER-TAB'))
+ ) {
+ return true;
+ }
+ const path: EventTarget[] = e.composedPath() ?? [];
+ for (const el of path) {
+ if (!isElementTarget(el)) continue;
+ if (el.tagName === 'GR-OVERLAY') return true;
+ }
+ return false;
+}
diff --git a/polygerrit-ui/app/utils/dom-util_test.ts b/polygerrit-ui/app/utils/dom-util_test.ts
index 2993c0e..9dd5be2 100644
--- a/polygerrit-ui/app/utils/dom-util_test.ts
+++ b/polygerrit-ui/app/utils/dom-util_test.ts
@@ -22,6 +22,7 @@
getEventPath,
Modifier,
querySelectorAll,
+ shouldSuppress,
strToClassName,
} from './dom-util';
import {PolymerElement} from '@polymer/polymer/polymer-element';
@@ -29,6 +30,22 @@
import * as MockInteractions from '@polymer/iron-test-helpers/mock-interactions';
import {queryAndAssert} from '../test/test-utils';
+async function keyEventOn(
+ el: HTMLElement,
+ callback: (e: KeyboardEvent) => void,
+ keyCode = 75,
+ key = 'k'
+): Promise<KeyboardEvent> {
+ let resolve: (e: KeyboardEvent) => void;
+ const promise = new Promise<KeyboardEvent>(r => (resolve = r));
+ el.addEventListener('keydown', (e: KeyboardEvent) => {
+ callback(e);
+ resolve(e);
+ });
+ MockInteractions.keyDownOn(el, keyCode, null, key);
+ return await promise;
+}
+
class TestEle extends PolymerElement {
static get is() {
return 'dom-util-test-element';
@@ -266,4 +283,53 @@
assert.isTrue(eventMatchesShortcut(e, sShift));
});
});
+
+ suite('shouldSuppress', () => {
+ test('do not suppress shortcut event from <div>', async () => {
+ await keyEventOn(document.createElement('div'), e => {
+ assert.isFalse(shouldSuppress(e));
+ });
+ });
+
+ test('suppress shortcut event from <input>', async () => {
+ await keyEventOn(document.createElement('input'), e => {
+ assert.isTrue(shouldSuppress(e));
+ });
+ });
+
+ test('suppress shortcut event from <textarea>', async () => {
+ await keyEventOn(document.createElement('textarea'), e => {
+ assert.isTrue(shouldSuppress(e));
+ });
+ });
+
+ test('do not suppress shortcut event from checkbox <input>', async () => {
+ const inputEl = document.createElement('input');
+ inputEl.setAttribute('type', 'checkbox');
+ await keyEventOn(inputEl, e => {
+ assert.isFalse(shouldSuppress(e));
+ });
+ });
+
+ test('suppress shortcut event from children of <gr-overlay>', async () => {
+ const overlay = document.createElement('gr-overlay');
+ const div = document.createElement('div');
+ overlay.appendChild(div);
+ await keyEventOn(div, e => {
+ assert.isTrue(shouldSuppress(e));
+ });
+ });
+
+ test('suppress "enter" shortcut event from <a>', async () => {
+ await keyEventOn(document.createElement('a'), e => {
+ assert.isFalse(shouldSuppress(e));
+ });
+ await keyEventOn(
+ document.createElement('a'),
+ e => assert.isTrue(shouldSuppress(e)),
+ 13,
+ 'enter'
+ );
+ });
+ });
});