Merge "Update to new gwtorm target"
diff --git a/java/com/google/gerrit/plugins/checks/api/PendingChecksImpl.java b/java/com/google/gerrit/plugins/checks/api/PendingChecksImpl.java
index 4d70071..e3a1a94 100644
--- a/java/com/google/gerrit/plugins/checks/api/PendingChecksImpl.java
+++ b/java/com/google/gerrit/plugins/checks/api/PendingChecksImpl.java
@@ -17,7 +17,6 @@
 import static com.google.gerrit.server.api.ApiUtil.asRestApiException;
 
 import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.extensions.restapi.TopLevelResource;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
@@ -37,18 +36,12 @@
     return new QueryRequest() {
       @Override
       public List<PendingChecksInfo> get() throws RestApiException {
-        return PendingChecksImpl.this.query(this);
+        try {
+          return queryPendingChecksProvider.get().setQuery(getQuery()).apply();
+        } catch (Exception e) {
+          throw asRestApiException("Cannot query pending checks", e);
+        }
       }
     };
   }
-
-  private List<PendingChecksInfo> query(QueryRequest queryRequest) throws RestApiException {
-    try {
-      QueryPendingChecks queryPendingChecks = queryPendingChecksProvider.get();
-      queryPendingChecks.setQuery(queryRequest.getQuery());
-      return queryPendingChecks.apply(TopLevelResource.INSTANCE);
-    } catch (Exception e) {
-      throw asRestApiException("Cannot query pending checks", e);
-    }
-  }
 }
diff --git a/java/com/google/gerrit/plugins/checks/api/QueryPendingChecks.java b/java/com/google/gerrit/plugins/checks/api/QueryPendingChecks.java
index ef5d324..cededfa 100644
--- a/java/com/google/gerrit/plugins/checks/api/QueryPendingChecks.java
+++ b/java/com/google/gerrit/plugins/checks/api/QueryPendingChecks.java
@@ -66,8 +66,9 @@
       aliases = {"-q"},
       metaVar = "QUERY",
       usage = "check query")
-  public void setQuery(String queryString) {
+  public QueryPendingChecks setQuery(String queryString) {
     this.queryString = queryString;
+    return this;
   }
 
   @Inject
@@ -86,6 +87,11 @@
     this.changeQueryProcessorProvider = changeQueryProcessorProvider;
   }
 
