--- /dev/null
+package de.juplo.demo;
+
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.reactive.server.WebTestClient;
+
+import java.util.Optional;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.*;
+
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@AutoConfigureWebTestClient
+class ExceptionHandlingApplicationIT {
+ private final static Logger LOG =
+ LoggerFactory.getLogger(ExceptionHandlingApplicationIT.class);
+
+ @MockBean
+ ExampleService service;
+
+ @Autowired
+ WebTestClient client;
+
+
+ @Test
+ void contextLoads() throws Exception {
+ }
+
+ @Test
+ void test200ForNoAnswer() throws Exception {
+ client
+ .get()
+ .uri("/")
+ .accept(MediaType.TEXT_HTML)
+ .exchange()
+ .expectStatus().isOk()
+ .expectBody(String.class).value(content -> {
+ Document doc = Jsoup.parse(content);
+ assertThat(doc.select("ul > li")).isEmpty();
+ });
+
+ verify(service, times(0)).checkAnswer(anyInt());
+ }
+
+ @Test
+ void test200ForEmptyAnswer() throws Exception {
+ client
+ .get()
+ .uri("/?answer= ")
+ .accept(MediaType.TEXT_HTML)
+ .exchange()
+ .expectStatus().isOk()
+ .expectBody(String.class).value(content -> {
+ Document doc = Jsoup.parse(content);
+ assertThat(doc.select("ul > li")).isEmpty();
+ });
+
+ verify(service, times(0)).checkAnswer(anyInt());
+ }
+
+ @Test
+ void test200ForAnswerThatContainsOnlyWhitespace() throws Exception {
+ client
+ .get()
+ .uri("/?answer=")
+ .accept(MediaType.TEXT_HTML)
+ .exchange()
+ .expectStatus().isOk()
+ .expectBody(String.class).value(content -> {
+ Document doc = Jsoup.parse(content);
+ assertThat(doc.select("ul > li")).isEmpty();
+ });
+
+ verify(service, times(0)).checkAnswer(anyInt());
+ }
+
+ @Test
+ void test200ForWrongAnswer() throws Exception {
+ when(service.checkAnswer(anyInt())).thenReturn(Optional.of(false));
+
+ client
+ .get()
+ .uri("/?answer=1234")
+ .accept(MediaType.TEXT_HTML)
+ .exchange()
+ .expectStatus().isOk()
+ .expectBody(String.class).value(content -> {
+ Document doc = Jsoup.parse(content);
+ assertThat(doc.selectFirst("ul > li:nth-child(2) > strong").text()).isEqualTo("false");
+ });
+
+ verify(service, times(1)).checkAnswer(anyInt());
+ }
+
+ @Test
+ void test200ForCorrectAnswer() throws Exception {
+ when(service.checkAnswer(anyInt())).thenReturn(Optional.of(true));
+
+ client
+ .get()
+ .uri("/?answer=1234")
+ .accept(MediaType.TEXT_HTML)
+ .exchange()
+ .expectStatus().isOk()
+ .expectBody(String.class).value(content -> {
+ Document doc = Jsoup.parse(content);
+ assertThat(doc.selectFirst("ul > li:nth-child(2) > strong").text()).isEqualTo("true");
+ });
+
+ verify(service, times(1)).checkAnswer(anyInt());
+ }
+
+ @Test
+ void testExceptionForNegativeAnswer() throws Exception {
+ when(service.checkAnswer(anyInt())).thenReturn(Optional.empty());
+
+ client
+ .get()
+ .uri("/?answer=1234")
+ .accept(MediaType.TEXT_HTML)
+ .exchange()
+ .expectStatus().isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR)
+ .expectBody(String.class).value(content -> {
+ Document doc = Jsoup.parse(content);
+ assertThat(doc.selectFirst("title").text())
+ .isEqualTo("500: Internal Server Error");
+ assertThat(doc.selectFirst("div > p > strong").text())
+ .isEqualTo("Catched exception: java.lang.IllegalArgumentException: FOO!");
+ });
+
+ verify(service, times(1)).checkAnswer(anyInt());
+ }
+
+ @Test
+ void test400ForStringInput() throws Exception {
+ when(service.checkAnswer(anyInt())).thenReturn(Optional.empty());
+
+ client
+ .get()
+ .uri("/?answer=bar")
+ .accept(MediaType.TEXT_HTML)
+ .exchange()
+ .expectStatus().isBadRequest()
+ .expectBody(String.class).value(content -> {
+ Document doc = Jsoup.parse(content);
+ assertThat(doc.selectFirst("title").text())
+ .isEqualTo("400: NumberFormatException");
+ assertThat(doc.selectFirst("div > p > strong").text())
+ .isEqualTo("Catched exception: java.lang.NumberFormatException: For input string: \"bar\"");
+ });
+
+ verify(service, times(0)).checkAnswer(anyInt());
+ }
+
+ @Test
+ void test400ForExceptionInBusinessLogic() throws Exception {
+ when(service.checkAnswer(anyInt())).thenThrow(new IllegalArgumentException("FOO!"));
+
+ client
+ .get()
+ .uri("/?answer=1234")
+ .accept(MediaType.TEXT_HTML)
+ .exchange()
+ .expectStatus().isBadRequest()
+ .expectBody(String.class).value(content -> {
+ Document doc = Jsoup.parse(content);
+ assertThat(doc.selectFirst("title").text())
+ .isEqualTo("400: IllegalArgumentException");
+ assertThat(doc.selectFirst("div > p > strong").text())
+ .isEqualTo("Catched exception: java.lang.IllegalArgumentException: FOO!");
+ });
+
+ verify(service, times(1)).checkAnswer(anyInt());
+ }
+}