import com.example.ReactiveWebFlux.ReactiveWebFluxApplication;
import com.example.ReactiveWebFlux.User;
import com.example.ReactiveWebFlux.UserRepository;
import org.assertj.core.api.Assertions;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.reactive.server.WebTestClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;

import static org.junit.Assert.assertEquals;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = ReactiveWebFluxApplication.class)
@ActiveProfiles("integration")
public class UserControllerIntegrationTest {
    @Mock
    private UserRepository userRepository;

    @Autowired
    private WebTestClient webTestClient;
    final private static int port = 8888;
    final private static String baseUrl = "http://localhost:8888";
    @Test
    public void saveUserTest () {

        User UserResponse =   webTestClient.post().uri(baseUrl+"/user/create")
                .body(Mono.just(getUser()), User.class)
                .exchange()
                .expectStatus().isOk()
                .expectBody(User.class)
                .returnResult()
                .getResponseBody();
        StepVerifier.create(Flux.just(UserResponse))
                .expectNextMatches(e-> e.getName().equals("praneeth")
                ).verifyComplete();

    }

    private User getUser () {
        User user = new User();
        user.setEmail("praneeth@gmail.com");
        user.setName("praneeth");
        return user;
    }
    @Test
    public void testGetUserById () {

        webTestClient.get().uri(baseUrl+"/user/5ec28b38f984df21c54a19e6")
                .exchange()
                .expectStatus().isOk()
                .expectBody(User.class)
                .consumeWith(resp -> {
                    if (resp.getResponseBody() != null) {
                        assertEquals("Adi", resp.getResponseBody().getName());
                    }
                });
    }

    @Test
    public void testGetUsers () {

        webTestClient.get()
                .uri(baseUrl+"/user")
                .exchange()
                .expectStatus().isOk()
                .expectBodyList(User.class)
                .value(userResponse -> {
                           Assertions.assertThat(userResponse.get(0).getId()).isEqualTo("5ec28b29f984df21c54a19e5");
                           Assertions.assertThat(userResponse.get(0).getName()).isEqualTo("");
                           Assertions.assertThat(userResponse.get(0).getEmail()).isEqualTo("dia@gmail.com");
                           Assertions.assertThat(userResponse.get(1).getId()).isEqualTo("5ec28b38f984df21c54a19e6");
                           Assertions.assertThat(userResponse.get(1).getName()).isEqualTo("Adi");
                           Assertions.assertThat(userResponse.get(1).getEmail()).isEqualTo("adi@gmail.com");
                       }
                );
    }
}