org.sonarqube.ws.client.HttpConnectorTest.java Source code

Java tutorial

Introduction

Here is the source code for org.sonarqube.ws.client.HttpConnectorTest.java

Source

/*
 * SonarQube
 * Copyright (C) 2009-2017 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.sonarqube.ws.client;

import java.io.File;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.List;
import javax.net.ssl.SSLSocketFactory;
import okhttp3.ConnectionSpec;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.sonarqube.ws.MediaTypes;

import static okhttp3.Credentials.basic;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.sonarqube.ws.client.HttpConnector.newBuilder;

public class HttpConnectorTest {

    @Rule
    public TemporaryFolder temp = new TemporaryFolder();
    @Rule
    public ExpectedException expectedException = ExpectedException.none();

    private MockWebServer server;
    private String serverUrl;
    private HttpConnector underTest;

    @Before
    public void setUp() throws Exception {
        server = new MockWebServer();
        server.start();
        serverUrl = server.url("").url().toString();
    }

    @Test
    public void test_default_settings() throws Exception {
        answerHelloWorld();
        underTest = HttpConnector.newBuilder().url(serverUrl).build();
        assertThat(underTest.baseUrl()).isEqualTo(serverUrl);
        GetRequest request = new GetRequest("api/issues/search").setMediaType(MediaTypes.PROTOBUF);
        WsResponse response = underTest.call(request);

        // verify default timeouts on client
        assertThat(underTest.okHttpClient().connectTimeoutMillis())
                .isEqualTo(HttpConnector.DEFAULT_CONNECT_TIMEOUT_MILLISECONDS);
        assertThat(underTest.okHttpClient().readTimeoutMillis())
                .isEqualTo(HttpConnector.DEFAULT_READ_TIMEOUT_MILLISECONDS);

        // verify response
        assertThat(response.hasContent()).isTrue();
        assertThat(response.content()).isEqualTo("hello, world!");

        // verify the request received by server
        RecordedRequest recordedRequest = server.takeRequest();
        assertThat(recordedRequest.getMethod()).isEqualTo("GET");
        assertThat(recordedRequest.getPath()).isEqualTo("/api/issues/search");
        assertThat(recordedRequest.getHeader("Accept")).isEqualTo(MediaTypes.PROTOBUF);
        assertThat(recordedRequest.getHeader("Accept-Charset")).isEqualTo("UTF-8");
        assertThat(recordedRequest.getHeader("User-Agent")).startsWith("okhttp/");
        // compression is handled by OkHttp
        assertThat(recordedRequest.getHeader("Accept-Encoding")).isEqualTo("gzip");
    }

    @Test
    public void use_basic_authentication() throws Exception {
        answerHelloWorld();
        underTest = HttpConnector.newBuilder().url(serverUrl).credentials("theLogin", "thePassword").build();

        GetRequest request = new GetRequest("api/issues/search");
        underTest.call(request);

        RecordedRequest recordedRequest = server.takeRequest();
        assertThat(recordedRequest.getHeader("Authorization")).isEqualTo(basic("theLogin", "thePassword"));
    }

    @Test
    public void use_basic_authentication_with_null_password() throws Exception {
        answerHelloWorld();
        underTest = HttpConnector.newBuilder().url(serverUrl).credentials("theLogin", null).build();

        GetRequest request = new GetRequest("api/issues/search");
        underTest.call(request);

        RecordedRequest recordedRequest = server.takeRequest();
        assertThat(recordedRequest.getHeader("Authorization")).isEqualTo(basic("theLogin", ""));
    }

    /**
     * Access token replaces the couple {login,password} and is sent through
     * the login field
     */
    @Test
    public void use_access_token() throws Exception {
        answerHelloWorld();
        underTest = HttpConnector.newBuilder().url(serverUrl).token("theToken").build();

        GetRequest request = new GetRequest("api/issues/search");
        underTest.call(request);

        RecordedRequest recordedRequest = server.takeRequest();
        assertThat(recordedRequest.getHeader("Authorization")).isEqualTo(basic("theToken", ""));
    }

    @Test
    public void use_proxy_authentication() throws Exception {
        MockWebServer proxy = new MockWebServer();
        proxy.start();
        underTest = HttpConnector.newBuilder().url(serverUrl)
                .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxy.getHostName(), proxy.getPort())))
                .proxyCredentials("theProxyLogin", "theProxyPassword").build();

        GetRequest request = new GetRequest("api/issues/search");
        proxy.enqueue(new MockResponse().setResponseCode(407));
        proxy.enqueue(new MockResponse().setBody("OK!"));
        underTest.call(request);

        RecordedRequest recordedRequest = proxy.takeRequest();
        assertThat(recordedRequest.getHeader("Proxy-Authorization")).isNull();
        recordedRequest = proxy.takeRequest();
        assertThat(recordedRequest.getHeader("Proxy-Authorization"))
                .isEqualTo(basic("theProxyLogin", "theProxyPassword"));
    }

    @Test
    public void override_timeouts() {
        underTest = HttpConnector.newBuilder().url(serverUrl).readTimeoutMilliseconds(42)
                .connectTimeoutMilliseconds(74).build();

        assertThat(underTest.okHttpClient().readTimeoutMillis()).isEqualTo(42);
        assertThat(underTest.okHttpClient().connectTimeoutMillis()).isEqualTo(74);
    }

    @Test
    public void send_user_agent() throws Exception {
        answerHelloWorld();
        underTest = HttpConnector.newBuilder().url(serverUrl).userAgent("Maven Plugin/2.3").build();

        underTest.call(new GetRequest("api/issues/search"));

        RecordedRequest recordedRequest = server.takeRequest();
        assertThat(recordedRequest.getHeader("User-Agent")).isEqualTo("Maven Plugin/2.3");
    }

    @Test
    public void fail_if_unknown_implementation_of_request() {
        underTest = HttpConnector.newBuilder().url(serverUrl).build();
        try {
            underTest.call(mock(WsRequest.class));
            fail();
        } catch (IllegalArgumentException e) {
            assertThat(e).hasMessageContaining("Unsupported implementation: ");
        }
    }

    @Test
    public void fail_if_malformed_URL() {
        expectedException.expect(IllegalArgumentException.class);
        expectedException.expectMessage("Malformed URL: 'wrong URL'");

        underTest = newBuilder().url("wrong URL").build();
    }

    @Test
    public void send_post_request() throws Exception {
        answerHelloWorld();
        PostRequest request = new PostRequest("api/issues/search").setParam("severity", "MAJOR")
                .setMediaType(MediaTypes.PROTOBUF);

        underTest = HttpConnector.newBuilder().url(serverUrl).build();
        WsResponse response = underTest.call(request);

        // verify response
        assertThat(response.hasContent()).isTrue();
        assertThat(response.content()).isEqualTo("hello, world!");

        // verify the request received by server
        RecordedRequest recordedRequest = server.takeRequest();
        assertThat(recordedRequest.getMethod()).isEqualTo("POST");
        assertThat(recordedRequest.getPath()).isEqualTo("/api/issues/search");
        assertThat(recordedRequest.getBody().readUtf8()).isEqualTo("severity=MAJOR");
    }

    @Test
    public void upload_file() throws Exception {
        answerHelloWorld();
        File reportFile = temp.newFile();
        FileUtils.write(reportFile, "the report content");
        PostRequest request = new PostRequest("api/report/upload").setParam("project", "theKey")
                .setPart("report", new PostRequest.Part(MediaTypes.TXT, reportFile))
                .setMediaType(MediaTypes.PROTOBUF);

        underTest = HttpConnector.newBuilder().url(serverUrl).build();
        WsResponse response = underTest.call(request);

        assertThat(response.hasContent()).isTrue();
        RecordedRequest recordedRequest = server.takeRequest();
        assertThat(recordedRequest.getMethod()).isEqualTo("POST");
        assertThat(recordedRequest.getPath()).isEqualTo("/api/report/upload?project=theKey");
        String body = IOUtils.toString(recordedRequest.getBody().inputStream());
        assertThat(body).contains("Content-Disposition: form-data; name=\"report\"")
                .contains("Content-Type: text/plain").contains("the report content");
    }

    @Test
    public void http_error() throws Exception {
        server.enqueue(new MockResponse().setResponseCode(404));
        PostRequest request = new PostRequest("api/issues/search");
        underTest = HttpConnector.newBuilder().url(serverUrl).build();

        WsResponse wsResponse = underTest.call(request);
        assertThat(wsResponse.code()).isEqualTo(404);
    }

    @Test
    public void support_base_url_ending_with_slash() throws Exception {
        assertThat(serverUrl).endsWith("/");
        underTest = HttpConnector.newBuilder().url(StringUtils.removeEnd(serverUrl, "/")).build();
        GetRequest request = new GetRequest("api/issues/search");

        answerHelloWorld();
        WsResponse response = underTest.call(request);

        assertThat(response.hasContent()).isTrue();
    }

    @Test
    public void support_base_url_with_context() {
        // just to be sure
        assertThat(serverUrl).endsWith("/");
        underTest = HttpConnector.newBuilder().url(serverUrl + "sonar").build();

        GetRequest request = new GetRequest("api/issues/search");
        answerHelloWorld();
        assertThat(underTest.call(request).requestUrl()).isEqualTo(serverUrl + "sonar/api/issues/search");

        request = new GetRequest("/api/issues/search");
        answerHelloWorld();
        assertThat(underTest.call(request).requestUrl()).isEqualTo(serverUrl + "sonar/api/issues/search");
    }

    @Test
    public void support_tls_versions_of_java8() {
        underTest = HttpConnector.newBuilder().url(serverUrl).build();

        assertTlsAndClearTextSpecifications(underTest);
        assertThat(underTest.okHttpClient().sslSocketFactory())
                .isInstanceOf(SSLSocketFactory.getDefault().getClass());
    }

    private void assertTlsAndClearTextSpecifications(HttpConnector underTest) {
        List<ConnectionSpec> connectionSpecs = underTest.okHttpClient().connectionSpecs();
        assertThat(connectionSpecs).hasSize(2);

        // TLS. tlsVersions()==null means all TLS versions
        assertThat(connectionSpecs.get(0).tlsVersions()).isNull();
        assertThat(connectionSpecs.get(0).isTls()).isTrue();

        // HTTP
        assertThat(connectionSpecs.get(1).tlsVersions()).isNull();
        assertThat(connectionSpecs.get(1).isTls()).isFalse();
    }

    private void answerHelloWorld() {
        server.enqueue(new MockResponse().setBody("hello, world!"));
    }
}