com.github.shredder121.gh_event_api.handler.AbstractHandlerTest.java Source code

Java tutorial

Introduction

Here is the source code for com.github.shredder121.gh_event_api.handler.AbstractHandlerTest.java

Source

/*
 * Copyright 2016 Shredder121.
 *
 * 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.github.shredder121.gh_event_api.handler;

import static com.github.shredder121.gh_event_api.TestConstants.DEVELOPER_GITHUB_COM_REVISION;
import static com.github.shredder121.gh_event_api.TestConstants.HMACS;
import static com.jayway.restassured.RestAssured.given;
import static com.jayway.restassured.http.ContentType.JSON;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

import org.apache.commons.io.FileUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.DisableOnDebug;
import org.junit.rules.ErrorCollector;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
import org.junit.runner.RunWith;
import org.kohsuke.github.GHContent;
import org.kohsuke.github.GitHub;
import org.kohsuke.github.GitHubBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.fasterxml.jackson.core.util.MinimalPrettyPrinter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.shredder121.gh_event_api.testutil.RawGitOkHttpConnector;
import com.google.common.base.Throwables;
import com.google.common.collect.Maps;
import com.jayway.restassured.RestAssured;
import com.squareup.okhttp.Cache;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.OkUrlFactory;

import lombok.experimental.NonFinal;

@DirtiesContext
@WebIntegrationTest
@RunWith(SpringJUnit4ClassRunner.class)
public abstract class AbstractHandlerTest {

    static Map<String, GHContent> eventPayloadMap;

    static {
        try {
            GitHub github = getGitHub();

            List<GHContent> directoryContent = github.getRepository("github/developer.github.com")
                    .getDirectoryContent("lib/webhooks", DEVELOPER_GITHUB_COM_REVISION);

            // Map the event name (fileNameWithoutPayloadJsonSuffix) to the event's payload.json file
            //             push/pull_request/* -> lib/webhooks/*.payload.json
            eventPayloadMap = Maps.uniqueIndex(directoryContent,
                    AbstractHandlerTest::fileNameWithoutPayloadJsonSuffix);
        } catch (IOException ex) {
            throw Throwables.propagate(ex);
        }
    }

    private static GitHub getGitHub() throws IOException {
        OkHttpClient client = new OkHttpClient();
        client.setCache(new Cache(Paths.get(".", ".cache").toFile(), FileUtils.ONE_MB * 10));
        return new GitHubBuilder().withConnector(new RawGitOkHttpConnector(new OkUrlFactory(client))).build();
    }

    private static String fileNameWithoutPayloadJsonSuffix(GHContent content) {
        String fileName = content.getName();
        return fileName.substring(0, fileName.indexOf('.'));
    }

    String event;
    String hmac;

    @Rule
    public ErrorCollector errorCollector = new ErrorCollector();

    @Rule
    public TestRule timeout = new DisableOnDebug(Timeout.seconds(30));

    protected CountDownLatch completion = new CountDownLatch(1);

    @Autowired
    @NonFinal
    AbstractTestHandlerBean handlerBean;

    @Autowired
    @NonFinal
    Environment env;

    protected AbstractHandlerTest(String event) {
        this.event = event;
        /* This will be the HMAC as reported by https://www.freeformatter.com/hmac-generator.html */
        this.hmac = HMACS.get(event);
    }

    @Before
    public final void prepareTest() {
        handlerBean.setCountDownLatch(completion);
        handlerBean.setErrorCollector(errorCollector);

        RestAssured.port = env.getRequiredProperty("local.server.port", int.class);
    }

    @After
    public void resetRestAssured() {
        RestAssured.reset();
    }

    @Test
    public void test() throws InterruptedException {
        given().headers("X-GitHub-Event", event, "X-Hub-Signature", "sha1=" + hmac).and().body(getBody()).with()
                .contentType(JSON).expect().statusCode(HttpStatus.OK.value()).when().post();

        completion.await();
    }

    private String getBody() {
        GHContent payloadFile = eventPayloadMap.get(event);
        try (InputStream stream = payloadFile.read()) {
            return minimize(stream);
        } catch (IOException ex) {
            throw Throwables.propagate(ex);
        }
    }

    public String minimize(final InputStream stream) throws IOException {
        ObjectMapper mapper = Jackson2ObjectMapperBuilder.json().build();
        Map<String, Object> content = mapper.reader().forType(Map.class).readValue(stream);
        return mapper.writer(new MinimalPrettyPrinter(null/*minimizes*/)).writeValueAsString(content);
    }
}