Merge pull request #1943 from zed-industries/fix-inviting-existing-users-via-different-mail

Antonio Scandurra created

Fix inviting existing users via a different email address

Change summary

crates/collab/src/db.rs       | 12 ++++-
crates/collab/src/db/tests.rs | 77 +++++++++++++++++++++++++++++++++++++
2 files changed, 86 insertions(+), 3 deletions(-)

Detailed changes

crates/collab/src/db.rs 🔗

@@ -878,10 +878,16 @@ impl Database {
             let signup = signup.update(&*tx).await?;
 
             if let Some(inviting_user_id) = signup.inviting_user_id {
+                let (user_id_a, user_id_b, a_to_b) = if inviting_user_id < user.id {
+                    (inviting_user_id, user.id, true)
+                } else {
+                    (user.id, inviting_user_id, false)
+                };
+
                 contact::Entity::insert(contact::ActiveModel {
-                    user_id_a: ActiveValue::set(inviting_user_id),
-                    user_id_b: ActiveValue::set(user.id),
-                    a_to_b: ActiveValue::set(true),
+                    user_id_a: ActiveValue::set(user_id_a),
+                    user_id_b: ActiveValue::set(user_id_b),
+                    a_to_b: ActiveValue::set(a_to_b),
                     should_notify: ActiveValue::set(true),
                     accepted: ActiveValue::set(true),
                     ..Default::default()

crates/collab/src/db/tests.rs 🔗

@@ -595,6 +595,8 @@ async fn test_invite_codes() {
             busy: false,
         }]
     );
+    assert!(db.has_contact(user1, user2).await.unwrap());
+    assert!(db.has_contact(user2, user1).await.unwrap());
     assert_eq!(
         db.get_invite_code_for_user(user2).await.unwrap().unwrap().1,
         7
@@ -649,6 +651,8 @@ async fn test_invite_codes() {
             busy: false,
         }]
     );
+    assert!(db.has_contact(user1, user3).await.unwrap());
+    assert!(db.has_contact(user3, user1).await.unwrap());
     assert_eq!(
         db.get_invite_code_for_user(user3).await.unwrap().unwrap().1,
         3
@@ -714,6 +718,8 @@ async fn test_invite_codes() {
             busy: false,
         }]
     );
+    assert!(db.has_contact(user1, user4).await.unwrap());
+    assert!(db.has_contact(user4, user1).await.unwrap());
     assert_eq!(
         db.get_invite_code_for_user(user4).await.unwrap().unwrap().1,
         5
@@ -725,6 +731,77 @@ async fn test_invite_codes() {
         .unwrap_err();
     let (_, invite_count) = db.get_invite_code_for_user(user1).await.unwrap().unwrap();
     assert_eq!(invite_count, 1);
+
+    // A newer user can invite an existing one via a different email address
+    // than the one they used to sign up.
+    let user5 = db
+        .create_user(
+            "user5@example.com",
+            false,
+            NewUserParams {
+                github_login: "user5".into(),
+                github_user_id: 5,
+                invite_count: 0,
+            },
+        )
+        .await
+        .unwrap()
+        .user_id;
+    db.set_invite_count_for_user(user5, 5).await.unwrap();
+    let (user5_invite_code, _) = db.get_invite_code_for_user(user5).await.unwrap().unwrap();
+    let user5_invite_to_user1 = db
+        .create_invite_from_code(&user5_invite_code, "user1@different.com", None)
+        .await
+        .unwrap();
+    let user1_2 = db
+        .create_user_from_invite(
+            &user5_invite_to_user1,
+            NewUserParams {
+                github_login: "user1".into(),
+                github_user_id: 1,
+                invite_count: 5,
+            },
+        )
+        .await
+        .unwrap()
+        .unwrap()
+        .user_id;
+    assert_eq!(user1_2, user1);
+    assert_eq!(
+        db.get_contacts(user1).await.unwrap(),
+        [
+            Contact::Accepted {
+                user_id: user2,
+                should_notify: true,
+                busy: false,
+            },
+            Contact::Accepted {
+                user_id: user3,
+                should_notify: true,
+                busy: false,
+            },
+            Contact::Accepted {
+                user_id: user4,
+                should_notify: true,
+                busy: false,
+            },
+            Contact::Accepted {
+                user_id: user5,
+                should_notify: false,
+                busy: false,
+            }
+        ]
+    );
+    assert_eq!(
+        db.get_contacts(user5).await.unwrap(),
+        [Contact::Accepted {
+            user_id: user1,
+            should_notify: true,
+            busy: false,
+        }]
+    );
+    assert!(db.has_contact(user1, user5).await.unwrap());
+    assert!(db.has_contact(user5, user1).await.unwrap());
 }
 
 #[gpui::test]