1 package de.juplo.kafka.chat.backend;
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.web.reactive.server.WebTestClient;
13 import org.testcontainers.shaded.org.awaitility.Awaitility;
15 import java.io.IOException;
16 import java.time.Duration;
17 import java.util.UUID;
19 import static org.hamcrest.Matchers.endsWith;
23 public abstract class AbstractConfigurationIT
25 final static String EXISTING_CHATROOM = "5c73531c-6fc4-426c-adcb-afc5c140a0f7";
26 String NONEXISTENT_CHATROOM = "7f59ec77-832e-4a17-8d22-55ef46242c17";
32 WebTestClient webTestClient;
34 ObjectMapper objectMapper;
42 .atMost(Duration.ofSeconds(15))
48 "http://localhost:{port}/actuator/health",
51 .expectStatus().isOk()
52 .expectBody().jsonPath("$.status").isEqualTo("UP");
57 @DisplayName("Restored chat-rooms can be listed")
58 void testRestoredChatRoomsCanBeListed()
62 .atMost(Duration.ofSeconds(15))
68 "http://localhost:{port}/list",
70 .accept(MediaType.APPLICATION_JSON)
72 .expectStatus().isOk()
74 .jsonPath("$.length()").isEqualTo(1)
75 .jsonPath("$[0].name").isEqualTo("FOO");
80 @DisplayName("Details as expected for restored chat-room")
81 void testRestoredChatRoomHasExpectedDetails()
85 .atMost(Duration.ofSeconds(15))
91 "http://localhost:{port}/{chatRoomId}",
94 .accept(MediaType.APPLICATION_JSON)
96 .expectStatus().isOk()
97 .expectBody().jsonPath("$.name").isEqualTo("FOO");
102 @DisplayName("Restored message from Ute has expected Text")
103 void testRestoredMessageForUteHasExpectedText()
107 .atMost(Duration.ofSeconds(15))
113 "http://localhost:{port}/{chatRoomId}/ute/1",
116 .accept(MediaType.APPLICATION_JSON)
118 .expectStatus().isOk()
119 .expectBody().jsonPath("$.text").isEqualTo("Ich bin Ute...");
124 @DisplayName("Restored message from Peter has expected Text")
125 void testRestoredMessageForPeterHasExpectedText()
129 .atMost(Duration.ofSeconds(15))
135 "http://localhost:{port}/{chatRoomId}/peter/1",
138 .accept(MediaType.APPLICATION_JSON)
140 .expectStatus().isOk()
141 .expectBody().jsonPath("$.text").isEqualTo("Hallo, ich heiße Peter!");
146 @DisplayName("A PUT-message for a non-existent chat-room yields 404 NOT FOUND")
147 void testNotFoundForPutMessageToNonExistentChatRoom()
151 .atMost(Duration.ofSeconds(15))
157 "http://localhost:{port}/{chatRoomId}/otto/66",
159 NONEXISTENT_CHATROOM)
160 .contentType(MediaType.TEXT_PLAIN)
161 .accept(MediaType.APPLICATION_JSON)
162 .bodyValue("The devil rules route 66")
164 .expectStatus().isNotFound()
166 .jsonPath("$.type").value(endsWith("/problem/unknown-chatroom"))
167 .jsonPath("$.chatroomId").isEqualTo(NONEXISTENT_CHATROOM);
172 @DisplayName("A message can be put into a newly created chat-room")
173 void testPutMessageInNewChatRoom() throws IOException
177 .atMost(Duration.ofSeconds(15))
180 byte[] result = webTestClient
182 .uri("http://localhost:{port}/create", port)
183 .contentType(MediaType.TEXT_PLAIN)
185 .accept(MediaType.APPLICATION_JSON)
187 .expectStatus().isOk()
189 .jsonPath("$.id").exists()
190 .jsonPath("$.name").isEqualTo("bar")
191 // The hard must not be asserted, because not all implementations ar aware of it
192 // .jsonPath("$.shard").isEqualTo(Integer.valueOf(2))
195 ChatRoomInfoTo chatRoomInfo = objectMapper.readValue(result, ChatRoomInfoTo.class);
196 UUID chatRoomId = chatRoomInfo.getId();
200 "http://localhost:{port}/{chatRoomId}/nerd/7",
203 .contentType(MediaType.TEXT_PLAIN)
204 .accept(MediaType.APPLICATION_JSON)
205 .bodyValue("Hello world!")
207 .expectStatus().isOk()
209 .jsonPath("$.id").isEqualTo(Integer.valueOf(7))
210 .jsonPath("$.user").isEqualTo("nerd")
211 .jsonPath("$.text").isEqualTo("Hello world!");