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.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> invoke(UriSpec spec, Function<UriBuilder, URI> url,
                                                     BodyInserter<HelloRequest, ReactiveHttpOutputMessage> object) {
        return spec.uri(url)
                .accept(APPLICATION_JSON_UTF8)
                .exchange(object)
                .expectStatus().isOk()
                .expectHeader().contentType(APPLICATION_JSON_UTF8)
                .expectBody(HelloResponse.class)
                .returnResult();
    }

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

    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));
                }
        );
    }

}

@@ -612,16 +612,99 @@
 Client;%0A
+import org.springframework.test.web.reactive.server.WebTestClient.RequestBodySpec;%0A
 import o
@@ -1953,173 +1953,63 @@
 se%3E 
-invoke(UriSpec spec, Function%3CUriBuilder, URI%3E url,%0A                                                     BodyInserter%3CHelloRequest, ReactiveHttpOutputMessage%3E obj
+completeInvoke(WebTestClient.RequestHeadersSpec%3C?%3E sp
 ec
-t
 ) %7B%0A
@@ -2031,34 +2031,8 @@
 spec
-.uri(url)%0A                
 .acc
@@ -2057,33 +2057,16 @@
 ON_UTF8)
-%0A                
 .exchang
@@ -2071,14 +2071,8 @@
 nge(
-object
 )%0A  
@@ -2256,32 +2256,330 @@
 esult();%0A    %7D%0A%0A
+    private FluxExchangeResult%3CHelloResponse%3E invoke(UriSpec%3CRequestBodySpec%3E spec, Function%3CUriBuilder, URI%3E url,%0A                                                     BodyInserter%3CHelloRequest, ReactiveHttpOutputMessage%3E object) %7B%0A        return completeInvoke(spec.uri(url).body(object));%0A    %7D%0A%0A
     private Flux
@@ -2658,24 +2658,25 @@
 URI%3E url) %7B%0A
+%0A
         retu
@@ -2678,17 +2678,25 @@
  return 
-i
+completeI
 nvoke(sp
@@ -2701,19 +2701,17 @@
 spec
-, url, null
+.uri(url)
 );%0A 

fix a issue in the test after a possible change on dependencies