]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6947 add missing coverage on PermissionsServiceTest
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Mon, 7 Dec 2015 14:36:11 +0000 (15:36 +0100)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Mon, 7 Dec 2015 14:36:40 +0000 (15:36 +0100)
sonar-ws/src/main/java/org/sonarqube/ws/client/BaseService.java
sonar-ws/src/test/java/org/sonarqube/ws/client/ServiceTester.java [new file with mode: 0644]
sonar-ws/src/test/java/org/sonarqube/ws/client/permission/PermissionsServiceTest.java [new file with mode: 0644]

index fea0cecd61528f79aef36fcfb3062302d8dc3e7b..e452e6f3e1accc1c112c2e421fc5a21f888fe055 100644 (file)
@@ -30,7 +30,7 @@ import static com.google.common.base.Strings.isNullOrEmpty;
 public abstract class BaseService {
 
   private final WsConnector wsConnector;
-  private final String controller;
+  protected final String controller;
 
   public BaseService(WsConnector wsConnector, String controllerPath) {
     checkArgument(!isNullOrEmpty(controllerPath));
diff --git a/sonar-ws/src/test/java/org/sonarqube/ws/client/ServiceTester.java b/sonar-ws/src/test/java/org/sonarqube/ws/client/ServiceTester.java
new file mode 100644 (file)
index 0000000..417e142
--- /dev/null
@@ -0,0 +1,320 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonarqube.ws.client;
+
+import com.google.protobuf.Parser;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.Immutable;
+import org.assertj.core.api.AbstractAssert;
+import org.assertj.core.api.Assertions;
+import org.assertj.core.data.MapEntry;
+import org.junit.rules.ExternalResource;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.spy;
+
+/**
+ * Convenient rule to test a subclass of {@link BaseService}.
+ *
+ * <p>
+ * Declaration sample:
+ * <pre>
+ * {@literal @}Rule
+ * public ServiceTester<PermissionsService> serviceTester = new ServiceTester&lt;&gt;(new PermissionsService(mock(WsConnector.class)));
+ *
+ * private PermissionsService underTest = serviceTester.getInstanceUnderTest();
+ * </pre>
+ * </p>
+ *
+ * <p>
+ * Method {@link #getInstanceUnderTest()} will return an instance of the class under test which will be instrumented
+ * and will allow recording internal calls to {@link BaseService#call(BaseRequest, Parser)} and
+ * {@link BaseService#call(WsRequest)}.
+ * </p>
+ * <p>
+ * Argument of calls to these method will be logged and can be accessed through {@link #getGetCalls()}, {@link #getPostCalls()}
+ * and {@link #getRawCalls()} depending on whether they are made respectively with {@link GetRequest}, {@link PostRequest}
+ * or other subclass of {@link BaseRequest}.
+ * </p>
+ * <p>
+ * For convenience, when one is testing a single Ws call, on case use {@link #getGetRequest()} (and its associated
+ * {@link #getGetParser()}) or {@link #getPostRequest()} (and its associated {@link #getPostParser()}). Those three
+ * method will make the appropriate assertions assuming that only a single GET (or POST) request has been made.
+ * </p>
+ * <p>
+ * Last but not least, to easily verify the content of a {@link GetRequest} (or a {@link PostRequest}), one can use
+ * methods {@link #assertThat(GetRequest)} (or {@link #assertThat(PostRequest)}) to write assertions on a
+ * {@link GetRequest} (or {@link PostRequest}) returned by methods of this Rule.
+ * </p>
+ *
+ * <p>
+ * Assertion usage sample:
+ * <pre>
+ * PostRequest postRequest = serviceTester.getPostRequest();
+ * serviceTester.assertThat(postRequest)
+ * .hasPath("add_group")
+ * .hasParam(PARAM_PERMISSION, PERMISSION_VALUE)
+ * .hasParam(PARAM_PROJECT_ID, PROJECT_ID_VALUE)
+ * .hasParam(PARAM_PROJECT_KEY, PROJECT_KEY_VALUE)
+ * .hasParam(PARAM_GROUP_ID, GROUP_ID_VALUE)
+ * .hasParam(PARAM_GROUP_NAME, GROUP_NAME_VALUE)
+ * .andNoOtherParam();
+ * </pre>
+ * </p>
+ *
+ */
+public class ServiceTester<T extends BaseService> extends ExternalResource {
+  private final T underTest;
+  private final List<GetCall> getCalls = new ArrayList<>();
+  private final List<PostCall> postCalls = new ArrayList<>();
+  private final List<RawCall> rawCalls = new ArrayList<>();
+
+  /**
+   * @param underTestInstance an instance of the type to test. Use {@link #getInstanceUnderTest()} to retrieve the
+   *                          instrumented instance to use in your test.
+   */
+  public ServiceTester(T underTestInstance) {
+    this.underTest = spy(underTestInstance);
+  }
+
+  @Override
+  protected void before() throws Throwable {
+    Answer<Object> answer = new Answer<Object>() {
+      @Override
+      public Object answer(InvocationOnMock invocation) throws Throwable {
+        Object[] arguments = invocation.getArguments();
+        Object request = arguments[0];
+        Parser<?> parser = arguments.length == 2 ? (Parser<?>) arguments[1] : null;
+        if (request instanceof PostRequest) {
+          postCalls.add(new PostCall((PostRequest) request, parser));
+        } else if (request instanceof GetRequest) {
+          getCalls.add(new GetCall((GetRequest) request, parser));
+        } else {
+          rawCalls.add(new RawCall((WsRequest) request));
+        }
+        return null;
+      }
+    };
+    doAnswer(answer).when(this.underTest).call(any(GetRequest.class), any(Parser.class));
+    doAnswer(answer).when(this.underTest).call(any(WsRequest.class));
+  }
+
+  @Override
+  protected void after() {
+    this.getCalls.clear();
+  }
+
+  public T getInstanceUnderTest() {
+    return underTest;
+  }
+
+  public List<GetCall> getGetCalls() {
+    return getCalls;
+  }
+
+  @CheckForNull
+  public GetRequest getGetRequest() {
+    assertSingleGetCall();
+    return getCalls.iterator().next().getRequest();
+  }
+
+  public RequestAssert<GetRequest> assertThat(GetRequest getRequest) {
+    return new RequestAssert<>(getRequest);
+  }
+
+  public RequestAssert<PostRequest> assertThat(PostRequest postRequest) {
+    return new RequestAssert<>(postRequest);
+  }
+
+  @CheckForNull
+  public Parser<?> getGetParser() {
+    assertSingleGetCall();
+    return getCalls.iterator().next().getParser();
+  }
+
+  public List<PostCall> getPostCalls() {
+    return postCalls;
+  }
+
+  public PostRequest getPostRequest() {
+    assertSinglePostCall();
+    return postCalls.iterator().next().getRequest();
+  }
+
+  @CheckForNull
+  public Parser<?> getPostParser() {
+    assertSinglePostCall();
+    return postCalls.iterator().next().getParser();
+  }
+
+  private void assertSingleGetCall() {
+    Assertions.assertThat(getCalls).hasSize(1);
+    Assertions.assertThat(postCalls).isEmpty();
+    Assertions.assertThat(rawCalls).isEmpty();
+  }
+
+  private void assertSinglePostCall() {
+    Assertions.assertThat(postCalls).hasSize(1);
+    Assertions.assertThat(getRawCalls()).isEmpty();
+    Assertions.assertThat(rawCalls).isEmpty();
+  }
+
+  public List<RawCall> getRawCalls() {
+    return rawCalls;
+  }
+
+  @Immutable
+  public static final class GetCall extends CallWithParser<GetRequest> {
+
+    public GetCall(GetRequest getRequest, @Nullable Parser<?> parser) {
+      super(getRequest, parser);
+    }
+
+  }
+
+  @Immutable
+  public static final class PostCall extends CallWithParser<PostRequest> {
+
+    public PostCall(PostRequest postRequest, @Nullable Parser<?> parser) {
+      super(postRequest, parser);
+    }
+  }
+
+  @Immutable
+  public static final class RawCall {
+    private final WsRequest wsRequest;
+
+    public RawCall(WsRequest wsRequest) {
+      this.wsRequest = wsRequest;
+    }
+
+    public WsRequest getWsRequest() {
+      return wsRequest;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+      if (this == o) {
+        return true;
+      }
+      if (o == null || getClass() != o.getClass()) {
+        return false;
+      }
+      RawCall rawCalls = (RawCall) o;
+      return Objects.equals(wsRequest, rawCalls.wsRequest);
+    }
+
+    @Override
+    public int hashCode() {
+      return Objects.hash(wsRequest);
+    }
+  }
+
+  public static abstract class CallWithParser<T extends BaseRequest<T>> {
+    private final T request;
+    private final Parser<?> parser;
+
+    public CallWithParser(T request, @Nullable Parser<?> parser) {
+      this.request = request;
+      this.parser = parser;
+    }
+
+    public T getRequest() {
+      return request;
+    }
+
+    public Parser<?> getParser() {
+      return parser;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+      if (this == o) {
+        return true;
+      }
+      if (o == null || getClass() != o.getClass()) {
+        return false;
+      }
+      CallWithParser getCall = (CallWithParser) o;
+      return Objects.equals(request, getCall.request) &&
+        Objects.equals(parser, getCall.request);
+    }
+
+    @Override
+    public int hashCode() {
+      return Objects.hash(request, parser);
+    }
+  }
+
+  public final class RequestAssert<T extends BaseRequest<T>> extends AbstractAssert<RequestAssert<T>, BaseRequest<T>> {
+    private final List<MapEntry<String, String>> assertedParams = new ArrayList<>();
+
+    protected RequestAssert(T actual) {
+      super(actual, RequestAssert.class);
+    }
+
+    public RequestAssert hasPath(String path) {
+      isNotNull();
+
+      String expectedPath = underTest.controller + "/" + path;
+      if (!Objects.equals(actual.getPath(), expectedPath)) {
+        failWithMessage("Expected path to be <%s> but was <%s>", expectedPath, actual.getPath());
+      }
+
+      return this;
+    }
+
+    public RequestAssert hasParam(String key, String value) {
+      isNotNull();
+
+      MapEntry<String, String> entry = MapEntry.entry(key, value);
+      Assertions.assertThat(actual.getParams()).contains(entry);
+      this.assertedParams.add(entry);
+
+      return this;
+    }
+
+    public RequestAssert hasParam(String key, int value) {
+      isNotNull();
+
+      MapEntry<String, String> entry = MapEntry.entry(key, String.valueOf(value));
+      Assertions.assertThat(actual.getParams()).contains(entry);
+      this.assertedParams.add(entry);
+
+      return this;
+    }
+
+    public RequestAssert andNoOtherParam() {
+      isNotNull();
+
+      Assertions.assertThat(actual.getParams()).hasSize(assertedParams.size());
+
+      return this;
+    }
+
+  }
+}
diff --git a/sonar-ws/src/test/java/org/sonarqube/ws/client/permission/PermissionsServiceTest.java b/sonar-ws/src/test/java/org/sonarqube/ws/client/permission/PermissionsServiceTest.java
new file mode 100644 (file)
index 0000000..5bdac30
--- /dev/null
@@ -0,0 +1,438 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonarqube.ws.client.permission;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonarqube.ws.WsPermissions;
+import org.sonarqube.ws.client.GetRequest;
+import org.sonarqube.ws.client.PostRequest;
+import org.sonarqube.ws.client.ServiceTester;
+import org.sonarqube.ws.client.WsConnector;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_DESCRIPTION;
+import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_GROUP_ID;
+import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_GROUP_NAME;
+import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_ID;
+import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_NAME;
+import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION;
+import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID;
+import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY;
+import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY_PATTERN;
+import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_QUALIFIER;
+import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_ID;
+import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_NAME;
+import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_USER_LOGIN;
+
+public class PermissionsServiceTest {
+  private static final String PERMISSION_VALUE = "permission value";
+  private static final String PROJECT_ID_VALUE = "project id value";
+  private static final String PROJECT_KEY_VALUE = "project key value";
+  private static final String QUERY_VALUE = "query value";
+  private static final String SELECTED_VALUE = "selected value";
+  private static final int PAGE_VALUE = 66;
+  private static final int PAGE_SIZE_VALUE = 99;
+  private static final String GROUP_ID_VALUE = "group id value";
+  private static final String GROUP_NAME_VALUE = "group name value";
+  private static final String TEMPLATE_ID_VALUE = "template id value";
+  private static final String TEMPLATE_NAME_VALUE = "template name value";
+  private static final String LOGIN_VALUE = "login value";
+  private static final String NAME_VALUE = "name value";
+  private static final String DESCRIPTION_VALUE = "description value";
+  private static final String PROJECT_KEY_PATTERN_VALUE = "project key pattern value";
+  private static final String QUALIFIER_VALUE = "qualifier value";
+  private static final String PARAM_Q = "q";
+  private static final String PARAM_PS = "ps";
+  private static final String PARAM_P = "p";
+  private static final String PARAM_SELECTED = "selected";
+
+  @Rule
+  public ServiceTester<PermissionsService> serviceTester = new ServiceTester<>(new PermissionsService(mock(WsConnector.class)));
+
+  private PermissionsService underTest = serviceTester.getInstanceUnderTest();
+
+  @Test(expected = NullPointerException.class)
+  public void groups_throws_NPE_if_GroupWsRequest_argument_is_null() {
+    underTest.groups(null);
+  }
+
+  @Test
+  public void groups_does_POST_on_WS_groups() {
+    GroupsWsRequest request = new GroupsWsRequest();
+    underTest.groups(request
+      .setPermission(PERMISSION_VALUE)
+      .setProjectId(PROJECT_ID_VALUE)
+      .setProjectKey(PROJECT_KEY_VALUE)
+      .setPage(PAGE_VALUE)
+      .setPageSize(PAGE_SIZE_VALUE)
+      .setSelected(SELECTED_VALUE)
+      .setQuery(QUERY_VALUE));
+
+    assertThat(serviceTester.getGetParser()).isSameAs(WsPermissions.WsGroupsResponse.parser());
+    GetRequest getRequest = serviceTester.getGetRequest();
+    serviceTester.assertThat(getRequest)
+      .hasPath("groups")
+      .hasParam(PARAM_PERMISSION, PERMISSION_VALUE)
+      .hasParam(PARAM_PROJECT_ID, PROJECT_ID_VALUE)
+      .hasParam(PARAM_PROJECT_KEY, PROJECT_KEY_VALUE)
+      .hasParam(PARAM_P, PAGE_VALUE)
+      .hasParam(PARAM_PS, PAGE_SIZE_VALUE)
+      .hasParam(PARAM_SELECTED, SELECTED_VALUE)
+      .hasParam(PARAM_Q, QUERY_VALUE)
+      .andNoOtherParam();
+  }
+
+  @Test
+  public void addGroup_does_POST_on_Ws_add_group() {
+    underTest.addGroup(new AddGroupWsRequest()
+      .setPermission(PERMISSION_VALUE)
+      .setProjectId(PROJECT_ID_VALUE)
+      .setProjectKey(PROJECT_KEY_VALUE)
+      .setGroupId(GROUP_ID_VALUE)
+      .setGroupName(GROUP_NAME_VALUE));
+
+    assertThat(serviceTester.getPostParser()).isNull();
+    PostRequest postRequest = serviceTester.getPostRequest();
+    serviceTester.assertThat(postRequest)
+      .hasPath("add_group")
+      .hasParam(PARAM_PERMISSION, PERMISSION_VALUE)
+      .hasParam(PARAM_PROJECT_ID, PROJECT_ID_VALUE)
+      .hasParam(PARAM_PROJECT_KEY, PROJECT_KEY_VALUE)
+      .hasParam(PARAM_GROUP_ID, GROUP_ID_VALUE)
+      .hasParam(PARAM_GROUP_NAME, GROUP_NAME_VALUE)
+      .andNoOtherParam();
+  }
+
+  @Test
+  public void addGroupToTemplate_does_POST_on_Ws_add_group_to_template() {
+    underTest.addGroupToTemplate(
+      new AddGroupToTemplateWsRequest()
+        .setGroupId(GROUP_ID_VALUE)
+        .setGroupName(GROUP_NAME_VALUE)
+        .setPermission(PERMISSION_VALUE)
+        .setTemplateId(TEMPLATE_ID_VALUE)
+        .setTemplateName(TEMPLATE_NAME_VALUE)
+      );
+
+    assertThat(serviceTester.getPostParser()).isNull();
+    PostRequest postRequest = serviceTester.getPostRequest();
+    serviceTester.assertThat(postRequest)
+      .hasPath("add_group_to_template")
+      .hasParam(PARAM_GROUP_ID, GROUP_ID_VALUE)
+      .hasParam(PARAM_GROUP_NAME, GROUP_NAME_VALUE)
+      .hasParam(PARAM_PERMISSION, PERMISSION_VALUE)
+      .hasParam(PARAM_TEMPLATE_ID, TEMPLATE_ID_VALUE)
+      .hasParam(PARAM_TEMPLATE_NAME, TEMPLATE_NAME_VALUE)
+      .andNoOtherParam();
+  }
+
+  @Test
+  public void addUser_does_POST_on_Ws_add_user() {
+    underTest.addUser(new AddUserWsRequest()
+      .setLogin(LOGIN_VALUE)
+      .setPermission(PERMISSION_VALUE)
+      .setProjectId(PROJECT_ID_VALUE)
+      .setProjectKey(PROJECT_KEY_VALUE)
+      );
+
+    assertThat(serviceTester.getPostParser()).isNull();
+    PostRequest postRequest = serviceTester.getPostRequest();
+    serviceTester.assertThat(postRequest)
+      .hasPath("add_user")
+      .hasParam(PARAM_USER_LOGIN, LOGIN_VALUE)
+      .hasParam(PARAM_PERMISSION, PERMISSION_VALUE)
+      .hasParam(PARAM_PROJECT_ID, PROJECT_ID_VALUE)
+      .hasParam(PARAM_PROJECT_KEY, PROJECT_KEY_VALUE)
+      .andNoOtherParam();
+  }
+
+  @Test
+  public void addUserToTemplate_does_POST_on_Ws_add_user_to_template() {
+    underTest.addUserToTemplate(new AddUserToTemplateWsRequest()
+      .setPermission(PERMISSION_VALUE)
+      .setLogin(LOGIN_VALUE)
+      .setTemplateId(TEMPLATE_ID_VALUE)
+      .setTemplateName(TEMPLATE_NAME_VALUE)
+      );
+
+    assertThat(serviceTester.getPostParser()).isNull();
+    PostRequest postRequest = serviceTester.getPostRequest();
+    serviceTester.assertThat(postRequest)
+      .hasPath("add_user_to_template")
+      .hasParam(PARAM_PERMISSION, PERMISSION_VALUE)
+      .hasParam(PARAM_USER_LOGIN, LOGIN_VALUE)
+      .hasParam(PARAM_TEMPLATE_ID, TEMPLATE_ID_VALUE)
+      .hasParam(PARAM_TEMPLATE_NAME, TEMPLATE_NAME_VALUE)
+      .andNoOtherParam();
+  }
+
+  @Test
+  public void applyTemplate_does_POST_on_Ws_apply_template() {
+    underTest.applyTemplate(new ApplyTemplateWsRequest()
+      .setProjectId(PROJECT_ID_VALUE)
+      .setProjectKey(PROJECT_KEY_VALUE)
+      .setTemplateId(TEMPLATE_ID_VALUE)
+      .setTemplateName(TEMPLATE_NAME_VALUE)
+      );
+
+    assertThat(serviceTester.getPostParser()).isNull();
+    PostRequest postRequest = serviceTester.getPostRequest();
+    serviceTester.assertThat(postRequest)
+      .hasPath("apply_template")
+      .hasParam(PARAM_PROJECT_ID, PROJECT_ID_VALUE)
+      .hasParam(PARAM_PROJECT_KEY, PROJECT_KEY_VALUE)
+      .hasParam(PARAM_TEMPLATE_ID, TEMPLATE_ID_VALUE)
+      .hasParam(PARAM_TEMPLATE_NAME, TEMPLATE_NAME_VALUE)
+      .andNoOtherParam();
+  }
+
+  @Test
+  public void createTemplate_does_POST_on_Ws_create_template() {
+    underTest.createTemplate(new CreateTemplateWsRequest()
+      .setName(NAME_VALUE)
+      .setDescription(DESCRIPTION_VALUE)
+      .setProjectKeyPattern(PROJECT_KEY_PATTERN_VALUE)
+      );
+
+    assertThat(serviceTester.getPostParser()).isSameAs(WsPermissions.CreateTemplateWsResponse.parser());
+    PostRequest postRequest = serviceTester.getPostRequest();
+    serviceTester.assertThat(postRequest)
+      .hasPath("create_template")
+      .hasParam(PARAM_NAME, NAME_VALUE)
+      .hasParam(PARAM_DESCRIPTION, DESCRIPTION_VALUE)
+      .hasParam(PARAM_PROJECT_KEY_PATTERN, PROJECT_KEY_PATTERN_VALUE)
+      .andNoOtherParam();
+  }
+
+  @Test
+  public void deleteTemplate_does_POST_on_Ws_delete_template() {
+    underTest.deleteTemplate(new DeleteTemplateWsRequest()
+      .setTemplateId(TEMPLATE_ID_VALUE)
+      .setTemplateName(TEMPLATE_NAME_VALUE)
+      );
+
+    assertThat(serviceTester.getPostParser()).isNull();
+    PostRequest postRequest = serviceTester.getPostRequest();
+    serviceTester.assertThat(postRequest)
+      .hasPath("delete_template")
+      .hasParam(PARAM_TEMPLATE_ID, TEMPLATE_ID_VALUE)
+      .hasParam(PARAM_TEMPLATE_NAME, TEMPLATE_NAME_VALUE)
+      .andNoOtherParam();
+  }
+
+  @Test
+  public void removeGroup_does_POST_on_Ws_remove_group() {
+    underTest.removeGroup(new RemoveGroupWsRequest()
+      .setPermission(PERMISSION_VALUE)
+      .setGroupId(GROUP_ID_VALUE)
+      .setGroupName(GROUP_NAME_VALUE)
+      .setProjectId(PROJECT_ID_VALUE)
+      .setProjectKey(PROJECT_KEY_VALUE)
+      );
+
+    assertThat(serviceTester.getPostParser()).isNull();
+    PostRequest postRequest = serviceTester.getPostRequest();
+    serviceTester.assertThat(postRequest)
+      .hasPath("remove_group")
+      .hasParam(PARAM_PERMISSION, PERMISSION_VALUE)
+      .hasParam(PARAM_GROUP_ID, GROUP_ID_VALUE)
+      .hasParam(PARAM_GROUP_NAME, GROUP_NAME_VALUE)
+      .hasParam(PARAM_PROJECT_ID, PROJECT_ID_VALUE)
+      .hasParam(PARAM_PROJECT_KEY, PROJECT_KEY_VALUE)
+      .andNoOtherParam();
+  }
+
+  @Test
+  public void removeGroupFromTemplate_does_POST_on_Ws_remove_group_from_template() {
+    underTest.removeGroupFromTemplate(new RemoveGroupFromTemplateWsRequest()
+      .setPermission(PERMISSION_VALUE)
+      .setGroupId(GROUP_ID_VALUE)
+      .setGroupName(GROUP_NAME_VALUE)
+      .setTemplateId(TEMPLATE_ID_VALUE)
+      .setTemplateName(TEMPLATE_NAME_VALUE)
+      );
+
+    assertThat(serviceTester.getPostParser()).isNull();
+    PostRequest postRequest = serviceTester.getPostRequest();
+    serviceTester.assertThat(postRequest)
+      .hasPath("remove_group_from_template")
+      .hasParam(PARAM_PERMISSION, PERMISSION_VALUE)
+      .hasParam(PARAM_GROUP_ID, GROUP_ID_VALUE)
+      .hasParam(PARAM_GROUP_NAME, GROUP_NAME_VALUE)
+      .hasParam(PARAM_TEMPLATE_ID, TEMPLATE_ID_VALUE)
+      .hasParam(PARAM_TEMPLATE_NAME, TEMPLATE_NAME_VALUE)
+      .andNoOtherParam();
+  }
+
+  @Test
+  public void removeUser_does_POST_on_Ws_remove_user() {
+    underTest.removeUser(new RemoveUserWsRequest()
+      .setPermission(PERMISSION_VALUE)
+      .setLogin(LOGIN_VALUE)
+      .setProjectId(PROJECT_ID_VALUE)
+      .setProjectKey(PROJECT_KEY_VALUE)
+      );
+
+    assertThat(serviceTester.getPostParser()).isNull();
+    PostRequest postRequest = serviceTester.getPostRequest();
+    serviceTester.assertThat(postRequest)
+      .hasPath("remove_user")
+      .hasParam(PARAM_PERMISSION, PERMISSION_VALUE)
+      .hasParam(PARAM_USER_LOGIN, LOGIN_VALUE)
+      .hasParam(PARAM_PROJECT_ID, PROJECT_ID_VALUE)
+      .hasParam(PARAM_PROJECT_KEY, PROJECT_KEY_VALUE)
+      .andNoOtherParam();
+  }
+
+  @Test
+  public void removeUserFromTemplate_does_POST_on_Ws_remove_user_from_template() {
+    underTest.removeUserFromTemplate(new RemoveUserFromTemplateWsRequest()
+      .setPermission(PERMISSION_VALUE)
+      .setLogin(LOGIN_VALUE)
+      .setTemplateId(TEMPLATE_ID_VALUE)
+      .setTemplateName(TEMPLATE_NAME_VALUE)
+      );
+
+    assertThat(serviceTester.getPostParser()).isNull();
+    PostRequest postRequest = serviceTester.getPostRequest();
+    serviceTester.assertThat(postRequest)
+      .hasPath("remove_user_from_template")
+      .hasParam(PARAM_PERMISSION, PERMISSION_VALUE)
+      .hasParam(PARAM_USER_LOGIN, LOGIN_VALUE)
+      .hasParam(PARAM_TEMPLATE_ID, TEMPLATE_ID_VALUE)
+      .hasParam(PARAM_TEMPLATE_NAME, TEMPLATE_NAME_VALUE)
+      .andNoOtherParam();
+  }
+
+  @Test
+  public void searchGlobalPermissions_does_GET_on_Ws_search_global_permissions() {
+    underTest.searchGlobalPermissions();
+
+    assertThat(serviceTester.getGetParser()).isSameAs(WsPermissions.WsSearchGlobalPermissionsResponse.parser());
+    GetRequest getRequest = serviceTester.getGetRequest();
+    serviceTester.assertThat(getRequest)
+      .hasPath("search_global_permissions")
+      .andNoOtherParam();
+  }
+
+  @Test
+  public void searchProjectPermissions_does_GET_on_Ws_search_project_permissions() {
+    underTest.searchProjectPermissions(new SearchProjectPermissionsWsRequest()
+      .setProjectId(PROJECT_ID_VALUE)
+      .setProjectKey(PROJECT_KEY_VALUE)
+      .setQualifier(QUALIFIER_VALUE)
+      .setPage(PAGE_VALUE)
+      .setPageSize(PAGE_SIZE_VALUE)
+      .setQuery(QUERY_VALUE)
+      );
+
+    assertThat(serviceTester.getGetParser()).isSameAs(WsPermissions.SearchProjectPermissionsWsResponse.parser());
+    GetRequest getRequest = serviceTester.getGetRequest();
+    serviceTester.assertThat(getRequest)
+      .hasPath("search_project_permissions")
+      .hasParam(PARAM_PROJECT_ID, PROJECT_ID_VALUE)
+      .hasParam(PARAM_PROJECT_KEY, PROJECT_KEY_VALUE)
+      .hasParam(PARAM_QUALIFIER, QUALIFIER_VALUE)
+      .hasParam(PARAM_P, PAGE_VALUE)
+      .hasParam(PARAM_PS, PAGE_SIZE_VALUE)
+      .hasParam(PARAM_Q, QUERY_VALUE)
+      .andNoOtherParam();
+  }
+
+  @Test
+  public void searchTemplates_does_GET_on_Ws_search_templates() {
+    underTest.searchTemplates(new SearchTemplatesWsRequest()
+      .setQuery(QUERY_VALUE)
+      );
+
+    assertThat(serviceTester.getGetParser()).isSameAs(WsPermissions.SearchTemplatesWsResponse.parser());
+    GetRequest getRequest = serviceTester.getGetRequest();
+    serviceTester.assertThat(getRequest)
+      .hasPath("search_templates")
+      .hasParam(PARAM_Q, QUERY_VALUE)
+      .andNoOtherParam();
+  }
+
+  @Test
+  public void setDefaultTemplate_does_POST_on_Ws_set_default_template() {
+    underTest.setDefaultTemplate(new SetDefaultTemplateWsRequest()
+      .setQualifier(QUALIFIER_VALUE)
+      .setTemplateId(TEMPLATE_ID_VALUE)
+      .setTemplateName(TEMPLATE_NAME_VALUE)
+      );
+
+    assertThat(serviceTester.getPostParser()).isNull();
+    PostRequest postRequest = serviceTester.getPostRequest();
+    serviceTester.assertThat(postRequest)
+      .hasPath("set_default_template")
+      .hasParam(PARAM_QUALIFIER, QUALIFIER_VALUE)
+      .hasParam(PARAM_TEMPLATE_ID, TEMPLATE_ID_VALUE)
+      .hasParam(PARAM_TEMPLATE_NAME, TEMPLATE_NAME_VALUE)
+      .andNoOtherParam();
+  }
+
+  @Test
+  public void updateTemplate_does_POST_on_Ws_update_template() {
+    underTest.updateTemplate(new UpdateTemplateWsRequest()
+      .setDescription(DESCRIPTION_VALUE)
+      .setId(TEMPLATE_ID_VALUE)
+      .setName(TEMPLATE_NAME_VALUE)
+      .setProjectKeyPattern(PROJECT_KEY_PATTERN_VALUE)
+      );
+
+    assertThat(serviceTester.getPostParser()).isSameAs(WsPermissions.UpdateTemplateWsResponse.parser());
+    PostRequest postRequest = serviceTester.getPostRequest();
+    serviceTester.assertThat(postRequest)
+      .hasPath("update_template")
+      .hasParam(PARAM_DESCRIPTION, DESCRIPTION_VALUE)
+      .hasParam(PARAM_ID, TEMPLATE_ID_VALUE)
+      .hasParam(PARAM_NAME, TEMPLATE_NAME_VALUE)
+      .hasParam(PARAM_PROJECT_KEY_PATTERN, PROJECT_KEY_PATTERN_VALUE)
+      .andNoOtherParam();
+  }
+
+  @Test
+  public void users_does_GET_on_Ws_users() {
+    underTest.users(new UsersWsRequest()
+      .setPermission(PERMISSION_VALUE)
+      .setProjectId(PROJECT_ID_VALUE)
+      .setProjectKey(PROJECT_KEY_VALUE)
+      .setSelected(SELECTED_VALUE)
+      .setPage(PAGE_VALUE)
+      .setPageSize(PAGE_SIZE_VALUE)
+      .setQuery(QUERY_VALUE)
+      );
+
+    assertThat(serviceTester.getGetParser()).isSameAs(WsPermissions.UsersWsResponse.parser());
+    GetRequest getRequest = serviceTester.getGetRequest();
+    serviceTester.assertThat(getRequest)
+      .hasPath("users")
+      .hasParam(PARAM_PERMISSION, PERMISSION_VALUE)
+      .hasParam(PARAM_PROJECT_ID, PROJECT_ID_VALUE)
+      .hasParam(PARAM_PROJECT_KEY, PROJECT_KEY_VALUE)
+      .hasParam(PARAM_SELECTED, SELECTED_VALUE)
+      .hasParam(PARAM_P, PAGE_VALUE)
+      .hasParam(PARAM_PS, PAGE_SIZE_VALUE)
+      .hasParam(PARAM_Q, QUERY_VALUE)
+      .andNoOtherParam();
+  }
+}