diff --git a/crates/crates_io_test_utils/src/builders/user.rs b/crates/crates_io_test_utils/src/builders/user.rs index a360474bccc..47fa7847dbb 100644 --- a/crates/crates_io_test_utils/src/builders/user.rs +++ b/crates/crates_io_test_utils/src/builders/user.rs @@ -22,6 +22,7 @@ static ENCRYPTED_TOKEN: LazyLock> = LazyLock::new(|| { /// If you want to test logic that happens as part of signing up or logging in, pub struct UserBuilder<'a> { username: &'a str, + display_name: Option<&'a str>, } impl<'a> UserBuilder<'a> { @@ -30,18 +31,26 @@ impl<'a> UserBuilder<'a> { pub fn new() -> Self { Self { username: "octocat", + display_name: None, } } pub fn with_username(self, username: &'a str) -> Self { - Self { username } + Self { username, ..self } + } + + pub fn with_display_name(self, display_name: &'a str) -> Self { + Self { + display_name: Some(display_name), + ..self + } } pub fn build(self) -> User { User { id: 1, gh_login: self.username.into(), - name: Some("The Octocat".into()), + name: self.display_name.map(ToString::to_string), gh_id: 123, gh_avatar: None, gh_encrypted_token: vec![], @@ -59,6 +68,7 @@ impl<'a> UserBuilder<'a> { .gh_id(next_gh_id()) .gh_login(self.username) .username(self.username) + .maybe_name(self.display_name) .gh_encrypted_token(&ENCRYPTED_TOKEN) .build() } diff --git a/src/bin/crates-admin/backfill_cache_tags.rs b/src/bin/crates-admin/backfill_cache_tags.rs index ef0baba5f9d..76268ab3179 100644 --- a/src/bin/crates-admin/backfill_cache_tags.rs +++ b/src/bin/crates-admin/backfill_cache_tags.rs @@ -137,17 +137,14 @@ impl NewBackgroundJob { mod tests { use super::*; use crates_io::schema::cache_tags_backfills; - use crates_io_database::models::{NewCacheTagsBackfillRow, NewUser}; + use crates_io_database::models::NewCacheTagsBackfillRow; use crates_io_test_db::TestDatabase; - use crates_io_test_utils::builders::CrateBuilder; + use crates_io_test_utils::builders::{CrateBuilder, UserBuilder}; async fn create_user(conn: &AsyncPgConnection) -> i32 { - NewUser::builder() - .gh_id(1) - .gh_login("testuser") - .username("testuser") - .gh_encrypted_token(&[]) - .build() + UserBuilder::new() + .with_username("testuser") + .new_user() .insert(conn) .await .unwrap() diff --git a/src/index.rs b/src/index.rs index 25812fc3073..d486ed4eb66 100644 --- a/src/index.rs +++ b/src/index.rs @@ -142,10 +142,9 @@ pub async fn index_metadata( #[cfg(test)] mod tests { use super::*; - use crate::schema::users; use chrono::{Days, Utc}; use crates_io_test_db::TestDatabase; - use crates_io_test_utils::builders::{CrateBuilder, VersionBuilder}; + use crates_io_test_utils::builders::{CrateBuilder, UserBuilder, VersionBuilder}; use insta::assert_json_snapshot; #[tokio::test] @@ -153,16 +152,10 @@ mod tests { let test_db = TestDatabase::new(); let mut conn = test_db.async_connect().await; - let user_id = diesel::insert_into(users::table) - .values(( - users::name.eq("user1"), - users::gh_login.eq("user1"), - users::username.eq("user1"), - users::gh_id.eq(42), - users::gh_encrypted_token.eq(&[]), - )) - .returning(users::id) - .get_result::(&mut conn) + let user_id = UserBuilder::new() + .with_username("user1") + .new_user() + .insert(&conn) .await .unwrap(); @@ -205,16 +198,10 @@ mod tests { let test_db = TestDatabase::new(); let mut conn = test_db.async_connect().await; - let user_id = diesel::insert_into(users::table) - .values(( - users::name.eq("user1"), - users::gh_login.eq("user1"), - users::username.eq("user1"), - users::gh_id.eq(42), - users::gh_encrypted_token.eq(&[]), - )) - .returning(users::id) - .get_result::(&mut conn) + let user_id = UserBuilder::new() + .with_username("user1") + .new_user() + .insert(&conn) .await .unwrap(); diff --git a/src/rate_limiter.rs b/src/rate_limiter.rs index 67e84490cf0..b27688f0ac3 100644 --- a/src/rate_limiter.rs +++ b/src/rate_limiter.rs @@ -187,6 +187,7 @@ mod tests { use super::*; use chrono::NaiveDateTime; use crates_io_test_db::TestDatabase; + use crates_io_test_utils::builders::UserBuilder; #[tokio::test] async fn default_rate_limits() -> anyhow::Result<()> { @@ -703,14 +704,9 @@ mod tests { } async fn new_user(conn: &mut AsyncPgConnection, gh_login: &str) -> QueryResult { - use crate::models::NewUser; - - NewUser::builder() - .gh_id(0) - .gh_login(gh_login) - .username(gh_login) - .gh_encrypted_token(&[]) - .build() + UserBuilder::new() + .with_username(gh_login) + .new_user() .insert(conn) .await } diff --git a/src/tests/routes/crates/versions/docs.rs b/src/tests/routes/crates/versions/docs.rs index 8a33de2a2e3..fa9ef597c1f 100644 --- a/src/tests/routes/crates/versions/docs.rs +++ b/src/tests/routes/crates/versions/docs.rs @@ -1,7 +1,7 @@ use crate::builders::{CrateBuilder, VersionBuilder}; use crate::util::{RequestHelper as _, TestApp}; -use crates_io_database::models::NewUser; use crates_io_docs_rs::MockDocsRsClient; +use crates_io_test_utils::builders::UserBuilder; use insta::assert_snapshot; #[tokio::test(flavor = "multi_thread")] @@ -45,12 +45,9 @@ async fn test_trigger_rebuild_permission_failed() -> anyhow::Result<()> { let mut conn = app.db_conn().await; - let other_user_id = NewUser::builder() - .gh_id(111) - .gh_login("other_user") - .username("other_user") - .gh_encrypted_token(&[]) - .build() + let other_user_id = UserBuilder::new() + .with_username("other_user") + .new_user() .insert(&conn) .await?; diff --git a/src/tests/routes/users/read.rs b/src/tests/routes/users/read.rs index bd4a1d54a1e..95ab92d7311 100644 --- a/src/tests/routes/users/read.rs +++ b/src/tests/routes/users/read.rs @@ -1,9 +1,7 @@ use crate::util::{RequestHelper, TestApp}; -use claims::assert_ok; -use crates_io::models::NewUser; -use crates_io::schema::users; +use crates_io::models::{NewUser, User}; use crates_io::views::EncodablePublicUser; -use diesel_async::RunQueryDsl; +use crates_io_test_utils::builders::{OauthGithubBuilder, UserBuilder}; use insta::assert_snapshot; use serde::Deserialize; @@ -33,7 +31,7 @@ async fn show() { #[tokio::test(flavor = "multi_thread")] async fn show_latest_user_case_insensitively() { let (app, anon) = TestApp::init().empty().await; - let mut conn = app.db_conn().await; + let conn = app.db_conn().await; // Please do not delete or modify the setup of this test in order to get it to pass. // This setup mimics how GitHub works. If someone abandons a GitHub account, the username is @@ -43,28 +41,21 @@ async fn show_latest_user_case_insensitively() { // crates.io/user/{username} pages, the best we can do is show the last crates.io account // created with that username. - let user1 = NewUser::builder() - .gh_id(1) - .gh_login("foobar") - .username("foobar") - .name("I was first then deleted my github account") - .gh_encrypted_token(&[]) - .build(); + let user1 = UserBuilder::new() + .with_username("foobar") + .with_display_name("I was first then deleted my github account") + .new_user(); + let user1_id = user1.insert(&conn).await.unwrap(); + let user1 = User::find(&conn, user1_id).await.unwrap(); + OauthGithubBuilder::for_user(&user1).insert(&conn).await; - let user2 = NewUser::builder() - .gh_id(2) - .gh_login("FOOBAR") - .username("FOOBAR") - .name("I was second, I took the foobar username on github") - .gh_encrypted_token(&[]) - .build(); - - assert_ok!( - diesel::insert_into(users::table) - .values(&vec![user1, user2]) - .execute(&mut conn) - .await - ); + let user2 = UserBuilder::new() + .with_username("FOOBAR") + .with_display_name("I was second, I took the foobar username on github") + .new_user(); + let user2_id = user2.insert(&conn).await.unwrap(); + let user2 = User::find(&conn, user2_id).await.unwrap(); + OauthGithubBuilder::for_user(&user2).insert(&conn).await; let json: UserShowPublicResponse = anon.get("/api/v1/users/fOObAr").await.good(); assert_eq!( diff --git a/src/typosquat/test_util.rs b/src/typosquat/test_util.rs index 433262335fc..687d3abb4c3 100644 --- a/src/typosquat/test_util.rs +++ b/src/typosquat/test_util.rs @@ -1,12 +1,12 @@ use diesel::prelude::*; -use crate::models::{Crate, NewTeam, NewUser, Team}; +use crate::models::{Crate, NewTeam, Team}; use crates_io_test_utils::github::next_gh_id; pub mod faker { use super::*; use anyhow::anyhow; - use crates_io_test_utils::builders::CrateBuilder; + use crates_io_test_utils::builders::{CrateBuilder, UserBuilder}; use diesel_async::AsyncPgConnection; pub async fn crate_and_version( @@ -38,12 +38,9 @@ pub mod faker { } pub async fn user(conn: &mut AsyncPgConnection, login: &str) -> QueryResult { - NewUser::builder() - .gh_id(next_gh_id()) - .gh_login(login) - .username(login) - .gh_encrypted_token(&[]) - .build() + UserBuilder::new() + .with_username(login) + .new_user() .insert(conn) .await } diff --git a/src/worker/jobs/downloads/update_metadata.rs b/src/worker/jobs/downloads/update_metadata.rs index 2221e368327..43fa3befb81 100644 --- a/src/worker/jobs/downloads/update_metadata.rs +++ b/src/worker/jobs/downloads/update_metadata.rs @@ -107,19 +107,17 @@ async fn batch_update(batch_size: i64, conn: &mut AsyncPgConnection) -> QueryRes #[cfg(test)] mod tests { use super::*; - use crate::models::{Crate, NewCrate, NewUser, NewVersion, Version}; + use crate::models::{Crate, NewCrate, NewVersion, Version}; use crate::schema::{crate_downloads, crates, versions}; use crates_io_test_db::TestDatabase; + use crates_io_test_utils::builders::UserBuilder; use diesel::sql_types::Timestamptz; use diesel_async::AsyncConnection; async fn user(conn: &mut AsyncPgConnection) -> i32 { - NewUser::builder() - .gh_id(2) - .gh_login("login") - .username("login") - .gh_encrypted_token(&[]) - .build() + UserBuilder::new() + .with_username("login") + .new_user() .insert(conn) .await .unwrap() diff --git a/src/worker/jobs/expiry_notification.rs b/src/worker/jobs/expiry_notification.rs index c9b66daaa27..d8d6f2eb6d4 100644 --- a/src/worker/jobs/expiry_notification.rs +++ b/src/worker/jobs/expiry_notification.rs @@ -142,9 +142,10 @@ pub async fn find_expiring_tokens( #[cfg(test)] mod tests { use super::*; - use crate::models::{NewEmail, NewUser}; + use crate::models::NewEmail; use crate::{models::token::ApiToken, schema::api_tokens, util::token::PlainToken}; use crates_io_test_db::TestDatabase; + use crates_io_test_utils::builders::UserBuilder; use diesel::dsl::IntervalDsl; use lettre::Address; @@ -154,14 +155,12 @@ mod tests { let mut conn = test_db.async_connect().await; // Set up a user and a token that is about to expire. - let user_id = NewUser::builder() - .gh_id(0) - .gh_login("a") - .username("a") - .gh_encrypted_token(&[]) - .build() + let user_id = UserBuilder::new() + .with_username("a") + .new_user() .insert(&conn) - .await?; + .await + .unwrap(); NewEmail::builder() .user_id(user_id)