1use super::new_test_user;
2use crate::{
3 db::{ChannelRole, Database, MessageId},
4 test_both_dbs,
5};
6use channel::mentions_to_proto;
7use std::sync::Arc;
8use time::OffsetDateTime;
9
10test_both_dbs!(
11 test_channel_message_retrieval,
12 test_channel_message_retrieval_postgres,
13 test_channel_message_retrieval_sqlite
14);
15
16async fn test_channel_message_retrieval(db: &Arc<Database>) {
17 let user = new_test_user(db, "user@example.com").await;
18 let channel = db.create_channel("channel", None, user).await.unwrap().0;
19
20 let owner_id = db.create_server("test").await.unwrap().0 as u32;
21 db.join_channel_chat(channel.id, rpc::ConnectionId { owner_id, id: 0 }, user)
22 .await
23 .unwrap();
24
25 let mut all_messages = Vec::new();
26 for i in 0..10 {
27 all_messages.push(
28 db.create_channel_message(
29 channel.id,
30 user,
31 &i.to_string(),
32 &[],
33 OffsetDateTime::now_utc(),
34 i,
35 None,
36 )
37 .await
38 .unwrap()
39 .message_id
40 .to_proto(),
41 );
42 }
43
44 let messages = db
45 .get_channel_messages(channel.id, user, 3, None)
46 .await
47 .unwrap()
48 .into_iter()
49 .map(|message| message.id)
50 .collect::<Vec<_>>();
51 assert_eq!(messages, &all_messages[7..10]);
52
53 let messages = db
54 .get_channel_messages(
55 channel.id,
56 user,
57 4,
58 Some(MessageId::from_proto(all_messages[6])),
59 )
60 .await
61 .unwrap()
62 .into_iter()
63 .map(|message| message.id)
64 .collect::<Vec<_>>();
65 assert_eq!(messages, &all_messages[2..6]);
66}
67
68test_both_dbs!(
69 test_channel_message_nonces,
70 test_channel_message_nonces_postgres,
71 test_channel_message_nonces_sqlite
72);
73
74async fn test_channel_message_nonces(db: &Arc<Database>) {
75 let user_a = new_test_user(db, "user_a@example.com").await;
76 let user_b = new_test_user(db, "user_b@example.com").await;
77 let user_c = new_test_user(db, "user_c@example.com").await;
78 let channel = db.create_root_channel("channel", user_a).await.unwrap();
79 db.invite_channel_member(channel, user_b, user_a, ChannelRole::Member)
80 .await
81 .unwrap();
82 db.invite_channel_member(channel, user_c, user_a, ChannelRole::Member)
83 .await
84 .unwrap();
85 db.respond_to_channel_invite(channel, user_b, true)
86 .await
87 .unwrap();
88 db.respond_to_channel_invite(channel, user_c, true)
89 .await
90 .unwrap();
91
92 let owner_id = db.create_server("test").await.unwrap().0 as u32;
93 db.join_channel_chat(channel, rpc::ConnectionId { owner_id, id: 0 }, user_a)
94 .await
95 .unwrap();
96 db.join_channel_chat(channel, rpc::ConnectionId { owner_id, id: 1 }, user_b)
97 .await
98 .unwrap();
99
100 // As user A, create messages that reuse the same nonces. The requests
101 // succeed, but return the same ids.
102 let id1 = db
103 .create_channel_message(
104 channel,
105 user_a,
106 "hi @user_b",
107 &mentions_to_proto(&[(3..10, user_b.to_proto())]),
108 OffsetDateTime::now_utc(),
109 100,
110 None,
111 )
112 .await
113 .unwrap()
114 .message_id;
115 let id2 = db
116 .create_channel_message(
117 channel,
118 user_a,
119 "hello, fellow users",
120 &mentions_to_proto(&[]),
121 OffsetDateTime::now_utc(),
122 200,
123 None,
124 )
125 .await
126 .unwrap()
127 .message_id;
128 let id3 = db
129 .create_channel_message(
130 channel,
131 user_a,
132 "bye @user_c (same nonce as first message)",
133 &mentions_to_proto(&[(4..11, user_c.to_proto())]),
134 OffsetDateTime::now_utc(),
135 100,
136 None,
137 )
138 .await
139 .unwrap()
140 .message_id;
141 let id4 = db
142 .create_channel_message(
143 channel,
144 user_a,
145 "omg (same nonce as second message)",
146 &mentions_to_proto(&[]),
147 OffsetDateTime::now_utc(),
148 200,
149 None,
150 )
151 .await
152 .unwrap()
153 .message_id;
154
155 // As a different user, reuse one of the same nonces. This request succeeds
156 // and returns a different id.
157 let id5 = db
158 .create_channel_message(
159 channel,
160 user_b,
161 "omg @user_a (same nonce as user_a's first message)",
162 &mentions_to_proto(&[(4..11, user_a.to_proto())]),
163 OffsetDateTime::now_utc(),
164 100,
165 None,
166 )
167 .await
168 .unwrap()
169 .message_id;
170
171 assert_ne!(id1, id2);
172 assert_eq!(id1, id3);
173 assert_eq!(id2, id4);
174 assert_ne!(id5, id1);
175
176 let messages = db
177 .get_channel_messages(channel, user_a, 5, None)
178 .await
179 .unwrap()
180 .into_iter()
181 .map(|m| (m.id, m.body, m.mentions))
182 .collect::<Vec<_>>();
183 assert_eq!(
184 messages,
185 &[
186 (
187 id1.to_proto(),
188 "hi @user_b".into(),
189 mentions_to_proto(&[(3..10, user_b.to_proto())]),
190 ),
191 (
192 id2.to_proto(),
193 "hello, fellow users".into(),
194 mentions_to_proto(&[])
195 ),
196 (
197 id5.to_proto(),
198 "omg @user_a (same nonce as user_a's first message)".into(),
199 mentions_to_proto(&[(4..11, user_a.to_proto())]),
200 ),
201 ]
202 );
203}
204
205test_both_dbs!(
206 test_unseen_channel_messages,
207 test_unseen_channel_messages_postgres,
208 test_unseen_channel_messages_sqlite
209);
210
211async fn test_unseen_channel_messages(db: &Arc<Database>) {
212 let user = new_test_user(db, "user_a@example.com").await;
213 let observer = new_test_user(db, "user_b@example.com").await;
214
215 let channel_1 = db.create_root_channel("channel", user).await.unwrap();
216 let channel_2 = db.create_root_channel("channel-2", user).await.unwrap();
217
218 db.invite_channel_member(channel_1, observer, user, ChannelRole::Member)
219 .await
220 .unwrap();
221 db.invite_channel_member(channel_2, observer, user, ChannelRole::Member)
222 .await
223 .unwrap();
224
225 db.respond_to_channel_invite(channel_1, observer, true)
226 .await
227 .unwrap();
228 db.respond_to_channel_invite(channel_2, observer, true)
229 .await
230 .unwrap();
231
232 let owner_id = db.create_server("test").await.unwrap().0 as u32;
233 let user_connection_id = rpc::ConnectionId { owner_id, id: 0 };
234
235 db.join_channel_chat(channel_1, user_connection_id, user)
236 .await
237 .unwrap();
238
239 let _ = db
240 .create_channel_message(
241 channel_1,
242 user,
243 "1_1",
244 &[],
245 OffsetDateTime::now_utc(),
246 1,
247 None,
248 )
249 .await
250 .unwrap();
251
252 let _ = db
253 .create_channel_message(
254 channel_1,
255 user,
256 "1_2",
257 &[],
258 OffsetDateTime::now_utc(),
259 2,
260 None,
261 )
262 .await
263 .unwrap();
264
265 let third_message = db
266 .create_channel_message(
267 channel_1,
268 user,
269 "1_3",
270 &[],
271 OffsetDateTime::now_utc(),
272 3,
273 None,
274 )
275 .await
276 .unwrap()
277 .message_id;
278
279 db.join_channel_chat(channel_2, user_connection_id, user)
280 .await
281 .unwrap();
282
283 let fourth_message = db
284 .create_channel_message(
285 channel_2,
286 user,
287 "2_1",
288 &[],
289 OffsetDateTime::now_utc(),
290 4,
291 None,
292 )
293 .await
294 .unwrap()
295 .message_id;
296
297 // Check that observer has new messages
298 let latest_messages = db
299 .transaction(|tx| async move {
300 db.latest_channel_messages(&[channel_1, channel_2], &tx)
301 .await
302 })
303 .await
304 .unwrap();
305
306 assert_eq!(
307 latest_messages,
308 [
309 rpc::proto::ChannelMessageId {
310 channel_id: channel_1.to_proto(),
311 message_id: third_message.to_proto(),
312 },
313 rpc::proto::ChannelMessageId {
314 channel_id: channel_2.to_proto(),
315 message_id: fourth_message.to_proto(),
316 },
317 ]
318 );
319}
320
321test_both_dbs!(
322 test_channel_message_mentions,
323 test_channel_message_mentions_postgres,
324 test_channel_message_mentions_sqlite
325);
326
327async fn test_channel_message_mentions(db: &Arc<Database>) {
328 let user_a = new_test_user(db, "user_a@example.com").await;
329 let user_b = new_test_user(db, "user_b@example.com").await;
330 let user_c = new_test_user(db, "user_c@example.com").await;
331
332 let channel = db
333 .create_channel("channel", None, user_a)
334 .await
335 .unwrap()
336 .0
337 .id;
338 db.invite_channel_member(channel, user_b, user_a, ChannelRole::Member)
339 .await
340 .unwrap();
341 db.respond_to_channel_invite(channel, user_b, true)
342 .await
343 .unwrap();
344
345 let owner_id = db.create_server("test").await.unwrap().0 as u32;
346 let connection_id = rpc::ConnectionId { owner_id, id: 0 };
347 db.join_channel_chat(channel, connection_id, user_a)
348 .await
349 .unwrap();
350
351 db.create_channel_message(
352 channel,
353 user_a,
354 "hi @user_b and @user_c",
355 &mentions_to_proto(&[(3..10, user_b.to_proto()), (15..22, user_c.to_proto())]),
356 OffsetDateTime::now_utc(),
357 1,
358 None,
359 )
360 .await
361 .unwrap();
362 db.create_channel_message(
363 channel,
364 user_a,
365 "bye @user_c",
366 &mentions_to_proto(&[(4..11, user_c.to_proto())]),
367 OffsetDateTime::now_utc(),
368 2,
369 None,
370 )
371 .await
372 .unwrap();
373 db.create_channel_message(
374 channel,
375 user_a,
376 "umm",
377 &mentions_to_proto(&[]),
378 OffsetDateTime::now_utc(),
379 3,
380 None,
381 )
382 .await
383 .unwrap();
384 db.create_channel_message(
385 channel,
386 user_a,
387 "@user_b, stop.",
388 &mentions_to_proto(&[(0..7, user_b.to_proto())]),
389 OffsetDateTime::now_utc(),
390 4,
391 None,
392 )
393 .await
394 .unwrap();
395
396 let messages = db
397 .get_channel_messages(channel, user_b, 5, None)
398 .await
399 .unwrap()
400 .into_iter()
401 .map(|m| (m.body, m.mentions))
402 .collect::<Vec<_>>();
403 assert_eq!(
404 &messages,
405 &[
406 (
407 "hi @user_b and @user_c".into(),
408 mentions_to_proto(&[(3..10, user_b.to_proto()), (15..22, user_c.to_proto())]),
409 ),
410 (
411 "bye @user_c".into(),
412 mentions_to_proto(&[(4..11, user_c.to_proto())]),
413 ),
414 ("umm".into(), mentions_to_proto(&[]),),
415 (
416 "@user_b, stop.".into(),
417 mentions_to_proto(&[(0..7, user_b.to_proto())]),
418 ),
419 ]
420 );
421}