channel_message_tests.rs

  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}