refactor(tests): introduce shared tests/common/ support module
Lift duplicated test-harness code (User factories, TestConfig builder, login/CSRF flow, form/json helpers, case-directory seeding, URL path builders) into `server/tests/common/` so future API changes touch one file instead of every integration test. Migrated batches: csrf_attack, auth, login, magic_link, security_headers (28 tests); analyze, case_page, delete_recording, close_watermark, retention_sweep (67 tests). All 95 tests still green. Net line delta across these 10 files: +1113 / -1896 (~780 lines removed), plus ~500 lines of new shared infrastructure under tests/common/.
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
//! 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(),
|
||||
whisper: Default::default(),
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user