Skip to content
This repository was archived by the owner on Jan 2, 2026. It is now read-only.

Commit 2e42de3

Browse files
author
bitfl0wer
committed
feat: tests!
1 parent a5ee771 commit 2e42de3

File tree

5 files changed

+520
-0
lines changed

5 files changed

+520
-0
lines changed

src/constraints/session_id.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,69 @@ impl Constrained for SessionId {
1919
Ok(())
2020
}
2121
}
22+
23+
#[cfg(test)]
24+
mod tests {
25+
use super::*;
26+
use crate::certs::{SessionId, Target};
27+
28+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
29+
#[cfg_attr(not(target_arch = "wasm32"), test)]
30+
fn session_id_valid_lengths_validate() {
31+
let test_cases = [
32+
"a", // 1 character (minimum)
33+
"short", // 5 characters
34+
"mediumLengthSessionId", // 18 characters
35+
"12345678901234567890123456789012", // 32 characters (maximum)
36+
];
37+
38+
for case in test_cases {
39+
let session_id = SessionId::new_validated(case).unwrap();
40+
assert!(
41+
session_id.validate(None).is_ok(),
42+
"SessionId '{case}' should validate"
43+
);
44+
assert!(
45+
session_id.validate(Some(Target::Actor)).is_ok(),
46+
"SessionId '{case}' should validate with Actor target"
47+
);
48+
assert!(
49+
session_id.validate(Some(Target::HomeServer)).is_ok(),
50+
"SessionId '{case}' should validate with HomeServer target"
51+
);
52+
}
53+
}
54+
55+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
56+
#[cfg_attr(not(target_arch = "wasm32"), test)]
57+
fn session_id_empty_fails_construction() {
58+
let result = SessionId::new_validated("");
59+
assert!(result.is_err(), "Empty SessionId should fail construction");
60+
}
61+
62+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
63+
#[cfg_attr(not(target_arch = "wasm32"), test)]
64+
fn session_id_too_long_fails_construction() {
65+
let too_long = "123456789012345678901234567890123"; // 33 characters
66+
let result = SessionId::new_validated(too_long);
67+
assert!(
68+
result.is_err(),
69+
"SessionId longer than 32 characters should fail construction"
70+
);
71+
}
72+
73+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
74+
#[cfg_attr(not(target_arch = "wasm32"), test)]
75+
fn session_id_boundary_lengths() {
76+
// Test exact boundary conditions
77+
let exactly_32 = "12345678901234567890123456789012";
78+
assert_eq!(exactly_32.len(), 32);
79+
let session_id = SessionId::new_validated(exactly_32).unwrap();
80+
assert!(session_id.validate(None).is_ok());
81+
82+
let exactly_1 = "a";
83+
assert_eq!(exactly_1.len(), 1);
84+
let session_id = SessionId::new_validated(exactly_1).unwrap();
85+
assert!(session_id.validate(None).is_ok());
86+
}
87+
}

