1 package de.juplo.kafka.chat.backend.api;
3 import de.juplo.kafka.chat.backend.domain.*;
4 import lombok.extern.slf4j.Slf4j;
5 import org.junit.jupiter.api.DisplayName;
6 import org.junit.jupiter.api.Test;
7 import org.springframework.beans.factory.annotation.Autowired;
8 import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
9 import org.springframework.boot.test.context.SpringBootTest;
10 import org.springframework.boot.test.mock.mockito.MockBean;
11 import org.springframework.http.MediaType;
12 import org.springframework.test.web.reactive.server.WebTestClient;
13 import reactor.core.publisher.Mono;
15 import java.time.Clock;
16 import java.time.LocalDateTime;
17 import java.util.UUID;
19 import static org.mockito.ArgumentMatchers.any;
20 import static org.mockito.Mockito.*;
23 @SpringBootTest(properties = "spring.main.allow-bean-definition-overriding=true")
24 @AutoConfigureWebTestClient
26 public class ChatBackendControllerTest
29 ChatHomeService chatHomeService;
31 ChatRoomService chatRoomService;
34 @DisplayName("Assert expected problem-details for unknown chatroom on GET /list/{chatroomId}")
35 void testUnknownChatroomExceptionForListChatroom(@Autowired WebTestClient client)
38 UUID chatroomId = UUID.randomUUID();
39 when(chatHomeService.getChatRoom(any(UUID.class))).thenReturn(Mono.empty());
42 WebTestClient.ResponseSpec responseSpec = client
44 .uri("/list/{chatroomId}", chatroomId)
45 .accept(MediaType.APPLICATION_JSON)
49 assertProblemDetailsForUnknownChatroomException(responseSpec, chatroomId);
54 @DisplayName("Assert expected problem-details for unknown chatroom on GET /get/{chatroomId}")
55 void testUnknownChatroomExceptionForGetChatroom(@Autowired WebTestClient client)
58 UUID chatroomId = UUID.randomUUID();
59 when(chatHomeService.getChatRoom(any(UUID.class))).thenReturn(Mono.empty());
62 WebTestClient.ResponseSpec responseSpec = client
64 .uri("/get/{chatroomId}", chatroomId)
65 .accept(MediaType.APPLICATION_JSON)
69 assertProblemDetailsForUnknownChatroomException(responseSpec, chatroomId);
73 @DisplayName("Assert expected problem-details for unknown chatroom on PUT /put/{chatroomId}/{username}/{messageId}")
74 void testUnknownChatroomExceptionForPutMessage(@Autowired WebTestClient client)
77 UUID chatroomId = UUID.randomUUID();
78 String username = "foo";
80 when(chatHomeService.getChatRoom(any(UUID.class))).thenReturn(Mono.empty());
83 WebTestClient.ResponseSpec responseSpec = client
86 "/put/{chatroomId}/{username}/{messageId}",
91 .accept(MediaType.APPLICATION_JSON)
95 assertProblemDetailsForUnknownChatroomException(responseSpec, chatroomId);
99 @DisplayName("Assert expected problem-details for unknown chatroom on GET /get/{chatroomId}/{username}/{messageId}")
100 void testUnknownChatroomExceptionForGetMessage(@Autowired WebTestClient client)
103 UUID chatroomId = UUID.randomUUID();
104 String username = "foo";
105 Long messageId = 66l;
106 when(chatHomeService.getChatRoom(any(UUID.class))).thenReturn(Mono.empty());
109 WebTestClient.ResponseSpec responseSpec = client
112 "/get/{chatroomId}/{username}/{messageId}",
116 .accept(MediaType.APPLICATION_JSON)
120 assertProblemDetailsForUnknownChatroomException(responseSpec, chatroomId);
124 @DisplayName("Assert expected problem-details for unknown chatroom on GET /listen/{chatroomId}")
125 void testUnknownChatroomExceptionForListenChatroom(@Autowired WebTestClient client)
128 UUID chatroomId = UUID.randomUUID();
129 when(chatHomeService.getChatRoom(any(UUID.class))).thenReturn(Mono.empty());
132 WebTestClient.ResponseSpec responseSpec = client
134 .uri("/listen/{chatroomId}", chatroomId)
135 // .accept(MediaType.TEXT_EVENT_STREAM, MediaType.APPLICATION_JSON) << TODO: Does not work!
139 assertProblemDetailsForUnknownChatroomException(responseSpec, chatroomId);
142 private void assertProblemDetailsForUnknownChatroomException(
143 WebTestClient.ResponseSpec responseSpec,
147 .expectStatus().isNotFound()
149 .jsonPath("$.type").isEqualTo("/problem/unknown-chatroom")
150 .jsonPath("$.chatroomId").isEqualTo(chatroomId.toString());
154 @DisplayName("Assert expected problem-details for message mutation on PUT /put/{chatroomId}/{username}/{messageId}")
155 void testMessageMutationException(@Autowired WebTestClient client) throws Exception
158 UUID chatroomId = UUID.randomUUID();
160 Long messageId = 66l;
161 Message.MessageKey key = Message.MessageKey.of(user, messageId);
162 Long serialNumberExistingMessage = 0l;
163 String timeExistingMessageAsString = "2023-01-09T20:44:57.389665447";
164 LocalDateTime timeExistingMessage = LocalDateTime.parse(timeExistingMessageAsString);
165 String textExistingMessage = "Existing";
166 String textMutatedMessage = "Mutated!";
167 ChatRoom chatRoom = new ChatRoom(
170 Clock.systemDefaultZone(),
172 when(chatHomeService.getChatRoom(any(UUID.class))).thenReturn(Mono.just(chatRoom));
173 Message existingMessage = new Message(
175 serialNumberExistingMessage,
177 textExistingMessage);
178 when(chatRoomService.getMessage(any(Message.MessageKey.class)))
179 .thenReturn(Mono.just(existingMessage));
180 // Needed for readable error-reports, in case of a bug that leads to according unwanted call
181 when(chatRoomService.persistMessage(any(Message.MessageKey.class), any(LocalDateTime.class), any(String.class)))
182 .thenReturn(mock(Message.class));
188 "/put/{chatroomId}/{username}/{messageId}",
192 .bodyValue(textMutatedMessage)
193 .accept(MediaType.APPLICATION_JSON)
196 .expectStatus().is4xxClientError()
198 .jsonPath("$.type").isEqualTo("/problem/message-mutation")
199 .jsonPath("$.existingMessage.id").isEqualTo(messageId)
200 .jsonPath("$.existingMessage.serial").isEqualTo(serialNumberExistingMessage)
201 .jsonPath("$.existingMessage.time").isEqualTo(timeExistingMessageAsString)
202 .jsonPath("$.existingMessage.user").isEqualTo(user)
203 .jsonPath("$.existingMessage.text").isEqualTo(textExistingMessage)
204 .jsonPath("$.mutatedText").isEqualTo(textMutatedMessage);
205 verify(chatRoomService, never()).persistMessage(eq(key), any(LocalDateTime.class), any(String.class));
209 @DisplayName("Assert expected problem-details for invalid username on PUT /put/{chatroomId}/{username}/{messageId}")
210 void testInvalidUsernameException(@Autowired WebTestClient client) throws Exception
213 UUID chatroomId = UUID.randomUUID();
215 Long messageId = 66l;
216 Message.MessageKey key = Message.MessageKey.of(user, messageId);
217 String textMessage = "Hallo Welt";
218 ChatRoom chatRoom = new ChatRoom(
221 Clock.systemDefaultZone(),
223 when(chatHomeService.getChatRoom(any(UUID.class)))
224 .thenReturn(Mono.just(chatRoom));
225 when(chatRoomService.getMessage(any(Message.MessageKey.class)))
226 .thenReturn(Mono.empty());
227 // Needed for readable error-reports, in case of a bug that leads to according unwanted call
228 when(chatRoomService.persistMessage(any(Message.MessageKey.class), any(LocalDateTime.class), any(String.class)))
229 .thenReturn(mock(Message.class));
235 "/put/{chatroomId}/{username}/{messageId}",
239 .bodyValue(textMessage)
240 .accept(MediaType.APPLICATION_JSON)
243 .expectStatus().is4xxClientError()
245 .jsonPath("$.type").isEqualTo("/problem/invalid-username")
246 .jsonPath("$.username").isEqualTo(user);
247 verify(chatRoomService, never()).persistMessage(eq(key), any(LocalDateTime.class), any(String.class));