Fix error when loading users without github user ids from the db

Max Brunsfeld created

Change summary

crates/collab/src/bin/seed.rs | 25 ++++++++++++++++++-------
crates/collab/src/db.rs       |  8 ++++----
crates/collab/src/db_tests.rs | 12 ++++++------
3 files changed, 28 insertions(+), 17 deletions(-)

Detailed changes

crates/collab/src/bin/seed.rs 🔗

@@ -11,7 +11,7 @@ mod db;
 
 #[derive(Debug, Deserialize)]
 struct GitHubUser {
-    id: usize,
+    id: i32,
     login: String,
     email: Option<String>,
 }
@@ -26,8 +26,11 @@ async fn main() {
     let github_token = std::env::var("GITHUB_TOKEN").expect("missing GITHUB_TOKEN env var");
     let client = reqwest::Client::new();
 
-    let current_user =
+    let mut current_user =
         fetch_github::<GitHubUser>(&client, &github_token, "https://api.github.com/user").await;
+    current_user
+        .email
+        .get_or_insert_with(|| "placeholder@example.com".to_string());
     let staff_users = fetch_github::<Vec<GitHubUser>>(
         &client,
         &github_token,
@@ -64,16 +67,24 @@ async fn main() {
     let mut zed_user_ids = Vec::<UserId>::new();
     for (github_user, admin) in zed_users {
         if let Some(user) = db
-            .get_user_by_github_login(&github_user.login)
+            .get_user_by_github_account(&github_user.login, Some(github_user.id))
             .await
             .expect("failed to fetch user")
         {
             zed_user_ids.push(user.id);
-        } else {
+        } else if let Some(email) = &github_user.email {
             zed_user_ids.push(
-                db.create_user(&github_user.login, github_user.email.as_deref(), admin)
-                    .await
-                    .expect("failed to insert user"),
+                db.create_user(
+                    email,
+                    admin,
+                    db::NewUserParams {
+                        github_login: github_user.login,
+                        github_user_id: github_user.id,
+                        invite_count: 5,
+                    },
+                )
+                .await
+                .expect("failed to insert user"),
             );
         }
     }

crates/collab/src/db.rs 🔗

@@ -1563,7 +1563,7 @@ id_type!(UserId);
 pub struct User {
     pub id: UserId,
     pub github_login: String,
-    pub github_user_id: i32,
+    pub github_user_id: Option<i32>,
     pub email_address: Option<String>,
     pub admin: bool,
     pub invite_code: Option<String>,
@@ -1795,7 +1795,7 @@ mod test {
                     User {
                         id: user_id,
                         github_login: params.github_login,
-                        github_user_id: params.github_user_id,
+                        github_user_id: Some(params.github_user_id),
                         email_address: Some(email_address.to_string()),
                         admin,
                         invite_code: None,
@@ -1838,12 +1838,12 @@ mod test {
             self.background.simulate_random_delay().await;
             if let Some(github_user_id) = github_user_id {
                 for user in self.users.lock().values_mut() {
-                    if user.github_user_id == github_user_id {
+                    if user.github_user_id == Some(github_user_id) {
                         user.github_login = github_login.into();
                         return Ok(Some(user.clone()));
                     }
                     if user.github_login == github_login {
-                        user.github_user_id = github_user_id;
+                        user.github_user_id = Some(github_user_id);
                         return Ok(Some(user.clone()));
                     }
                 }

crates/collab/src/db_tests.rs 🔗

@@ -69,7 +69,7 @@ async fn test_get_users_by_ids() {
                 User {
                     id: user1,
                     github_login: "u1".to_string(),
-                    github_user_id: 1,
+                    github_user_id: Some(1),
                     email_address: Some("u1@example.com".to_string()),
                     admin: false,
                     ..Default::default()
@@ -77,7 +77,7 @@ async fn test_get_users_by_ids() {
                 User {
                     id: user2,
                     github_login: "u2".to_string(),
-                    github_user_id: 2,
+                    github_user_id: Some(2),
                     email_address: Some("u2@example.com".to_string()),
                     admin: false,
                     ..Default::default()
@@ -85,7 +85,7 @@ async fn test_get_users_by_ids() {
                 User {
                     id: user3,
                     github_login: "u3".to_string(),
-                    github_user_id: 3,
+                    github_user_id: Some(3),
                     email_address: Some("u3@example.com".to_string()),
                     admin: false,
                     ..Default::default()
@@ -93,7 +93,7 @@ async fn test_get_users_by_ids() {
                 User {
                     id: user4,
                     github_login: "u4".to_string(),
-                    github_user_id: 4,
+                    github_user_id: Some(4),
                     email_address: Some("u4@example.com".to_string()),
                     admin: false,
                     ..Default::default()
@@ -142,7 +142,7 @@ async fn test_get_user_by_github_account() {
             .unwrap();
         assert_eq!(user.id, user_id1);
         assert_eq!(&user.github_login, "login1");
-        assert_eq!(user.github_user_id, 101);
+        assert_eq!(user.github_user_id, Some(101));
 
         assert!(db
             .get_user_by_github_account("non-existent-login", None)
@@ -157,7 +157,7 @@ async fn test_get_user_by_github_account() {
             .unwrap();
         assert_eq!(user.id, user_id2);
         assert_eq!(&user.github_login, "the-new-login2");
-        assert_eq!(user.github_user_id, 102);
+        assert_eq!(user.github_user_id, Some(102));
     }
 }