1use crate::{rpc::RECONNECT_TIMEOUT, tests::TestServer};
2use channel::ChannelChat;
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#[track_caller]
127fn assert_messages(chat: &ModelHandle<ChannelChat>, messages: &[&str], cx: &mut TestAppContext) {
128 chat.update(cx, |chat, _| {
129 assert_eq!(
130 chat.messages()
131 .iter()
132 .map(|m| m.body.as_str())
133 .collect::<Vec<_>>(),
134 messages
135 );
136 })
137}