src/constraints/types/domain_name.rs

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,113 @@ impl Constrained for DomainName {
2626
}
2727
}
2828
}
29+
30+
#[cfg(test)]
31+
mod tests {
32+
use super::*;
33+
use crate::certs::Target;
34+
use crate::types::DomainName;
35+
36+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
37+
#[cfg_attr(not(target_arch = "wasm32"), test)]
38+
fn domain_name_valid_formats_validate() {
39+
let test_cases = [
40+
"example.com",
41+
"subdomain.example.org",
42+
"multi-word.example.co.uk",
43+
"localhost",
44+
"example-domain.com",
45+
"a.b.c.d.e.com",
46+
"single",
47+
];
48+
49+
for case in test_cases {
50+
let domain_name = DomainName::new(case).unwrap();
51+
assert!(
52+
domain_name.validate(None).is_ok(),
53+
"DomainName '{}' should validate",
54+
case
55+
);
56+
assert!(
57+
domain_name.validate(Some(Target::Actor)).is_ok(),
58+
"DomainName '{}' should validate with Actor target",
59+
case
60+
);
61+
assert!(
62+
domain_name.validate(Some(Target::HomeServer)).is_ok(),
63+
"DomainName '{}' should validate with HomeServer target",
64+
case
65+
);
66+
}
67+
}
68+
69+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
70+
#[cfg_attr(not(target_arch = "wasm32"), test)]
71+
fn domain_name_empty_value_fails() {
72+
// Test that an empty domain name fails validation
73+
let empty_domain = DomainName {
74+
value: String::new(),
75+
};
76+
77+
let result = empty_domain.validate(None);
78+
assert!(result.is_err());
79+
80+
let error = result.unwrap_err();
81+
assert!(matches!(error, ConstraintError::Malformed(_)));
82+
assert!(error.to_string().contains("malformed"));
83+
}
84+
85+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
86+
#[cfg_attr(not(target_arch = "wasm32"), test)]
87+
fn domain_name_whitespace_only_fails() {
88+
// Test that whitespace-only domain name fails validation
89+
let whitespace_domain = DomainName {
90+
value: " ".to_string(),
91+
};
92+
93+
let result = whitespace_domain.validate(None);
94+
assert!(result.is_err());
95+
96+
let error = result.unwrap_err();
97+
assert!(matches!(error, ConstraintError::Malformed(_)));
98+
assert!(error.to_string().contains("malformed"));
99+
}
100+
101+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
102+
#[cfg_attr(not(target_arch = "wasm32"), test)]
103+
fn domain_name_invalid_formats_fail_construction() {
104+
let invalid_cases = [
105+
"EXAMPLE.COM", // Uppercase not allowed
106+
"", // Empty string
107+
];
108+
109+
for case in invalid_cases {
110+
let result = DomainName::new(case);
111+
assert!(
112+
result.is_err(),
113+
"DomainName construction should fail for invalid format: '{}'",
114+
case
115+
);
116+
}
117+
}
118+
119+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
120+
#[cfg_attr(not(target_arch = "wasm32"), test)]
121+
fn domain_name_regex_validation() {
122+
// Test regex validation specifically
123+
let valid_domain = DomainName::new("example.com").unwrap();
124+
assert!(valid_domain.validate(None).is_ok());
125+
126+
// Create an invalid domain that bypasses constructor validation to test constraint validation
127+
let invalid_domain = DomainName {
128+
value: "INVALID.COM".to_string(),
129+
};
130+
131+
let result = invalid_domain.validate(None);
132+
assert!(result.is_err());
133+
134+
let error = result.unwrap_err();
135+
assert!(matches!(error, ConstraintError::Malformed(_)));
136+
assert!(error.to_string().contains("malformed"));
137+
}
138+
}

