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