Merge branch 'stable-2.16'

* stable-2.16:
  Shorten command to run tests
  Update documentation of where Bazel puts the jar
  Give an example of an API token in Documentation
  Drop `username` requirement from documentation
  Drop failing tests
  Drop documentation for `remove-project`

Change-Id: I49328309eaf9f5b64a6d0a58e024cb72f2fe8c24
diff --git a/src/main/resources/Documentation/build.md b/src/main/resources/Documentation/build.md
index 2d18690..a90457c 100644
--- a/src/main/resources/Documentation/build.md
+++ b/src/main/resources/Documentation/build.md
@@ -18,7 +18,7 @@
 The output is created in
 
 ```
-  bazel-genfiles/plugins/@PLUGIN@/@PLUGIN@.jar
+  bazel-bin/plugins/@PLUGIN@/@PLUGIN@.jar
 ```
 
 This project can be imported into the Eclipse IDE,
@@ -32,7 +32,7 @@
 To execute the tests run:
 
 ```
-  bazel test plugins/@PLUGIN@:its_phabricator_tests
+  bazel test plugins/@PLUGIN@:all
 ```
 
 [Back to @PLUGIN@ documentation index][index]
diff --git a/src/main/resources/Documentation/config-connectivity.md b/src/main/resources/Documentation/config-connectivity.md
index daa947a..84bc67f 100644
--- a/src/main/resources/Documentation/config-connectivity.md
+++ b/src/main/resources/Documentation/config-connectivity.md
@@ -2,7 +2,7 @@
 ========================
 
 In order for @PLUGIN@ to connect to your Phabricator instance, url (without
-trailing “/api”, “/conduit” or some such), user, and certificate are required in
+trailing “/api”, “/conduit” or some such), and certificate are required in
 your site's `etc/gerrit.config` or `etc/secure.config` under the `@PLUGIN@`
 section.
 
@@ -11,10 +11,12 @@
 ```
 [@PLUGIN@]
   url = http://my.phabricator.instance.example.org
-  token = TOKEN_FOR_ABOVE_USERNAME
+  token = TOKEN_AS_DESCRIBED_BELOW
 ```
 
 You can get your token by going to http://my.phabricator.instance.example.org/conduit/login/
+Tokens typically start in `cli-` and are followed by letters and digits, as
+for example `cli-zoenau772kfsrofqxt7cn55q4rng`.
 
 [Back to @PLUGIN@ documentation index][index]
 
diff --git a/src/main/resources/Documentation/config-rulebase-plugin-actions.md b/src/main/resources/Documentation/config-rulebase-plugin-actions.md
index 9fb7bf7..0662ff1 100644
--- a/src/main/resources/Documentation/config-rulebase-plugin-actions.md
+++ b/src/main/resources/Documentation/config-rulebase-plugin-actions.md
@@ -7,9 +7,6 @@
 [`add-project`][action-add-project]
 : adds a project to the task
 
-[`remove-project`][action-remove-project]
-: removes a project from the task
-
 [basic-actions]: config-rulebase-common.html#actions
 
 [action-add-project]: #action-add-project
@@ -24,18 +21,6 @@
 
 adds the project `MyCoolProject` to the task.
 
