From c3cf056fc512ffeda6d4348451954c527ee24bb7 Mon Sep 17 00:00:00 2001 From: Joseph Lyons Date: Tue, 15 Nov 2022 20:04:56 -0500 Subject: [PATCH] allow users to sign up multiple times without throwing a 500 --- crates/collab/src/api.rs | 2 +- crates/collab/src/db.rs | 10 ++++---- crates/collab/src/db_tests.rs | 45 ++++++++++++++++++++++------------- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/crates/collab/src/api.rs b/crates/collab/src/api.rs index 5fcdc5fcfd..eb750bed55 100644 --- a/crates/collab/src/api.rs +++ b/crates/collab/src/api.rs @@ -338,7 +338,7 @@ async fn create_signup( Json(params): Json, Extension(app): Extension>, ) -> Result<()> { - app.db.create_signup(params).await?; + app.db.create_signup(¶ms).await?; Ok(()) } diff --git a/crates/collab/src/db.rs b/crates/collab/src/db.rs index 281c176360..1609764f6e 100644 --- a/crates/collab/src/db.rs +++ b/crates/collab/src/db.rs @@ -157,7 +157,7 @@ impl Db { unimplemented!() } - pub async fn create_signup(&self, _signup: Signup) -> Result<()> { + pub async fn create_signup(&self, _signup: &Signup) -> Result<()> { unimplemented!() } @@ -375,7 +375,7 @@ impl Db { }) } - pub async fn create_signup(&self, signup: Signup) -> Result<()> { + pub async fn create_signup(&self, signup: &Signup) -> Result<()> { test_support!(self, { sqlx::query( " @@ -394,6 +394,8 @@ impl Db { ) VALUES ($1, $2, FALSE, $3, $4, $5, FALSE, $6, $7, $8) + ON CONFLICT (email_address) DO UPDATE SET + email_address = excluded.email_address RETURNING id ", ) @@ -1259,7 +1261,7 @@ pub struct IncomingContactRequest { pub should_notify: bool, } -#[derive(Clone, Deserialize)] +#[derive(Clone, Deserialize, Default)] pub struct Signup { pub email_address: String, pub platform_mac: bool, @@ -1284,7 +1286,7 @@ pub struct WaitlistSummary { pub unknown_count: i64, } -#[derive(FromRow, PartialEq, Debug, Serialize, Deserialize)] +#[derive(Clone, FromRow, PartialEq, Debug, Serialize, Deserialize)] pub struct Invite { pub email_address: String, pub email_confirmation_code: String, diff --git a/crates/collab/src/db_tests.rs b/crates/collab/src/db_tests.rs index 8eda7d34e2..c4e95f10ce 100644 --- a/crates/collab/src/db_tests.rs +++ b/crates/collab/src/db_tests.rs @@ -644,10 +644,14 @@ async fn test_signups() { let test_db = PostgresTestDb::new(build_background_executor()); let db = test_db.db(); + let usernames = (0..8).map(|i| format!("person-{i}")).collect::>(); + // people sign up on the waitlist - for i in 0..8 { - db.create_signup(Signup { - email_address: format!("person-{i}@example.com"), + let all_signups = usernames + .iter() + .enumerate() + .map(|(i, username)| Signup { + email_address: format!("{username}@example.com"), platform_mac: true, platform_linux: i % 2 == 0, platform_windows: i % 4 == 0, @@ -655,8 +659,13 @@ async fn test_signups() { programming_languages: vec!["rust".into(), "c".into()], device_id: Some(format!("device_id_{i}")), }) - .await - .unwrap(); + .collect::>(); + + for signup in &all_signups { + // Users can sign up multiple times without issues + for _ in 0..2 { + db.create_signup(&signup).await.unwrap(); + } } assert_eq!( @@ -679,9 +688,9 @@ async fn test_signups() { assert_eq!( addresses, &[ - "person-0@example.com", - "person-1@example.com", - "person-2@example.com" + all_signups[0].email_address.as_str(), + all_signups[1].email_address.as_str(), + all_signups[2].email_address.as_str() ] ); assert_ne!( @@ -705,9 +714,9 @@ async fn test_signups() { assert_eq!( addresses, &[ - "person-3@example.com", - "person-4@example.com", - "person-5@example.com" + all_signups[3].email_address.as_str(), + all_signups[4].email_address.as_str(), + all_signups[5].email_address.as_str() ] ); @@ -733,11 +742,10 @@ async fn test_signups() { } = db .create_user_from_invite( &Invite { - email_address: signups_batch1[0].email_address.clone(), - email_confirmation_code: signups_batch1[0].email_confirmation_code.clone(), + ..signups_batch1[0].clone() }, NewUserParams { - github_login: "person-0".into(), + github_login: usernames[0].clone(), github_user_id: 0, invite_count: 5, }, @@ -747,8 +755,11 @@ async fn test_signups() { .unwrap(); let user = db.get_user_by_id(user_id).await.unwrap().unwrap(); assert!(inviting_user_id.is_none()); - assert_eq!(user.github_login, "person-0"); - assert_eq!(user.email_address.as_deref(), Some("person-0@example.com")); + assert_eq!(user.github_login, usernames[0]); + assert_eq!( + user.email_address, + Some(all_signups[0].email_address.clone()) + ); assert_eq!(user.invite_count, 5); assert_eq!(signup_device_id.unwrap(), "device_id_0"); @@ -776,7 +787,7 @@ async fn test_signups() { email_confirmation_code: "the-wrong-code".to_string(), }, NewUserParams { - github_login: "person-1".into(), + github_login: usernames[1].clone(), github_user_id: 2, invite_count: 5, },