refactor: refined the endpoint-uri's
[demos/kafka/chat] / src / test / java / de / juplo / kafka / chat / backend / api / ChatBackendControllerTest.java
1 package de.juplo.kafka.chat.backend.api;
2
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;
14
15 import java.time.Clock;
16 import java.time.LocalDateTime;
17 import java.util.UUID;
18
19 import static org.mockito.ArgumentMatchers.any;
20 import static org.mockito.Mockito.*;
21
22
23 @SpringBootTest(properties = "spring.main.allow-bean-definition-overriding=true")
24 @AutoConfigureWebTestClient
25 @Slf4j
26 public class ChatBackendControllerTest
27 {
28   @MockBean
29   ChatHomeService chatHomeService;
30   @MockBean
31   ChatRoomService chatRoomService;
32
33   @Test
34   @DisplayName("Assert expected problem-details for unknown chatroom on GET /list/{chatroomId}")
35   void testUnknownChatroomExceptionForListChatroom(@Autowired WebTestClient client)
36   {
37     // Given
38     UUID chatroomId = UUID.randomUUID();
39     when(chatHomeService.getChatRoom(any(UUID.class))).thenReturn(Mono.empty());
40
41     // When
42     WebTestClient.ResponseSpec responseSpec = client
43         .get()
44         .uri("/{chatroomId}/list", chatroomId)
45         .accept(MediaType.APPLICATION_JSON)
46         .exchange();
47
48     // Then
49     assertProblemDetailsForUnknownChatroomException(responseSpec, chatroomId);
50   }
51
52
53   @Test
54   @DisplayName("Assert expected problem-details for unknown chatroom on GET /get/{chatroomId}")
55   void testUnknownChatroomExceptionForGetChatroom(@Autowired WebTestClient client)
56   {
57     // Given
58     UUID chatroomId = UUID.randomUUID();
59     when(chatHomeService.getChatRoom(any(UUID.class))).thenReturn(Mono.empty());
60
61     // When
62     WebTestClient.ResponseSpec responseSpec = client
63         .get()
64         .uri("/{chatroomId}", chatroomId)
65         .accept(MediaType.APPLICATION_JSON)
66         .exchange();
67
68     // Then
69     assertProblemDetailsForUnknownChatroomException(responseSpec, chatroomId);
70   }
71
72   @Test
73   @DisplayName("Assert expected problem-details for unknown chatroom on PUT /put/{chatroomId}/{username}/{messageId}")
74   void testUnknownChatroomExceptionForPutMessage(@Autowired WebTestClient client)
75   {
76     // Given
77     UUID chatroomId = UUID.randomUUID();
78     String username = "foo";
79     Long messageId = 66l;
80     when(chatHomeService.getChatRoom(any(UUID.class))).thenReturn(Mono.empty());
81
82     // When
83     WebTestClient.ResponseSpec responseSpec = client
84         .put()
85         .uri(
86             "/{chatroomId}/{username}/{messageId}",
87             chatroomId,
88             username,
89             messageId)
90         .bodyValue("bar")
91         .accept(MediaType.APPLICATION_JSON)
92         .exchange();
93
94     // Then
95     assertProblemDetailsForUnknownChatroomException(responseSpec, chatroomId);
96   }
97
98   @Test
99   @DisplayName("Assert expected problem-details for unknown chatroom on GET /get/{chatroomId}/{username}/{messageId}")
100   void testUnknownChatroomExceptionForGetMessage(@Autowired WebTestClient client)
101   {
102     // Given
103     UUID chatroomId = UUID.randomUUID();
104     String username = "foo";
105     Long messageId = 66l;
106     when(chatHomeService.getChatRoom(any(UUID.class))).thenReturn(Mono.empty());
107
108     // When
109     WebTestClient.ResponseSpec responseSpec = client
110         .get()
111         .uri(
112             "/{chatroomId}/{username}/{messageId}",
113             chatroomId,
114             username,
115             messageId)
116         .accept(MediaType.APPLICATION_JSON)
117         .exchange();
118
119     // Then
120     assertProblemDetailsForUnknownChatroomException(responseSpec, chatroomId);
121   }
122
123   @Test
124   @DisplayName("Assert expected problem-details for unknown chatroom on GET /listen/{chatroomId}")
125   void testUnknownChatroomExceptionForListenChatroom(@Autowired WebTestClient client)
126   {
127     // Given
128     UUID chatroomId = UUID.randomUUID();
129     when(chatHomeService.getChatRoom(any(UUID.class))).thenReturn(Mono.empty());
130
131     // When
132     WebTestClient.ResponseSpec responseSpec = client
133         .get()
134         .uri("/{chatroomId}/listen", chatroomId)
135         // .accept(MediaType.TEXT_EVENT_STREAM, MediaType.APPLICATION_JSON) << TODO: Does not work!
136         .exchange();
137
138     // Then
139     assertProblemDetailsForUnknownChatroomException(responseSpec, chatroomId);
140   }
141
142   private void assertProblemDetailsForUnknownChatroomException(
143       WebTestClient.ResponseSpec responseSpec,
144       UUID chatroomId)
145   {
146     responseSpec
147         .expectStatus().isNotFound()
148         .expectBody()
149         .jsonPath("$.type").isEqualTo("/problem/unknown-chatroom")
150         .jsonPath("$.chatroomId").isEqualTo(chatroomId.toString());
151   }
152
153   @Test
154   @DisplayName("Assert expected problem-details for message mutation on PUT /put/{chatroomId}/{username}/{messageId}")
155   void testMessageMutationException(@Autowired WebTestClient client) throws Exception
156   {
157     // Given
158     UUID chatroomId = UUID.randomUUID();
159     String user = "foo";
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(
168         chatroomId,
169         "Test-ChatRoom",
170         Clock.systemDefaultZone(),
171         chatRoomService, 8);
172     when(chatHomeService.getChatRoom(any(UUID.class))).thenReturn(Mono.just(chatRoom));
173     Message existingMessage = new Message(
174         key,
175         serialNumberExistingMessage,
176         timeExistingMessage,
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));
183
184     // When
185     client
186         .put()
187         .uri(
188             "/{chatroomId}/{username}/{messageId}",
189             chatroomId,
190             user,
191             messageId)
192         .bodyValue(textMutatedMessage)
193         .accept(MediaType.APPLICATION_JSON)
194         .exchange()
195         // Then
196         .expectStatus().is4xxClientError()
197         .expectBody()
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));
206   }
207
208   @Test
209   @DisplayName("Assert expected problem-details for invalid username on PUT /put/{chatroomId}/{username}/{messageId}")
210   void testInvalidUsernameException(@Autowired WebTestClient client) throws Exception
211   {
212     // Given
213     UUID chatroomId = UUID.randomUUID();
214     String user = "Foo";
215     Long messageId = 66l;
216     Message.MessageKey key = Message.MessageKey.of(user, messageId);
217     String textMessage = "Hallo Welt";
218     ChatRoom chatRoom = new ChatRoom(
219         chatroomId,
220         "Test-ChatRoom",
221         Clock.systemDefaultZone(),
222         chatRoomService, 8);
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));
230
231     // When
232     client
233         .put()
234         .uri(
235             "/{chatroomId}/{username}/{messageId}",
236             chatroomId,
237             user,
238             messageId)
239         .bodyValue(textMessage)
240         .accept(MediaType.APPLICATION_JSON)
241         .exchange()
242         // Then
243         .expectStatus().is4xxClientError()
244         .expectBody()
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));
248   }
249 }