Merge changes I180de2b6,I04470446,I8184cc4e

* changes:
  Add labels to the settings web interface
  Properly indent attributes
  Fix the way the rest API is called
diff --git a/BUILD b/BUILD
index 38fcfd6..b4a3fc8 100644
--- a/BUILD
+++ b/BUILD
@@ -1,7 +1,7 @@
 load("//tools/bzl:genrule2.bzl", "genrule2")
 load("//tools/bzl:js.bzl", "polygerrit_plugin")
 load("//tools/bzl:junit.bzl", "junit_tests")
-load("//tools/bzl:plugin.bzl", "gerrit_plugin", "PLUGIN_DEPS", "PLUGIN_TEST_DEPS")
+load("//tools/bzl:plugin.bzl", "PLUGIN_DEPS", "PLUGIN_TEST_DEPS", "gerrit_plugin")
 
 gerrit_plugin(
     name = "simple-submit-rules",
@@ -15,27 +15,13 @@
     resources = glob(["src/main/resources/**/*"]),
 )
 
-ABSTRACT_TEST_BASE = ["src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/AbstractSimpleSubmitRulesIT.java"]
-
-java_library(
-    name = "abstract_test_base",
-    testonly = 1,
-    srcs = ABSTRACT_TEST_BASE,
-    visibility = ["//visibility:public"],
-    deps = PLUGIN_TEST_DEPS + PLUGIN_DEPS + [
-        ":simple-submit-rules__plugin",
-    ],
-)
-
 junit_tests(
     name = "tests",
     srcs = glob(
         ["src/test/java/**/*.java"],
-        exclude = ABSTRACT_TEST_BASE,
     ),
     visibility = ["//visibility:public"],
     deps = PLUGIN_TEST_DEPS + PLUGIN_DEPS + [
-        ":abstract_test_base",
         ":simple-submit-rules__plugin",
     ],
 )
diff --git a/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/BatchModule.java b/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/BatchModule.java
index 3e9d696..76f8385 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/BatchModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/BatchModule.java
@@ -19,14 +19,12 @@
 import com.google.inject.AbstractModule;
 import com.googlesource.gerrit.plugins.simplesubmitrules.config.ConfigTranslator;
 import com.googlesource.gerrit.plugins.simplesubmitrules.rules.NoUnresolvedCommentsRule;