src/constraints/types/federation_id.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,77 @@ impl Constrained for FederationId {
2525
}
2626
}
2727
}
28+
29+
#[cfg(test)]
30+
mod tests {
31+
use super::*;
32+
use crate::types::FederationId;
33+
34+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
35+
#[cfg_attr(not(target_arch = "wasm32"), test)]
36+
fn federation_id_valid_formats_validate() {
37+
let test_cases = [
38+
"alice@example.com",
39+
"user123@subdomain.example.org",
40+
"test.user@multi-word.example.co.uk",
41+
"simple@localhost",
42+
"user+tag@example.com",
43+
"user_name@example-domain.com",
44+
];
45+
46+
for case in test_cases {
47+
let federation_id = FederationId::new(case).unwrap();
48+
assert!(
49+
federation_id.validate(None).is_ok(),
50+
"FederationId '{}' should validate",
51+
case
52+
);
53+
assert!(
54+
federation_id.validate(Some(Target::Actor)).is_ok(),
55+
"FederationId '{}' should validate with Actor target",
56+
case
57+
);
58+
assert!(
59+
federation_id.validate(Some(Target::HomeServer)).is_ok(),
60+
"FederationId '{}' should validate with HomeServer target",
61+
case
62+
);
63+
}
64+
}
65+
66+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
67+
#[cfg_attr(not(target_arch = "wasm32"), test)]
68+
fn federation_id_with_whitespace_fails() {
69+
let federation_id = FederationId {
70+
local_name: crate::types::local_name::LocalName::new("alice").unwrap(),
71+
domain_name: crate::types::DomainName::new("example.com").unwrap(),
72+
};
73+
74+
// Note: In practice, whitespace validation happens during construction
75+
// This test ensures the validation method works correctly
76+
let result = federation_id.validate(None);
77+
assert!(result.is_ok());
78+
}
79+
80+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
81+
#[cfg_attr(not(target_arch = "wasm32"), test)]
82+
fn federation_id_invalid_formats_fail_construction() {
83+
let invalid_cases = [
84+
"alice", // Missing domain
85+
"@example.com", // Missing local name
86+
"alice@", // Missing domain
87+
"alice@.com", // Invalid domain format
88+
"ALICE@EXAMPLE.COM", // Uppercase not allowed
89+
"", // Empty string
90+
];
91+
92+
for case in invalid_cases {
93+
let result = FederationId::new(case);
94+
assert!(
95+
result.is_err(),
96+
"FederationId construction should fail for invalid format: '{}'",
97+
case
98+
);
99+
}
100+
}
101+
}

src/constraints/types/local_name.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,84 @@ impl super::Constrained for LocalName {
1919
}
2020
}
2121
}
22+
23+
#[cfg(test)]
24+
mod tests {
25+
use crate::Constrained;
26+
use crate::certs::Target;
27+
use crate::types::local_name::LocalName;
28+
29+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
30+
#[cfg_attr(not(target_arch = "wasm32"), test)]
31+
fn local_name_valid_formats_validate() {
32+
let test_cases = [
33+
"alice",
34+
"user123",
35+
"test.user",
36+
"user+tag",
37+
"user_name",
38+
"a",
39+
"user-name",
40+
"user%plus",
41+
];
42+
43+
for case in test_cases {
44+
let local_name = LocalName::new(case).unwrap();
45+
assert!(
46+
local_name.validate(None).is_ok(),
47+
"LocalName '{}' should validate",
48+
case
49+
);
50+
assert!(
51+
local_name.validate(Some(Target::Actor)).is_ok(),
52+
"LocalName '{}' should validate with Actor target",
53+
case
54+
);
55+
assert!(
56+
local_name.validate(Some(Target::HomeServer)).is_ok(),
57+
"LocalName '{}' should validate with HomeServer target",
58+
case
59+
);
60+
}
61+
}
62+
63+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
64+
#[cfg_attr(not(target_arch = "wasm32"), test)]
65+
fn local_name_invalid_formats_fail_construction() {
66+
let invalid_cases = [
67+
"ALICE", // Uppercase not allowed
68+
"", // Empty string
69+
];
70+
71+
for case in invalid_cases {
72+
let result = LocalName::new(case);
73+
assert!(
74+
result.is_err(),
75+
"LocalName construction should fail for invalid format: '{}'",
76+
case
77+
);
78+
}
79+
}
80+
81+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
82+
#[cfg_attr(not(target_arch = "wasm32"), test)]
83+
fn local_name_edge_cases() {
84+
// Test edge cases that should be valid
85+
let edge_cases = [
86+
"a", // Single character
87+
"123", // Only numbers
88+
"user.name.long", // Multiple dots
89+
"user+test+more", // Multiple plus signs
90+
"user_test_more", // Multiple underscores
91+
];
92+
93+
for case in edge_cases {
94+
let local_name = LocalName::new(case).unwrap();
95+
assert!(
96+
local_name.validate(None).is_ok(),
97+
"LocalName edge case '{}' should validate",
98+
case
99+
);
100+
}
101+
}
102+
}

0 commit comments

Comments
 (0)