1use call::ActiveCall;
2use client::Channel;
3use gpui::{executor::Deterministic, TestAppContext};
4use std::sync::Arc;
5
6use crate::tests::{room_participants, RoomParticipants};
7
8use super::TestServer;
9
10#[gpui::test]
11async fn test_basic_channels(
12 deterministic: Arc<Deterministic>,
13 cx_a: &mut TestAppContext,
14 cx_b: &mut TestAppContext,
15) {
16 deterministic.forbid_parking();
17 let mut server = TestServer::start(&deterministic).await;
18 let client_a = server.create_client(cx_a, "user_a").await;
19 let client_b = server.create_client(cx_b, "user_b").await;
20
21 let channel_a_id = client_a
22 .channel_store()
23 .update(cx_a, |channel_store, _| {
24 channel_store.create_channel("channel-a", None)
25 })
26 .await
27 .unwrap();
28
29 client_a.channel_store().read_with(cx_a, |channels, _| {
30 assert_eq!(
31 channels.channels(),
32 &[Arc::new(Channel {
33 id: channel_a_id,
34 name: "channel-a".to_string(),
35 parent_id: None,
36 depth: 0,
37 })]
38 )
39 });
40
41 client_b
42 .channel_store()
43 .read_with(cx_b, |channels, _| assert_eq!(channels.channels(), &[]));
44
45 // Invite client B to channel A as client A.
46 client_a
47 .channel_store()
48 .update(cx_a, |channel_store, _| {
49 channel_store.invite_member(channel_a_id, client_b.user_id().unwrap(), false)
50 })
51 .await
52 .unwrap();
53
54 // Wait for client b to see the invitation
55 deterministic.run_until_parked();
56
57 client_b.channel_store().read_with(cx_b, |channels, _| {
58 assert_eq!(
59 channels.channel_invitations(),
60 &[Arc::new(Channel {
61 id: channel_a_id,
62 name: "channel-a".to_string(),
63 parent_id: None,
64 depth: 0,
65 })]
66 )
67 });
68
69 // Client B now sees that they are in channel A.
70 client_b
71 .channel_store()
72 .update(cx_b, |channels, _| {
73 channels.respond_to_channel_invite(channel_a_id, true)
74 })
75 .await
76 .unwrap();
77 client_b.channel_store().read_with(cx_b, |channels, _| {
78 assert_eq!(channels.channel_invitations(), &[]);
79 assert_eq!(
80 channels.channels(),
81 &[Arc::new(Channel {
82 id: channel_a_id,
83 name: "channel-a".to_string(),
84 parent_id: None,
85 depth: 0,
86 })]
87 )
88 });
89
90 // Client A deletes the channel
91 client_a
92 .channel_store()
93 .update(cx_a, |channel_store, _| {
94 channel_store.remove_channel(channel_a_id)
95 })
96 .await
97 .unwrap();
98
99 deterministic.run_until_parked();
100 client_a
101 .channel_store()
102 .read_with(cx_a, |channels, _| assert_eq!(channels.channels(), &[]));
103 client_b
104 .channel_store()
105 .read_with(cx_b, |channels, _| assert_eq!(channels.channels(), &[]));
106}
107
108#[gpui::test]
109async fn test_channel_room(
110 deterministic: Arc<Deterministic>,
111 cx_a: &mut TestAppContext,
112 cx_b: &mut TestAppContext,
113) {
114 deterministic.forbid_parking();
115 let mut server = TestServer::start(&deterministic).await;
116 let client_a = server.create_client(cx_a, "user_a").await;
117 let client_b = server.create_client(cx_b, "user_b").await;
118
119 let zed_id = server
120 .make_channel("zed", (&client_a, cx_a), &mut [(&client_b, cx_b)])
121 .await;
122
123 let active_call_a = cx_a.read(ActiveCall::global);
124 let active_call_b = cx_b.read(ActiveCall::global);
125
126 active_call_a
127 .update(cx_a, |active_call, cx| active_call.join_channel(zed_id, cx))
128 .await
129 .unwrap();
130
131 active_call_b
132 .update(cx_b, |active_call, cx| active_call.join_channel(zed_id, cx))
133 .await
134 .unwrap();
135
136 deterministic.run_until_parked();
137
138 let room_a = active_call_a.read_with(cx_a, |call, _| call.room().unwrap().clone());
139 room_a.read_with(cx_a, |room, _| assert!(room.is_connected()));
140 assert_eq!(
141 room_participants(&room_a, cx_a),
142 RoomParticipants {
143 remote: vec!["user_b".to_string()],
144 pending: vec![]
145 }
146 );
147
148 let room_b = active_call_b.read_with(cx_b, |call, _| call.room().unwrap().clone());
149 room_b.read_with(cx_b, |room, _| assert!(room.is_connected()));
150 assert_eq!(
151 room_participants(&room_b, cx_b),
152 RoomParticipants {
153 remote: vec!["user_a".to_string()],
154 pending: vec![]
155 }
156 );
157
158 // Make sure that leaving and rejoining works
159
160 active_call_a
161 .update(cx_a, |active_call, cx| active_call.hang_up(cx))
162 .await
163 .unwrap();
164
165 active_call_b
166 .update(cx_b, |active_call, cx| active_call.hang_up(cx))
167 .await
168 .unwrap();
169
170 // Make sure room exists?
171
172 active_call_a
173 .update(cx_a, |active_call, cx| active_call.join_channel(zed_id, cx))
174 .await
175 .unwrap();
176
177 active_call_b
178 .update(cx_b, |active_call, cx| active_call.join_channel(zed_id, cx))
179 .await
180 .unwrap();
181
182 deterministic.run_until_parked();
183
184 let room_a = active_call_a.read_with(cx_a, |call, _| call.room().unwrap().clone());
185 room_a.read_with(cx_a, |room, _| assert!(room.is_connected()));
186 assert_eq!(
187 room_participants(&room_a, cx_a),
188 RoomParticipants {
189 remote: vec!["user_b".to_string()],
190 pending: vec![]
191 }
192 );
193
194 let room_b = active_call_b.read_with(cx_b, |call, _| call.room().unwrap().clone());
195 room_b.read_with(cx_b, |room, _| assert!(room.is_connected()));
196 assert_eq!(
197 room_participants(&room_b, cx_b),
198 RoomParticipants {
199 remote: vec!["user_a".to_string()],
200 pending: vec![]
201 }
202 );
203}