389d12a57e0c1c9150829a9d3c31b09f89c48231
[demos/kafka/chat] / src / test / java / de / juplo / kafka / chat / backend / domain / ChatRoomDataTest.java
1 package de.juplo.kafka.chat.backend.domain;
2
3 import org.junit.jupiter.api.BeforeEach;
4 import org.junit.jupiter.api.DisplayName;
5 import org.junit.jupiter.api.Test;
6 import reactor.core.publisher.Mono;
7
8 import java.time.Clock;
9 import java.time.Instant;
10 import java.time.LocalDateTime;
11 import java.time.ZoneId;
12
13 import static org.mockito.Mockito.*;
14 import static pl.rzrz.assertj.reactor.Assertions.assertThat;
15
16
17 public class ChatRoomDataTest
18 {
19   Clock now;
20   ChatMessageService chatMessageService;
21   ChatRoomData chatRoomData;
22
23   String user;
24   Long messageId;
25   Message.MessageKey key;
26   LocalDateTime timestamp;
27
28
29   @BeforeEach
30   public void setUp()
31   {
32     now = Clock.fixed(Instant.now(), ZoneId.systemDefault());
33     chatMessageService = mock(ChatMessageService.class);
34     chatRoomData = new ChatRoomData(
35         now,
36         chatMessageService,
37         8);
38
39     user = "foo";
40     messageId = 1l;
41     key = Message.MessageKey.of(user, messageId);
42     timestamp = LocalDateTime.now(now);
43   }
44
45
46   @Test
47   @DisplayName("Assert, that Mono emits expected message, if it exists")
48   void testGetExistingMessage()
49   {
50     // Given
51     when(chatMessageService.getMessage(any(Message.MessageKey.class)))
52         .thenReturn(Mono.just(someMessage()));
53
54     // When
55     Mono<Message> mono = chatRoomData.getMessage(user, messageId);
56
57     // Then
58     assertThat(mono).emitsExactly(someMessage());
59   }
60
61   @Test
62   @DisplayName("Assert, that Mono is empty, if message does not exists")
63   void testGetNonExistentMessage()
64   {
65     // Given
66     when(chatMessageService.getMessage(any(Message.MessageKey.class)))
67         .thenReturn(Mono.empty());
68
69     // When
70     Mono<Message> mono = chatRoomData.getMessage(user, messageId);
71
72     // Then
73     assertThat(mono).emitsCount(0);
74   }
75
76   @Test
77   @DisplayName("Assert, that Mono emits the persisted message, if a new message is added")
78   void testAddNewMessageEmitsPersistedMessage()
79   {
80     // Given
81     when(chatMessageService.getMessage(any(Message.MessageKey.class)))
82         .thenReturn(Mono.empty());
83     when(chatMessageService.persistMessage(any(Message.MessageKey.class), any(LocalDateTime.class), any(String.class)))
84         .thenReturn(Mono.just(someMessage()));
85
86     // When
87     Mono<Message> mono = chatRoomData.addMessage(messageId, user, "Some Text");
88
89     // Then
90     assertThat(mono).emitsExactly(someMessage());
91   }
92
93   @Test
94   @DisplayName("Assert, that ChatMessageService.persistMessage() is called correctly, if a new message is added")
95   void testAddNewMessageTriggersPersistence()
96   {
97     // Given
98     String messageText = "Bar";
99     when(chatMessageService.getMessage(any(Message.MessageKey.class)))
100         .thenReturn(Mono.empty());
101     when(chatMessageService.persistMessage(any(Message.MessageKey.class), any(LocalDateTime.class), any(String.class)))
102         .thenReturn(Mono.just(someMessage()));
103
104     // When
105     chatRoomData
106         .addMessage(messageId, user, messageText)
107         .block();
108
109     // Then
110     verify(chatMessageService, times(1)).persistMessage(eq(key), eq(timestamp), eq(messageText));
111   }
112
113   @Test
114   @DisplayName("Assert, that Mono emits the already persisted message, if an unchanged message is added")
115   void testAddUnchangedMessageEmitsAlreadyPersistedMessage()
116   {
117     // Given
118     String messageText = "Bar";
119     Message existingMessage = new Message(key, 0l, timestamp, messageText);
120     when(chatMessageService.getMessage(any(Message.MessageKey.class)))
121         .thenReturn(Mono.just(existingMessage));
122
123     // When
124     Mono<Message> mono = chatRoomData.addMessage(messageId, user, messageText);
125
126     // Then
127     assertThat(mono).emitsExactly(existingMessage);
128   }
129
130   @Test
131   @DisplayName("Assert, that ChatMessageService.persistMessage() is not called, if an unchanged message is added")
132   void testAddUnchangedMessageDoesNotTriggerPersistence()
133   {
134     // Given
135     String messageText = "Bar";
136     Message existingMessage = new Message(key, 0l, timestamp, messageText);
137     when(chatMessageService.getMessage(any(Message.MessageKey.class)))
138         .thenReturn(Mono.just(existingMessage));
139
140     // When
141     chatRoomData
142         .addMessage(messageId, user, messageText)
143         .block();
144
145     // Then
146     verify(chatMessageService, never()).persistMessage(any(), any(), any());
147   }
148
149   @Test
150   @DisplayName("Assert, that Mono sends an error, if a message is added again with mutated text")
151   void testAddMutatedMessageSendsError()
152   {
153     // Given
154     String messageText = "Bar";
155     String mutatedText = "Boom!";
156     Message existingMessage = new Message(key, 0l, timestamp, messageText);
157     when(chatMessageService.getMessage(any(Message.MessageKey.class)))
158         .thenReturn(Mono.just(existingMessage));
159
160     // When
161     Mono<Message> mono = chatRoomData.addMessage(messageId, user, mutatedText);
162
163     // Then
164     assertThat(mono).sendsError();
165   }
166
167   @Test
168   @DisplayName("Assert, that ChatMessageService.persistMessage() is not called, if a message is added again with mutated text")
169   void testAddMutatedDoesNotTriggerPersistence()
170   {
171     // Given
172     String messageText = "Bar";
173     String mutatedText = "Boom!";
174     Message existingMessage = new Message(key, 0l, timestamp, messageText);
175     when(chatMessageService.getMessage(any(Message.MessageKey.class)))
176         .thenReturn(Mono.just(existingMessage));
177
178     // When
179     chatRoomData
180         .addMessage(messageId, user, mutatedText)
181         .onErrorResume((throwable) -> Mono.empty())
182         .block();
183
184     // Then
185     verify(chatMessageService, never()).persistMessage(any(), any(), any());
186   }
187
188
189   /**
190    * This message is used, when methods of {@link ChatMessageService} are mocked,
191    * that return a {@link Message}.
192    * The contents of the message are set to arbitrary values, in order to underline
193    * the fact, that the test can only assert, that the message that was returned
194    * by {@link ChatMessageService} is handed on by {@link ChatRoomData} correctly.
195    * @return a message.
196    */
197   private Message someMessage()
198   {
199     return new Message(
200         Message.MessageKey.of("FOO", 666l),
201         666l,
202         LocalDateTime.of(2024, 3, 8, 12, 13, 00),
203         "Just some message...");
204   }
205 }