1use super::*;
2use crate::test_both_dbs;
3use language::proto;
4use text::Buffer;
5
6test_both_dbs!(
7 test_channel_buffers,
8 test_channel_buffers_postgres,
9 test_channel_buffers_sqlite
10);
11
12async fn test_channel_buffers(db: &Arc<Database>) {
13 // Prep database test info
14 let a_id = db
15 .create_user(
16 "user_a@example.com",
17 false,
18 NewUserParams {
19 github_login: "user_a".into(),
20 github_user_id: 101,
21 invite_count: 0,
22 },
23 )
24 .await
25 .unwrap()
26 .user_id;
27 let b_id = db
28 .create_user(
29 "user_b@example.com",
30 false,
31 NewUserParams {
32 github_login: "user_b".into(),
33 github_user_id: 102,
34 invite_count: 0,
35 },
36 )
37 .await
38 .unwrap()
39 .user_id;
40
41 // This user will not be a part of the channel
42 let c_id = db
43 .create_user(
44 "user_c@example.com",
45 false,
46 NewUserParams {
47 github_login: "user_c".into(),
48 github_user_id: 102,
49 invite_count: 0,
50 },
51 )
52 .await
53 .unwrap()
54 .user_id;
55
56 let owner_id = db.create_server("production").await.unwrap().0 as u32;
57
58 let zed_id = db.create_root_channel("zed", "1", a_id).await.unwrap();
59
60 db.invite_channel_member(zed_id, b_id, a_id, false)
61 .await
62 .unwrap();
63
64 db.respond_to_channel_invite(zed_id, b_id, true)
65 .await
66 .unwrap();
67
68 let connection_id_a = ConnectionId { owner_id, id: 1 };
69 let buffer_response_a = db
70 .join_channel_buffer(zed_id, a_id, connection_id_a)
71 .await
72 .unwrap();
73 let buffer_id = BufferId::from_proto(buffer_response_a.buffer_id);
74
75 let mut buffer_a = Buffer::new(0, 0, "".to_string());
76 let mut operations = Vec::new();
77 operations.push(buffer_a.edit([(0..0, "hello world")]));
78 operations.push(buffer_a.edit([(5..5, ", cruel")]));
79 operations.push(buffer_a.edit([(0..5, "goodbye")]));
80 operations.push(buffer_a.undo().unwrap().1);
81 assert_eq!(buffer_a.text(), "hello, cruel world");
82
83 let operations = operations
84 .into_iter()
85 .map(|op| proto::serialize_operation(&language::Operation::Buffer(op)))
86 .collect::<Vec<_>>();
87
88 db.update_channel_buffer(buffer_id, &operations)
89 .await
90 .unwrap();
91
92 let connection_id_b = ConnectionId { owner_id, id: 2 };
93 let buffer_response_b = db
94 .join_channel_buffer(zed_id, b_id, connection_id_b)
95 .await
96 .unwrap();
97
98 let mut buffer_b = Buffer::new(0, 0, buffer_response_b.base_text);
99 buffer_b
100 .apply_ops(buffer_response_b.operations.into_iter().map(|operation| {
101 let operation = proto::deserialize_operation(operation).unwrap();
102 if let language::Operation::Buffer(operation) = operation {
103 operation
104 } else {
105 unreachable!()
106 }
107 }))
108 .unwrap();
109
110 assert_eq!(buffer_b.text(), "hello, cruel world");
111
112 // Ensure that C fails to open the buffer
113 assert!(db
114 .join_channel_buffer(zed_id, c_id, ConnectionId { owner_id, id: 3 })
115 .await
116 .is_err());
117
118 //Ensure that both collaborators have shown up
119 assert_eq!(
120 buffer_response_b.collaborators,
121 &[
122 rpc::proto::Collaborator {
123 user_id: a_id.to_proto(),
124 peer_id: Some(rpc::proto::PeerId { id: 1, owner_id }),
125 replica_id: 0,
126 },
127 rpc::proto::Collaborator {
128 user_id: b_id.to_proto(),
129 peer_id: Some(rpc::proto::PeerId { id: 2, owner_id }),
130 replica_id: 1,
131 }
132 ]
133 );
134
135 let collaborators = db
136 .leave_channel_buffer(zed_id, connection_id_b)
137 .await
138 .unwrap();
139
140 assert_eq!(collaborators, &[connection_id_a],);
141
142 db.connection_lost(connection_id_a).await.unwrap();
143 // assert!()
144 // Test buffer epoch incrementing?
145}