1use crate::{rpc::RECONNECT_TIMEOUT, tests::TestServer};
2use channel::{ChannelChat, ChannelMessageId};
3use gpui::{executor::Deterministic, ModelHandle, TestAppContext};
4use std::sync::Arc;
5
6#[gpui::test]
7async fn test_basic_channel_messages(
8 deterministic: Arc<Deterministic>,
9 cx_a: &mut TestAppContext,
10 cx_b: &mut TestAppContext,
11) {
12 deterministic.forbid_parking();
13 let mut server = TestServer::start(&deterministic).await;
14 let client_a = server.create_client(cx_a, "user_a").await;
15 let client_b = server.create_client(cx_b, "user_b").await;
16
17 let channel_id = server
18 .make_channel(
19 "the-channel",
20 None,
21 (&client_a, cx_a),
22 &mut [(&client_b, cx_b)],
23 )
24 .await;
25
26 let channel_chat_a = client_a
27 .channel_store()
28 .update(cx_a, |store, cx| store.open_channel_chat(channel_id, cx))
29 .await
30 .unwrap();
31 let channel_chat_b = client_b
32 .channel_store()
33 .update(cx_b, |store, cx| store.open_channel_chat(channel_id, cx))
34 .await
35 .unwrap();
36
37 channel_chat_a
38 .update(cx_a, |c, cx| c.send_message("one".into(), cx).unwrap())
39 .await
40 .unwrap();
41 channel_chat_a
42 .update(cx_a, |c, cx| c.send_message("two".into(), cx).unwrap())
43 .await
44 .unwrap();
45
46 deterministic.run_until_parked();
47 channel_chat_b
48 .update(cx_b, |c, cx| c.send_message("three".into(), cx).unwrap())
49 .await
50 .unwrap();
51
52 deterministic.run_until_parked();
53 channel_chat_a.update(cx_a, |c, _| {
54 assert_eq!(
55 c.messages()
56 .iter()
57 .map(|m| m.body.as_str())
58 .collect::<Vec<_>>(),
59 vec!["one", "two", "three"]
60 );
61 })
62}
63
64#[gpui::test]
65async fn test_rejoin_channel_chat(
66 deterministic: Arc<Deterministic>,
67 cx_a: &mut TestAppContext,
68 cx_b: &mut TestAppContext,
69) {
70 deterministic.forbid_parking();
71 let mut server = TestServer::start(&deterministic).await;
72 let client_a = server.create_client(cx_a, "user_a").await;
73 let client_b = server.create_client(cx_b, "user_b").await;
74
75 let channel_id = server
76 .make_channel(
77 "the-channel",
78 None,
79 (&client_a, cx_a),
80 &mut [(&client_b, cx_b)],
81 )
82 .await;
83
84 let channel_chat_a = client_a
85 .channel_store()
86 .update(cx_a, |store, cx| store.open_channel_chat(channel_id, cx))
87 .await
88 .unwrap();
89 let channel_chat_b = client_b
90 .channel_store()
91 .update(cx_b, |store, cx| store.open_channel_chat(channel_id, cx))
92 .await
93 .unwrap();
94
95 channel_chat_a
96 .update(cx_a, |c, cx| c.send_message("one".into(), cx).unwrap())
97 .await
98 .unwrap();
99 channel_chat_b
100 .update(cx_b, |c, cx| c.send_message("two".into(), cx).unwrap())
101 .await
102 .unwrap();
103
104 server.forbid_connections();
105 server.disconnect_client(client_a.peer_id().unwrap());
106
107 // While client A is disconnected, clients A and B both send new messages.
108 channel_chat_a
109 .update(cx_a, |c, cx| c.send_message("three".into(), cx).unwrap())
110 .await
111 .unwrap_err();
112 channel_chat_a
113 .update(cx_a, |c, cx| c.send_message("four".into(), cx).unwrap())
114 .await
115 .unwrap_err();
116 channel_chat_b
117 .update(cx_b, |c, cx| c.send_message("five".into(), cx).unwrap())
118 .await
119 .unwrap();
120 channel_chat_b
121 .update(cx_b, |c, cx| c.send_message("six".into(), cx).unwrap())
122 .await
123 .unwrap();
124
125 // Client A reconnects.
126 server.allow_connections();
127 deterministic.advance_clock(RECONNECT_TIMEOUT);
128
129 // Client A fetches the messages that were sent while they were disconnected
130 // and resends their own messages which failed to send.
131 let expected_messages = &["one", "two", "five", "six", "three", "four"];
132 assert_messages(&channel_chat_a, expected_messages, cx_a);
133 assert_messages(&channel_chat_b, expected_messages, cx_b);
134}
135
136#[gpui::test]
137async fn test_remove_channel_message(
138 deterministic: Arc<Deterministic>,
139 cx_a: &mut TestAppContext,
140 cx_b: &mut TestAppContext,
141 cx_c: &mut TestAppContext,
142) {
143 deterministic.forbid_parking();
144 let mut server = TestServer::start(&deterministic).await;
145 let client_a = server.create_client(cx_a, "user_a").await;
146 let client_b = server.create_client(cx_b, "user_b").await;
147 let client_c = server.create_client(cx_c, "user_c").await;
148
149 let channel_id = server
150 .make_channel(
151 "the-channel",
152 None,
153 (&client_a, cx_a),
154 &mut [(&client_b, cx_b), (&client_c, cx_c)],
155 )
156 .await;
157
158 let channel_chat_a = client_a
159 .channel_store()
160 .update(cx_a, |store, cx| store.open_channel_chat(channel_id, cx))
161 .await
162 .unwrap();
163 let channel_chat_b = client_b
164 .channel_store()
165 .update(cx_b, |store, cx| store.open_channel_chat(channel_id, cx))
166 .await
167 .unwrap();
168
169 // Client A sends some messages.
170 channel_chat_a
171 .update(cx_a, |c, cx| c.send_message("one".into(), cx).unwrap())
172 .await
173 .unwrap();
174 channel_chat_a
175 .update(cx_a, |c, cx| c.send_message("two".into(), cx).unwrap())
176 .await
177 .unwrap();
178 channel_chat_a
179 .update(cx_a, |c, cx| c.send_message("three".into(), cx).unwrap())
180 .await
181 .unwrap();
182
183 // Clients A and B see all of the messages.
184 deterministic.run_until_parked();
185 let expected_messages = &["one", "two", "three"];
186 assert_messages(&channel_chat_a, expected_messages, cx_a);
187 assert_messages(&channel_chat_b, expected_messages, cx_b);
188
189 // Client A deletes one of their messages.
190 channel_chat_a
191 .update(cx_a, |c, cx| {
192 let ChannelMessageId::Saved(id) = c.message(1).id else {
193 panic!("message not saved")
194 };
195 c.remove_message(id, cx)
196 })
197 .await
198 .unwrap();
199
200 // Client B sees that the message is gone.
201 deterministic.run_until_parked();
202 let expected_messages = &["one", "three"];
203 assert_messages(&channel_chat_a, expected_messages, cx_a);
204 assert_messages(&channel_chat_b, expected_messages, cx_b);
205
206 // Client C joins the channel chat, and does not see the deleted message.
207 let channel_chat_c = client_c
208 .channel_store()
209 .update(cx_c, |store, cx| store.open_channel_chat(channel_id, cx))
210 .await
211 .unwrap();
212 assert_messages(&channel_chat_c, expected_messages, cx_c);
213}
214
215#[track_caller]
216fn assert_messages(chat: &ModelHandle<ChannelChat>, messages: &[&str], cx: &mut TestAppContext) {
217 assert_eq!(
218 chat.read_with(cx, |chat, _| chat
219 .messages()
220 .iter()
221 .map(|m| m.body.clone())
222 .collect::<Vec<_>>(),),
223 messages
224 );
225}