package com.juan.medina.microservices;

import com.juan.medina.microservices.model.HelloRequest;
import com.juan.medina.microservices.model.HelloResponse;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.ReactiveHttpOutputMessage;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.reactive.server.FluxExchangeResult;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.test.web.reactive.server.WebTestClient.RequestBodySpec;
import org.springframework.test.web.reactive.server.WebTestClient.UriSpec;
import org.springframework.web.reactive.function.BodyInserter;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.util.UriBuilder;
import reactor.test.StepVerifier;

import java.net.URI;
import java.util.function.Consumer;
import java.util.function.Function;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ReactiveMsExampleApplicationTests {

    private static final String DEFAULT_VALUE = "world";
    private static final String CUSTOM_VALUE = "reactive";
    private static final String JSON_VALUE = "json";
    private static final String HELLO_PATH = "/hello";
    private static final String NAME_ARG = "{name}";

    private WebTestClient client;

    @Autowired
    private RouterFunction<?> helloRouterFunction;

    @Before
    public void setup() {
        client = WebTestClient.bindToRouterFunction(helloRouterFunction).build();
    }

    private FluxExchangeResult<HelloResponse> completeInvoke(WebTestClient.RequestHeadersSpec<?> spec) {
        return spec.accept(APPLICATION_JSON_UTF8).exchange()
                .expectStatus().isOk()
                .expectHeader().contentType(APPLICATION_JSON_UTF8)
                .expectBody(HelloResponse.class)
                .returnResult();
    }

    private FluxExchangeResult<HelloResponse> invoke(UriSpec<RequestBodySpec> spec, Function<UriBuilder, URI> url,
                                                     BodyInserter<HelloRequest, ReactiveHttpOutputMessage> object) {
        return completeInvoke(spec.uri(url).body(object));
    }

    private FluxExchangeResult<HelloResponse> invoke(UriSpec spec, Function<UriBuilder, URI> url) {

        return completeInvoke(spec.uri(url));
    }

    private void verify(FluxExchangeResult<HelloResponse> result, Consumer<HelloResponse> check) {
        StepVerifier.create(result.getResponseBody())
                .consumeNextWith(check)
                .expectComplete()
                .verify();
    }

    @Test
    public void defaultHelloTest() {

        verify(
                invoke(
                        client.get(),
                        builder -> builder.path(HELLO_PATH).build()),
                it -> {
                    assertThat(it.getHello(), is(DEFAULT_VALUE));
                }
        );
    }

    @Test
    public void getHelloTest() {
        verify(
                invoke(
                        client.get(),
                        builder -> builder.path(HELLO_PATH).path("/").path(NAME_ARG).build(CUSTOM_VALUE)),
                it -> {
                    assertThat(it.getHello(), is(CUSTOM_VALUE));
                }
        );
    }

    @Test
    public void postHelloTest() {

        verify(
                invoke(
                        client.post(),
                        builder -> builder.path(HELLO_PATH).build(),
                        BodyInserters.fromObject(new HelloRequest(JSON_VALUE))),
                it -> {
                    assertThat(it.getHello(), is(JSON_VALUE));
                }
        );
    }

}

@@ -525,20 +525,22 @@
 .server.
-Flux
+Entity
 Exchange
@@ -1022,42 +1022,8 @@
 der;
-%0Aimport reactor.test.StepVerifier;
 %0A%0Aim
@@ -1145,61 +1145,72 @@
 est.
-core.Is.is;%0Aimport static org.junit.Assert.assertThat
+MatcherAssert.assertThat;%0Aimport static org.hamcrest.Matchers.is
 ;%0Aim
@@ -1886,36 +1886,38 @@
  %7D%0A%0A    private 
-Flux
+Entity
 ExchangeResult%3CH
@@ -2249,36 +2249,38 @@
  %7D%0A%0A    private 
-Flux
+Entity
 ExchangeResult%3CH
@@ -2557,20 +2557,22 @@
 private 
-Flux
+Entity
 Exchange
@@ -2729,12 +2729,14 @@
 ify(
-Flux
+Entity
 Exch
@@ -2814,27 +2814,20 @@
     
-StepVerifier.create
+check.accept
 (res
@@ -2852,108 +2852,8 @@
 y())
-%0A                .consumeNextWith(check)%0A                .expectComplete()%0A                .verify()
 ;%0A  
@@ -2849,32 +2849,33 @@
 Body());%0A    %7D%0A%0A
+%0A
     @Test%0A    pu
@@ -2897,33 +2897,32 @@
 ltHelloTest() %7B%0A
-%0A
         verify(%0A

fix test