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