Merge "Fix template problems with gr-change-status"
diff --git a/java/com/google/gerrit/entities/LabelTypes.java b/java/com/google/gerrit/entities/LabelTypes.java
index 1c38c59..55a9976 100644
--- a/java/com/google/gerrit/entities/LabelTypes.java
+++ b/java/com/google/gerrit/entities/LabelTypes.java
@@ -20,6 +20,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
public class LabelTypes {
protected List<LabelType> labelTypes;
@@ -36,12 +37,12 @@
return labelTypes;
}
- public LabelType byLabel(LabelId labelId) {
- return byLabel().get(labelId.get().toLowerCase());
+ public Optional<LabelType> byLabel(LabelId labelId) {
+ return Optional.ofNullable(byLabel().get(labelId.get().toLowerCase()));
}
- public LabelType byLabel(String labelName) {
- return byLabel().get(labelName.toLowerCase());
+ public Optional<LabelType> byLabel(String labelName) {
+ return Optional.ofNullable(byLabel().get(labelName.toLowerCase()));
}
private Map<String, LabelType> byLabel() {
diff --git a/java/com/google/gerrit/server/PatchSetUtil.java b/java/com/google/gerrit/server/PatchSetUtil.java
index d60bc8f..326ddf4 100644
--- a/java/com/google/gerrit/server/PatchSetUtil.java
+++ b/java/com/google/gerrit/server/PatchSetUtil.java
@@ -151,8 +151,10 @@
ApprovalsUtil approvalsUtil = approvalsUtilProvider.get();
for (PatchSetApproval ap : approvalsUtil.byPatchSet(notes, change.currentPatchSetId())) {
- LabelType type = projectState.getLabelTypes(notes).byLabel(ap.label());
- if (type != null && ap.value() == 1 && type.getFunction() == LabelFunction.PATCH_SET_LOCK) {
+ Optional<LabelType> type = projectState.getLabelTypes(notes).byLabel(ap.label());
+ if (type.isPresent()
+ && ap.value() == 1
+ && type.get().getFunction() == LabelFunction.PATCH_SET_LOCK) {
return true;
}
}
diff --git a/java/com/google/gerrit/server/approval/ApprovalInference.java b/java/com/google/gerrit/server/approval/ApprovalInference.java
index 1efbd37..8d409e5 100644
--- a/java/com/google/gerrit/server/approval/ApprovalInference.java
+++ b/java/com/google/gerrit/server/approval/ApprovalInference.java
@@ -52,6 +52,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
+import java.util.Optional;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.revwalk.RevWalk;
@@ -397,14 +398,14 @@
if (resultByUser.contains(psa.label(), psa.accountId())) {
continue;
}
- LabelType type = labelTypes.byLabel(psa.labelId());
+ Optional<LabelType> type = labelTypes.byLabel(psa.labelId());
// Only compute modified files if there is a relevant label, since this is expensive.
if (modifiedFiles == null
- && type != null
- && type.isCopyAllScoresIfListOfFilesDidNotChange()) {
+ && type.isPresent()
+ && type.get().isCopyAllScoresIfListOfFilesDidNotChange()) {
modifiedFiles = listModifiedFiles(project, ps, priorPatchSet);
}
- if (type == null) {
+ if (!type.isPresent()) {
logger.atFine().log(
"approval %d on label %s of patch set %d of change %d cannot be copied"
+ " to patch set %d because the label no longer exists on project %s",
@@ -416,8 +417,8 @@
project.getName());
continue;
}
- if (!canCopyBasedOnBooleanLabelConfigs(project, psa, ps.id(), kind, type, modifiedFiles)
- && !canCopyBasedOnCopyCondition(notes, psa, ps.id(), type, kind)) {
+ if (!canCopyBasedOnBooleanLabelConfigs(project, psa, ps.id(), kind, type.get(), modifiedFiles)
+ && !canCopyBasedOnCopyCondition(notes, psa, ps.id(), type.get(), kind)) {
continue;
}
resultByUser.put(psa.label(), psa.accountId(), psa.copyWithPatchSet(ps.id()));
diff --git a/java/com/google/gerrit/server/approval/ApprovalsUtil.java b/java/com/google/gerrit/server/approval/ApprovalsUtil.java
index b1e85e9..a1cdd99 100644
--- a/java/com/google/gerrit/server/approval/ApprovalsUtil.java
+++ b/java/com/google/gerrit/server/approval/ApprovalsUtil.java
@@ -61,6 +61,7 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.Set;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.revwalk.RevWalk;
@@ -299,8 +300,12 @@
List<PatchSetApproval> cells = new ArrayList<>(approvals.size());
Date ts = update.getWhen();
for (Map.Entry<String, Short> vote : approvals.entrySet()) {
- LabelType lt = labelTypes.byLabel(vote.getKey());
- cells.add(newApproval(ps.id(), user, lt.getLabelId(), vote.getValue(), ts).build());
+ Optional<LabelType> lt = labelTypes.byLabel(vote.getKey());
+ if (!lt.isPresent()) {
+ throw new BadRequestException(
+ String.format("label \"%s\" is not a configured label", vote.getKey()));
+ }
+ cells.add(newApproval(ps.id(), user, lt.get().getLabelId(), vote.getValue(), ts).build());
}
for (PatchSetApproval psa : cells) {
update.putApproval(psa.label(), psa.value());
@@ -310,11 +315,11 @@
public static void checkLabel(LabelTypes labelTypes, String name, Short value)
throws BadRequestException {
- LabelType label = labelTypes.byLabel(name);
- if (label == null) {
+ Optional<LabelType> label = labelTypes.byLabel(name);
+ if (!label.isPresent()) {
throw new BadRequestException(String.format("label \"%s\" is not a configured label", name));
}
- if (label.getValue(value) == null) {
+ if (label.get().getValue(value) == null) {
throw new BadRequestException(
String.format("label \"%s\": %d is not a valid value", name, value));
}
diff --git a/java/com/google/gerrit/server/change/LabelNormalizer.java b/java/com/google/gerrit/server/change/LabelNormalizer.java
index 30343d4..b5527d7 100644
--- a/java/com/google/gerrit/server/change/LabelNormalizer.java
+++ b/java/com/google/gerrit/server/change/LabelNormalizer.java
@@ -33,6 +33,7 @@
import com.google.inject.Singleton;
import java.util.Collection;
import java.util.List;
+import java.util.Optional;
/**
* Normalizes votes on labels according to project config.
@@ -101,12 +102,12 @@
unchanged.add(psa);
continue;
}
- LabelType label = labelTypes.byLabel(psa.labelId());
- if (label == null) {
+ Optional<LabelType> label = labelTypes.byLabel(psa.labelId());
+ if (!label.isPresent()) {
deleted.add(psa);
continue;
}
- PatchSetApproval copy = applyTypeFloor(label, psa);
+ PatchSetApproval copy = applyTypeFloor(label.get(), psa);
if (copy.value() != psa.value()) {
updated.add(copy);
} else {
diff --git a/java/com/google/gerrit/server/change/LabelsJson.java b/java/com/google/gerrit/server/change/LabelsJson.java
index acff03c..5ce121b 100644
--- a/java/com/google/gerrit/server/change/LabelsJson.java
+++ b/java/com/google/gerrit/server/change/LabelsJson.java
@@ -57,6 +57,7 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.TreeMap;
@@ -103,9 +104,9 @@
for (SubmitRecord rec : submitRecords(cd)) {
if (rec.labels != null) {
for (SubmitRecord.Label r : rec.labels) {
- LabelType type = labelTypes.byLabel(r.label);
- if (type != null && (!isMerged || type.isAllowPostSubmit())) {
- toCheck.put(type.getName(), type);
+ Optional<LabelType> type = labelTypes.byLabel(r.label);
+ if (type.isPresent() && (!isMerged || type.get().isAllowPostSubmit())) {
+ toCheck.put(type.get().getName(), type.get());
}
}
}
@@ -120,18 +121,18 @@
continue;
}
for (SubmitRecord.Label r : rec.labels) {
- LabelType type = labelTypes.byLabel(r.label);
- if (type == null || (isMerged && !type.isAllowPostSubmit())) {
+ Optional<LabelType> type = labelTypes.byLabel(r.label);
+ if (!type.isPresent() || (isMerged && !type.get().isAllowPostSubmit())) {
continue;
}
- for (LabelValue v : type.getValues()) {
- boolean ok = can.contains(new LabelPermission.WithValue(type, v));
+ for (LabelValue v : type.get().getValues()) {
+ boolean ok = can.contains(new LabelPermission.WithValue(type.get(), v));
if (isMerged) {
if (labels == null) {
labels = currentLabels(filterApprovalsBy, cd);
}
- short prev = labels.getOrDefault(type.getName(), (short) 0);
+ short prev = labels.getOrDefault(type.get().getName(), (short) 0);
ok &= v.getValue() >= prev;
}
if (ok) {
@@ -176,21 +177,21 @@
setAllApprovals(accountLoader, cd, labels);
}
for (Map.Entry<String, LabelWithStatus> e : labels.entrySet()) {
- LabelType type = labelTypes.byLabel(e.getKey());
- if (type == null) {
+ Optional<LabelType> type = labelTypes.byLabel(e.getKey());
+ if (!type.isPresent()) {
continue;
}
if (standard) {
for (PatchSetApproval psa : cd.currentApprovals()) {
- if (type.matches(psa)) {
+ if (type.get().matches(psa)) {
short val = psa.value();
Account.Id accountId = psa.accountId();
- setLabelScores(accountLoader, type, e.getValue(), val, accountId);
+ setLabelScores(accountLoader, type.get(), e.getValue(), val, accountId);
}
}
}
if (detailed) {
- setLabelValues(type, e.getValue());
+ setLabelValues(type.get(), e.getValue());
}
}
return labels;
@@ -261,9 +262,9 @@
MultimapBuilder.hashKeys().hashSetValues().build();
for (PatchSetApproval a : cd.currentApprovals()) {
allUsers.add(a.accountId());
- LabelType type = labelTypes.byLabel(a.labelId());
- if (type != null) {
- labelNames.add(type.getName());
+ Optional<LabelType> type = labelTypes.byLabel(a.labelId());
+ if (type.isPresent()) {
+ labelNames.add(type.get().getName());
// Not worth the effort to distinguish between votable/non-votable for 0
// values on closed changes, since they can't vote anyway.
current.put(a.accountId(), a);
@@ -292,8 +293,8 @@
if (detailed) {
labels.entrySet().stream()
- .filter(e -> labelTypes.byLabel(e.getKey()) != null)
- .forEach(e -> setLabelValues(labelTypes.byLabel(e.getKey()), e.getValue()));
+ .filter(e -> labelTypes.byLabel(e.getKey()).isPresent())
+ .forEach(e -> setLabelValues(labelTypes.byLabel(e.getKey()).get(), e.getValue()));
}
for (Account.Id accountId : allUsers) {
@@ -308,16 +309,16 @@
}
}
for (PatchSetApproval psa : current.get(accountId)) {
- LabelType type = labelTypes.byLabel(psa.labelId());
- if (type == null) {
+ Optional<LabelType> type = labelTypes.byLabel(psa.labelId());
+ if (!type.isPresent()) {
continue;
}
short val = psa.value();
- ApprovalInfo info = byLabel.get(type.getName());
+ ApprovalInfo info = byLabel.get(type.get().getName());
if (info != null) {
info.value = Integer.valueOf(val);
- info.permittedVotingRange = pvr.getOrDefault(type.getName(), null);
+ info.permittedVotingRange = pvr.getOrDefault(type.get().getName(), null);
info.date = psa.granted();
info.tag = psa.tag().orElse(null);
if (psa.postSubmit()) {
@@ -328,7 +329,7 @@
continue;
}
- setLabelScores(accountLoader, type, labels.get(type.getName()), val, accountId);
+ setLabelScores(accountLoader, type.get(), labels.get(type.get().getName()), val, accountId);
}
}
return labels;
@@ -428,24 +429,24 @@
PermissionBackend.ForChange perm = permissionBackend.absentUser(accountId).change(cd);
Map<String, VotingRangeInfo> pvr = getPermittedVotingRanges(permittedLabels(accountId, cd));
for (Map.Entry<String, LabelWithStatus> e : labels.entrySet()) {
- LabelType lt = labelTypes.byLabel(e.getKey());
- if (lt == null) {
+ Optional<LabelType> lt = labelTypes.byLabel(e.getKey());
+ if (!lt.isPresent()) {
// Ignore submit record for undefined label; likely the submit rule
// author didn't intend for the label to show up in the table.
continue;
}
Integer value;
- VotingRangeInfo permittedVotingRange = pvr.getOrDefault(lt.getName(), null);
+ VotingRangeInfo permittedVotingRange = pvr.getOrDefault(lt.get().getName(), null);
String tag = null;
Timestamp date = null;
- PatchSetApproval psa = current.get(accountId, lt.getName());
+ PatchSetApproval psa = current.get(accountId, lt.get().getName());
if (psa != null) {
value = Integer.valueOf(psa.value());
if (value == 0) {
// This may be a dummy approval that was inserted when the reviewer
// was added. Explicitly check whether the user can vote on this
// label.
- value = perm.test(new LabelPermission(lt)) ? 0 : null;
+ value = perm.test(new LabelPermission(lt.get())) ? 0 : null;
}
tag = psa.tag().orElse(null);
date = psa.granted();
@@ -456,7 +457,7 @@
// Either the user cannot vote on this label, or they were added as a
// reviewer but have not responded yet. Explicitly check whether the
// user can vote on this label.
- value = perm.test(new LabelPermission(lt)) ? 0 : null;
+ value = perm.test(new LabelPermission(lt.get())) ? 0 : null;
}
addApproval(
e.getValue().label(),
diff --git a/java/com/google/gerrit/server/change/ReviewerJson.java b/java/com/google/gerrit/server/change/ReviewerJson.java
index d5b74a8..6189708 100644
--- a/java/com/google/gerrit/server/change/ReviewerJson.java
+++ b/java/com/google/gerrit/server/change/ReviewerJson.java
@@ -38,6 +38,7 @@
import com.google.inject.Singleton;
import java.util.Collection;
import java.util.List;
+import java.util.Optional;
import java.util.TreeMap;
@Singleton
@@ -107,10 +108,8 @@
out.approvals = new TreeMap<>(labelTypes.nameComparator());
for (PatchSetApproval ca : approvals) {
- LabelType at = labelTypes.byLabel(ca.labelId());
- if (at != null) {
- out.approvals.put(at.getName(), formatValue(ca.value()));
- }
+ Optional<LabelType> at = labelTypes.byLabel(ca.labelId());
+ at.ifPresent(lt -> out.approvals.put(lt.getName(), formatValue(ca.value())));
}
// Add dummy approvals for all permitted labels for the user even if they
@@ -125,13 +124,13 @@
}
for (SubmitRecord.Label label : rec.labels) {
String name = label.label;
- LabelType type = labelTypes.byLabel(name);
- if (out.approvals.containsKey(name) || type == null) {
+ Optional<LabelType> type = labelTypes.byLabel(name);
+ if (out.approvals.containsKey(name) || !type.isPresent()) {
continue;
}
try {
- perm.check(new LabelPermission(type));
+ perm.check(new LabelPermission(type.get()));
out.approvals.put(name, formatValue((short) 0));
} catch (AuthException e) {
// Do nothing.
diff --git a/java/com/google/gerrit/server/events/EventFactory.java b/java/com/google/gerrit/server/events/EventFactory.java
index 3f988a3..1bb694a 100644
--- a/java/com/google/gerrit/server/events/EventFactory.java
+++ b/java/com/google/gerrit/server/events/EventFactory.java
@@ -71,6 +71,7 @@
import java.util.Collection;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
@@ -535,10 +536,8 @@
a.grantedOn = approval.granted().getTime() / 1000L;
a.oldValue = null;
- LabelType lt = labelTypes.byLabel(approval.labelId());
- if (lt != null) {
- a.description = lt.getName();
- }
+ Optional<LabelType> lt = labelTypes.byLabel(approval.labelId());
+ lt.ifPresent(l -> a.description = l.getName());
return a;
}
diff --git a/java/com/google/gerrit/server/events/StreamEventsApiListener.java b/java/com/google/gerrit/server/events/StreamEventsApiListener.java
index 439f53e..edd1928 100644
--- a/java/com/google/gerrit/server/events/StreamEventsApiListener.java
+++ b/java/com/google/gerrit/server/events/StreamEventsApiListener.java
@@ -23,7 +23,6 @@
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.entities.Change;
-import com.google.gerrit.entities.LabelType;
import com.google.gerrit.entities.LabelTypes;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.Project;
@@ -202,10 +201,7 @@
a.oldValue = Short.toString(oldApprovals.get(approval.getKey()));
}
}
- LabelType lt = labelTypes.byLabel(approval.getKey());
- if (lt != null) {
- a.description = lt.getName();
- }
+ labelTypes.byLabel(approval.getKey()).ifPresent(lt -> a.description = lt.getName());
if (approval.getValue() != null) {
a.value = Short.toString(approval.getValue());
}
diff --git a/java/com/google/gerrit/server/git/MergeUtil.java b/java/com/google/gerrit/server/git/MergeUtil.java
index 1da14f8..a5ea24d 100644
--- a/java/com/google/gerrit/server/git/MergeUtil.java
+++ b/java/com/google/gerrit/server/git/MergeUtil.java
@@ -600,11 +600,11 @@
} else if (isVerified(a.labelId())) {
tag = "Tested-by";
} else {
- final LabelType lt = project.getLabelTypes().byLabel(a.labelId());
- if (lt == null) {
+ final Optional<LabelType> lt = project.getLabelTypes().byLabel(a.labelId());
+ if (!lt.isPresent()) {
continue;
}
- tag = lt.getName();
+ tag = lt.get().getName();
}
if (!contains(footers, new FooterKey(tag), identbuf.toString())) {
diff --git a/java/com/google/gerrit/server/git/receive/ReplaceOp.java b/java/com/google/gerrit/server/git/receive/ReplaceOp.java
index f00b48eb..b2a31b9 100644
--- a/java/com/google/gerrit/server/git/receive/ReplaceOp.java
+++ b/java/com/google/gerrit/server/git/receive/ReplaceOp.java
@@ -465,10 +465,10 @@
continue;
}
- LabelType lt = projectState.getLabelTypes().byLabel(a.labelId());
- if (lt != null) {
- current.put(lt.getName(), a);
- }
+ projectState
+ .getLabelTypes()
+ .byLabel(a.labelId())
+ .ifPresent(l -> current.put(l.getName(), a));
}
}
return current;
diff --git a/java/com/google/gerrit/server/index/change/ChangeField.java b/java/com/google/gerrit/server/index/change/ChangeField.java
index 810cd4d..1ee12fe 100644
--- a/java/com/google/gerrit/server/index/change/ChangeField.java
+++ b/java/com/google/gerrit/server/index/change/ChangeField.java
@@ -605,7 +605,7 @@
for (PatchSetApproval a : cd.currentApprovals()) {
if (a.value() != 0 && !a.isLegacySubmit()) {
allApprovals.add(formatLabel(a.label(), a.value(), a.accountId()));
- LabelType labelType = cd.getLabelTypes().byLabel(a.labelId());
+ Optional<LabelType> labelType = cd.getLabelTypes().byLabel(a.labelId());
allApprovals.addAll(getMaxMinAnyLabels(a.label(), a.value(), labelType, a.accountId()));
if (owners && cd.change().getOwner().equals(a.accountId())) {
allApprovals.add(formatLabel(a.label(), a.value(), ChangeQueryBuilder.OWNER_ACCOUNT_ID));
@@ -622,13 +622,15 @@
}
private static List<String> getMaxMinAnyLabels(
- String label, short labelVal, LabelType labelType, @Nullable Account.Id accountId) {
+ String label, short labelVal, Optional<LabelType> labelType, @Nullable Account.Id accountId) {
List<String> labels = new ArrayList<>();
- if (labelVal == labelType.getMaxPositive()) {
- labels.add(formatLabel(label, MagicLabelValue.MAX.name(), accountId));
- }
- if (labelVal == labelType.getMaxNegative()) {
- labels.add(formatLabel(label, MagicLabelValue.MIN.name(), accountId));
+ if (labelType.isPresent()) {
+ if (labelVal == labelType.get().getMaxPositive()) {
+ labels.add(formatLabel(label, MagicLabelValue.MAX.name(), accountId));
+ }
+ if (labelVal == labelType.get().getMaxNegative()) {
+ labels.add(formatLabel(label, MagicLabelValue.MIN.name(), accountId));
+ }
}
labels.add(formatLabel(label, MagicLabelValue.ANY.name(), accountId));
return labels;
diff --git a/java/com/google/gerrit/server/mail/send/MergedSender.java b/java/com/google/gerrit/server/mail/send/MergedSender.java
index 6af2345..56528df 100644
--- a/java/com/google/gerrit/server/mail/send/MergedSender.java
+++ b/java/com/google/gerrit/server/mail/send/MergedSender.java
@@ -79,14 +79,14 @@
Table<Account.Id, String, PatchSetApproval> pos = HashBasedTable.create();
Table<Account.Id, String, PatchSetApproval> neg = HashBasedTable.create();
for (PatchSetApproval ca : args.approvalsUtil.byPatchSet(changeData.notes(), patchSet.id())) {
- LabelType lt = labelTypes.byLabel(ca.labelId());
- if (lt == null) {
+ Optional<LabelType> lt = labelTypes.byLabel(ca.labelId());
+ if (!lt.isPresent()) {
continue;
}
if (ca.value() > 0) {
- pos.put(ca.accountId(), lt.getName(), ca);
+ pos.put(ca.accountId(), lt.get().getName(), ca);
} else if (ca.value() < 0) {
- neg.put(ca.accountId(), lt.getName(), ca);
+ neg.put(ca.accountId(), lt.get().getName(), ca);
}
}
diff --git a/java/com/google/gerrit/server/patch/SubmitWithStickyApprovalDiff.java b/java/com/google/gerrit/server/patch/SubmitWithStickyApprovalDiff.java
index e33b261..62cfa47 100644
--- a/java/com/google/gerrit/server/patch/SubmitWithStickyApprovalDiff.java
+++ b/java/com/google/gerrit/server/patch/SubmitWithStickyApprovalDiff.java
@@ -18,6 +18,7 @@
import com.google.gerrit.common.data.PatchScript;
import com.google.gerrit.entities.LabelId;
+import com.google.gerrit.entities.LabelType;
import com.google.gerrit.entities.Patch;
import com.google.gerrit.entities.Patch.ChangeType;
import com.google.gerrit.entities.PatchSet;
@@ -43,6 +44,7 @@
import java.io.IOException;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.stream.Collectors;
import org.eclipse.jgit.diff.Edit;
import org.eclipse.jgit.lib.Config;
@@ -242,10 +244,9 @@
if (!patchSetApproval.label().equals(LabelId.CODE_REVIEW)) {
continue;
}
- if (!projectState
- .getLabelTypes(notes)
- .byLabel(patchSetApproval.labelId())
- .isMaxPositive(patchSetApproval)) {
+ Optional<LabelType> lt =
+ projectState.getLabelTypes(notes).byLabel(patchSetApproval.labelId());
+ if (!lt.isPresent() || !lt.get().isMaxPositive(patchSetApproval)) {
continue;
}
if (patchSetApproval.patchSetId().get() > maxPatchSetId.get()) {
diff --git a/java/com/google/gerrit/server/query/approval/MagicValuePredicate.java b/java/com/google/gerrit/server/query/approval/MagicValuePredicate.java
index 2924e6e..326620d 100644
--- a/java/com/google/gerrit/server/query/approval/MagicValuePredicate.java
+++ b/java/com/google/gerrit/server/query/approval/MagicValuePredicate.java
@@ -23,6 +23,7 @@
import com.google.inject.assistedinject.Assisted;
import java.util.Collection;
import java.util.Objects;
+import java.util.Optional;
/** Predicate that matches patch set approvals we want to copy based on the value. */
public class MagicValuePredicate extends ApprovalPredicate {
@@ -47,19 +48,23 @@
@Override
public boolean match(ApprovalContext ctx) {
+ Optional<LabelType> lt =
+ getLabelType(ctx.changeNotes().getProjectName(), ctx.patchSetApproval().labelId());
short pValue;
switch (value) {
case ANY:
return true;
case MIN:
- pValue =
- getLabelType(ctx.changeNotes().getProjectName(), ctx.patchSetApproval().labelId())
- .getMaxNegative();
+ if (!lt.isPresent()) {
+ return false;
+ }
+ pValue = lt.get().getMaxNegative();
break;
case MAX:
- pValue =
- getLabelType(ctx.changeNotes().getProjectName(), ctx.patchSetApproval().labelId())
- .getMaxPositive();
+ if (!lt.isPresent()) {
+ return false;
+ }
+ pValue = lt.get().getMaxPositive();
break;
default:
throw new IllegalArgumentException("unrecognized label value: " + value);
@@ -67,7 +72,7 @@
return pValue == ctx.patchSetApproval().value();
}
- private LabelType getLabelType(Project.NameKey project, LabelId labelId) {
+ private Optional<LabelType> getLabelType(Project.NameKey project, LabelId labelId) {
return projectCache
.get(project)
.orElseThrow(() -> new IllegalStateException(project + " absent"))
diff --git a/java/com/google/gerrit/server/query/change/EqualsLabelPredicate.java b/java/com/google/gerrit/server/query/change/EqualsLabelPredicate.java
index 30d5e2f..ade615c 100644
--- a/java/com/google/gerrit/server/query/change/EqualsLabelPredicate.java
+++ b/java/com/google/gerrit/server/query/change/EqualsLabelPredicate.java
@@ -91,8 +91,8 @@
}
protected static LabelType type(LabelTypes types, String toFind) {
- if (types.byLabel(toFind) != null) {
- return types.byLabel(toFind);
+ if (types.byLabel(toFind).isPresent()) {
+ return types.byLabel(toFind).get();
}
for (LabelType lt : types.getLabelTypes()) {
diff --git a/java/com/google/gerrit/server/query/change/MagicLabelPredicate.java b/java/com/google/gerrit/server/query/change/MagicLabelPredicate.java
index e3c58e47..2c56322 100644
--- a/java/com/google/gerrit/server/query/change/MagicLabelPredicate.java
+++ b/java/com/google/gerrit/server/query/change/MagicLabelPredicate.java
@@ -87,8 +87,8 @@
}
protected static LabelType type(LabelTypes types, String toFind) {
- if (types.byLabel(toFind) != null) {
- return types.byLabel(toFind);
+ if (types.byLabel(toFind).isPresent()) {
+ return types.byLabel(toFind).get();
}
for (LabelType lt : types.getLabelTypes()) {
diff --git a/java/com/google/gerrit/server/restapi/change/DeleteVote.java b/java/com/google/gerrit/server/restapi/change/DeleteVote.java
index 84424a8..2c358d0 100644
--- a/java/com/google/gerrit/server/restapi/change/DeleteVote.java
+++ b/java/com/google/gerrit/server/restapi/change/DeleteVote.java
@@ -194,7 +194,7 @@
for (PatchSetApproval a :
approvalsUtil.byPatchSetUser(
ctx.getNotes(), psId, accountId, ctx.getRevWalk(), ctx.getRepoView().getConfig())) {
- if (labelTypes.byLabel(a.labelId()) == null) {
+ if (!labelTypes.byLabel(a.labelId()).isPresent()) {
continue; // Ignore undefined labels.
} else if (!a.label().equals(label)) {
// Populate map for non-matching labels, needed by VoteDeleted.
diff --git a/java/com/google/gerrit/server/restapi/change/Move.java b/java/com/google/gerrit/server/restapi/change/Move.java
index 9263971..8c21841 100644
--- a/java/com/google/gerrit/server/restapi/change/Move.java
+++ b/java/com/google/gerrit/server/restapi/change/Move.java
@@ -64,6 +64,7 @@
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.io.IOException;
+import java.util.Optional;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
@@ -265,11 +266,13 @@
approvalsUtil.byPatchSet(
ctx.getNotes(), psId, ctx.getRevWalk(), ctx.getRepoView().getConfig())) {
ProjectState projectState = projectCache.get(project).orElseThrow(illegalState(project));
- LabelType type = projectState.getLabelTypes(ctx.getNotes()).byLabel(psa.labelId());
+ Optional<LabelType> type =
+ projectState.getLabelTypes(ctx.getNotes()).byLabel(psa.labelId());
// Only keep veto votes, defined as votes where:
// 1- the label function allows minimum values to block submission.
// 2- the vote holds the minimum value.
- if (type == null || (type.isMaxNegative(psa) && type.getFunction().isBlock())) {
+ if (!type.isPresent()
+ || (type.get().isMaxNegative(psa) && type.get().getFunction().isBlock())) {
continue;
}
diff --git a/java/com/google/gerrit/server/restapi/change/PostReview.java b/java/com/google/gerrit/server/restapi/change/PostReview.java
index 6816361..4dbb6ee 100644
--- a/java/com/google/gerrit/server/restapi/change/PostReview.java
+++ b/java/com/google/gerrit/server/restapi/change/PostReview.java
@@ -22,7 +22,6 @@
import static com.google.gerrit.server.permissions.LabelPermission.ForUser.ON_BEHALF_OF;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static java.nio.charset.StandardCharsets.UTF_8;
-import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
@@ -502,8 +501,8 @@
Iterator<Map.Entry<String, Short>> itr = in.labels.entrySet().iterator();
while (itr.hasNext()) {
Map.Entry<String, Short> ent = itr.next();
- LabelType type = labelTypes.byLabel(ent.getKey());
- if (type == null) {
+ Optional<LabelType> type = labelTypes.byLabel(ent.getKey());
+ if (!type.isPresent()) {
logger.atFine().log("label %s not found", ent.getKey());
if (strictLabels) {
throw new BadRequestException(
@@ -518,15 +517,15 @@
logger.atFine().log(
"skipping on behalf of permission check for label %s"
+ " because caller is an internal user",
- type.getName());
+ type.get().getName());
} else {
try {
- perm.check(new LabelPermission.WithValue(ON_BEHALF_OF, type, ent.getValue()));
+ perm.check(new LabelPermission.WithValue(ON_BEHALF_OF, type.get(), ent.getValue()));
} catch (AuthException e) {
throw new AuthException(
String.format(
"not permitted to modify label \"%s\" on behalf of \"%s\"",
- type.getName(), in.onBehalfOf),
+ type.get().getName(), in.onBehalfOf),
e);
}
}
@@ -558,8 +557,8 @@
Iterator<Map.Entry<String, Short>> itr = labels.entrySet().iterator();
while (itr.hasNext()) {
Map.Entry<String, Short> ent = itr.next();
- LabelType lt = labelTypes.byLabel(ent.getKey());
- if (lt == null) {
+ Optional<LabelType> lt = labelTypes.byLabel(ent.getKey());
+ if (!lt.isPresent()) {
logger.atFine().log("label %s not found", ent.getKey());
if (strictLabels) {
throw new BadRequestException(
@@ -576,7 +575,7 @@
continue;
}
- if (lt.getValue(ent.getValue()) == null) {
+ if (lt.get().getValue(ent.getValue()) == null) {
logger.atFine().log("label value %s not found", ent.getValue());
if (strictLabels) {
throw new BadRequestException(
@@ -590,10 +589,10 @@
short val = ent.getValue();
try {
- perm.check(new LabelPermission.WithValue(lt, val));
+ perm.check(new LabelPermission.WithValue(lt.get(), val));
} catch (AuthException e) {
throw new AuthException(
- String.format("Applying label \"%s\": %d is restricted", lt.getName(), val), e);
+ String.format("Applying label \"%s\": %d is restricted", lt.get().getName(), val), e);
}
}
}
@@ -1356,7 +1355,10 @@
ChangeUpdate update = ctx.getUpdate(psId);
for (Map.Entry<String, Short> ent : allApprovals.entrySet()) {
String name = ent.getKey();
- LabelType lt = requireNonNull(labelTypes.byLabel(name), name);
+ LabelType lt =
+ labelTypes
+ .byLabel(name)
+ .orElseThrow(() -> new IllegalStateException("no label config for " + name));
PatchSetApproval c = current.remove(lt.getName());
String normName = lt.getName();
@@ -1448,7 +1450,10 @@
List<String> disallowed = new ArrayList<>(labelTypes.getLabelTypes().size());
for (PatchSetApproval psa : del) {
- LabelType lt = requireNonNull(labelTypes.byLabel(psa.label()));
+ LabelType lt =
+ labelTypes
+ .byLabel(psa.label())
+ .orElseThrow(() -> new IllegalStateException("no label config for " + psa.label()));
String normName = lt.getName();
if (!lt.isAllowPostSubmit()) {
disallowed.add(normName);
@@ -1460,7 +1465,10 @@
}
for (PatchSetApproval psa : ups) {
- LabelType lt = requireNonNull(labelTypes.byLabel(psa.label()));
+ LabelType lt =
+ labelTypes
+ .byLabel(psa.label())
+ .orElseThrow(() -> new IllegalStateException("no label config for " + psa.label()));
String normName = lt.getName();
if (!lt.isAllowPostSubmit()) {
disallowed.add(normName);
@@ -1508,9 +1516,9 @@
continue;
}
- LabelType lt = labelTypes.byLabel(a.labelId());
- if (lt != null) {
- current.put(lt.getName(), a);
+ Optional<LabelType> lt = labelTypes.byLabel(a.labelId());
+ if (lt.isPresent()) {
+ current.put(lt.get().getName(), a);
} else {
del.add(a);
}
diff --git a/java/gerrit/PRED__load_commit_labels_1.java b/java/gerrit/PRED__load_commit_labels_1.java
index 5ee292ff..9a656b8 100644
--- a/java/gerrit/PRED__load_commit_labels_1.java
+++ b/java/gerrit/PRED__load_commit_labels_1.java
@@ -16,6 +16,7 @@
import com.googlecode.prolog_cafe.lang.StructureTerm;
import com.googlecode.prolog_cafe.lang.SymbolTerm;
import com.googlecode.prolog_cafe.lang.Term;
+import java.util.Optional;
/** Exports list of {@code commit_label( label('Code-Review', 2), user(12345789) )}. */
class PRED__load_commit_labels_1 extends Predicate.P1 {
@@ -38,13 +39,14 @@
LabelTypes types = cd.getLabelTypes();
for (PatchSetApproval a : cd.currentApprovals()) {
- LabelType t = types.byLabel(a.labelId());
- if (t == null) {
+ Optional<LabelType> t = types.byLabel(a.labelId());
+ if (!t.isPresent()) {
continue;
}
StructureTerm labelTerm =
- new StructureTerm(sym_label, SymbolTerm.intern(t.getName()), new IntegerTerm(a.value()));
+ new StructureTerm(
+ sym_label, SymbolTerm.intern(t.get().getName()), new IntegerTerm(a.value()));
StructureTerm userTerm = new StructureTerm(sym_user, new IntegerTerm(a.accountId().get()));
diff --git a/javatests/com/google/gerrit/server/schema/SchemaCreatorImplTest.java b/javatests/com/google/gerrit/server/schema/SchemaCreatorImplTest.java
index fc6b412..9cba362 100644
--- a/javatests/com/google/gerrit/server/schema/SchemaCreatorImplTest.java
+++ b/javatests/com/google/gerrit/server/schema/SchemaCreatorImplTest.java
@@ -72,7 +72,7 @@
@Test
public void createSchema_Label_CodeReview() throws Exception {
- LabelType codeReview = getLabelTypes().byLabel("Code-Review");
+ LabelType codeReview = getLabelTypes().byLabel("Code-Review").get();
assertThat(codeReview).isNotNull();
assertThat(codeReview.getName()).isEqualTo("Code-Review");
assertThat(codeReview.getDefaultValue()).isEqualTo(0);
diff --git a/plugins/replication b/plugins/replication
index dc9bb2e..46cfb7d 160000
--- a/plugins/replication
+++ b/plugins/replication
@@ -1 +1 @@
-Subproject commit dc9bb2e946e4c6c31e8a4665f30eca6d00017523
+Subproject commit 46cfb7dd5b6891f991cfe66e72c08953487c1c81
diff --git a/plugins/reviewnotes b/plugins/reviewnotes
index 35e6449..a28ae59 160000
--- a/plugins/reviewnotes
+++ b/plugins/reviewnotes
@@ -1 +1 @@
-Subproject commit 35e6449a517691a880c94e7467bc07360f8e6666
+Subproject commit a28ae590486934690e4e0a95d7eb75f8b60644a6
diff --git a/plugins/webhooks b/plugins/webhooks
index 9fc9c2d..73f9dc7 160000
--- a/plugins/webhooks
+++ b/plugins/webhooks
@@ -1 +1 @@
-Subproject commit 9fc9c2d4e69f7e2701cbcd873977d3312a231a81
+Subproject commit 73f9dc72bd52f5d64853db31e711717a995f0a46
diff --git a/polygerrit-ui/app/BUILD b/polygerrit-ui/app/BUILD
index 54d92d1..4d0bb1f 100644
--- a/polygerrit-ui/app/BUILD
+++ b/polygerrit-ui/app/BUILD
@@ -109,7 +109,6 @@
"elements/checks/gr-hovercard-run_html.ts",
"elements/core/gr-main-header/gr-main-header_html.ts",
"elements/core/gr-search-bar/gr-search-bar_html.ts",
- "elements/core/gr-smart-search/gr-smart-search_html.ts",
"elements/diff/gr-apply-fix-dialog/gr-apply-fix-dialog_html.ts",
"elements/diff/gr-diff-builder/gr-diff-builder-element_html.ts",
"elements/diff/gr-diff-host/gr-diff-host_html.ts",
@@ -126,13 +125,11 @@
"elements/shared/gr-comment-thread/gr-comment-thread_html.ts",
"elements/shared/gr-comment/gr-comment_html.ts",
"elements/shared/gr-confirm-delete-comment-dialog/gr-confirm-delete-comment-dialog_html.ts",
- "elements/shared/gr-copy-clipboard/gr-copy-clipboard_html.ts",
"elements/shared/gr-dialog/gr-dialog_html.ts",
"elements/shared/gr-diff-preferences/gr-diff-preferences_html.ts",
"elements/shared/gr-download-commands/gr-download-commands_html.ts",
"elements/shared/gr-dropdown-list/gr-dropdown-list_html.ts",
"elements/shared/gr-dropdown/gr-dropdown_html.ts",
- "elements/shared/gr-editable-content/gr-editable-content_html.ts",
"elements/shared/gr-hovercard-account/gr-hovercard-account_html.ts",
"elements/shared/gr-label-info/gr-label-info_html.ts",
"elements/shared/gr-labeled-autocomplete/gr-labeled-autocomplete_html.ts",
diff --git a/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search.ts b/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search.ts
index aa7e2e0..7419713 100644
--- a/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search.ts
+++ b/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search.ts
@@ -32,6 +32,12 @@
const SELF_EXPRESSION = 'self';
const ME_EXPRESSION = 'me';
+declare global {
+ interface HTMLElementEventMap {
+ 'handle-search': CustomEvent<SearchBarHandleSearchDetail>;
+ }
+}
+
@customElement('gr-smart-search')
export class GrSmartSearch extends PolymerElement {
static get template() {
@@ -39,7 +45,7 @@
}
@property({type: String})
- searchQuery?: string;
+ searchQuery = '';
@property({type: Object})
_config?: ServerInfo;
diff --git a/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search_test.js b/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search_test.js
deleted file mode 100644
index f3a9965..0000000
--- a/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search_test.js
+++ /dev/null
@@ -1,137 +0,0 @@
-/**
- * @license
- * Copyright (C) 2016 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 '../../../test/common-test-setup-karma.js';
-import './gr-smart-search.js';
-import {stubRestApi} from '../../../test/test-utils.js';
-
-const basicFixture = fixtureFromElement('gr-smart-search');
-
-suite('gr-smart-search tests', () => {
- let element;
-
- setup(() => {
- element = basicFixture.instantiate();
- });
-
- test('Autocompletes accounts', () => {
- stubRestApi('getSuggestedAccounts').callsFake(() =>
- Promise.resolve([
- {
- name: 'fred',
- email: 'fred@goog.co',
- },
- ])
- );
- return element._fetchAccounts('owner', 'fr').then(s => {
- assert.deepEqual(s[0], {text: 'owner:fred@goog.co', label: 'fred'});
- });
- });
-
- test('Inserts self as option when valid', () => {
- stubRestApi('getSuggestedAccounts').callsFake( () =>
- Promise.resolve([
- {
- name: 'fred',
- email: 'fred@goog.co',
- },
- ])
- );
- element._fetchAccounts('owner', 's')
- .then(s => {
- assert.deepEqual(s[0], {text: 'owner:fred@goog.co', label: 'fred'});
- assert.deepEqual(s[1], {text: 'owner:self'});
- })
- .then(() => element._fetchAccounts('owner', 'selfs'))
- .then(s => {
- assert.notEqual(s[0], {text: 'owner:self'});
- });
- });
-
- test('Inserts me as option when valid', () => {
- stubRestApi('getSuggestedAccounts').callsFake( () =>
- Promise.resolve([
- {
- name: 'fred',
- email: 'fred@goog.co',
- },
- ])
- );
- return element._fetchAccounts('owner', 'm')
- .then(s => {
- assert.deepEqual(s[0], {text: 'owner:fred@goog.co', label: 'fred'});
- assert.deepEqual(s[1], {text: 'owner:me'});
- })
- .then(() => element._fetchAccounts('owner', 'meme'))
- .then(s => {
- assert.notEqual(s[0], {text: 'owner:me'});
- });
- });
-
- test('Autocompletes groups', () => {
- stubRestApi('getSuggestedGroups').callsFake( () =>
- Promise.resolve({
- Polygerrit: 0,
- gerrit: 0,
- gerrittest: 0,
- })
- );
- return element._fetchGroups('ownerin', 'pol').then(s => {
- assert.deepEqual(s[0], {text: 'ownerin:Polygerrit'});
- });
- });
-
- test('Autocompletes projects', () => {
- stubRestApi('getSuggestedProjects').callsFake( () =>
- Promise.resolve({Polygerrit: 0}));
- return element._fetchProjects('project', 'pol').then(s => {
- assert.deepEqual(s[0], {text: 'project:Polygerrit'});
- });
- });
-
- test('Autocomplete doesnt override exact matches to input', () => {
- stubRestApi('getSuggestedGroups').callsFake( () =>
- Promise.resolve({
- Polygerrit: 0,
- gerrit: 0,
- gerrittest: 0,
- })
- );
- return element._fetchGroups('ownerin', 'gerrit').then(s => {
- assert.deepEqual(s[0], {text: 'ownerin:Polygerrit'});
- assert.deepEqual(s[1], {text: 'ownerin:gerrit'});
- assert.deepEqual(s[2], {text: 'ownerin:gerrittest'});
- });
- });
-
- test('Autocompletes accounts with no email', () => {
- stubRestApi('getSuggestedAccounts').callsFake( () =>
- Promise.resolve([{name: 'fred'}]));
- return element._fetchAccounts('owner', 'fr').then(s => {
- assert.deepEqual(s[0], {text: 'owner:"fred"', label: 'fred'});
- });
- });
-
- test('Autocompletes accounts with email', () => {
- stubRestApi('getSuggestedAccounts').callsFake( () =>
- Promise.resolve([{email: 'fred@goog.co'}]));
- return element._fetchAccounts('owner', 'fr').then(s => {
- assert.deepEqual(s[0], {text: 'owner:fred@goog.co', label: ''});
- });
- });
-});
-
diff --git a/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search_test.ts b/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search_test.ts
new file mode 100644
index 0000000..0218a8f
--- /dev/null
+++ b/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search_test.ts
@@ -0,0 +1,143 @@
+/**
+ * @license
+ * Copyright (C) 2016 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 '../../../test/common-test-setup-karma';
+import './gr-smart-search';
+import {GrSmartSearch} from './gr-smart-search';
+import {stubRestApi} from '../../../test/test-utils';
+import {EmailAddress, GroupId, UrlEncodedRepoName} from '../../../types/common';
+
+const basicFixture = fixtureFromElement('gr-smart-search');
+
+suite('gr-smart-search tests', () => {
+ let element: GrSmartSearch;
+
+ setup(() => {
+ element = basicFixture.instantiate();
+ });
+
+ test('Autocompletes accounts', () => {
+ stubRestApi('getSuggestedAccounts').callsFake(() =>
+ Promise.resolve([
+ {
+ name: 'fred',
+ email: 'fred@goog.co' as EmailAddress,
+ },
+ ])
+ );
+ return element._fetchAccounts('owner', 'fr').then(s => {
+ assert.deepEqual(s[0], {text: 'owner:fred@goog.co', label: 'fred'});
+ });
+ });
+
+ test('Inserts self as option when valid', () => {
+ stubRestApi('getSuggestedAccounts').callsFake(() =>
+ Promise.resolve([
+ {
+ name: 'fred',
+ email: 'fred@goog.co' as EmailAddress,
+ },
+ ])
+ );
+ element
+ ._fetchAccounts('owner', 's')
+ .then(s => {
+ assert.deepEqual(s[0], {text: 'owner:fred@goog.co', label: 'fred'});
+ assert.deepEqual(s[1], {text: 'owner:self'});
+ })
+ .then(() => element._fetchAccounts('owner', 'selfs'))
+ .then(s => {
+ assert.notEqual(s[0], {text: 'owner:self'});
+ });
+ });
+
+ test('Inserts me as option when valid', () => {
+ stubRestApi('getSuggestedAccounts').callsFake(() =>
+ Promise.resolve([
+ {
+ name: 'fred',
+ email: 'fred@goog.co' as EmailAddress,
+ },
+ ])
+ );
+ return element
+ ._fetchAccounts('owner', 'm')
+ .then(s => {
+ assert.deepEqual(s[0], {text: 'owner:fred@goog.co', label: 'fred'});
+ assert.deepEqual(s[1], {text: 'owner:me'});
+ })
+ .then(() => element._fetchAccounts('owner', 'meme'))
+ .then(s => {
+ assert.notEqual(s[0], {text: 'owner:me'});
+ });
+ });
+
+ test('Autocompletes groups', () => {
+ stubRestApi('getSuggestedGroups').callsFake(() =>
+ Promise.resolve({
+ Polygerrit: {id: '4c97682e6ce61b7247f3381b6f1789356666de7f' as GroupId},
+ gerrit: {id: '4c97682e6ce61b7247f3381b6f1789356666de7f' as GroupId},
+ gerrittest: {id: '4c97682e6ce61b7247f3381b6f1789356666de7f' as GroupId},
+ })
+ );
+ return element._fetchGroups('ownerin', 'pol').then(s => {
+ assert.deepEqual(s[0], {text: 'ownerin:Polygerrit'});
+ });
+ });
+
+ test('Autocompletes projects', () => {
+ stubRestApi('getSuggestedProjects').callsFake(() =>
+ Promise.resolve({Polygerrit: {id: 'test' as UrlEncodedRepoName}})
+ );
+ return element._fetchProjects('project', 'pol').then(s => {
+ assert.deepEqual(s[0], {text: 'project:Polygerrit'});
+ });
+ });
+
+ test('Autocomplete doesnt override exact matches to input', () => {
+ stubRestApi('getSuggestedGroups').callsFake(() =>
+ Promise.resolve({
+ Polygerrit: {id: '4c97682e6ce61b7247f3381b6f1789356666de7f' as GroupId},
+ gerrit: {id: '4c97682e6ce61b7247f3381b6f1789356666de7f' as GroupId},
+ gerrittest: {id: '4c97682e6ce61b7247f3381b6f1789356666de7f' as GroupId},
+ })
+ );
+ return element._fetchGroups('ownerin', 'gerrit').then(s => {
+ assert.deepEqual(s[0], {text: 'ownerin:Polygerrit'});
+ assert.deepEqual(s[1], {text: 'ownerin:gerrit'});
+ assert.deepEqual(s[2], {text: 'ownerin:gerrittest'});
+ });
+ });
+
+ test('Autocompletes accounts with no email', () => {
+ stubRestApi('getSuggestedAccounts').callsFake(() =>
+ Promise.resolve([{name: 'fred'}])
+ );
+ return element._fetchAccounts('owner', 'fr').then(s => {
+ assert.deepEqual(s[0], {text: 'owner:"fred"', label: 'fred'});
+ });
+ });
+
+ test('Autocompletes accounts with email', () => {
+ stubRestApi('getSuggestedAccounts').callsFake(() =>
+ Promise.resolve([{email: 'fred@goog.co' as EmailAddress}])
+ );
+ return element._fetchAccounts('owner', 'fr').then(s => {
+ assert.deepEqual(s[0], {text: 'owner:fred@goog.co', label: ''});
+ });
+ });
+});
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.ts b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.ts
index eb50914..864fd79 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.ts
@@ -514,9 +514,7 @@
if (beforeNumber !== 'FILE' && beforeNumber !== 'LOST') {
const responsiveMode = getResponsiveMode(this._prefs, this._renderPrefs);
const lineLimit =
- responsiveMode !== 'FULL_RESPONSIVE'
- ? this._prefs.line_length
- : Infinity;
+ responsiveMode === 'NONE' ? this._prefs.line_length : Infinity;
const contentText = this._formatText(
line.text,
this._prefs.tab_size,
diff --git a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard.ts b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard.ts
index 4a2bcee..36cffb7 100644
--- a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard.ts
+++ b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard.ts
@@ -20,6 +20,7 @@
import {IronIconElement} from '@polymer/iron-icon';
import {assertIsDefined, queryAndAssert} from '../../../utils/common-util';
import {classMap} from 'lit-html/directives/class-map';
+import {ifDefined} from 'lit-html/directives/if-defined';
import {css, customElement, html, property} from 'lit-element';
import {GrLitElement} from '../../lit/gr-lit-element';
import {GrButton} from '../gr-button/gr-button';
@@ -126,7 +127,7 @@
link=""
?has-tooltip=${this.hasTooltip}
class="copyToClipboard"
- title="${this.buttonTitle}"
+ title="${ifDefined(this.buttonTitle)}"
@click="${this._copyToClipboard}"
aria-label="Click to copy to clipboard"
>
diff --git a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.js b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.ts
similarity index 73%
rename from polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.js
rename to polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.ts
index 45847d7..ef62fe9 100644
--- a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.ts
@@ -15,14 +15,16 @@
* limitations under the License.
*/
-import '../../../test/common-test-setup-karma.js';
-import './gr-copy-clipboard.js';
-import {queryAndAssert} from '../../../test/test-utils.js';
+import '../../../test/common-test-setup-karma';
+import './gr-copy-clipboard';
+import {GrCopyClipboard} from './gr-copy-clipboard';
+import {queryAndAssert} from '../../../test/test-utils';
+import * as MockInteractions from '@polymer/iron-test-helpers/mock-interactions';
const basicFixture = fixtureFromElement('gr-copy-clipboard');
suite('gr-copy-clipboard tests', () => {
- let element;
+ let element: GrCopyClipboard;
setup(async () => {
element = basicFixture.instantiate();
@@ -33,35 +35,34 @@
test('copy to clipboard', () => {
const clipboardSpy = sinon.spy(navigator.clipboard, 'writeText');
- const copyBtn = element.shadowRoot
- .querySelector('.copyToClipboard');
+ const copyBtn = queryAndAssert(element, '.copyToClipboard');
MockInteractions.click(copyBtn);
assert.isTrue(clipboardSpy.called);
});
test('focusOnCopy', () => {
element.focusOnCopy();
- const activeElement = element.shadowRoot.activeElement;
- const button = element.shadowRoot.querySelector('.copyToClipboard');
+ const activeElement = element.shadowRoot!.activeElement;
+ const button = queryAndAssert(element, '.copyToClipboard');
assert.deepEqual(activeElement, button);
});
test('_handleInputClick', () => {
// iron-input as parent should never be hidden as copy won't work
// on nested hidden elements
- const ironInputElement = element.shadowRoot.querySelector('iron-input');
+ const ironInputElement = queryAndAssert(element, 'iron-input');
assert.notEqual(getComputedStyle(ironInputElement).display, 'none');
- const inputElement = element.shadowRoot.querySelector('input');
+ const inputElement = queryAndAssert(element, 'input') as HTMLInputElement;
MockInteractions.tap(inputElement);
assert.equal(inputElement.selectionStart, 0);
- assert.equal(inputElement.selectionEnd, element.text.length - 1);
+ assert.equal(inputElement.selectionEnd, element.text!.length! - 1);
});
test('hideInput', async () => {
// iron-input as parent should never be hidden as copy won't work
// on nested hidden elements
- const ironInputElement = element.shadowRoot.querySelector('iron-input');
+ const ironInputElement = queryAndAssert(element, 'iron-input');
assert.notEqual(getComputedStyle(ironInputElement).display, 'none');
const input = queryAndAssert(element, 'input');
@@ -76,10 +77,8 @@
divParent.appendChild(element);
const clickStub = sinon.stub();
divParent.addEventListener('click', clickStub);
- element.stopPropagation = true;
- const copyBtn = element.shadowRoot.querySelector('.copyToClipboard');
+ const copyBtn = queryAndAssert(element, '.copyToClipboard');
MockInteractions.tap(copyBtn);
assert.isFalse(clickStub.called);
});
});
-
diff --git a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.ts b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.ts
index 83cd380..592efba 100644
--- a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.ts
+++ b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.ts
@@ -106,13 +106,14 @@
_saveDisabled!: boolean;
@property({type: String, observer: '_newContentChanged'})
- _newContent?: string;
+ _newContent = '';
private readonly storage = appContext.storageService;
private readonly reporting = appContext.reportingService;
- private storeTask?: DelayedTask;
+ // Tests use this so needs to be non private
+ storeTask?: DelayedTask;
/** @override */
ready() {
diff --git a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_html.ts b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_html.ts
index c6ff903..7877a1f 100644
--- a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_html.ts
+++ b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_html.ts
@@ -69,7 +69,7 @@
box-shadow: var(--elevation-level-1);
/* slightly up to cover rounded corner of the commit msg */
margin-top: calc(-1 * var(--spacing-xs));
- /* To make this bar pop over editor, since editor has relative position.
+ /* To make this bar pop over editor, since editor has relative position.
*/
position: relative;
}
diff --git a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.js b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.ts
similarity index 73%
rename from polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.js
rename to polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.ts
index 94a7b96..074678e 100644
--- a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.ts
@@ -15,13 +15,17 @@
* limitations under the License.
*/
-import '../../../test/common-test-setup-karma.js';
-import './gr-editable-content.js';
+import '../../../test/common-test-setup-karma';
+import './gr-editable-content';
+import {GrEditableContent} from './gr-editable-content';
+import {queryAndAssert, stubStorage} from '../../../test/test-utils';
+import * as MockInteractions from '@polymer/iron-test-helpers/mock-interactions';
+import {GrButton} from '../gr-button/gr-button';
const basicFixture = fixtureFromElement('gr-editable-content');
suite('gr-editable-content tests', () => {
- let element;
+ let element: GrEditableContent;
setup(() => {
element = basicFixture.instantiate();
@@ -33,8 +37,7 @@
const handler = sinon.spy();
element.addEventListener('editable-content-save', handler);
- MockInteractions.tap(element.shadowRoot
- .querySelector('gr-button[primary]'));
+ MockInteractions.tap(queryAndAssert(element, 'gr-button[primary]'));
assert.isTrue(handler.called);
assert.equal(handler.lastCall.args[0].detail.content, 'foo');
@@ -44,8 +47,7 @@
const handler = sinon.spy();
element.addEventListener('editable-content-cancel', handler);
- MockInteractions.tap(element.shadowRoot
- .querySelector('gr-button.cancel-button'));
+ MockInteractions.tap(queryAndAssert(element, 'gr-button.cancel-button'));
assert.isTrue(handler.called);
});
@@ -79,19 +81,22 @@
});
test('save button is disabled initially', () => {
- assert.isTrue(element.shadowRoot
- .querySelector('gr-button[primary]').disabled);
+ assert.isTrue(
+ queryAndAssert<GrButton>(element, 'gr-button[primary]').disabled
+ );
});
test('save button is enabled when content changes', () => {
element._newContent = 'new content';
- assert.isFalse(element.shadowRoot
- .querySelector('gr-button[primary]').disabled);
+ assert.isFalse(
+ queryAndAssert<GrButton>(element, 'gr-button[primary]').disabled
+ );
});
});
suite('storageKey and related behavior', () => {
- let dispatchSpy;
+ let dispatchSpy: sinon.SinonSpy;
+
setup(() => {
element.content = 'current content';
element.storageKey = 'test';
@@ -99,8 +104,10 @@
});
test('editing toggled to true, has stored data', () => {
- sinon.stub(element.storage, 'getEditableContentItem')
- .returns({message: 'stored content'});
+ stubStorage('getEditableContentItem').returns({
+ message: 'stored content',
+ updated: 0,
+ });
element.editing = true;
assert.equal(element._newContent, 'stored content');
@@ -109,8 +116,7 @@
});
test('editing toggled to true, has no stored data', () => {
- sinon.stub(element.storage, 'getEditableContentItem')
- .returns({});
+ stubStorage('getEditableContentItem').returns(null);
element.editing = true;
assert.equal(element._newContent, 'current content');
@@ -118,28 +124,26 @@
});
test('edits are cached', () => {
- const storeStub =
- sinon.stub(element.storage, 'setEditableContentItem');
- const eraseStub =
- sinon.stub(element.storage, 'eraseEditableContentItem');
+ const storeStub = stubStorage('setEditableContentItem');
+ const eraseStub = stubStorage('eraseEditableContentItem');
element.editing = true;
element._newContent = 'new content';
flush();
- element.storeTask.flush();
+ element.storeTask?.flush();
assert.isTrue(storeStub.called);
assert.deepEqual(
- [element.storageKey, element._newContent],
- storeStub.lastCall.args);
+ [element.storageKey, element._newContent],
+ storeStub.lastCall.args
+ );
element._newContent = '';
flush();
- element.storeTask.flush();
+ element.storeTask?.flush();
assert.isTrue(eraseStub.called);
assert.deepEqual([element.storageKey], eraseStub.lastCall.args);
});
});
});
-