The parameter "path" is added to the model
[demos/testing] / src / test / java / de / juplo / demo / HtmlControllerTest.java
1 package de.juplo.demo;
2
3
4 import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
5 import org.junit.jupiter.api.BeforeEach;
6 import org.junit.jupiter.api.DisplayName;
7 import org.junit.jupiter.api.Test;
8 import org.junit.jupiter.api.extension.ExtendWith;
9 import org.junit.jupiter.params.ParameterizedTest;
10 import org.junit.jupiter.params.provider.EnumSource;
11 import org.mockito.ArgumentCaptor;
12 import static org.mockito.ArgumentMatchers.eq;
13 import static org.mockito.Mockito.verify;
14 import static org.mockito.Mockito.when;
15 import org.springframework.boot.test.mock.mockito.MockBean;
16 import org.springframework.http.HttpStatus;
17 import org.springframework.test.context.junit.jupiter.SpringExtension;
18 import org.springframework.ui.Model;
19 import org.springframework.web.reactive.function.client.WebClientResponseException;
20 import reactor.core.publisher.Mono;
21 import reactor.test.StepVerifier;
22
23
24 /**
25  * Unit-Test for class {@link RemoteContentHtmlController}.
26  * @author Kai Moritz
27  */
28 @ExtendWith(SpringExtension.class)
29 public class HtmlControllerTest
30 {
31   HtmlController controller;
32
33   @MockBean
34   RemoteContentService service;
35   @MockBean
36   Model model;
37
38
39   @BeforeEach
40   void setUp()
41   {
42     controller = new HtmlController(service);
43   }
44
45
46   @Test
47   @DisplayName("Data successfully fetched from remote-server")
48   void testOK()
49   {
50     when(service.getRemoteText("foo")).thenReturn(Mono.just("bar"));
51
52     String result = controller.fetch(model, "foo");
53
54     assertThat(result).isEqualTo("home");
55     ArgumentCaptor<Mono<String>> captor = ArgumentCaptor.forClass(Mono.class);
56     verify(model).addAttribute("path", "foo");
57     verify(model).addAttribute(eq("text"), captor.capture());
58     StepVerifier
59         .create(captor.getValue())
60         .expectNext("bar")
61         .expectComplete()
62         .verify();
63   }
64
65   @Test
66   @DisplayName("Data not found on remote-server")
67   void testNotFoud()
68   {
69     Mono<String> mono = Mono.error(WebClientResponseException.create(404, "", null, null, null));
70     when(service.getRemoteText("foo")).thenReturn(mono);
71
72     String result = controller.fetch(model, "foo");
73
74     assertThat(result).isEqualTo("home");
75     ArgumentCaptor<Mono<String>> captor = ArgumentCaptor.forClass(Mono.class);
76     verify(model).addAttribute("path", "foo");
77     verify(model).addAttribute(eq("text"), captor.capture());
78     StepVerifier
79         .create(captor.getValue())
80         .expectNext("404 ")
81         .expectComplete()
82         .verify();
83   }
84
85   /**
86    * Only the behavior on the common errors, as defined in {@link
87    * WebClientResponseException#create(int, String, org.springframework.http.HttpHeaders, byte[], java.nio.charset.Charset, org.springframework.http.HttpRequest)
88    * WebClientResponseException.create()} is tested.
89    */
90   @DisplayName("Other error while fetching data from remote-server")
91   @ParameterizedTest(name = "{arguments} ==> HTTP-status={0}")
92   @EnumSource(value = HttpStatus.class, names = {
93     "BAD_REQUEST",
94     "UNAUTHORIZED",
95     "FORBIDDEN",
96     "METHOD_NOT_ALLOWED",
97     "NOT_ACCEPTABLE",
98     "CONFLICT",
99     "GONE",
100     "UNSUPPORTED_MEDIA_TYPE",
101     "TOO_MANY_REQUESTS",
102     "UNPROCESSABLE_ENTITY",
103     "INTERNAL_SERVER_ERROR",
104     "NOT_IMPLEMENTED",
105     "BAD_GATEWAY",
106     "SERVICE_UNAVAILABLE",
107     "GATEWAY_TIMEOUT"
108   })
109   void testOtherError(HttpStatus status)
110   {
111     Mono<String> mono = Mono.error(WebClientResponseException.create(status.value(), "", null, null, null));
112     when(service.getRemoteText("foo")).thenReturn(mono);
113
114     String result = controller.fetch(model, "foo");
115
116     assertThat(result).isEqualTo("home");
117     ArgumentCaptor<Mono<String>> captor = ArgumentCaptor.forClass(Mono.class);
118     verify(model).addAttribute(eq("text"), captor.capture());
119     StepVerifier
120         .create(captor.getValue())
121         .expectNextMatches(message -> message.startsWith(Integer.toString(status.value())))
122         .expectComplete()
123         .verify();
124   }
125 }