1use crate::{
2 db::{ChannelRole, Database, MessageId, NewUserParams},
3 test_both_dbs,
4};
5use std::sync::Arc;
6use time::OffsetDateTime;
7
8test_both_dbs!(
9 test_channel_message_retrieval,
10 test_channel_message_retrieval_postgres,
11 test_channel_message_retrieval_sqlite
12);
13
14async fn test_channel_message_retrieval(db: &Arc<Database>) {
15 let user = db
16 .create_user(
17 "user@example.com",
18 false,
19 NewUserParams {
20 github_login: "user".into(),
21 github_user_id: 1,
22 invite_count: 0,
23 },
24 )
25 .await
26 .unwrap()
27 .user_id;
28 let channel = db.create_channel("channel", None, user).await.unwrap();
29
30 let owner_id = db.create_server("test").await.unwrap().0 as u32;
31 db.join_channel_chat(channel, rpc::ConnectionId { owner_id, id: 0 }, user)
32 .await
33 .unwrap();
34
35 let mut all_messages = Vec::new();
36 for i in 0..10 {
37 all_messages.push(
38 db.create_channel_message(channel, user, &i.to_string(), OffsetDateTime::now_utc(), i)
39 .await
40 .unwrap()
41 .0
42 .to_proto(),
43 );
44 }
45
46 let messages = db
47 .get_channel_messages(channel, user, 3, None)
48 .await
49 .unwrap()
50 .into_iter()
51 .map(|message| message.id)
52 .collect::<Vec<_>>();
53 assert_eq!(messages, &all_messages[7..10]);
54
55 let messages = db
56 .get_channel_messages(
57 channel,
58 user,
59 4,
60 Some(MessageId::from_proto(all_messages[6])),
61 )
62 .await
63 .unwrap()
64 .into_iter()
65 .map(|message| message.id)
66 .collect::<Vec<_>>();
67 assert_eq!(messages, &all_messages[2..6]);
68}
69
70test_both_dbs!(
71 test_channel_message_nonces,
72 test_channel_message_nonces_postgres,
73 test_channel_message_nonces_sqlite
74);
75
76async fn test_channel_message_nonces(db: &Arc<Database>) {
77 let user = db
78 .create_user(
79 "user@example.com",
80 false,
81 NewUserParams {
82 github_login: "user".into(),
83 github_user_id: 1,
84 invite_count: 0,
85 },
86 )
87 .await
88 .unwrap()
89 .user_id;
90 let channel = db.create_channel("channel", None, user).await.unwrap();
91
92 let owner_id = db.create_server("test").await.unwrap().0 as u32;
93
94 db.join_channel_chat(channel, rpc::ConnectionId { owner_id, id: 0 }, user)
95 .await
96 .unwrap();
97
98 let msg1_id = db
99 .create_channel_message(channel, user, "1", OffsetDateTime::now_utc(), 1)
100 .await
101 .unwrap();
102 let msg2_id = db
103 .create_channel_message(channel, user, "2", OffsetDateTime::now_utc(), 2)
104 .await
105 .unwrap();
106 let msg3_id = db
107 .create_channel_message(channel, user, "3", OffsetDateTime::now_utc(), 1)
108 .await
109 .unwrap();
110 let msg4_id = db
111 .create_channel_message(channel, user, "4", OffsetDateTime::now_utc(), 2)
112 .await
113 .unwrap();
114
115 assert_ne!(msg1_id, msg2_id);
116 assert_eq!(msg1_id, msg3_id);
117 assert_eq!(msg2_id, msg4_id);
118}
119
120test_both_dbs!(
121 test_channel_message_new_notification,
122 test_channel_message_new_notification_postgres,
123 test_channel_message_new_notification_sqlite
124);
125
126async fn test_channel_message_new_notification(db: &Arc<Database>) {
127 let user = db
128 .create_user(
129 "user_a@example.com",
130 false,
131 NewUserParams {
132 github_login: "user_a".into(),
133 github_user_id: 1,
134 invite_count: 0,
135 },
136 )
137 .await
138 .unwrap()
139 .user_id;
140 let observer = db
141 .create_user(
142 "user_b@example.com",
143 false,
144 NewUserParams {
145 github_login: "user_b".into(),
146 github_user_id: 1,
147 invite_count: 0,
148 },
149 )
150 .await
151 .unwrap()
152 .user_id;
153
154 let channel_1 = db.create_channel("channel", None, user).await.unwrap();
155
156 let channel_2 = db.create_channel("channel-2", None, user).await.unwrap();
157
158 db.invite_channel_member(channel_1, observer, user, ChannelRole::Member)
159 .await
160 .unwrap();
161
162 db.respond_to_channel_invite(channel_1, observer, true)
163 .await
164 .unwrap();
165
166 db.invite_channel_member(channel_2, observer, user, ChannelRole::Member)
167 .await
168 .unwrap();
169
170 db.respond_to_channel_invite(channel_2, observer, true)
171 .await
172 .unwrap();
173
174 let owner_id = db.create_server("test").await.unwrap().0 as u32;
175 let user_connection_id = rpc::ConnectionId { owner_id, id: 0 };
176
177 db.join_channel_chat(channel_1, user_connection_id, user)
178 .await
179 .unwrap();
180
181 let _ = db
182 .create_channel_message(channel_1, user, "1_1", OffsetDateTime::now_utc(), 1)
183 .await
184 .unwrap();
185
186 let (second_message, _, _) = db
187 .create_channel_message(channel_1, user, "1_2", OffsetDateTime::now_utc(), 2)
188 .await
189 .unwrap();
190
191 let (third_message, _, _) = db
192 .create_channel_message(channel_1, user, "1_3", OffsetDateTime::now_utc(), 3)
193 .await
194 .unwrap();
195
196 db.join_channel_chat(channel_2, user_connection_id, user)
197 .await
198 .unwrap();
199
200 let (fourth_message, _, _) = db
201 .create_channel_message(channel_2, user, "2_1", OffsetDateTime::now_utc(), 4)
202 .await
203 .unwrap();
204
205 // Check that observer has new messages
206 let unseen_messages = db
207 .transaction(|tx| async move {
208 db.unseen_channel_messages(observer, &[channel_1, channel_2], &*tx)
209 .await
210 })
211 .await
212 .unwrap();
213
214 assert_eq!(
215 unseen_messages,
216 [
217 rpc::proto::UnseenChannelMessage {
218 channel_id: channel_1.to_proto(),
219 message_id: third_message.to_proto(),
220 },
221 rpc::proto::UnseenChannelMessage {
222 channel_id: channel_2.to_proto(),
223 message_id: fourth_message.to_proto(),
224 },
225 ]
226 );
227
228 // Observe the second message
229 db.observe_channel_message(channel_1, observer, second_message)
230 .await
231 .unwrap();
232
233 // Make sure the observer still has a new message
234 let unseen_messages = db
235 .transaction(|tx| async move {
236 db.unseen_channel_messages(observer, &[channel_1, channel_2], &*tx)
237 .await
238 })
239 .await
240 .unwrap();
241 assert_eq!(
242 unseen_messages,
243 [
244 rpc::proto::UnseenChannelMessage {
245 channel_id: channel_1.to_proto(),
246 message_id: third_message.to_proto(),
247 },
248 rpc::proto::UnseenChannelMessage {
249 channel_id: channel_2.to_proto(),
250 message_id: fourth_message.to_proto(),
251 },
252 ]
253 );
254
255 // Observe the third message,
256 db.observe_channel_message(channel_1, observer, third_message)
257 .await
258 .unwrap();
259
260 // Make sure the observer does not have a new method
261 let unseen_messages = db
262 .transaction(|tx| async move {
263 db.unseen_channel_messages(observer, &[channel_1, channel_2], &*tx)
264 .await
265 })
266 .await
267 .unwrap();
268
269 assert_eq!(
270 unseen_messages,
271 [rpc::proto::UnseenChannelMessage {
272 channel_id: channel_2.to_proto(),
273 message_id: fourth_message.to_proto(),
274 }]
275 );
276
277 // Observe the second message again, should not regress our observed state
278 db.observe_channel_message(channel_1, observer, second_message)
279 .await
280 .unwrap();
281
282 // Make sure the observer does not have a new message
283 let unseen_messages = db
284 .transaction(|tx| async move {
285 db.unseen_channel_messages(observer, &[channel_1, channel_2], &*tx)
286 .await
287 })
288 .await
289 .unwrap();
290 assert_eq!(
291 unseen_messages,
292 [rpc::proto::UnseenChannelMessage {
293 channel_id: channel_2.to_proto(),
294 message_id: fourth_message.to_proto(),
295 }]
296 );
297}