mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-27 02:48:34 +00:00
Get basic test of accepting a contact request passing
This commit is contained in:
parent
93dae88cac
commit
5d20338f69
5 changed files with 125 additions and 24 deletions
|
@ -125,7 +125,7 @@ impl UserStore {
|
||||||
user_ids.insert(contact.user_id);
|
user_ids.insert(contact.user_id);
|
||||||
user_ids.extend(contact.projects.iter().flat_map(|w| &w.guests).copied());
|
user_ids.extend(contact.projects.iter().flat_map(|w| &w.guests).copied());
|
||||||
}
|
}
|
||||||
user_ids.extend(message.incoming_requests.iter().map(|req| req.user_id));
|
user_ids.extend(message.incoming_requests.iter().map(|req| req.requester_id));
|
||||||
user_ids.extend(message.outgoing_requests.iter());
|
user_ids.extend(message.outgoing_requests.iter());
|
||||||
|
|
||||||
let load_users = self.get_users(user_ids.into_iter().collect(), cx);
|
let load_users = self.get_users(user_ids.into_iter().collect(), cx);
|
||||||
|
@ -144,7 +144,9 @@ impl UserStore {
|
||||||
let mut incoming_requests = Vec::new();
|
let mut incoming_requests = Vec::new();
|
||||||
for request in message.incoming_requests {
|
for request in message.incoming_requests {
|
||||||
incoming_requests.push(
|
incoming_requests.push(
|
||||||
this.update(&mut cx, |this, cx| this.fetch_user(request.user_id, cx))
|
this.update(&mut cx, |this, cx| {
|
||||||
|
this.fetch_user(request.requester_id, cx)
|
||||||
|
})
|
||||||
.await?,
|
.await?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -199,12 +201,20 @@ impl UserStore {
|
||||||
.is_ok()
|
.is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn request_contact(&self, to_user_id: u64) -> impl Future<Output = Result<()>> {
|
pub fn incoming_contact_requests(&self) -> &[Arc<User>] {
|
||||||
|
&self.incoming_contact_requests
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn outgoing_contact_requests(&self) -> &[Arc<User>] {
|
||||||
|
&self.outgoing_contact_requests
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn request_contact(&self, responder_id: u64) -> impl Future<Output = Result<()>> {
|
||||||
let client = self.client.upgrade();
|
let client = self.client.upgrade();
|
||||||
async move {
|
async move {
|
||||||
client
|
client
|
||||||
.ok_or_else(|| anyhow!("not logged in"))?
|
.ok_or_else(|| anyhow!("not logged in"))?
|
||||||
.request(proto::RequestContact { to_user_id })
|
.request(proto::RequestContact { responder_id })
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -212,7 +222,7 @@ impl UserStore {
|
||||||
|
|
||||||
pub fn respond_to_contact_request(
|
pub fn respond_to_contact_request(
|
||||||
&self,
|
&self,
|
||||||
from_user_id: u64,
|
requester_id: u64,
|
||||||
accept: bool,
|
accept: bool,
|
||||||
) -> impl Future<Output = Result<()>> {
|
) -> impl Future<Output = Result<()>> {
|
||||||
let client = self.client.upgrade();
|
let client = self.client.upgrade();
|
||||||
|
@ -220,7 +230,7 @@ impl UserStore {
|
||||||
client
|
client
|
||||||
.ok_or_else(|| anyhow!("not logged in"))?
|
.ok_or_else(|| anyhow!("not logged in"))?
|
||||||
.request(proto::RespondToContactRequest {
|
.request(proto::RespondToContactRequest {
|
||||||
requesting_user_id: from_user_id,
|
requester_id,
|
||||||
response: if accept {
|
response: if accept {
|
||||||
proto::ContactRequestResponse::Accept
|
proto::ContactRequestResponse::Accept
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -211,7 +211,7 @@ impl Db for PostgresDb {
|
||||||
outgoing_requests.push(user_id_b);
|
outgoing_requests.push(user_id_b);
|
||||||
} else {
|
} else {
|
||||||
incoming_requests.push(IncomingContactRequest {
|
incoming_requests.push(IncomingContactRequest {
|
||||||
requesting_user_id: user_id_b,
|
requester_id: user_id_b,
|
||||||
should_notify,
|
should_notify,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -220,7 +220,7 @@ impl Db for PostgresDb {
|
||||||
current.push(user_id_a);
|
current.push(user_id_a);
|
||||||
} else if a_to_b {
|
} else if a_to_b {
|
||||||
incoming_requests.push(IncomingContactRequest {
|
incoming_requests.push(IncomingContactRequest {
|
||||||
requesting_user_id: user_id_a,
|
requester_id: user_id_a,
|
||||||
should_notify,
|
should_notify,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -675,7 +675,7 @@ pub struct Contacts {
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct IncomingContactRequest {
|
pub struct IncomingContactRequest {
|
||||||
pub requesting_user_id: UserId,
|
pub requester_id: UserId,
|
||||||
pub should_notify: bool,
|
pub should_notify: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -935,7 +935,7 @@ pub mod tests {
|
||||||
current: vec![],
|
current: vec![],
|
||||||
outgoing_requests: vec![],
|
outgoing_requests: vec![],
|
||||||
incoming_requests: vec![IncomingContactRequest {
|
incoming_requests: vec![IncomingContactRequest {
|
||||||
requesting_user_id: user_1,
|
requester_id: user_1,
|
||||||
should_notify: true
|
should_notify: true
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
|
@ -953,7 +953,7 @@ pub mod tests {
|
||||||
current: vec![],
|
current: vec![],
|
||||||
outgoing_requests: vec![],
|
outgoing_requests: vec![],
|
||||||
incoming_requests: vec![IncomingContactRequest {
|
incoming_requests: vec![IncomingContactRequest {
|
||||||
requesting_user_id: user_1,
|
requester_id: user_1,
|
||||||
should_notify: false
|
should_notify: false
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
|
@ -1195,7 +1195,7 @@ pub mod tests {
|
||||||
current.push(contact.requester_id);
|
current.push(contact.requester_id);
|
||||||
} else {
|
} else {
|
||||||
incoming_requests.push(IncomingContactRequest {
|
incoming_requests.push(IncomingContactRequest {
|
||||||
requesting_user_id: contact.requester_id,
|
requester_id: contact.requester_id,
|
||||||
should_notify: contact.should_notify,
|
should_notify: contact.should_notify,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -276,7 +276,7 @@ impl Server {
|
||||||
store.add_connection(connection_id, user_id);
|
store.add_connection(connection_id, user_id);
|
||||||
let update_contacts = store.build_initial_contacts_update(contacts);
|
let update_contacts = store.build_initial_contacts_update(contacts);
|
||||||
for connection_id in store.connection_ids_for_user(user_id) {
|
for connection_id in store.connection_ids_for_user(user_id) {
|
||||||
this.peer.send(connection_id, update_contacts.clone());
|
this.peer.send(connection_id, update_contacts.clone())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -953,11 +953,30 @@ impl Server {
|
||||||
.read()
|
.read()
|
||||||
.await
|
.await
|
||||||
.user_id_for_connection(request.sender_id)?;
|
.user_id_for_connection(request.sender_id)?;
|
||||||
let responder_id = UserId::from_proto(request.payload.to_user_id);
|
let responder_id = UserId::from_proto(request.payload.responder_id);
|
||||||
self.app_state
|
self.app_state
|
||||||
.db
|
.db
|
||||||
.send_contact_request(requester_id, responder_id)
|
.send_contact_request(requester_id, responder_id)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|
||||||
|
// Update outgoing contact requests of requester
|
||||||
|
let mut update = proto::UpdateContacts::default();
|
||||||
|
update.outgoing_requests.push(responder_id.to_proto());
|
||||||
|
for connection_id in self.store().await.connection_ids_for_user(requester_id) {
|
||||||
|
self.peer.send(connection_id, update.clone())?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update incoming contact requests of responder
|
||||||
|
let mut update = proto::UpdateContacts::default();
|
||||||
|
update.incoming_requests.push(proto::IncomingContactRequest {
|
||||||
|
requester_id: requester_id.to_proto(),
|
||||||
|
should_notify: true,
|
||||||
|
});
|
||||||
|
for connection_id in self.store().await.connection_ids_for_user(responder_id) {
|
||||||
|
self.peer.send(connection_id, update.clone())?;
|
||||||
|
}
|
||||||
|
|
||||||
response.send(proto::Ack {})?;
|
response.send(proto::Ack {})?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -972,15 +991,45 @@ impl Server {
|
||||||
.read()
|
.read()
|
||||||
.await
|
.await
|
||||||
.user_id_for_connection(request.sender_id)?;
|
.user_id_for_connection(request.sender_id)?;
|
||||||
let requester_id = UserId::from_proto(request.payload.requesting_user_id);
|
let requester_id = UserId::from_proto(request.payload.requester_id);
|
||||||
|
let accept = request.payload.response == proto::ContactRequestResponse::Accept as i32;
|
||||||
self.app_state
|
self.app_state
|
||||||
.db
|
.db
|
||||||
.respond_to_contact_request(
|
.respond_to_contact_request(
|
||||||
responder_id,
|
responder_id,
|
||||||
requester_id,
|
requester_id,
|
||||||
request.payload.response == proto::ContactRequestResponse::Accept as i32,
|
accept,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
if accept {
|
||||||
|
// Update responder with new contact
|
||||||
|
let mut update = proto::UpdateContacts::default();
|
||||||
|
update.contacts.push(proto::Contact {
|
||||||
|
user_id: requester_id.to_proto(),
|
||||||
|
projects: Default::default(), // TODO
|
||||||
|
online: true, // TODO
|
||||||
|
});
|
||||||
|
update.remove_incoming_requests.push(requester_id.to_proto());
|
||||||
|
for connection_id in self.store.read().await.connection_ids_for_user(responder_id) {
|
||||||
|
self.peer.send(connection_id, update.clone())?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update requester with new contact
|
||||||
|
let mut update = proto::UpdateContacts::default();
|
||||||
|
update.contacts.push(proto::Contact {
|
||||||
|
user_id: responder_id.to_proto(),
|
||||||
|
projects: Default::default(), // TODO
|
||||||
|
online: true, // TODO
|
||||||
|
});
|
||||||
|
update.remove_outgoing_requests.push(responder_id.to_proto());
|
||||||
|
for connection_id in self.store.read().await.connection_ids_for_user(requester_id) {
|
||||||
|
self.peer.send(connection_id, update.clone())?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
response.send(proto::Ack {})?;
|
response.send(proto::Ack {})?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -4987,8 +5036,8 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test(iterations = 10)]
|
#[gpui::test(iterations = 1)] // TODO: More iterations
|
||||||
async fn test_contacts_requests(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
|
async fn test_contacts_requests(executor: Arc<Deterministic>, cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
|
||||||
cx_a.foreground().forbid_parking();
|
cx_a.foreground().forbid_parking();
|
||||||
|
|
||||||
// Connect to a server as 3 clients.
|
// Connect to a server as 3 clients.
|
||||||
|
@ -4996,6 +5045,8 @@ mod tests {
|
||||||
let client_a = server.create_client(cx_a, "user_a").await;
|
let client_a = server.create_client(cx_a, "user_a").await;
|
||||||
let client_b = server.create_client(cx_b, "user_b").await;
|
let client_b = server.create_client(cx_b, "user_b").await;
|
||||||
|
|
||||||
|
// User A requests that user B become their contact
|
||||||
|
|
||||||
client_a
|
client_a
|
||||||
.user_store
|
.user_store
|
||||||
.read_with(cx_a, |store, _| {
|
.read_with(cx_a, |store, _| {
|
||||||
|
@ -5004,14 +5055,54 @@ mod tests {
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
executor.run_until_parked();
|
||||||
|
|
||||||
|
// Both parties see the pending request appear. User B accepts the request.
|
||||||
|
|
||||||
|
client_a.user_store.read_with(cx_a, |store, _| {
|
||||||
|
let contacts = store
|
||||||
|
.outgoing_contact_requests()
|
||||||
|
.iter()
|
||||||
|
.map(|contact| contact.github_login.clone())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
assert_eq!(contacts, &["user_b"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
client_b.user_store.read_with(cx_b, |store, _| {
|
||||||
|
let contacts = store
|
||||||
|
.incoming_contact_requests()
|
||||||
|
.iter()
|
||||||
|
.map(|contact| contact.github_login.clone())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
assert_eq!(contacts, &["user_a"]);
|
||||||
|
|
||||||
|
store.respond_to_contact_request(client_a.user_id().unwrap(), true)
|
||||||
|
}).await.unwrap();
|
||||||
|
|
||||||
|
executor.run_until_parked();
|
||||||
|
|
||||||
|
// User B sees user A as their contact now, and the incoming request from them is removed
|
||||||
|
client_b.user_store.read_with(cx_b, |store, _| {
|
||||||
|
let contacts = store
|
||||||
|
.contacts()
|
||||||
|
.iter()
|
||||||
|
.map(|contact| contact.user.github_login.clone())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
assert_eq!(contacts, &["user_a"]);
|
||||||
|
assert!(store.incoming_contact_requests().is_empty());
|
||||||
|
});
|
||||||
|
|
||||||
|
// User A sees user B as their contact now, and the outgoing request to them is removed
|
||||||
client_a.user_store.read_with(cx_a, |store, _| {
|
client_a.user_store.read_with(cx_a, |store, _| {
|
||||||
let contacts = store
|
let contacts = store
|
||||||
.contacts()
|
.contacts()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|contact| contact.user.github_login.clone())
|
.map(|contact| contact.user.github_login.clone())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
assert_eq!(contacts, &["user_b"])
|
assert_eq!(contacts, &["user_b"]);
|
||||||
|
assert!(store.outgoing_contact_requests().is_empty());
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test(iterations = 10)]
|
#[gpui::test(iterations = 10)]
|
||||||
|
|
|
@ -225,7 +225,7 @@ impl Store {
|
||||||
update
|
update
|
||||||
.incoming_requests
|
.incoming_requests
|
||||||
.push(proto::IncomingContactRequest {
|
.push(proto::IncomingContactRequest {
|
||||||
user_id: request.requesting_user_id.to_proto(),
|
requester_id: request.requester_id.to_proto(),
|
||||||
should_notify: request.should_notify,
|
should_notify: request.should_notify,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -550,11 +550,11 @@ message UsersResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
message RequestContact {
|
message RequestContact {
|
||||||
uint64 to_user_id = 1;
|
uint64 responder_id = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message RespondToContactRequest {
|
message RespondToContactRequest {
|
||||||
uint64 requesting_user_id = 1;
|
uint64 requester_id = 1;
|
||||||
ContactRequestResponse response = 2;
|
ContactRequestResponse response = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -599,7 +599,7 @@ message UpdateContacts {
|
||||||
}
|
}
|
||||||
|
|
||||||
message IncomingContactRequest {
|
message IncomingContactRequest {
|
||||||
uint64 user_id = 1;
|
uint64 requester_id = 1;
|
||||||
bool should_notify = 2;
|
bool should_notify = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue