//! Factory functions for the `User` struct from `doctate_server::config`. //! //! Tests previously copy-pasted a 10-line `make_user` in every file. //! These factories centralise the defaults (doctor role, bcrypt cost 4, //! window 72 h, password "s") so an API change to `User` touches one //! file, not twenty. use doctate_server::config::{RetentionUserSettings, User}; /// Bcrypt cost factor used in all tests. The production default is 12; /// tests drop it to 4 because the hash is computed on every `test_user()` /// call and a cost-12 hash adds ~200 ms per test. Security is irrelevant /// for test-only passwords; speed is not. pub const TEST_BCRYPT_COST: u32 = 4; /// Default plaintext password across tests. Individual tests that need /// a specific password (e.g. for a login-wrong-password assertion) use /// [`test_user_with_password`] instead. pub const TEST_PASSWORD: &str = "s"; /// Bcrypt-hash the test password. Extracted so the cost factor lives in /// one place. fn hash_password(plain: &str) -> String { bcrypt::hash(plain, TEST_BCRYPT_COST).unwrap() } /// Doctor user. `api_key = "key-{slug}"` — kept deterministic so tests /// that send the X-API-Key header can compute it from the slug without /// keeping a separate constant. pub fn test_user(slug: &str) -> User { User { slug: slug.into(), api_key: format!("key-{slug}"), web_password: hash_password(TEST_PASSWORD), role: "doctor".into(), language: None, retention: Default::default(), window_hours: 72, preview_lines: 2, } } /// Admin variant — used by bulk/reset/purge-closed tests where the /// handler enforces `role == "admin"`. pub fn test_admin(slug: &str) -> User { let mut u = test_user(slug); u.role = "admin".into(); u } /// Doctor user with an explicit plaintext password. Used by tests that /// log in with a specific password (e.g. wrong-password rejection). pub fn test_user_with_password(slug: &str, password: &str) -> User { let mut u = test_user(slug); u.web_password = hash_password(password); u } /// Doctor user with custom retention settings — for the retention sweep /// tests that drive the lazy auto-close / auto-purge logic. pub fn test_user_with_retention(slug: &str, auto_close_days: u32, auto_delete_days: u32) -> User { let mut u = test_user(slug); u.retention = RetentionUserSettings { auto_close_days, auto_delete_days, }; u } /// Doctor user with a custom `window_hours` — used by `/api/oneliners` /// tests that verify the visibility window is server-authoritative. pub fn test_user_with_window_hours(slug: &str, hours: u32) -> User { let mut u = test_user(slug); u.window_hours = hours; u }