package net.spals.appbuilder.app.dropwizard;

import io.dropwizard.Configuration;
import io.dropwizard.testing.DropwizardTestSupport;
import io.opentracing.mock.MockSpan;
import io.opentracing.mock.MockTracer;
import net.spals.appbuilder.app.dropwizard.tracing.TracingDropwizardWebApp;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import java.util.List;
import java.util.Optional;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

/**
 * Functional tests for a minimal {@link DropwizardWebApp}
 *
 * @author tkral
 */
public class TracingDropwizardWebAppFTest {

    private final DropwizardTestSupport<Configuration> testServerWrapper =
            new DropwizardTestSupport<>(TracingDropwizardWebApp.class, new Configuration());
    private MockTracer mockTracer;

    private final Client webClient = ClientBuilder.newClient();

    @BeforeClass
    void classSetup() {
        testServerWrapper.before();
        mockTracer = ((TracingDropwizardWebApp)testServerWrapper.getApplication()).getMockTracer();
    }

    @AfterClass
    void classTearDown() {
        testServerWrapper.after();
    }

    @DataProvider
    Object[][] serverRequestTracingProvider() {
        return new Object[][] {
                {"tracing/noAnnotation", "tracing/noAnnotation"},
                {"tracing/withAnnotation", "customOperationName"},
        };
    }

    @Test(dataProvider = "serverRequestTracingProvider")
    public void testServerRequestTracing(final String path,
                                         final String expectedOperationName) {
        final String target = "http://localhost:" + testServerWrapper.getLocalPort() + "/" + path;
        final WebTarget webTarget = webClient.target(target);
        webTarget.request().get();

        final MockSpan mockSpan = findMockSpan(expectedOperationName);
        assertThat(mockSpan.generatedErrors(), empty());
        assertThat(mockSpan.tags(), hasEntry("http.method", "GET"));
        assertThat(mockSpan.tags(), hasEntry("http.status_code", 200));
        assertThat(mockSpan.tags(), hasEntry("http.url", target));
        assertThat(mockSpan.tags(), hasEntry("span.kind", "server"));
    }

    private MockSpan findMockSpan(final String expectedOperationName) {
        final List<MockSpan> finishedSpans = mockTracer.finishedSpans();
        assertThat("No finished spans found.", finishedSpans, hasSize(greaterThan(0)));

        final Optional<MockSpan> mockSpan = finishedSpans.stream()
                .filter(span -> expectedOperationName.equals(span.operationName()))
                .findAny();
        assertThat("Could not find span with operationName '" + expectedOperationName + "'",
                mockSpan, not(Optional.empty()));
        return mockSpan.get();
    }
}

@@ -313,141 +313,9 @@
 ons.
-AfterClass;%0Aimport org.testng.annotations.BeforeClass;%0Aimport org.testng.annotations.DataProvider;%0Aimport org.testng.annotations.Test
+*
 ;%0A%0Ai
@@ -601,25 +601,69 @@
 for 
-a minimal
+request tracing in a %7B@link DropwizardWebApp%7D%0A * (see
  %7B@link 
 Drop
@@ -650,32 +650,39 @@
 %0A * (see %7B@link 
+Tracing
 DropwizardWebApp
@@ -682,16 +682,18 @@
 dWebApp%7D
+).
 %0A *%0A * @
@@ -1203,24 +1203,102 @@
 r();%0A    %7D%0A%0A
+    @BeforeMethod%0A    void resetTracer() %7B%0A        mockTracer.reset();%0A    %7D%0A%0A
     @AfterCl
@@ -2026,24 +2026,29 @@
   final 
+List%3C
 MockSpan
  mockSpa
@@ -2039,16 +2039,17 @@
 MockSpan
+%3E
  mockSpa
@@ -2053,45 +2053,161 @@
 Span
+s
  = 
-findMockSpan(expectedOperationName
+mockTracer.finishedSpans();%0A        assertThat(%22No finished spans found.%22, mockSpans, hasSize(1));%0A%0A        final MockSpan mockSpan = mockSpans.get(0
 );%0A 
@@ -2258,24 +2258,97 @@
 , empty());%0A
+        assertThat(mockSpan.operationName(), is(expectedOperationName));%0A
         asse
@@ -2622,601 +2622,7 @@
    %7D
-%0A%0A    private MockSpan findMockSpan(final String expectedOperationName) %7B%0A        final List%3CMockSpan%3E finishedSpans = mockTracer.finishedSpans();%0A        assertThat(%22No finished spans found.%22, finishedSpans, hasSize(greaterThan(0)));%0A%0A        final Optional%3CMockSpan%3E mockSpan = finishedSpans.stream()%0A                .filter(span -%3E expectedOperationName.equals(span.operationName()))%0A                .findAny();%0A        assertThat(%22Could not find span with operationName '%22 + expectedOperationName + %22'%22,%0A                mockSpan, not(Optional.empty()));%0A        return mockSpan.get();%0A    %7D
 %0A%7D%0A

Simplify request tracing tests for Dropwizard