io.spring.initializr.actuate.stat.MainControllerStatsIntegrationTests.java Source code

Java tutorial

Introduction

Here is the source code for io.spring.initializr.actuate.stat.MainControllerStatsIntegrationTests.java

Source

/*
 * Copyright 2012-2017 the original author or authors.
 *
 * 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 io.spring.initializr.actuate.stat;

import java.net.URI;
import java.util.ArrayList;
import java.util.List;

import io.spring.initializr.actuate.stat.MainControllerStatsIntegrationTests.StatsMockController;
import io.spring.initializr.web.AbstractFullStackInitializrIntegrationTests;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.RequestEntity;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.HttpClientErrorException;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

/**
 * Integration tests for stats processing.
 *
 * @author Stephane Nicoll
 */
@Import(StatsMockController.class)
@ActiveProfiles({ "test-default", "test-custom-stats" })
public class MainControllerStatsIntegrationTests extends AbstractFullStackInitializrIntegrationTests {

    @Autowired
    private StatsMockController statsMockController;

    @Autowired
    private StatsProperties statsProperties;

    @Before
    public void setup() {
        this.statsMockController.stats.clear();
        // Make sure our mock is going to be invoked with the stats
        this.statsProperties.getElastic().setUri("http://localhost:" + port + "/elastic");
    }

    @Test
    public void simpleProject() {
        downloadArchive("/starter.zip?groupId=com.foo&artifactId=bar&dependencies=web");
        assertEquals("No stat got generated", 1, statsMockController.stats.size());
        StatsMockController.Content content = statsMockController.stats.get(0);

        JSONObject json = new JSONObject(content.json);
        assertEquals("com.foo", json.get("groupId"));
        assertEquals("bar", json.get("artifactId"));
        JSONArray list = json.getJSONArray("dependencies");
        assertEquals(1, list.length());
        assertEquals("web", list.get(0));
    }

    @Test
    public void authorizationHeaderIsSet() {
        downloadArchive("/starter.zip");
        assertEquals("No stat got generated", 1, statsMockController.stats.size());
        StatsMockController.Content content = statsMockController.stats.get(0);

        String authorization = content.authorization;
        assertNotNull("Authorization header must be set", authorization);
        assertTrue("Wrong value for authorization header", authorization.startsWith("Basic "));
        String token = authorization.substring("Basic ".length(), authorization.length());
        String[] data = new String(Base64Utils.decodeFromString(token)).split(":");
        assertEquals("Wrong user from " + token, "test-user", data[0]);
        assertEquals("Wrong password " + token, "test-password", data[1]);
    }

    @Test
    public void requestIpNotSetByDefault() {
        downloadArchive("/starter.zip?groupId=com.foo&artifactId=bar&dependencies=web");
        assertEquals("No stat got generated", 1, statsMockController.stats.size());
        StatsMockController.Content content = statsMockController.stats.get(0);

        JSONObject json = new JSONObject(content.json);
        assertFalse("requestIp property should not be set", json.has("requestIp"));
    }

    @Test
    public void requestIpIsSetWhenHeaderIsPresent() throws Exception {
        RequestEntity<?> request = RequestEntity.get(new URI(createUrl("/starter.zip")))
                .header("X-FORWARDED-FOR", "10.0.0.123").build();
        getRestTemplate().exchange(request, String.class);
        assertEquals("No stat got generated", 1, statsMockController.stats.size());
        StatsMockController.Content content = statsMockController.stats.get(0);

        JSONObject json = new JSONObject(content.json);
        assertEquals("Wrong requestIp", "10.0.0.123", json.get("requestIp"));
    }

    @Test
    public void requestIpv4IsNotSetWhenHeaderHasGarbage() throws Exception {
        RequestEntity<?> request = RequestEntity.get(new URI(createUrl("/starter.zip")))
                .header("x-forwarded-for", "foo-bar").build();
        getRestTemplate().exchange(request, String.class);
        assertEquals("No stat got generated", 1, statsMockController.stats.size());
        StatsMockController.Content content = statsMockController.stats.get(0);

        JSONObject json = new JSONObject(content.json);
        assertFalse("requestIpv4 property should not be set if value is not a valid IPv4", json.has("requestIpv4"));
    }

    @Test
    public void requestCountryIsNotSetWhenHeaderIsSetToXX() throws Exception {
        RequestEntity<?> request = RequestEntity.get(new URI(createUrl("/starter.zip")))
                .header("cf-ipcountry", "XX").build();
        getRestTemplate().exchange(request, String.class);
        assertEquals("No stat got generated", 1, statsMockController.stats.size());
        StatsMockController.Content content = statsMockController.stats.get(0);

        JSONObject json = new JSONObject(content.json);
        assertFalse("requestCountry property should not be set if value is set to xx", json.has("requestCountry"));
    }

    @Test
    public void invalidProjectSillHasStats() {
        try {
            downloadArchive("/starter.zip?type=invalid-type");
            fail("Should have failed to generate project with invalid type");
        } catch (HttpClientErrorException ex) {
            assertEquals(HttpStatus.BAD_REQUEST, ex.getStatusCode());
        }
        assertEquals("No stat got generated", 1, statsMockController.stats.size());
        StatsMockController.Content content = statsMockController.stats.get(0);

        JSONObject json = new JSONObject(content.json);
        assertEquals("com.example", json.get("groupId"));
        assertEquals("demo", json.get("artifactId"));
        assertEquals(true, json.get("invalid"));
        assertEquals(true, json.get("invalidType"));
        assertNotNull(json.get("errorMessage"));
        assertTrue(((String) json.get("errorMessage")).contains("invalid-type"));
    }

    @Test
    public void errorPublishingStatsDoesNotBubbleUp() {
        this.statsProperties.getElastic().setUri("http://localhost:" + port + "/elastic-error");
        downloadArchive("/starter.zip");
        assertEquals("No stat should be available", 0, statsMockController.stats.size());
    }

    @RestController
    protected static class StatsMockController {

        private final List<Content> stats = new ArrayList<>();

        @RequestMapping(path = "/elastic/test/my-entity", method = RequestMethod.POST)
        public void handleProjectRequestDocument(RequestEntity<String> input) {
            String authorization = input.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
            Content content = new Content(authorization, input.getBody());
            this.stats.add(content);
        }

        @RequestMapping(path = "/elastic-error/test/my-entity", method = RequestMethod.POST)
        public void handleExpectedError() {
            throw new IllegalStateException("Expected exception");
        }

        public static class Content {

            private final String authorization;
            private final String json;

            Content(String authorization, String body) {
                this.authorization = authorization;
                json = body;
            }

        }

    }

}