FIX
[demos/kafka/chat] / src / test / java / de / juplo / kafka / chat / backend / AbstractConfigurationIT.java
1 package de.juplo.kafka.chat.backend;
2
3 import com.fasterxml.jackson.databind.ObjectMapper;
4 import de.juplo.kafka.chat.backend.api.ChatRoomInfoTo;
5 import lombok.extern.slf4j.Slf4j;
6 import org.junit.jupiter.api.BeforeEach;
7 import org.junit.jupiter.api.DisplayName;
8 import org.junit.jupiter.api.Test;
9 import org.springframework.beans.factory.annotation.Autowired;
10 import org.springframework.boot.test.web.server.LocalServerPort;
11 import org.springframework.http.MediaType;
12 import org.springframework.test.annotation.DirtiesContext;
13 import org.springframework.test.web.reactive.server.WebTestClient;
14 import org.testcontainers.shaded.org.awaitility.Awaitility;
15
16 import java.io.IOException;
17 import java.time.Duration;
18 import java.util.UUID;
19 import java.util.concurrent.atomic.AtomicBoolean;
20
21 import static org.assertj.core.api.Assertions.assertThat;
22 import static org.hamcrest.Matchers.endsWith;
23
24
25 @Slf4j
26 @DirtiesContext
27 public abstract class AbstractConfigurationIT
28 {
29   final static String EXISTING_CHATROOM = "5c73531c-6fc4-426c-adcb-afc5c140a0f7";
30   String NONEXISTENT_CHATROOM = "7f59ec77-832e-4a17-8d22-55ef46242c17";
31
32
33   @LocalServerPort
34   int port;
35   @Autowired
36   WebTestClient webTestClient;
37   @Autowired
38   ObjectMapper objectMapper;
39
40
41   @BeforeEach
42   void waitForApp()
43   {
44     Awaitility
45         .await()
46         .atMost(Duration.ofSeconds(15))
47         .untilAsserted(() ->
48         {
49           webTestClient
50               .get()
51               .uri(
52                   "http://localhost:{port}/actuator/health",
53                   port)
54               .exchange()
55               .expectStatus().isOk()
56               .expectBody().jsonPath("$.status").isEqualTo("UP");
57         });
58   }
59
60   @Test
61   @DisplayName("Restored chat-rooms can be listed")
62   void testRestoredChatRoomsCanBeListed()
63   {
64     Awaitility
65         .await()
66         .atMost(Duration.ofSeconds(15))
67         .untilAsserted(() ->
68         {
69           AtomicBoolean existingChatRoomFound = new AtomicBoolean(false);
70           webTestClient
71               .get()
72               .uri(
73                   "http://localhost:{port}/list",
74                   port)
75               .accept(MediaType.APPLICATION_JSON)
76               .exchange()
77               .expectStatus().isOk()
78               .returnResult(ChatRoomInfoTo.class)
79               .getResponseBody()
80               .toIterable()
81               .forEach(chatRoomInfoTo ->
82               {
83                 log.debug("Inspecting chat-room {}", chatRoomInfoTo);
84                 if (chatRoomInfoTo.getId().equals(UUID.fromString(EXISTING_CHATROOM)))
85                 {
86                   log.debug("Found existing chat-room {}", chatRoomInfoTo);
87                   existingChatRoomFound.set(true);
88                   assertThat(chatRoomInfoTo.getName().equals("FOO"));
89                 }
90               });
91           assertThat(existingChatRoomFound.get()).isTrue();
92         });
93   }
94
95   @Test
96   @DisplayName("Details as expected for restored chat-room")
97   void testRestoredChatRoomHasExpectedDetails()
98   {
99     Awaitility
100         .await()
101         .atMost(Duration.ofSeconds(15))
102         .untilAsserted(() ->
103         {
104           webTestClient
105               .get()
106               .uri(
107                   "http://localhost:{port}/{chatRoomId}",
108                   port,
109                   EXISTING_CHATROOM)
110               .accept(MediaType.APPLICATION_JSON)
111               .exchange()
112               .expectStatus().isOk()
113               .expectBody().jsonPath("$.name").isEqualTo("FOO");
114         });
115   }
116
117   @Test
118   @DisplayName("Restored message from Ute has expected Text")
119   void testRestoredMessageForUteHasExpectedText()
120   {
121     Awaitility
122         .await()
123         .atMost(Duration.ofSeconds(15))
124         .untilAsserted(() ->
125         {
126           webTestClient
127               .get()
128               .uri(
129                   "http://localhost:{port}/{chatRoomId}/ute/1",
130                   port,
131                   EXISTING_CHATROOM)
132               .accept(MediaType.APPLICATION_JSON)
133               .exchange()
134               .expectStatus().isOk()
135               .expectBody().jsonPath("$.text").isEqualTo("Ich bin Ute...");
136         });
137   }
138
139   @Test
140   @DisplayName("Restored message from Peter has expected Text")
141   void testRestoredMessageForPeterHasExpectedText()
142   {
143     Awaitility
144         .await()
145         .atMost(Duration.ofSeconds(15))
146         .untilAsserted(() ->
147         {
148           webTestClient
149               .get()
150               .uri(
151                   "http://localhost:{port}/{chatRoomId}/peter/1",
152                   port,
153                   EXISTING_CHATROOM)
154               .accept(MediaType.APPLICATION_JSON)
155               .exchange()
156               .expectStatus().isOk()
157               .expectBody().jsonPath("$.text").isEqualTo("Hallo, ich heiße Peter!");
158         });
159   }
160
161   @Test
162   @DisplayName("A PUT-message for a non-existent chat-room yields 404 NOT FOUND")
163   void testNotFoundForPutMessageToNonExistentChatRoom()
164   {
165     Awaitility
166         .await()
167         .atMost(Duration.ofSeconds(15))
168         .untilAsserted(() ->
169         {
170           webTestClient
171               .put()
172               .uri(
173                   "http://localhost:{port}/{chatRoomId}/otto/66",
174                   port,
175                   NONEXISTENT_CHATROOM)
176               .contentType(MediaType.TEXT_PLAIN)
177               .accept(MediaType.APPLICATION_JSON)
178               .bodyValue("The devil rules route 66")
179               .exchange()
180               .expectStatus().isNotFound()
181               .expectBody()
182                 .jsonPath("$.type").value(endsWith("/problem/unknown-chatroom"))
183                 .jsonPath("$.chatroomId").isEqualTo(NONEXISTENT_CHATROOM);
184         });
185   }
186
187   @Test
188   @DisplayName("A message can be put into a newly created chat-room")
189   void testPutMessageInNewChatRoom() throws IOException
190   {
191     Awaitility
192         .await()
193         .atMost(Duration.ofSeconds(15))
194         .untilAsserted(() ->
195         {
196           byte[] result = webTestClient
197               .post()
198               .uri("http://localhost:{port}/create", port)
199               .contentType(MediaType.TEXT_PLAIN)
200               .bodyValue("bar")
201               .accept(MediaType.APPLICATION_JSON)
202               .exchange()
203               .expectStatus().isOk()
204               .expectBody()
205                 .jsonPath("$.id").exists()
206                 .jsonPath("$.name").isEqualTo("bar")
207                 // The hard must not be asserted, because not all implementations ar aware of it
208                 // .jsonPath("$.shard").isEqualTo(Integer.valueOf(2))
209               .returnResult()
210               .getResponseBody();
211           ChatRoomInfoTo chatRoomInfo = objectMapper.readValue(result, ChatRoomInfoTo.class);
212           UUID chatRoomId = chatRoomInfo.getId();
213           webTestClient
214               .put()
215               .uri(
216                   "http://localhost:{port}/{chatRoomId}/nerd/7",
217                   port,
218                   chatRoomId)
219               .contentType(MediaType.TEXT_PLAIN)
220               .accept(MediaType.APPLICATION_JSON)
221               .bodyValue("Hello world!")
222               .exchange()
223               .expectStatus().isOk()
224               .expectBody()
225                 .jsonPath("$.id").isEqualTo(Integer.valueOf(7))
226                 .jsonPath("$.user").isEqualTo("nerd")
227                 .jsonPath("$.text").isEqualTo("Hello world!");
228         });
229   }
230 }