From: Sébastien Lesaint Date: Wed, 28 Aug 2019 14:52:53 +0000 (+0200) Subject: use testFixtures instead of test configuration of webserver-ws X-Git-Tag: 8.0~181 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=f0f55945b8c05cfb3feda3d06ceea4173467c31a;p=sonarqube.git use testFixtures instead of test configuration of webserver-ws --- diff --git a/build.gradle b/build.gradle index a967d1a6267..1cb2102ad0f 100644 --- a/build.gradle +++ b/build.gradle @@ -95,6 +95,7 @@ subprojects { apply plugin: 'io.spring.dependency-management' apply plugin: 'jacoco' apply plugin: 'java' + apply plugin: 'java-test-fixtures' apply plugin: 'idea' apply plugin: 'org.owasp.dependencycheck' diff --git a/server/sonar-webserver-core/build.gradle b/server/sonar-webserver-core/build.gradle index 9e1d57fa1d7..ea21d81838d 100644 --- a/server/sonar-webserver-core/build.gradle +++ b/server/sonar-webserver-core/build.gradle @@ -75,7 +75,7 @@ dependencies { testCompile project(path: ":server:sonar-server-common", configuration: "tests") testCompile project(path: ":server:sonar-webserver-auth", configuration: "tests") testCompile project(path: ":server:sonar-webserver-es", configuration: "tests") - testCompile project(path: ":server:sonar-webserver-ws", configuration: "tests") + testCompile testFixtures(project(':server:sonar-webserver-ws')) testCompile project(':sonar-testing-harness') runtime 'io.jsonwebtoken:jjwt-jackson' diff --git a/server/sonar-webserver-webapi/build.gradle b/server/sonar-webserver-webapi/build.gradle index b1428c97c94..58b5f8e7064 100644 --- a/server/sonar-webserver-webapi/build.gradle +++ b/server/sonar-webserver-webapi/build.gradle @@ -37,7 +37,7 @@ dependencies { testCompile project(path: ":server:sonar-server-common", configuration: "tests") testCompile project(path: ":server:sonar-webserver-auth", configuration: "tests") testCompile project(path: ":server:sonar-webserver-es", configuration: "tests") - testCompile project(path: ":server:sonar-webserver-ws", configuration: "tests") + testCompile testFixtures(project(':server:sonar-webserver-ws')) testCompile project(':sonar-testing-harness') } diff --git a/server/sonar-webserver-ws/build.gradle b/server/sonar-webserver-ws/build.gradle index 7fa56ae5c0b..33d0249b7f1 100644 --- a/server/sonar-webserver-ws/build.gradle +++ b/server/sonar-webserver-ws/build.gradle @@ -6,12 +6,6 @@ sonarqube { } } -configurations { - tests - - testCompile.extendsFrom tests -} - dependencies { // please keep the list grouped by configuration and ordered by name @@ -30,14 +24,8 @@ dependencies { testCompile 'javax.servlet:javax.servlet-api' testCompile 'org.apache.tomcat.embed:tomcat-embed-core' testCompile 'org.mockito:mockito-core' - testCompile project(':sonar-testing-harness') -} -task testJar(type: Jar) { - classifier = 'tests' - from sourceSets.test.output -} + testFixturesApi project(':sonar-testing-harness') -artifacts { - tests testJar + testFixturesCompileOnly 'com.google.code.findbugs:jsr305' } diff --git a/server/sonar-webserver-ws/src/test/java/org/sonar/server/ws/DumbResponse.java b/server/sonar-webserver-ws/src/test/java/org/sonar/server/ws/DumbResponse.java deleted file mode 100644 index f7d2aeedd80..00000000000 --- a/server/sonar-webserver-ws/src/test/java/org/sonar/server/ws/DumbResponse.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program 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. - * - * This program 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.sonar.server.ws; - -import com.google.common.base.Throwables; -import com.google.common.collect.Maps; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.net.HttpURLConnection; -import java.nio.charset.StandardCharsets; -import java.util.Collection; -import java.util.Map; -import javax.annotation.CheckForNull; -import org.apache.commons.io.IOUtils; -import org.sonar.api.server.ws.Response; -import org.sonar.api.utils.text.JsonWriter; -import org.sonar.api.utils.text.XmlWriter; - -public class DumbResponse implements Response { - private InMemoryStream stream; - - private final ByteArrayOutputStream output = new ByteArrayOutputStream(); - - private Map headers = Maps.newHashMap(); - - public class InMemoryStream implements Response.Stream { - private String mediaType; - - private int status = 200; - - @CheckForNull - public String mediaType() { - return mediaType; - } - - public int status() { - return status; - } - - @Override - public Response.Stream setMediaType(String s) { - this.mediaType = s; - return this; - } - - @Override - public Response.Stream setStatus(int i) { - this.status = i; - return this; - } - - @Override - public OutputStream output() { - return output; - } - - public String outputAsString() { - return new String(output.toByteArray(), StandardCharsets.UTF_8); - } - } - - @Override - public JsonWriter newJsonWriter() { - return JsonWriter.of(new OutputStreamWriter(output, StandardCharsets.UTF_8)); - } - - @Override - public XmlWriter newXmlWriter() { - return XmlWriter.of(new OutputStreamWriter(output, StandardCharsets.UTF_8)); - } - - @Override - public InMemoryStream stream() { - if (stream == null) { - stream = new InMemoryStream(); - } - return stream; - } - - @Override - public Response noContent() { - stream().setStatus(HttpURLConnection.HTTP_NO_CONTENT); - IOUtils.closeQuietly(output); - return this; - } - - public String outputAsString() { - return new String(output.toByteArray(), StandardCharsets.UTF_8); - } - - @Override - public Response setHeader(String name, String value) { - headers.put(name, value); - return this; - } - - public Collection getHeaderNames() { - return headers.keySet(); - } - - @CheckForNull - public String getHeader(String name){ - return headers.get(name); - } - - public byte[] getFlushedOutput() { - try { - output.flush(); - return output.toByteArray(); - } catch (IOException e) { - throw Throwables.propagate(e); - } - } -} diff --git a/server/sonar-webserver-ws/src/test/java/org/sonar/server/ws/TestRequest.java b/server/sonar-webserver-ws/src/test/java/org/sonar/server/ws/TestRequest.java deleted file mode 100644 index aea0e0d69bd..00000000000 --- a/server/sonar-webserver-ws/src/test/java/org/sonar/server/ws/TestRequest.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program 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. - * - * This program 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.sonar.server.ws; - -import com.google.common.base.Throwables; -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ListMultimap; -import com.google.common.collect.Maps; -import com.google.protobuf.GeneratedMessageV3; -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.StringReader; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.stream.Collectors; -import org.apache.commons.io.IOUtils; -import org.sonar.api.impl.ws.PartImpl; -import org.sonar.api.impl.ws.ValidatingRequest; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; -import static java.util.Objects.requireNonNull; -import static org.sonarqube.ws.MediaTypes.PROTOBUF; - -public class TestRequest extends ValidatingRequest { - - private final ListMultimap multiParams = ArrayListMultimap.create(); - private final Map params = new HashMap<>(); - private final Map headers = new HashMap<>(); - private final Map parts = Maps.newHashMap(); - private String payload = ""; - private boolean payloadConsumed = false; - private String method = "GET"; - private String mimeType = "application/octet-stream"; - private String path; - - @Override - public BufferedReader getReader() { - checkState(!payloadConsumed, "Payload already consumed"); - if (payload == null) { - return super.getReader(); - } - - BufferedReader res = new BufferedReader(new StringReader(payload)); - payloadConsumed = true; - return res; - } - - public TestRequest setPayload(String payload) { - checkState(!payloadConsumed, "Payload already consumed"); - - this.payload = payload; - return this; - } - - @Override - protected String readParam(String key) { - return params.get(key); - } - - @Override - protected List readMultiParam(String key) { - return multiParams.get(key); - } - - @Override - protected InputStream readInputStreamParam(String key) { - String value = readParam(key); - if (value == null) { - return null; - } - return IOUtils.toInputStream(value); - } - - @Override - protected Part readPart(String key) { - return parts.get(key); - } - - public TestRequest setPart(String key, InputStream input, String fileName) { - parts.put(key, new PartImpl(input, fileName)); - return this; - } - - @Override - public String method() { - return method; - } - - @Override - public boolean hasParam(String key) { - return params.containsKey(key) || multiParams.containsKey(key); - } - - @Override - public String getPath() { - return path; - } - - @Override - public Map getParams() { - ArrayListMultimap result = ArrayListMultimap.create(multiParams); - params.forEach(result::put); - return result.asMap().entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().toArray(new String[0]))); - } - - public TestRequest setPath(String path) { - this.path = path; - return this; - } - - public TestRequest setMethod(String method) { - checkNotNull(method); - this.method = method; - return this; - } - - @Override - public String getMediaType() { - return mimeType; - } - - public TestRequest setMediaType(String type) { - checkNotNull(type); - this.mimeType = type; - return this; - } - - public TestRequest setParam(String key, String value) { - checkNotNull(key); - checkNotNull(value); - this.params.put(key, value); - return this; - } - - public TestRequest setMultiParam(String key, List values) { - requireNonNull(key); - requireNonNull(values); - - multiParams.putAll(key, values); - - return this; - } - - @Override - public Map getHeaders() { - return ImmutableMap.copyOf(headers); - } - - @Override - public Optional header(String name) { - return Optional.ofNullable(headers.get(name)); - } - - public TestRequest setHeader(String name, String value) { - headers.put(requireNonNull(name), requireNonNull(value)); - return this; - } - - public TestResponse execute() { - try { - DumbResponse response = new DumbResponse(); - action().handler().handle(this, response); - return new TestResponse(response); - } catch (Exception e) { - throw Throwables.propagate(e); - } - } - - public T executeProtobuf(Class protobufClass) { - return setMediaType(PROTOBUF).execute().getInputObject(protobufClass); - } - - @Override - public String toString() { - return path; - } -} diff --git a/server/sonar-webserver-ws/src/test/java/org/sonar/server/ws/TestResponse.java b/server/sonar-webserver-ws/src/test/java/org/sonar/server/ws/TestResponse.java deleted file mode 100644 index 352d0bb135d..00000000000 --- a/server/sonar-webserver-ws/src/test/java/org/sonar/server/ws/TestResponse.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program 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. - * - * This program 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.sonar.server.ws; - -import com.google.protobuf.GeneratedMessageV3; -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.lang.reflect.Method; -import java.net.HttpURLConnection; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import javax.annotation.CheckForNull; -import org.sonar.test.JsonAssert; - -import static org.assertj.core.api.Assertions.assertThat; - -public class TestResponse { - - private final DumbResponse dumbResponse; - - public TestResponse(DumbResponse dumbResponse) { - this.dumbResponse = dumbResponse; - } - - public InputStream getInputStream() { - return new ByteArrayInputStream(dumbResponse.getFlushedOutput()); - } - - public T getInputObject(Class protobufClass) { - try (InputStream input = getInputStream()) { - Method parseFromMethod = protobufClass.getMethod("parseFrom", InputStream.class); - @SuppressWarnings("unchecked") - T result = (T) parseFromMethod.invoke(null, input); - return result; - } catch (Exception e) { - throw new IllegalStateException(e); - } - } - - public String getInput() { - return new String(dumbResponse.getFlushedOutput(), StandardCharsets.UTF_8); - } - - public String getMediaType() { - return dumbResponse.stream().mediaType(); - } - - public int getStatus() { - return dumbResponse.stream().status(); - } - - @CheckForNull - public String getHeader(String headerKey) { - return dumbResponse.getHeader(headerKey); - } - - public void assertJson(String expectedJson) { - JsonAssert.assertJson(getInput()).isSimilarTo(expectedJson); - } - - /** - * Compares JSON response with JSON file available in classpath. For example if class - * is org.foo.BarTest and filename is index.json, then file must be located - * at src/test/resources/org/foo/BarTest/index.json. - * - * @param clazz the test class - * @param expectedJsonFilename name of the file containing the expected JSON - */ - public void assertJson(Class clazz, String expectedJsonFilename) { - String path = clazz.getSimpleName() + "/" + expectedJsonFilename; - URL url = clazz.getResource(path); - if (url == null) { - throw new IllegalStateException("Cannot find " + path); - } - JsonAssert.assertJson(getInput()).isSimilarTo(url); - } - - public void assertNoContent() { - assertThat(getStatus()).isEqualTo(HttpURLConnection.HTTP_NO_CONTENT); - } -} diff --git a/server/sonar-webserver-ws/src/test/java/org/sonar/server/ws/WsActionTester.java b/server/sonar-webserver-ws/src/test/java/org/sonar/server/ws/WsActionTester.java deleted file mode 100644 index fede932156e..00000000000 --- a/server/sonar-webserver-ws/src/test/java/org/sonar/server/ws/WsActionTester.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program 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. - * - * This program 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.sonar.server.ws; - -import com.google.common.collect.Iterables; -import org.sonar.api.server.ws.WebService; - -public class WsActionTester { - - public static final String CONTROLLER_KEY = "test"; - private final WebService.Action action; - - public WsActionTester(WsAction wsAction) { - WebService.Context context = new WebService.Context(); - WebService.NewController newController = context.createController(CONTROLLER_KEY); - wsAction.define(newController); - newController.done(); - action = Iterables.get(context.controller(CONTROLLER_KEY).actions(), 0); - } - - public WebService.Action getDef() { - return action; - } - - public TestRequest newRequest() { - TestRequest request = new TestRequest(); - request.setAction(action); - return request; - } -} diff --git a/server/sonar-webserver-ws/src/testFixtures/java/org/sonar/server/ws/DumbResponse.java b/server/sonar-webserver-ws/src/testFixtures/java/org/sonar/server/ws/DumbResponse.java new file mode 100644 index 00000000000..f7d2aeedd80 --- /dev/null +++ b/server/sonar-webserver-ws/src/testFixtures/java/org/sonar/server/ws/DumbResponse.java @@ -0,0 +1,133 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program 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. + * + * This program 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.sonar.server.ws; + +import com.google.common.base.Throwables; +import com.google.common.collect.Maps; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.net.HttpURLConnection; +import java.nio.charset.StandardCharsets; +import java.util.Collection; +import java.util.Map; +import javax.annotation.CheckForNull; +import org.apache.commons.io.IOUtils; +import org.sonar.api.server.ws.Response; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.api.utils.text.XmlWriter; + +public class DumbResponse implements Response { + private InMemoryStream stream; + + private final ByteArrayOutputStream output = new ByteArrayOutputStream(); + + private Map headers = Maps.newHashMap(); + + public class InMemoryStream implements Response.Stream { + private String mediaType; + + private int status = 200; + + @CheckForNull + public String mediaType() { + return mediaType; + } + + public int status() { + return status; + } + + @Override + public Response.Stream setMediaType(String s) { + this.mediaType = s; + return this; + } + + @Override + public Response.Stream setStatus(int i) { + this.status = i; + return this; + } + + @Override + public OutputStream output() { + return output; + } + + public String outputAsString() { + return new String(output.toByteArray(), StandardCharsets.UTF_8); + } + } + + @Override + public JsonWriter newJsonWriter() { + return JsonWriter.of(new OutputStreamWriter(output, StandardCharsets.UTF_8)); + } + + @Override + public XmlWriter newXmlWriter() { + return XmlWriter.of(new OutputStreamWriter(output, StandardCharsets.UTF_8)); + } + + @Override + public InMemoryStream stream() { + if (stream == null) { + stream = new InMemoryStream(); + } + return stream; + } + + @Override + public Response noContent() { + stream().setStatus(HttpURLConnection.HTTP_NO_CONTENT); + IOUtils.closeQuietly(output); + return this; + } + + public String outputAsString() { + return new String(output.toByteArray(), StandardCharsets.UTF_8); + } + + @Override + public Response setHeader(String name, String value) { + headers.put(name, value); + return this; + } + + public Collection getHeaderNames() { + return headers.keySet(); + } + + @CheckForNull + public String getHeader(String name){ + return headers.get(name); + } + + public byte[] getFlushedOutput() { + try { + output.flush(); + return output.toByteArray(); + } catch (IOException e) { + throw Throwables.propagate(e); + } + } +} diff --git a/server/sonar-webserver-ws/src/testFixtures/java/org/sonar/server/ws/TestRequest.java b/server/sonar-webserver-ws/src/testFixtures/java/org/sonar/server/ws/TestRequest.java new file mode 100644 index 00000000000..aea0e0d69bd --- /dev/null +++ b/server/sonar-webserver-ws/src/testFixtures/java/org/sonar/server/ws/TestRequest.java @@ -0,0 +1,198 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program 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. + * + * This program 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.sonar.server.ws; + +import com.google.common.base.Throwables; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ListMultimap; +import com.google.common.collect.Maps; +import com.google.protobuf.GeneratedMessageV3; +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.StringReader; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; +import org.apache.commons.io.IOUtils; +import org.sonar.api.impl.ws.PartImpl; +import org.sonar.api.impl.ws.ValidatingRequest; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static java.util.Objects.requireNonNull; +import static org.sonarqube.ws.MediaTypes.PROTOBUF; + +public class TestRequest extends ValidatingRequest { + + private final ListMultimap multiParams = ArrayListMultimap.create(); + private final Map params = new HashMap<>(); + private final Map headers = new HashMap<>(); + private final Map parts = Maps.newHashMap(); + private String payload = ""; + private boolean payloadConsumed = false; + private String method = "GET"; + private String mimeType = "application/octet-stream"; + private String path; + + @Override + public BufferedReader getReader() { + checkState(!payloadConsumed, "Payload already consumed"); + if (payload == null) { + return super.getReader(); + } + + BufferedReader res = new BufferedReader(new StringReader(payload)); + payloadConsumed = true; + return res; + } + + public TestRequest setPayload(String payload) { + checkState(!payloadConsumed, "Payload already consumed"); + + this.payload = payload; + return this; + } + + @Override + protected String readParam(String key) { + return params.get(key); + } + + @Override + protected List readMultiParam(String key) { + return multiParams.get(key); + } + + @Override + protected InputStream readInputStreamParam(String key) { + String value = readParam(key); + if (value == null) { + return null; + } + return IOUtils.toInputStream(value); + } + + @Override + protected Part readPart(String key) { + return parts.get(key); + } + + public TestRequest setPart(String key, InputStream input, String fileName) { + parts.put(key, new PartImpl(input, fileName)); + return this; + } + + @Override + public String method() { + return method; + } + + @Override + public boolean hasParam(String key) { + return params.containsKey(key) || multiParams.containsKey(key); + } + + @Override + public String getPath() { + return path; + } + + @Override + public Map getParams() { + ArrayListMultimap result = ArrayListMultimap.create(multiParams); + params.forEach(result::put); + return result.asMap().entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().toArray(new String[0]))); + } + + public TestRequest setPath(String path) { + this.path = path; + return this; + } + + public TestRequest setMethod(String method) { + checkNotNull(method); + this.method = method; + return this; + } + + @Override + public String getMediaType() { + return mimeType; + } + + public TestRequest setMediaType(String type) { + checkNotNull(type); + this.mimeType = type; + return this; + } + + public TestRequest setParam(String key, String value) { + checkNotNull(key); + checkNotNull(value); + this.params.put(key, value); + return this; + } + + public TestRequest setMultiParam(String key, List values) { + requireNonNull(key); + requireNonNull(values); + + multiParams.putAll(key, values); + + return this; + } + + @Override + public Map getHeaders() { + return ImmutableMap.copyOf(headers); + } + + @Override + public Optional header(String name) { + return Optional.ofNullable(headers.get(name)); + } + + public TestRequest setHeader(String name, String value) { + headers.put(requireNonNull(name), requireNonNull(value)); + return this; + } + + public TestResponse execute() { + try { + DumbResponse response = new DumbResponse(); + action().handler().handle(this, response); + return new TestResponse(response); + } catch (Exception e) { + throw Throwables.propagate(e); + } + } + + public T executeProtobuf(Class protobufClass) { + return setMediaType(PROTOBUF).execute().getInputObject(protobufClass); + } + + @Override + public String toString() { + return path; + } +} diff --git a/server/sonar-webserver-ws/src/testFixtures/java/org/sonar/server/ws/TestResponse.java b/server/sonar-webserver-ws/src/testFixtures/java/org/sonar/server/ws/TestResponse.java new file mode 100644 index 00000000000..352d0bb135d --- /dev/null +++ b/server/sonar-webserver-ws/src/testFixtures/java/org/sonar/server/ws/TestResponse.java @@ -0,0 +1,98 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program 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. + * + * This program 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.sonar.server.ws; + +import com.google.protobuf.GeneratedMessageV3; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.lang.reflect.Method; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import javax.annotation.CheckForNull; +import org.sonar.test.JsonAssert; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TestResponse { + + private final DumbResponse dumbResponse; + + public TestResponse(DumbResponse dumbResponse) { + this.dumbResponse = dumbResponse; + } + + public InputStream getInputStream() { + return new ByteArrayInputStream(dumbResponse.getFlushedOutput()); + } + + public T getInputObject(Class protobufClass) { + try (InputStream input = getInputStream()) { + Method parseFromMethod = protobufClass.getMethod("parseFrom", InputStream.class); + @SuppressWarnings("unchecked") + T result = (T) parseFromMethod.invoke(null, input); + return result; + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + + public String getInput() { + return new String(dumbResponse.getFlushedOutput(), StandardCharsets.UTF_8); + } + + public String getMediaType() { + return dumbResponse.stream().mediaType(); + } + + public int getStatus() { + return dumbResponse.stream().status(); + } + + @CheckForNull + public String getHeader(String headerKey) { + return dumbResponse.getHeader(headerKey); + } + + public void assertJson(String expectedJson) { + JsonAssert.assertJson(getInput()).isSimilarTo(expectedJson); + } + + /** + * Compares JSON response with JSON file available in classpath. For example if class + * is org.foo.BarTest and filename is index.json, then file must be located + * at src/test/resources/org/foo/BarTest/index.json. + * + * @param clazz the test class + * @param expectedJsonFilename name of the file containing the expected JSON + */ + public void assertJson(Class clazz, String expectedJsonFilename) { + String path = clazz.getSimpleName() + "/" + expectedJsonFilename; + URL url = clazz.getResource(path); + if (url == null) { + throw new IllegalStateException("Cannot find " + path); + } + JsonAssert.assertJson(getInput()).isSimilarTo(url); + } + + public void assertNoContent() { + assertThat(getStatus()).isEqualTo(HttpURLConnection.HTTP_NO_CONTENT); + } +} diff --git a/server/sonar-webserver-ws/src/testFixtures/java/org/sonar/server/ws/WsActionTester.java b/server/sonar-webserver-ws/src/testFixtures/java/org/sonar/server/ws/WsActionTester.java new file mode 100644 index 00000000000..fede932156e --- /dev/null +++ b/server/sonar-webserver-ws/src/testFixtures/java/org/sonar/server/ws/WsActionTester.java @@ -0,0 +1,47 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program 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. + * + * This program 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.sonar.server.ws; + +import com.google.common.collect.Iterables; +import org.sonar.api.server.ws.WebService; + +public class WsActionTester { + + public static final String CONTROLLER_KEY = "test"; + private final WebService.Action action; + + public WsActionTester(WsAction wsAction) { + WebService.Context context = new WebService.Context(); + WebService.NewController newController = context.createController(CONTROLLER_KEY); + wsAction.define(newController); + newController.done(); + action = Iterables.get(context.controller(CONTROLLER_KEY).actions(), 0); + } + + public WebService.Action getDef() { + return action; + } + + public TestRequest newRequest() { + TestRequest request = new TestRequest(); + request.setAction(action); + return request; + } +}