-import com.googlesource.gerrit.plugins.simplesubmitrules.rules.RequireNonAuthorApprovalRule;
 
 /** Rules for the batch programs (offline reindexer) */
 public class BatchModule extends AbstractModule {
   @Override
   protected void configure() {
     bind(ConfigTranslator.class);
-    DynamicSet.bind(binder(), SubmitRule.class).to(RequireNonAuthorApprovalRule.class);
     DynamicSet.bind(binder(), SubmitRule.class).to(NoUnresolvedCommentsRule.class);
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/SimpleSubmitRulesConfig.java b/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/SimpleSubmitRulesConfig.java
index 856e71a..ec2c88b 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/SimpleSubmitRulesConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/SimpleSubmitRulesConfig.java
@@ -15,7 +15,6 @@
 package com.googlesource.gerrit.plugins.simplesubmitrules;
 
 public final class SimpleSubmitRulesConfig {
-  public static final String KEY_REQUIRE_NON_AUTHOR_APPROVAL = "nonAuthorApprovalRequired";
   public static final String KEY_BLOCK_IF_UNRESOLVED_COMMENTS = "blockIfUnresolvedComments";
 
   private SimpleSubmitRulesConfig() {}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/api/CommentsRules.java b/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/api/CommentsRules.java
new file mode 100644
index 0000000..363f418
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/api/CommentsRules.java
@@ -0,0 +1,47 @@
+// Copyright (C) 2018 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.
+
+package com.googlesource.gerrit.plugins.simplesubmitrules.api;
+
+import com.google.common.base.MoreObjects;
+import java.util.Objects;
+
+public class CommentsRules {
+  public boolean blockIfUnresolvedComments;
+
+  public CommentsRules(boolean blockIfUnresolvedComments) {
+    this.blockIfUnresolvedComments = blockIfUnresolvedComments;
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hashCode(blockIfUnresolvedComments);
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (!(o instanceof CommentsRules)) {
+      return false;
+    }
+    CommentsRules other = (CommentsRules) o;
+    return blockIfUnresolvedComments == other.blockIfUnresolvedComments;
+  }
+
+  @Override
+  public String toString() {
+    return MoreObjects.toStringHelper(this)
+        .add("blockIfUnresolvedComments", blockIfUnresolvedComments)
+        .toString();
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/api/LabelDefinition.java b/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/api/LabelDefinition.java
new file mode 100644
index 0000000..3ded3c2
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/api/LabelDefinition.java
@@ -0,0 +1,67 @@
+// Copyright (C) 2018 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.
+
+package com.googlesource.gerrit.plugins.simplesubmitrules.api;
+
+import com.google.common.base.MoreObjects;
+import com.google.gerrit.common.data.LabelFunction;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+
+public class LabelDefinition {
+  public String function;
+  public Boolean ignoreSelfApproval;
+  public Set<String> copyScores;
+
+  public LabelDefinition() {
+    copyScores = new HashSet<>();
+  }
+
+  public LabelDefinition(String function, Boolean ignoreSelfApproval, Set<String> copyScores) {
+    this.function = function;
+    this.ignoreSelfApproval = ignoreSelfApproval;
+    this.copyScores = copyScores;
+  }
+
+  public Optional<LabelFunction> getFunction() {
+    return LabelFunction.parse(function);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(function, ignoreSelfApproval, copyScores);
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (!(o instanceof LabelDefinition)) {
+      return false;
+    }
+    LabelDefinition other = (LabelDefinition) o;
+    return Objects.equals(function, other.function)
+        && Objects.equals(ignoreSelfApproval, other.ignoreSelfApproval)
+        && Objects.equals(copyScores, other.copyScores);
+  }
+
+  @Override
+  public String toString() {
+    return MoreObjects.toStringHelper(this)
+        .add("function", function)
+        .add("ignoreSelfApproval", ignoreSelfApproval)
+        .add("copyScores", copyScores)
+        .toString();
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/api/SubmitConfig.java b/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/api/SubmitConfig.java
new file mode 100644
index 0000000..a538a57
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/api/SubmitConfig.java
@@ -0,0 +1,58 @@
+// Copyright (C) 2018 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.
+
+package com.googlesource.gerrit.plugins.simplesubmitrules.api;
+
+import com.google.common.base.MoreObjects;
+import com.google.inject.Singleton;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+@Singleton
+public class SubmitConfig {
+  public Map<String, LabelDefinition> labels;
+  public CommentsRules comments;
+
+  public SubmitConfig() {
+    labels = new HashMap<>();
+  }
+
+  public SubmitConfig(Map<String, LabelDefinition> labels, CommentsRules comments) {
+    this.labels = labels;
+    this.comments = comments;
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(labels, comments);
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (!(o instanceof SubmitConfig)) {
+      return false;
+    }
+    SubmitConfig other = (SubmitConfig) o;
+    return Objects.equals(labels, other.labels) && Objects.equals(comments, other.comments);
+  }
+
+  @Override
+  public String toString() {
+    return MoreObjects.toStringHelper(this)
+        .add("labels", labels)
+        .add("comments", comments)
+        .toString();
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/ConfigServlet.java b/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/ConfigServlet.java
index 1cf6e88..eae8d61 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/ConfigServlet.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/ConfigServlet.java
@@ -27,6 +27,7 @@
 import com.google.gerrit.server.project.ProjectResource;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
+import com.googlesource.gerrit.plugins.simplesubmitrules.api.SubmitConfig;
 import java.io.IOException;
 
 /** REST Endpoint to configure labels and our simple submit rules */
diff --git a/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/ConfigTranslator.java b/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/ConfigTranslator.java
index 6a8ce81..035a2a8 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/ConfigTranslator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/ConfigTranslator.java
@@ -14,6 +14,7 @@
 
 package com.googlesource.gerrit.plugins.simplesubmitrules.config;
 
+import com.google.gerrit.common.Nullable;
 import com.google.gerrit.common.data.LabelType;
 import com.google.gerrit.common.data.LabelTypes;
 import com.google.gerrit.extensions.annotations.PluginName;
@@ -25,6 +26,9 @@
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import com.googlesource.gerrit.plugins.simplesubmitrules.SimpleSubmitRulesConfig;
+import com.googlesource.gerrit.plugins.simplesubmitrules.api.CommentsRules;
+import com.googlesource.gerrit.plugins.simplesubmitrules.api.LabelDefinition;
+import com.googlesource.gerrit.plugins.simplesubmitrules.api.SubmitConfig;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Map;
@@ -41,8 +45,7 @@
     this.pluginName = pluginName;
   }
 
-  static void extractLabelCopyScores(
-      LabelType labelType, SubmitConfig.LabelDefinition labelDefinition) {
+  static void extractLabelCopyScores(LabelType labelType, LabelDefinition labelDefinition) {
     labelDefinition.copyScores = new HashSet<>();
     if (labelType.isCopyMinScore()) {
       labelDefinition.copyScores.add(ProjectConfig.KEY_COPY_MIN_SCORE);
@@ -65,20 +68,19 @@
     }
   }
 
-  static void applyCopyScoresTo(Collection<String> copyScores, LabelType labelType) {
+  static void applyCopyScoresTo(@Nullable Collection<String> copyScores, LabelType labelType) {
+    if (copyScores == null) {
+      return;
+    }
+
     labelType.setCopyMinScore(copyScores.contains(ProjectConfig.KEY_COPY_MIN_SCORE));
-
     labelType.setCopyMaxScore(copyScores.contains(ProjectConfig.KEY_COPY_MAX_SCORE));
-
     labelType.setCopyAllScoresIfNoChange(
         copyScores.contains(ProjectConfig.KEY_COPY_ALL_SCORES_IF_NO_CHANGE));
-
     labelType.setCopyAllScoresIfNoCodeChange(
         copyScores.contains(ProjectConfig.KEY_COPY_ALL_SCORES_IF_NO_CODE_CHANGE));
-
     labelType.setCopyAllScoresOnMergeFirstParentUpdate(
         copyScores.contains(ProjectConfig.KEY_COPY_ALL_SCORES_ON_MERGE_FIRST_PARENT_UPDATE));
-
     labelType.setCopyAllScoresOnTrivialRebase(
         copyScores.contains(ProjectConfig.KEY_COPY_ALL_SCORES_ON_TRIVIAL_REBASE));
   }
@@ -88,8 +90,9 @@
     PluginConfig config =
         pluginConfigFactory.getFromProjectConfigWithInheritance(projectState, pluginName);
 
-    submitConfig.comments.blockIfUnresolvedComments =
-        config.getBoolean(SimpleSubmitRulesConfig.KEY_BLOCK_IF_UNRESOLVED_COMMENTS, false);
+    submitConfig.comments =
+        new CommentsRules(
+            config.getBoolean(SimpleSubmitRulesConfig.KEY_BLOCK_IF_UNRESOLVED_COMMENTS, false));
 
     projectState
         .getLabelTypes()
@@ -108,13 +111,12 @@
     applyLabelsTo(inConfig.labels, projectState.getLabelTypes());
   }
 
-  private static void applyLabelsTo(
-      Map<String, SubmitConfig.LabelDefinition> labels, LabelTypes config)
+  private static void applyLabelsTo(Map<String, LabelDefinition> labels, LabelTypes labelTypes)
       throws BadRequestException {
-    for (Map.Entry<String, SubmitConfig.LabelDefinition> entry : labels.entrySet()) {
+    for (Map.Entry<String, LabelDefinition> entry : labels.entrySet()) {
       String label = entry.getKey();
-      SubmitConfig.LabelDefinition definition = entry.getValue();
-      LabelType labelType = config.byLabel(label);
+      LabelDefinition definition = entry.getValue();
+      LabelType labelType = labelTypes.byLabel(label);
 
       if (labelType == null) {
         throw new BadRequestException(
@@ -122,7 +124,9 @@
       }
 
       definition.getFunction().ifPresent(labelType::setFunction);
-
+      if (definition.ignoreSelfApproval != null) {
+        labelType.setIgnoreSelfApproval(definition.ignoreSelfApproval);
+      }
       applyCopyScoresTo(definition.copyScores, labelType);
     }
   }
@@ -132,15 +136,18 @@
       return;
     }
 
-    SubmitConfig.LabelDefinition labelDefinition = new SubmitConfig.LabelDefinition();
+    LabelDefinition labelDefinition = new LabelDefinition();
     config.labels.put(labelType.getName(), labelDefinition);
 
     labelDefinition.function = labelType.getFunction().getFunctionName();
     extractLabelCopyScores(labelType, labelDefinition);
+    labelDefinition.ignoreSelfApproval = labelType.ignoreSelfApproval();
   }
 
-  private static void applyCommentRulesTo(
-      SubmitConfig.CommentsRules comments, PluginConfig config) {
+  private static void applyCommentRulesTo(@Nullable CommentsRules comments, PluginConfig config) {
+    if (comments == null) {
+      return;
+    }
     config.setBoolean(
         SimpleSubmitRulesConfig.KEY_BLOCK_IF_UNRESOLVED_COMMENTS,
         comments.blockIfUnresolvedComments);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/SubmitConfig.java b/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/SubmitConfig.java
deleted file mode 100644
index 0d7ae98..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/SubmitConfig.java
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (C) 2018 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.
-
-package com.googlesource.gerrit.plugins.simplesubmitrules.config;
-
-import com.google.common.base.MoreObjects;
-import com.google.gerrit.common.data.LabelFunction;
-import com.google.inject.Singleton;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-
-@Singleton
-public class SubmitConfig {
-  public Map<String, SubmitConfig.LabelDefinition> labels = new HashMap<>();
-  public SubmitConfig.CommentsRules comments = new SubmitConfig.CommentsRules();
-
-  @Override
-  public String toString() {
-    return MoreObjects.toStringHelper(this)
-        .add("labels", labels)
-        .add("comments", comments)
-        .toString();
-  }
-
-  static class LabelDefinition {
-    String function;
-    boolean ignoreSelfApproval;
-    Set<String> copyScores;
-
-    Optional<LabelFunction> getFunction() {
-      return LabelFunction.parse(function);
-    }
-
-    @Override
-    public String toString() {
-      return MoreObjects.toStringHelper(this)
-          .add("function", function)
-          .add("ignoreSelfApproval", ignoreSelfApproval)
-          .add("copyScores", copyScores)
-          .toString();
-    }
-  }
-
-  static class CommentsRules {
-    boolean blockIfUnresolvedComments;
-
-    @Override
-    public String toString() {
-      return MoreObjects.toStringHelper(this)
-          .add("blockIfUnresolvedComments", blockIfUnresolvedComments)
-          .toString();
-    }
-  }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/rules/RequireNonAuthorApprovalRule.java b/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/rules/RequireNonAuthorApprovalRule.java
deleted file mode 100644
index b4df629..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/rules/RequireNonAuthorApprovalRule.java
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright (C) 2018 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.
-
-package com.googlesource.gerrit.plugins.simplesubmitrules.rules;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.gerrit.common.data.LabelFunction;
-import com.google.gerrit.common.data.LabelType;
-import com.google.gerrit.common.data.SubmitRecord;
-import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.PatchSetApproval;
-import com.google.gerrit.server.project.ProjectCache;
-import com.google.gerrit.server.project.ProjectConfig;
-import com.google.gerrit.server.project.ProjectState;
-import com.google.gerrit.server.project.SubmitRuleOptions;
-import com.google.gerrit.server.query.change.ChangeData;
-import com.google.gerrit.server.rules.SubmitRule;
-import com.google.gwtorm.server.OrmException;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-import com.googlesource.gerrit.plugins.simplesubmitrules.SimpleSubmitRulesConfig;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.stream.Collectors;
-import org.eclipse.jgit.lib.Config;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/** Simple rule: require a non-author approval or block submission */
-@Singleton
-public class RequireNonAuthorApprovalRule implements SubmitRule {
-  private static final Logger log = LoggerFactory.getLogger(RequireNonAuthorApprovalRule.class);
-  private static final String E_UNABLE_TO_FETCH_CHANGE_OWNER = "Unable to fetch the change owner";
-  private static final String E_UNABLE_TO_FETCH_LABELS =
-      "Unable to fetch labels and approvals for the change";
-  private final ProjectCache projectCache;
-
-  @Inject
-  public RequireNonAuthorApprovalRule(ProjectCache projectCache) {
-    this.projectCache = projectCache;
-  }
-
-  @Override
-  public Collection<SubmitRecord> evaluate(ChangeData cd, SubmitRuleOptions options) {
-    ProjectState projectState = projectCache.get(cd.project());
-    Config config = projectState.getConfig(ProjectConfig.PROJECT_CONFIG).getWithInheritance();
-
-    Account.Id owner;
-    try {
-      owner = cd.change().getOwner();
-    } catch (OrmException e) {
-      log.error(E_UNABLE_TO_FETCH_CHANGE_OWNER, e);
-
-      SubmitRecord submitRecord = new SubmitRecord();
-      submitRecord.errorMessage = E_UNABLE_TO_FETCH_CHANGE_OWNER;
-      submitRecord.status = SubmitRecord.Status.RULE_ERROR;
-      return Collections.singletonList(submitRecord);
-    }
-
-    List<LabelType> labelTypes;
-    List<PatchSetApproval> approvals;
-    try {
-      labelTypes = cd.getLabelTypes().getLabelTypes();
-      approvals = cd.currentApprovals();
-    } catch (OrmException e) {
-      log.error(E_UNABLE_TO_FETCH_LABELS, e);
-
-      SubmitRecord submitRecord = new SubmitRecord();
-      submitRecord.errorMessage = E_UNABLE_TO_FETCH_LABELS;
-      submitRecord.status = SubmitRecord.Status.RULE_ERROR;
-
-      return Collections.singletonList(submitRecord);
-    }
-
-    SubmitRecord submitRecord = new SubmitRecord();
-    submitRecord.status = SubmitRecord.Status.OK;
-    submitRecord.labels = new ArrayList<>(labelTypes.size());
-
-    for (LabelType t : labelTypes) {
-      if (!config.getBoolean(
-          t.getName(), SimpleSubmitRulesConfig.KEY_REQUIRE_NON_AUTHOR_APPROVAL, false)) {
-        // The default rules are enough in this case.
-        continue;
-      }
-
-      LabelFunction labelFunction = t.getFunction();
-      if (labelFunction == null) {
-        continue;
-      }
-
-      Collection<PatchSetApproval> approvalsForLabel = getApprovalsForLabel(approvals, t, owner);
-      SubmitRecord.Label label = labelFunction.check(t, approvalsForLabel);
-
-      switch (label.status) {
-        case OK:
-        case MAY:
-          break;
-
-        case NEED:
-        case REJECT:
-        case IMPOSSIBLE:
-          submitRecord.labels.add(label);
-          submitRecord.status = SubmitRecord.Status.NOT_READY;
-          break;
-      }
-    }
-
-    if (submitRecord.labels.isEmpty()) {
-      return Collections.emptyList();
-    }
-
-    return Collections.singletonList(submitRecord);
-  }
-
-  /**
-   * Returns the approvals for a given label, for everyone except from `user`, except if the vote is
-   * negative.
-   */
-  @VisibleForTesting
-  static Collection<PatchSetApproval> getApprovalsForLabel(
-      Collection<PatchSetApproval> approvals, LabelType t, Account.Id user) {
-    return approvals
-        .stream()
-        .filter(input -> input.getValue() < 0 || !input.getAccountId().equals(user))
-        .filter(input -> input.getLabel().equals(t.getLabelId().get()))
-        .collect(Collectors.toList());
-  }
-}
diff --git a/src/main/resources/Documentation/about.md b/src/main/resources/Documentation/about.md
index 8b35230..15c0e18 100644
--- a/src/main/resources/Documentation/about.md
+++ b/src/main/resources/Documentation/about.md
@@ -3,7 +3,8 @@
 ## Features
 - REST API to configure the options and labels.
 - Ability to prevent submission if there are unresolved comments.
-- Ability to require approval, and to consider approval from the change author or not.
+- Ability to require approval, and to consider approval from the uploader of the
+  latest patch set or not.
 - (soon!) a simple PolyGerrit UI to configure the labels and how they work.
 
 ### Inheritance
diff --git a/src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/AbstractSimpleSubmitRulesIT.java b/src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/AbstractSimpleSubmitRulesIT.java
deleted file mode 100644
index e73172f..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/AbstractSimpleSubmitRulesIT.java
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (C) 2018 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.
-
-package com.googlesource.gerrit.plugins.simplesubmitrules;
-
-import com.google.gerrit.acceptance.GitUtil;
-import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
-import com.google.gerrit.acceptance.PushOneCommit;
-import com.google.gerrit.acceptance.TestPlugin;
-import com.google.gerrit.reviewdb.client.RefNames;
-import com.google.gerrit.server.project.ProjectConfig;
-import java.util.function.Consumer;
-import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
-import org.eclipse.jgit.junit.TestRepository;
-import org.eclipse.jgit.lib.Config;
-import org.junit.Ignore;
-
-/** Base class used by IT tests, loads the Simple Submit Rules plugin. */
-@TestPlugin(
-    name = "my-plugin",
-    sysModule = "com.googlesource.gerrit.plugins.simplesubmitrules.SimpleSubmitRulesModule")
-@Ignore
-public abstract class AbstractSimpleSubmitRulesIT extends LightweightPluginDaemonTest {
-  /** Helper method to change the project.config file using a provided consumer. */
-  protected void changeProjectConfig(Consumer<Config> callback) throws Exception {
-    TestRepository<InMemoryRepository> projectRepo = cloneProject(project, admin);
-    // Fetch permission ref
-    GitUtil.fetch(projectRepo, "refs/meta/config:cfg");
-    projectRepo.reset("cfg");
-
-    String rawConfig =
-        gApi.projects()
-            .name(project.get())
-            .branch(RefNames.REFS_CONFIG)
-            .file(ProjectConfig.PROJECT_CONFIG)
-            .asString();
-
-    Config config = new Config();
-    config.fromText(rawConfig);
-
-    // Apply our custom function to the config
-    callback.accept(config);
-
-    rawConfig = config.toText();
-
-    PushOneCommit push =
-        pushFactory.create(
-            db, admin.getIdent(), projectRepo, "Subject", ProjectConfig.PROJECT_CONFIG, rawConfig);
-    push.to(RefNames.REFS_CONFIG).assertOkStatus();
-  }
-}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/PluginIT.java b/src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/PluginIT.java
new file mode 100644
index 0000000..d41ed1c
--- /dev/null
+++ b/src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/PluginIT.java
@@ -0,0 +1,158 @@
+// Copyright (C) 2018 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.
+
+package com.googlesource.gerrit.plugins.simplesubmitrules;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
+import com.google.gerrit.acceptance.PushOneCommit;
+import com.google.gerrit.acceptance.RestResponse;
+import com.google.gerrit.acceptance.TestPlugin;
+import com.google.gerrit.common.RawInputUtil;
+import com.google.gerrit.common.data.LabelType;
+import com.google.gerrit.extensions.api.changes.ReviewInput;
+import com.google.gerrit.extensions.client.Side;
+import com.google.gerrit.extensions.common.ChangeInfo;
+import com.google.gerrit.extensions.common.SubmitRequirementInfo;
+import com.google.gerrit.extensions.restapi.RawInput;
+import com.google.gerrit.reviewdb.client.Project;
+import com.googlesource.gerrit.plugins.simplesubmitrules.api.CommentsRules;
+import com.googlesource.gerrit.plugins.simplesubmitrules.api.LabelDefinition;
+import com.googlesource.gerrit.plugins.simplesubmitrules.api.SubmitConfig;
+import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
+import org.eclipse.jgit.junit.TestRepository;
+import org.junit.Before;
+import org.junit.Test;
+
+@TestPlugin(
+    name = "my-plugin",
+    sysModule = "com.googlesource.gerrit.plugins.simplesubmitrules.Module")
+/** Overall end-to-end integration test for configuring labels and comments and merging changes. */
+public class PluginIT extends LightweightPluginDaemonTest {
+  private static final String JSON_TYPE = "application/json";
+
+  @Before
+  public void setUpCodeReviewLabel() throws Exception {
+    // TODO(hiesel): Remove once copy-down logic is in place
+    try (ProjectConfigUpdate u = updateProject(project)) {
+      LabelType codeReview = projectCache.getAllProjects().getLabelTypes().byLabel("Code-Review");
+      u.getConfig().getLabelSections().put("Code-Review", codeReview);
+      u.save();
+    }
+  }
+
+  @Test
+  public void singleApprovalIsSufficientByDefault() throws Exception {
+    PushOneCommit.Result r = createChange();
+    approve(r.getChangeId());
+    ChangeInfo changeInfo = gApi.changes().id(r.getChangeId()).get();
+    assertThat(changeInfo.submittable).isTrue();
+    assertThat(changeInfo.requirements).isEmpty();
+  }
+
+  @Test
+  public void unresolvedCommentsBlockSubmissionIfConfigured() throws Exception {
+    SubmitConfig config = new SubmitConfig(null, new CommentsRules(true));
+    postConfig(project, config);
+
+    // Create change as user
+    TestRepository<InMemoryRepository> userTestRepo = cloneProject(project, user);
+    PushOneCommit push = pushFactory.create(db, user.getIdent(), userTestRepo);
+    PushOneCommit.Result r = push.to("refs/for/master");
+
+    // Approve as admin
+    approve(r.getChangeId());
+
+    ReviewInput reviewInput = new ReviewInput();
+    ReviewInput.CommentInput c = new ReviewInput.CommentInput();
+    c.path = "a.txt";
+    c.side = Side.REVISION;
+    c.unresolved = true;
+    c.message = "nit: double  space.";
+    reviewInput.comments = ImmutableMap.of(c.path, ImmutableList.of(c));
+    revision(r).review(reviewInput);
+
+    ChangeInfo changeInfo = gApi.changes().id(r.getChangeId()).get();
+    assertThat(changeInfo.submittable).isFalse();
+    SubmitRequirementInfo noUnresolveComments =
+        new SubmitRequirementInfo(
+            "NOT_READY",
+            "Resolve all comments",
+            "unresolved_comments",
+            ImmutableMap.<String, String>of());
+    assertThat(changeInfo.requirements).containsExactly(noUnresolveComments);
+  }
+
+  @Test
+  public void uploaderApprovalDoesNotGrantSubmissionIfConfigured() throws Exception {
+    LabelDefinition codeReviewNoSelfApproval = new LabelDefinition("MaxWithBlock", true, null);
+    SubmitConfig config =
+        new SubmitConfig(ImmutableMap.of("Code-Review", codeReviewNoSelfApproval), null);
+    postConfig(project, config);
+
+    // Create change, put an unresolved comment on it and approve it.
+    PushOneCommit.Result r = createChange();
+    approve(r.getChangeId());
+
+    ChangeInfo changeInfo = gApi.changes().id(r.getChangeId()).get();
+    assertThat(changeInfo.submittable).isFalse();
+    SubmitRequirementInfo noSelfApproval =
+        new SubmitRequirementInfo(
+            "NOT_READY",
+            "Approval from non-uploader required",
+            "non_uploader_approval",
+            ImmutableMap.<String, String>of());
+    assertThat(changeInfo.requirements).containsExactly(noSelfApproval);
+  }
+
+  @Test
+  public void labelConfigsGetPersisted() throws Exception {
+    LabelDefinition codeReviewNoSelfApproval =
+        new LabelDefinition("MaxNoBlock", true, ImmutableSet.of("copyAllScoresIfNoChange"));
+    SubmitConfig config =
+        new SubmitConfig(ImmutableMap.of("Code-Review", codeReviewNoSelfApproval), null);
+    postConfig(project, config);
+
+    String currentConfig = adminRestSession.get(endpointUrl(project)).getEntityContent();
+    SubmitConfig parsedConfig = newGson().fromJson(currentConfig, SubmitConfig.class);
+    assertThat(parsedConfig.labels)
+        .isEqualTo(ImmutableMap.of("Code-Review", codeReviewNoSelfApproval));
+  }
+
+  @Test
+  public void commentsConfigGetPersisted() throws Exception {
+    SubmitConfig config = new SubmitConfig(null, new CommentsRules(true));
+    postConfig(project, config);
+
+    String currentConfig = adminRestSession.get(endpointUrl(project)).getEntityContent();
+    SubmitConfig parsedConfig = newGson().fromJson(currentConfig, SubmitConfig.class);
+    assertThat(parsedConfig.comments).isEqualTo(new CommentsRules(true));
+  }
+
+  private void postConfig(Project.NameKey project, SubmitConfig config) throws Exception {
+    RawInput rawInput =
+        RawInputUtil.create(newGson().toJson(config).getBytes(Charsets.UTF_8), JSON_TYPE);
+    RestResponse configResult = adminRestSession.putRaw(endpointUrl(project), rawInput);
+    configResult.assertOK();
+  }
+
+  private static String endpointUrl(Project.NameKey project) {
+    return "/projects/" + project.get() + "/simple-submit-rules";
+  }
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/ConfigServletIT.java b/src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/ConfigServletIT.java
index e83b0e9..815198e 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/ConfigServletIT.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/ConfigServletIT.java
@@ -17,16 +17,20 @@
 import static com.google.gerrit.server.project.testing.Util.value;
 
 import com.google.common.base.Charsets;
+import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
 import com.google.gerrit.acceptance.RestResponse;
+import com.google.gerrit.acceptance.TestPlugin;
 import com.google.gerrit.common.RawInputUtil;
 import com.google.gerrit.common.data.LabelFunction;
 import com.google.gerrit.extensions.restapi.RawInput;
 import com.google.gerrit.reviewdb.client.Project;
-import com.googlesource.gerrit.plugins.simplesubmitrules.AbstractSimpleSubmitRulesIT;
 import org.junit.Before;
 import org.junit.Test;
 
-public class ConfigServletIT extends AbstractSimpleSubmitRulesIT {
+@TestPlugin(
+    name = "my-plugin",
+    sysModule = "com.googlesource.gerrit.plugins.simplesubmitrules.Module")
+public class ConfigServletIT extends LightweightPluginDaemonTest {
   @Before
   public void setUp() throws Exception {
     configLabel(
@@ -70,7 +74,7 @@
                 + "    \"labels\": {\n"
                 + "        \"Code-Review\": {\n"
                 + "            \"function\": \"MaxWithBlock\",\n"
-                + "            \"ignore_self_approval\": false,\n"
+                + "            \"ignore_self_approval\": true,\n"
                 + "            \"copy_scores\": [\n"
                 + "                \"copyAllScoresIfNoChange\",\n"
                 + "                \"copyMinScore\",\n"
diff --git a/src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/ConfigTranslatorTest.java b/src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/ConfigTranslatorTest.java
index 332afb5..0528194 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/ConfigTranslatorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/ConfigTranslatorTest.java
@@ -18,6 +18,7 @@
 
 import com.google.common.collect.ImmutableList;
 import com.google.gerrit.common.data.LabelType;
+import com.googlesource.gerrit.plugins.simplesubmitrules.api.LabelDefinition;
 import java.util.function.BiConsumer;
 import java.util.function.Predicate;
 import org.junit.Test;
@@ -66,7 +67,7 @@
       String copyScoreName, BiConsumer<LabelType, Boolean> functionToSet) {
 
     LabelType label = LabelType.withDefaultValues("Verified");
-    SubmitConfig.LabelDefinition labelDefinition = new SubmitConfig.LabelDefinition();
+    LabelDefinition labelDefinition = new LabelDefinition();
 
     functionToSet.accept(label, false);
     ConfigTranslator.extractLabelCopyScores(label, labelDefinition);
@@ -80,7 +81,7 @@
       String copyScoreName, BiConsumer<LabelType, Boolean> functionToSet) {
 
     LabelType label = LabelType.withDefaultValues("Verified");
-    SubmitConfig.LabelDefinition labelDefinition = new SubmitConfig.LabelDefinition();
+    LabelDefinition labelDefinition = new LabelDefinition();
 
     functionToSet.accept(label, true);
     ConfigTranslator.extractLabelCopyScores(label, labelDefinition);
diff --git a/src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/rules/NoUnresolvedCommentsRuleIT.java b/src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/rules/NoUnresolvedCommentsRuleIT.java
index 8e80861..ea58eb4 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/rules/NoUnresolvedCommentsRuleIT.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/rules/NoUnresolvedCommentsRuleIT.java
@@ -18,21 +18,25 @@
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
+import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
 import com.google.gerrit.acceptance.NoHttpd;
 import com.google.gerrit.acceptance.PushOneCommit;
+import com.google.gerrit.acceptance.TestPlugin;
 import com.google.gerrit.common.data.SubmitRecord;
 import com.google.gerrit.extensions.api.changes.ReviewInput;
 import com.google.gerrit.extensions.client.Side;
 import com.google.gerrit.server.project.SubmitRuleOptions;
 import com.google.gerrit.server.query.change.ChangeData;
-import com.googlesource.gerrit.plugins.simplesubmitrules.AbstractSimpleSubmitRulesIT;
 import com.googlesource.gerrit.plugins.simplesubmitrules.SimpleSubmitRulesConfig;
 import java.util.Collection;
 import org.junit.Before;
 import org.junit.Test;
 
+@TestPlugin(
+    name = "my-plugin",
+    sysModule = "com.googlesource.gerrit.plugins.simplesubmitrules.Module")
 @NoHttpd
-public class NoUnresolvedCommentsRuleIT extends AbstractSimpleSubmitRulesIT {
+public class NoUnresolvedCommentsRuleIT extends LightweightPluginDaemonTest {
   private static final String FILENAME = "my.file";
 
   @Before
@@ -97,7 +101,8 @@
     assertThat(submitRecords).isEmpty();
   }
 
-  private PushOneCommit.Result createChangeWithComment(ReviewInput.CommentInput comment) throws Exception {
+  private PushOneCommit.Result createChangeWithComment(ReviewInput.CommentInput comment)
+      throws Exception {
     PushOneCommit.Result r = createChange("My change", FILENAME, "new content");
     ReviewInput reviewInput = new ReviewInput();
     reviewInput.comments = ImmutableMap.of(comment.path, ImmutableList.of(comment));
@@ -107,13 +112,12 @@
   }
 
   private void enableRule(boolean newState) throws Exception {
-    changeProjectConfig(
-        config ->
-            config.setBoolean(
-                "plugin",
-                plugin.getName(),
-                SimpleSubmitRulesConfig.KEY_BLOCK_IF_UNRESOLVED_COMMENTS,
-                newState));
+    try (ProjectConfigUpdate u = updateProject(project)) {
+      u.getConfig()
+          .getPluginConfig(plugin.getName())
+          .setBoolean(SimpleSubmitRulesConfig.KEY_BLOCK_IF_UNRESOLVED_COMMENTS, newState);
+      u.save();
+    }
   }
 
   private Collection<SubmitRecord> evaluate(ChangeData cd, SubmitRuleOptions options) {
diff --git a/src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/rules/RequireNonAuthorApprovalRuleIT.java b/src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/rules/RequireNonAuthorApprovalRuleIT.java
deleted file mode 100644
index 1f989d5..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/rules/RequireNonAuthorApprovalRuleIT.java
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (C) 2018 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.
-
-package com.googlesource.gerrit.plugins.simplesubmitrules.rules;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.gerrit.acceptance.NoHttpd;
-import com.google.gerrit.acceptance.PushOneCommit;
-import com.google.gerrit.common.data.SubmitRecord;
-import com.google.gerrit.extensions.api.changes.ReviewInput;
-import com.google.gerrit.server.project.SubmitRuleOptions;
-import com.google.inject.Inject;
-import com.googlesource.gerrit.plugins.simplesubmitrules.AbstractSimpleSubmitRulesIT;
-import com.googlesource.gerrit.plugins.simplesubmitrules.SimpleSubmitRulesConfig;
-import java.util.Collection;
-import org.junit.Before;
-import org.junit.Test;
-
-@NoHttpd
-public class RequireNonAuthorApprovalRuleIT extends AbstractSimpleSubmitRulesIT {
-  private static final String FILENAME = "my.file";
-  @Inject private RequireNonAuthorApprovalRule rule;
-
-  @Before
-  public void enableRuleBeforeTest() throws Exception {
-    enableRule("Code-Review", true);
-  }
-
-  @Test
-  public void blocksWhenAutorIsOnlyApprover() throws Exception {
-    PushOneCommit.Result r = createChangeWithVote(2);
-
-    Collection<SubmitRecord> submitRecords =
-        rule.evaluate(r.getChange(), SubmitRuleOptions.defaults());
-
-    assertThat(submitRecords).hasSize(1);
-    SubmitRecord result = submitRecords.iterator().next();
-    assertThat(result.status).isEqualTo(SubmitRecord.Status.NOT_READY);
-    assertThat(result.labels).isNotEmpty();
-  }
-
-  @Test
-  public void doesNothingByDefault() throws Exception {
-    PushOneCommit.Result r = createChangeWithVote(+2);
-
-    enableRule("Code-Review", false);
-
-    Collection<SubmitRecord> submitRecords =
-        rule.evaluate(r.getChange(), SubmitRuleOptions.defaults());
-    assertThat(submitRecords).isEmpty();
-  }
-
-  private PushOneCommit.Result createChangeWithVote(int value) throws Exception {
-    PushOneCommit.Result r = createChange("My change", FILENAME, "new content");
-    ReviewInput reviewInput = new ReviewInput();
-    reviewInput.label("Code-Review", value);
-    revision(r).review(reviewInput);
-
-    return r;
-  }
-
-  private void enableRule(String labelName, boolean newState) throws Exception {
-    changeProjectConfig(
-        config ->
-            config.setBoolean(
-                labelName,
-                null,
-                SimpleSubmitRulesConfig.KEY_REQUIRE_NON_AUTHOR_APPROVAL,
-                newState));
-  }
-}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/rules/RequireNonAuthorApprovalRuleTest.java b/src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/rules/RequireNonAuthorApprovalRuleTest.java
deleted file mode 100644
index 7324f55..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/simplesubmitrules/rules/RequireNonAuthorApprovalRuleTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright (C) 2018 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.
-
-package com.googlesource.gerrit.plugins.simplesubmitrules.rules;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.googlesource.gerrit.plugins.simplesubmitrules.rules.RequireNonAuthorApprovalRule.getApprovalsForLabel;
-
-import com.google.common.collect.ImmutableList;
-import com.google.gerrit.common.data.LabelType;
-import com.google.gerrit.common.data.LabelValue;
-import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Change;
-import com.google.gerrit.reviewdb.client.LabelId;
-import com.google.gerrit.reviewdb.client.PatchSet;
-import com.google.gerrit.reviewdb.client.PatchSetApproval;
-import java.time.Instant;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-import org.junit.Test;
-
-public class RequireNonAuthorApprovalRuleTest {
-  private static final Change.Id CHANGE_ID = new Change.Id(100);
-  private static final PatchSet.Id PS_ID = new PatchSet.Id(CHANGE_ID, 1);
-  private static final LabelType VERIFIED = makeLabel("Verified");
-  private static final Account.Id USER1 = makeAccount(100001);
-  private static final Account.Id USER2 = makeAccount(100002);
-
-  @Test
-  public void filtersByLabel() {
-    LabelType codeReview = makeLabel("Code-Review");
-    PatchSetApproval approvalVerified = makeApproval(VERIFIED.getLabelId(), USER1, 2);
-    PatchSetApproval approvalCr = makeApproval(codeReview.getLabelId(), USER1, 2);
-
-    Collection<PatchSetApproval> filteredApprovals =
-        getApprovalsForLabel(ImmutableList.of(approvalVerified, approvalCr), codeReview, USER2);
-
-    assertThat(filteredApprovals).containsExactly(approvalCr);
-  }
-
-  @Test
-  public void filtersVotesFromUser() {
-    PatchSetApproval approvalM2 = makeApproval(VERIFIED.getLabelId(), USER1, -2);
-    PatchSetApproval approvalM1 = makeApproval(VERIFIED.getLabelId(), USER1, -1);
-
-    ImmutableList<PatchSetApproval> approvals =
-        ImmutableList.of(
-            approvalM2,
-            approvalM1,
-            makeApproval(VERIFIED.getLabelId(), USER1, 0),
-            makeApproval(VERIFIED.getLabelId(), USER1, +1),
-            makeApproval(VERIFIED.getLabelId(), USER1, +2));
-
-    Collection<PatchSetApproval> filteredApprovals =
-        getApprovalsForLabel(approvals, VERIFIED, USER1);
-
-    assertThat(filteredApprovals).containsExactly(approvalM1, approvalM2);
-  }
-
-  private static LabelType makeLabel(String labelName) {
-    List<LabelValue> values = new ArrayList<>();
-    // The label text is irrelevant here, only the numerical value is used
-    values.add(new LabelValue((short) -2, "-2"));
-    values.add(new LabelValue((short) -1, "-1"));
-    values.add(new LabelValue((short) 0, "No vote."));
-    values.add(new LabelValue((short) 1, "+1"));
-    values.add(new LabelValue((short) 2, "+2"));
-    return new LabelType(labelName, values);
-  }
-
-  private static PatchSetApproval makeApproval(LabelId labelId, Account.Id accountId, int value) {
-    PatchSetApproval.Key key = makeKey(PS_ID, accountId, labelId);
-    return new PatchSetApproval(key, (short) value, Date.from(Instant.now()));
-  }
-
-  private static PatchSetApproval.Key makeKey(
-      PatchSet.Id psId, Account.Id accountId, LabelId labelId) {
-    return new PatchSetApproval.Key(psId, accountId, labelId);
-  }
-
-  private static Account.Id makeAccount(int account) {
-    return new Account.Id(account);
-  }
-}