-[action-remove-project]: #action-remove-project
-### <a name="action-remove-project">Action: remove-project</a>
-
-The `remove-project` action removes a project from the task. The first
-parameter is the project name to remove. So for example
-
-```
-  action = remove-project MyCoolProject
-```
-
-removes the project `MyCoolProject` from the task.
-
 
 [Back to @PLUGIN@ documentation index][index]
 
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/phabricator/conduit/ConduitTest.java b/src/test/java/com/googlesource/gerrit/plugins/its/phabricator/conduit/ConduitTest.java
deleted file mode 100644
index 9dec435..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/its/phabricator/conduit/ConduitTest.java
+++ /dev/null
@@ -1,416 +0,0 @@
-// Copyright (C) 2017 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.its.phabricator.conduit;
-
-import static org.easymock.EasyMock.capture;
-import static org.easymock.EasyMock.eq;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.resetToStrict;
-import static org.powermock.api.easymock.PowerMock.expectNew;
-
-import com.google.gson.JsonObject;
-import com.google.gson.JsonPrimitive;
-import com.googlesource.gerrit.plugins.its.base.testutil.LoggingMockingTestCase;
-import com.googlesource.gerrit.plugins.its.phabricator.conduit.results.ConduitPing;
-import com.googlesource.gerrit.plugins.its.phabricator.conduit.results.ManiphestEdit;
-import com.googlesource.gerrit.plugins.its.phabricator.conduit.results.ManiphestInfo;
-import com.googlesource.gerrit.plugins.its.phabricator.conduit.results.ProjectInfo;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import org.easymock.Capture;
-import org.junit.runner.RunWith;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest(Conduit.class)
-public class ConduitTest extends LoggingMockingTestCase {
-  private static final String URL = "urlFoo";
-  private static final String TOKEN = "tokenFoo";
-
-  private ConduitConnection connection;
-
-  public void testConduitPingPass() throws Exception {
-    mockConnection();
-
-    resetToStrict(connection);
-
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    expect(connection.call(eq("conduit.ping"), capture(paramsCaptureRelevant), eq(TOKEN)))
-        .andReturn(new JsonPrimitive("foo"))
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, TOKEN);
-
-    ConduitPing actual = conduit.conduitPing();
-
-    assertEquals("Hostname does not match", "foo", actual.getHostname());
-  }
-
-  public void testConduitPingConnectionFail() throws Exception {
-    mockConnection();
-
-    resetToStrict(connection);
-
-    ConduitException conduitException = new ConduitException();
-
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    expect(connection.call(eq("conduit.ping"), capture(paramsCaptureRelevant), eq(TOKEN)))
-        .andThrow(conduitException)
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, TOKEN);
-
-    try {
-      conduit.conduitPing();
-      fail("no exception got thrown");
-    } catch (ConduitException e) {
-      assertSame(conduitException, e);
-    }
-  }
-
-  public void testManiphestInfoPass() throws Exception {
-    mockConnection();
-
-    resetToStrict(connection);
-
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    JsonObject retRelevant = new JsonObject();
-    retRelevant.add("id", new JsonPrimitive(42));
-
-    expect(connection.call(eq("maniphest.info"), capture(paramsCaptureRelevant), eq(TOKEN)))
-        .andReturn(retRelevant)
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, TOKEN);
-
-    ManiphestInfo maniphestInfo = conduit.maniphestInfo(42);
-
-    Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
-    assertEquals("Task id is not set", 42, paramsRelevant.get("task_id"));
-
-    assertEquals("ManiphestInfo's id does not match", 42, maniphestInfo.getId());
-  }
-
-  public void testManiphestInfoFailConnect() throws Exception {
-    mockConnection();
-
-    ConduitException conduitException = new ConduitException();
-
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    expect(connection.call(eq("maniphest.info"), capture(paramsCaptureRelevant), eq(TOKEN)))
-        .andThrow(conduitException)
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, TOKEN);
-
-    try {
-      conduit.maniphestInfo(42);
-      fail("no exception got thrown");
-    } catch (ConduitException e) {
-      assertSame(conduitException, e);
-    }
-  }
-
-  public void testManiphestInfoFailRelevant() throws Exception {
-    mockConnection();
-
-    resetToStrict(connection);
-
-    ConduitException conduitException = new ConduitException();
-
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    expect(connection.call(eq("maniphest.info"), capture(paramsCaptureRelevant), eq(TOKEN)))
-        .andThrow(conduitException)
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, TOKEN);
-
-    try {
-      conduit.maniphestInfo(42);
-      fail("no exception got thrown");
-    } catch (ConduitException e) {
-      assertSame(conduitException, e);
-    }
-
-    Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
-    assertEquals("Task id is not set", 42, paramsRelevant.get("task_id"));
-  }
-
-  public void testManiphestEditPassComment() throws Exception {
-    mockConnection();
-
-    resetToStrict(connection);
-
-    JsonObject retRelevant = new JsonObject();
-    retRelevant.add("id", new JsonPrimitive(42));
-
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    expect(connection.call(eq("maniphest.update"), capture(paramsCaptureRelevant), eq(TOKEN)))
-        .andReturn(retRelevant)
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, TOKEN);
-
-    ManiphestEdit maniphestEdit = conduit.maniphestEdit(42, "foo");
-
-    Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
-    assertEquals("Task id is not set", 42, paramsRelevant.get("id"));
-
-    assertEquals("ManiphestInfo's id does not match", 42, maniphestEdit.getId());
-  }
-
-  public void testManiphestEditPassProjects() throws Exception {
-    mockConnection();
-
-    resetToStrict(connection);
-
-    JsonObject retRelevant = new JsonObject();
-    retRelevant.add("id", new JsonPrimitive(42));
-
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    expect(connection.call(eq("maniphest.edit"), capture(paramsCaptureRelevant), eq(TOKEN)))
-        .andReturn(retRelevant)
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, TOKEN);
-
-    ManiphestEdit maniphestEdit =
-        conduit.maniphestEdit(42, Arrays.asList("foo", "bar"), Conduit.ACTION_PROJECT_ADD);
-
-    Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
-    assertEquals("Task id is not set", 42, paramsRelevant.get("id"));
-    assertEquals(
-        "Task projects are not set",
-        Arrays.asList("foo", "bar"),
-        paramsRelevant.get("projectPHIDs"));
-
-    assertEquals("ManiphestEdit's id does not match", 42, maniphestEdit.getId());
-  }
-
-  public void testManiphestEditPassCommentAndProjects() throws Exception {
-    mockConnection();
-
-    resetToStrict(connection);
-
-    JsonObject retRelevant = new JsonObject();
-    retRelevant.add("id", new JsonPrimitive(42));
-
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    expect(connection.call(eq("maniphest.edit"), capture(paramsCaptureRelevant), eq(TOKEN)))
-        .andReturn(retRelevant)
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, TOKEN);
-
-    ManiphestEdit maniphestEdit =
-        conduit.maniphestEdit(
-            42, "baz", Arrays.asList("foo", "bar"), Conduit.ACTION_PROJECT_REMOVE);
-
-    Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
-    assertEquals("Task id is not set", 42, paramsRelevant.get("id"));
-    assertEquals("Task comment is not set", "baz", paramsRelevant.get("comments"));
-    assertEquals(
-        "Task projects are not set",
-        Arrays.asList("foo", "bar"),
-        paramsRelevant.get("projectPHIDs"));
-
-    assertEquals("ManiphestUpdate's id does not match", 42, maniphestEdit.getId());
-  }
-
-  public void testManiphestEditFailConnect() throws Exception {
-    mockConnection();
-
-    ConduitException conduitException = new ConduitException();
-
-    Capture<Map<String, Object>> paramsCapture = new Capture<>();
-
-    expect(connection.call(eq("conduit.connect"), capture(paramsCapture), eq(TOKEN)))
-        .andThrow(conduitException)
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, null);
-
-    try {
-      conduit.maniphestEdit(42, "foo");
-      fail("no exception got thrown");
-    } catch (ConduitException e) {
-      assertSame(conduitException, e);
-    }
-  }
-
-  public void testManiphestEditFailRelevant() throws Exception {
-    mockConnection();
-
-    resetToStrict(connection);
-
-    ConduitException conduitException = new ConduitException();
-
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    expect(connection.call(eq("maniphest.edit"), capture(paramsCaptureRelevant), eq(TOKEN)))
-        .andThrow(conduitException)
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, TOKEN);
-
-    try {
-      conduit.maniphestEdit(42, "foo");
-      fail("no exception got thrown");
-    } catch (ConduitException e) {
-      assertSame(conduitException, e);
-    }
-
-    Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
-    assertEquals("Task id is not set", 42, paramsRelevant.get("id"));
-  }
-
-  public void testConnectionReuse() throws Exception {
-    mockConnection();
-
-    resetToStrict(connection);
-
-    JsonObject retRelevant = new JsonObject();
-    retRelevant.add("id", new JsonPrimitive(42));
-
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    expect(connection.call(eq("maniphest.info"), capture(paramsCaptureRelevant), eq(TOKEN)))
-        .andReturn(retRelevant)
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, TOKEN);
-
-    ManiphestInfo maniphestInfo = conduit.maniphestInfo(42);
-
-    Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
-    assertEquals("Task id is not set", 42, paramsRelevant.get("task_id"));
-
-    assertEquals("ManiphestInfo's id does not match", 42, maniphestInfo.getId());
-  }
-
-  public void testProjectQueryPass() throws Exception {
-    mockConnection();
-
-    resetToStrict(connection);
-
-    JsonObject projectInfoJson = new JsonObject();
-    projectInfoJson.addProperty("name", "foo");
-    projectInfoJson.addProperty("phid", "PHID-PROJ-bar");
-
-    JsonObject queryDataJson = new JsonObject();
-    queryDataJson.add("PHID-PROJ-bar", projectInfoJson);
-
-    JsonObject retRelevant = new JsonObject();
-    retRelevant.add("data", queryDataJson);
-
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    expect(connection.call(eq("project.query"), capture(paramsCaptureRelevant), eq(TOKEN)))
-        .andReturn(retRelevant)
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, TOKEN);
-
-    ProjectInfo projectInfo = conduit.projectQuery("foo");
-
-    Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
-    List<String> expectedNames = Arrays.asList("foo");
-    assertEquals("Project name does not match", expectedNames, paramsRelevant.get("names"));
-
-    assertEquals("ProjectInfo's name does not match", "foo", projectInfo.getName());
-  }
-
-  public void testProjectQueryPassMultipleResults() throws Exception {
-    mockConnection();
-
-    resetToStrict(connection);
-
-    JsonObject projectInfoJson1 = new JsonObject();
-    projectInfoJson1.addProperty("name", "foo1");
-    projectInfoJson1.addProperty("phid", "PHID-PROJ-bar1");
-
-    JsonObject projectInfoJson2 = new JsonObject();
-    projectInfoJson2.addProperty("name", "foo2");
-    projectInfoJson2.addProperty("phid", "PHID-PROJ-bar2");
-
-    JsonObject projectInfoJson3 = new JsonObject();
-    projectInfoJson3.addProperty("name", "foo3");
-    projectInfoJson3.addProperty("phid", "PHID-PROJ-bar3");
-
-    JsonObject queryDataJson = new JsonObject();
-    queryDataJson.add("PHID-PROJ-bar1", projectInfoJson1);
-    queryDataJson.add("PHID-PROJ-bar2", projectInfoJson2);
-    queryDataJson.add("PHID-PROJ-bar3", projectInfoJson3);
-
-    JsonObject retRelevant = new JsonObject();
-    retRelevant.add("data", queryDataJson);
-
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    expect(connection.call(eq("project.query"), capture(paramsCaptureRelevant), eq(TOKEN)))
-        .andReturn(retRelevant)
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, TOKEN);
-
-    ProjectInfo projectInfo = conduit.projectQuery("foo2");
-
-    Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
-    List<String> expectedNames = Arrays.asList("foo2");
-    assertEquals("Project name does not match", expectedNames, paramsRelevant.get("names"));
-
-    assertEquals("ProjectInfo's name does not match", "foo2", projectInfo.getName());
-  }
-
-  private void mockConnection() throws Exception {
-    connection = createMock(ConduitConnection.class);
-    expectNew(ConduitConnection.class, URL).andReturn(connection).once();
-  }
-}