+  public List<PendingChecksInfo> apply()
+      throws RestApiException, IOException, ConfigInvalidException, OrmException {
+    return apply(TopLevelResource.INSTANCE);
+  }
+
   @Override
   public List<PendingChecksInfo> apply(TopLevelResource resource)
       throws RestApiException, IOException, ConfigInvalidException, OrmException {
diff --git a/javatests/com/google/gerrit/plugins/checks/acceptance/ChecksRestApiBindingsIT.java b/javatests/com/google/gerrit/plugins/checks/acceptance/ChecksRestApiBindingsIT.java
index c492426..d34703d 100644
--- a/javatests/com/google/gerrit/plugins/checks/acceptance/ChecksRestApiBindingsIT.java
+++ b/javatests/com/google/gerrit/plugins/checks/acceptance/ChecksRestApiBindingsIT.java
@@ -14,9 +14,12 @@
 
 package com.google.gerrit.plugins.checks.acceptance;
 
+import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
+
 import com.google.common.collect.ImmutableList;
 import com.google.gerrit.acceptance.rest.util.RestApiCallHelper;
 import com.google.gerrit.acceptance.rest.util.RestCall;
+import com.google.gerrit.acceptance.rest.util.RestCall.Method;
 import com.google.gerrit.plugins.checks.CheckKey;
 import com.google.gerrit.plugins.checks.CheckerUuid;
 import com.google.gerrit.plugins.checks.api.CheckState;
@@ -26,8 +29,12 @@
 public class ChecksRestApiBindingsIT extends AbstractCheckersTest {
   private static final ImmutableList<RestCall> ROOT_ENDPOINTS =
       ImmutableList.of(
+          RestCall.get("/plugins/checks/checkers/"),
           RestCall.post("/plugins/checks/checkers/"),
-          RestCall.get("/plugins/checks/checks.pending/"));
+          RestCall.get("/plugins/checks/checks.pending/"),
+          RestCall.builder(Method.GET, "/plugins/checks/checks.pending/not-found")
+              .expectedResponseCode(SC_NOT_FOUND)
+              .build());
 
   private static final ImmutableList<RestCall> CHECKER_ENDPOINTS =
       ImmutableList.of(
diff --git a/javatests/com/google/gerrit/plugins/checks/acceptance/api/QueryPendingChecksIT.java b/javatests/com/google/gerrit/plugins/checks/acceptance/api/QueryPendingChecksIT.java
index c15b5d1..b5c9978 100644
--- a/javatests/com/google/gerrit/plugins/checks/acceptance/api/QueryPendingChecksIT.java
+++ b/javatests/com/google/gerrit/plugins/checks/acceptance/api/QueryPendingChecksIT.java
@@ -21,6 +21,7 @@
 import static org.hamcrest.CoreMatchers.instanceOf;
 
 import com.google.common.collect.Iterables;
+import com.google.gerrit.acceptance.RestResponse;
 import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
 import com.google.gerrit.common.data.Permission;
 import com.google.gerrit.extensions.restapi.BadRequestException;
@@ -35,6 +36,7 @@
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.server.project.testing.Util;
 import com.google.gerrit.testing.TestTimeUtil;
+import com.google.gson.reflect.TypeToken;
 import com.google.inject.Inject;
 import java.sql.Timestamp;
 import java.time.Instant;
@@ -111,13 +113,13 @@
   }
 
   @Test
-  public void canSpecifyCheckersAsRootPredicate() throws Exception {
+  public void canSpecifyCheckerAsRootPredicate() throws Exception {
     CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
     assertThat(queryPendingChecks(String.format("checker:\"%s\"", checkerUuid))).hasSize(1);
   }
 
   @Test
-  public void canSpecifyCheckersInAndCondition() throws Exception {
+  public void canSpecifyCheckerInAndCondition() throws Exception {
     CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
     assertThat(
             queryPendingChecks(String.format("checker:\"%s\" AND state:NOT_STARTED", checkerUuid)))
@@ -125,6 +127,19 @@
   }
 
   @Test
+  public void cannotSpecifyCheckerInAndConditionIfNotImmediateChild() throws Exception {
+    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
+
+    String expectedMessage =
+        "query must be 'checker:<checker-uuid>' or 'checker:<checker-uuid> AND <other-operators>'";
+    assertInvalidQuery(
+        String.format("state:NOT_STARTED AND (checker:\"%s\" OR state:NOT_STARTED)", checkerUuid),
+        expectedMessage);
+    assertInvalidQuery(
+        String.format("state:NOT_STARTED AND NOT checker:\"%s\"", checkerUuid), expectedMessage);
+  }
+
+  @Test
   public void andConditionAtRootCanContainAnyCombinationOfOtherPredicates() throws Exception {
     CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
 
@@ -146,7 +161,7 @@
   }
 
   @Test
-  public void cannotSpecifyCheckersInOrCondition() throws Exception {
+  public void cannotSpecifyCheckerInOrCondition() throws Exception {
     CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
 
     String expectedMessage =
@@ -158,7 +173,7 @@
   }
 
   @Test
-  public void cannotSpecifyCheckersInNotCondition() throws Exception {
+  public void cannotSpecifyCheckerInNotCondition() throws Exception {
     CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
     assertInvalidQuery(
         String.format("NOT checker:\"%s\"", checkerUuid),
@@ -551,6 +566,24 @@
     assertThat(pendingChecksList).isEmpty();
   }
 
+  @Test
+  public void pendingChecksViaRest() throws Exception {
+    CheckerUuid checkerUuid = checkerOperations.newChecker().repository(project).create();
+    checkOperations
+        .newCheck(CheckKey.create(project, patchSetId, checkerUuid))
+        .setState(CheckState.NOT_STARTED)
+        .upsert();
+
+    RestResponse r =
+        adminRestSession.get(
+            String.format("/plugins/checks/checks.pending/?q=checker:%s", checkerUuid.get()));
+    r.assertOK();
+    List<PendingChecksInfo> pendingChecksList =
+        newGson().fromJson(r.getReader(), new TypeToken<List<PendingChecksInfo>>() {}.getType());
+    r.consume();
+    assertThat(pendingChecksList).isNotEmpty();
+  }
+
   private void assertInvalidQuery(String query, String expectedMessage) throws RestApiException {
     try {
       pendingChecksApi.query(query).get();