40
crates/domain/tests/user/display_name_test.rs
Normal file
40
crates/domain/tests/user/display_name_test.rs
Normal file
@@ -0,0 +1,40 @@
|
||||
use domain::errors::DomainError;
|
||||
use domain::user::DisplayName;
|
||||
|
||||
#[test]
|
||||
fn valid_display_name_is_created() {
|
||||
let name = DisplayName::new("Alice").unwrap();
|
||||
assert_eq!(name.value(), "Alice");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_name_trims_whitespace() {
|
||||
let name = DisplayName::new(" Bob ").unwrap();
|
||||
assert_eq!(name.value(), "Bob");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_display_name_is_rejected() {
|
||||
let result = DisplayName::new("");
|
||||
assert!(matches!(result, Err(DomainError::InvalidInput(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn whitespace_only_display_name_is_rejected() {
|
||||
let result = DisplayName::new(" ");
|
||||
assert!(matches!(result, Err(DomainError::InvalidInput(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_name_over_100_chars_is_rejected() {
|
||||
let long = "a".repeat(101);
|
||||
let result = DisplayName::new(long);
|
||||
assert!(matches!(result, Err(DomainError::InvalidInput(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_name_at_100_chars_is_valid() {
|
||||
let exact = "a".repeat(100);
|
||||
let name = DisplayName::new(exact).unwrap();
|
||||
assert_eq!(name.value().len(), 100);
|
||||
}
|
||||
32
crates/domain/tests/user/email_test.rs
Normal file
32
crates/domain/tests/user/email_test.rs
Normal file
@@ -0,0 +1,32 @@
|
||||
use domain::errors::DomainError;
|
||||
use domain::user::Email;
|
||||
|
||||
#[test]
|
||||
fn valid_email_is_created() {
|
||||
let email = Email::new("user@example.com").unwrap();
|
||||
assert_eq!(email.value(), "user@example.com");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn email_is_lowercased() {
|
||||
let email = Email::new("User@Example.COM").unwrap();
|
||||
assert_eq!(email.value(), "user@example.com");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn email_trims_whitespace() {
|
||||
let email = Email::new(" user@example.com ").unwrap();
|
||||
assert_eq!(email.value(), "user@example.com");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn email_without_at_is_rejected() {
|
||||
let result = Email::new("not-an-email");
|
||||
assert!(matches!(result, Err(DomainError::InvalidInput(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_email_is_rejected() {
|
||||
let result = Email::new("");
|
||||
assert!(matches!(result, Err(DomainError::InvalidInput(_))));
|
||||
}
|
||||
32
crates/domain/tests/user/timezone_test.rs
Normal file
32
crates/domain/tests/user/timezone_test.rs
Normal file
@@ -0,0 +1,32 @@
|
||||
use domain::errors::DomainError;
|
||||
use domain::user::Timezone;
|
||||
|
||||
#[test]
|
||||
fn valid_timezone_is_created() {
|
||||
let tz = Timezone::new("Europe/Warsaw").unwrap();
|
||||
assert_eq!(tz.value(), "Europe/Warsaw");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn timezone_trims_whitespace() {
|
||||
let tz = Timezone::new(" America/New_York ").unwrap();
|
||||
assert_eq!(tz.value(), "America/New_York");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_timezone_is_rejected() {
|
||||
let result = Timezone::new("");
|
||||
assert!(matches!(result, Err(DomainError::InvalidInput(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn timezone_without_slash_is_rejected() {
|
||||
let result = Timezone::new("UTC");
|
||||
assert!(matches!(result, Err(DomainError::InvalidInput(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_persistence_bypasses_validation() {
|
||||
let tz = Timezone::from_persistence("UTC".into());
|
||||
assert_eq!(tz.value(), "UTC");
|
||||
}
|
||||
59
crates/domain/tests/user/user_test.rs
Normal file
59
crates/domain/tests/user/user_test.rs
Normal file
@@ -0,0 +1,59 @@
|
||||
use domain::user::{DisplayName, Email, PasswordHash, Timezone, User, UserRole, Username};
|
||||
|
||||
#[test]
|
||||
fn new_user_has_default_role() {
|
||||
let user = User::new(
|
||||
Username::new("gabriel").unwrap(),
|
||||
Email::new("gabriel@example.com").unwrap(),
|
||||
PasswordHash::new("hashed".into()),
|
||||
);
|
||||
|
||||
assert_eq!(user.role(), UserRole::User);
|
||||
assert!(!user.is_admin());
|
||||
assert!(user.display_name().is_none());
|
||||
assert!(user.timezone().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn promote_to_admin_changes_role() {
|
||||
let mut user = User::new(
|
||||
Username::new("gabriel").unwrap(),
|
||||
Email::new("gabriel@example.com").unwrap(),
|
||||
PasswordHash::new("hashed".into()),
|
||||
);
|
||||
|
||||
user.promote_to_admin();
|
||||
|
||||
assert_eq!(user.role(), UserRole::Admin);
|
||||
assert!(user.is_admin());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_display_name_touches_updated_at() {
|
||||
let mut user = User::new(
|
||||
Username::new("gabriel").unwrap(),
|
||||
Email::new("gabriel@example.com").unwrap(),
|
||||
PasswordHash::new("hashed".into()),
|
||||
);
|
||||
let before = *user.updated_at();
|
||||
|
||||
let name = DisplayName::new("Gabriel K").unwrap();
|
||||
user.update_display_name(Some(name));
|
||||
|
||||
assert_eq!(user.display_name().map(|d| d.value()), Some("Gabriel K"));
|
||||
assert!(*user.updated_at() >= before);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_timezone_sets_value() {
|
||||
let mut user = User::new(
|
||||
Username::new("gabriel").unwrap(),
|
||||
Email::new("gabriel@example.com").unwrap(),
|
||||
PasswordHash::new("hashed".into()),
|
||||
);
|
||||
|
||||
let tz = Timezone::new("Europe/Warsaw").unwrap();
|
||||
user.update_timezone(Some(tz));
|
||||
|
||||
assert_eq!(user.timezone().map(|t| t.value()), Some("Europe/Warsaw"));
|
||||
}
|
||||
45
crates/domain/tests/user/username_test.rs
Normal file
45
crates/domain/tests/user/username_test.rs
Normal file
@@ -0,0 +1,45 @@
|
||||
use domain::errors::DomainError;
|
||||
use domain::user::Username;
|
||||
|
||||
#[test]
|
||||
fn valid_username_is_created() {
|
||||
let username = Username::new("gabriel").unwrap();
|
||||
assert_eq!(username.value(), "gabriel");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn username_with_dots_and_underscores_is_valid() {
|
||||
let username = Username::new("gabriel.k_99").unwrap();
|
||||
assert_eq!(username.value(), "gabriel.k_99");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn username_trims_whitespace() {
|
||||
let username = Username::new(" gabriel ").unwrap();
|
||||
assert_eq!(username.value(), "gabriel");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_username_is_rejected() {
|
||||
let result = Username::new("");
|
||||
assert!(matches!(result, Err(DomainError::InvalidInput(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn username_longer_than_32_chars_is_rejected() {
|
||||
let long = "a".repeat(33);
|
||||
let result = Username::new(long);
|
||||
assert!(matches!(result, Err(DomainError::InvalidInput(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn username_with_special_chars_is_rejected() {
|
||||
let result = Username::new("gabriel@home");
|
||||
assert!(matches!(result, Err(DomainError::InvalidInput(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn username_with_spaces_is_rejected() {
|
||||
let result = Username::new("gabriel k");
|
||||
assert!(matches!(result, Err(DomainError::InvalidInput(_))));
|
||||
}
|
||||
Reference in New Issue
Block a user