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