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();
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 re-use 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.create_channel("channel", None, user_a).await.unwrap().id;
295 db.invite_channel_member(channel, user_b, user_a, ChannelRole::Member)
296 .await
297 .unwrap();
298 db.respond_to_channel_invite(channel, user_b, true)
299 .await
300 .unwrap();
301
302 let owner_id = db.create_server("test").await.unwrap().0 as u32;
303 let connection_id = rpc::ConnectionId { owner_id, id: 0 };
304 db.join_channel_chat(channel, connection_id, user_a)
305 .await
306 .unwrap();
307
308 db.create_channel_message(
309 channel,
310 user_a,
311 "hi @user_b and @user_c",
312 &mentions_to_proto(&[(3..10, user_b.to_proto()), (15..22, user_c.to_proto())]),
313 OffsetDateTime::now_utc(),
314 1,
315 )
316 .await
317 .unwrap();
318 db.create_channel_message(
319 channel,
320 user_a,
321 "bye @user_c",
322 &mentions_to_proto(&[(4..11, user_c.to_proto())]),
323 OffsetDateTime::now_utc(),
324 2,
325 )
326 .await
327 .unwrap();
328 db.create_channel_message(
329 channel,
330 user_a,
331 "umm",
332 &mentions_to_proto(&[]),
333 OffsetDateTime::now_utc(),
334 3,
335 )
336 .await
337 .unwrap();
338 db.create_channel_message(
339 channel,
340 user_a,
341 "@user_b, stop.",
342 &mentions_to_proto(&[(0..7, user_b.to_proto())]),
343 OffsetDateTime::now_utc(),
344 4,
345 )
346 .await
347 .unwrap();
348
349 let messages = db
350 .get_channel_messages(channel, user_b, 5, None)
351 .await
352 .unwrap()
353 .into_iter()
354 .map(|m| (m.body, m.mentions))
355 .collect::<Vec<_>>();
356 assert_eq!(
357 &messages,
358 &[
359 (
360 "hi @user_b and @user_c".into(),
361 mentions_to_proto(&[(3..10, user_b.to_proto()), (15..22, user_c.to_proto())]),
362 ),
363 (
364 "bye @user_c".into(),
365 mentions_to_proto(&[(4..11, user_c.to_proto())]),
366 ),
367 ("umm".into(), mentions_to_proto(&[]),),
368 (
369 "@user_b, stop.".into(),
370 mentions_to_proto(&[(0..7, user_b.to_proto())]),
371 ),
372 ]
373 );
374}