gitdataai/libs/room/src/helpers_tests.rs
2026-05-14 10:02:21 +08:00

205 lines
6.7 KiB
Rust

#[cfg(test)]
mod tests {
use crate::service::RoomService;
use models::rooms::MessageContentType;
#[test]
fn test_parse_message_content_type_valid() {
assert!(matches!(
RoomService::parse_message_content_type(Some("text".into())).unwrap(),
MessageContentType::Text
));
assert!(matches!(
RoomService::parse_message_content_type(Some("image".into())).unwrap(),
MessageContentType::Image
));
assert!(matches!(
RoomService::parse_message_content_type(Some("audio".into())).unwrap(),
MessageContentType::Audio
));
assert!(matches!(
RoomService::parse_message_content_type(Some("video".into())).unwrap(),
MessageContentType::Video
));
assert!(matches!(
RoomService::parse_message_content_type(Some("file".into())).unwrap(),
MessageContentType::File
));
}
#[test]
fn test_parse_message_content_type_case_insensitive() {
assert!(matches!(
RoomService::parse_message_content_type(Some("TEXT".into())).unwrap(),
MessageContentType::Text
));
assert!(matches!(
RoomService::parse_message_content_type(Some("Image".into())).unwrap(),
MessageContentType::Image
));
}
#[test]
fn test_parse_message_content_type_none_defaults_to_text() {
assert!(matches!(
RoomService::parse_message_content_type(None).unwrap(),
MessageContentType::Text
));
}
#[test]
fn test_parse_message_content_type_invalid() {
assert!(RoomService::parse_message_content_type(Some("pdf".into())).is_err());
}
#[test]
fn test_validate_name_valid() {
assert!(RoomService::validate_name("test-room", 100).is_ok());
assert!(RoomService::validate_name("a", 100).is_ok());
}
#[test]
fn test_validate_name_empty() {
assert!(RoomService::validate_name("", 100).is_err());
assert!(RoomService::validate_name(" ", 100).is_err());
}
#[test]
fn test_validate_name_too_long() {
let long = "x".repeat(101);
assert!(RoomService::validate_name(&long, 100).is_err());
}
#[test]
fn test_validate_content_valid() {
assert!(RoomService::validate_content("hello", 10000).is_ok());
}
#[test]
fn test_validate_content_empty() {
assert!(RoomService::validate_content("", 10000).is_err());
assert!(RoomService::validate_content(" ", 10000).is_err());
}
#[test]
fn test_validate_content_too_long() {
let long = "x".repeat(10001);
assert!(RoomService::validate_content(&long, 10000).is_err());
}
#[test]
fn test_sanitize_content_removes_script_tag() {
let input = "<script>alert('xss')</script>";
let result = RoomService::sanitize_content(input);
assert!(!result.contains("<script>"));
}
#[test]
fn test_sanitize_content_blocks_javascript_uri() {
let input = "javascript:alert(1)";
let result = RoomService::sanitize_content(input);
assert_eq!(result, "javascript:alert(1)");
}
#[test]
fn test_sanitize_content_blocks_onerror() {
let input = r#"<img src=x onerror="alert(1)">"#;
let result = RoomService::sanitize_content(input);
assert!(!result.contains("onerror"));
assert!(result.contains("<img"));
assert!(!result.contains("alert"));
}
#[test]
fn test_sanitize_content_preserves_safe_content() {
let input = "Hello <strong>world</strong>";
let result = RoomService::sanitize_content(input);
assert!(result.contains("Hello"));
assert!(result.contains("<strong>"));
}
#[test]
fn test_room_event_type_from_str_roundtrip() {
for variant in [
crate::RoomEventType::RoomCreated,
crate::RoomEventType::RoomDeleted,
crate::RoomEventType::NewMessage,
crate::RoomEventType::MessageEdited,
crate::RoomEventType::MessageRevoked,
crate::RoomEventType::MemberJoined,
] {
let s = variant.as_str();
let parsed = crate::RoomEventType::from_str(s);
assert_eq!(parsed, Some(variant));
}
}
#[test]
fn test_room_event_type_from_str_unknown() {
assert_eq!(crate::RoomEventType::from_str("unknown_event"), None);
}
#[test]
fn test_mention_bracket_re_matches_ai_model() {
let re = crate::service::mention_bracket_re();
let caps: Vec<_> = re
.captures_iter("@[ai:550e8400-0000-0000-0000-000000000001:GPT-4]")
.collect();
assert_eq!(caps.len(), 1);
assert_eq!(&caps[0][1], "ai");
assert_eq!(&caps[0][2], "550e8400-0000-0000-0000-000000000001");
}
#[test]
fn test_mention_bracket_re_matches_user() {
let re = crate::service::mention_bracket_re();
let caps: Vec<_> = re
.captures_iter("@[user:850e8400-0000-0000-0000-000000000002:John]")
.collect();
assert_eq!(caps.len(), 1);
assert_eq!(&caps[0][1], "user");
}
#[test]
fn test_mention_bracket_re_matches_repo() {
let re = crate::service::mention_bracket_re();
let caps: Vec<_> = re.captures_iter("@[repo:my-repo:My Repository]").collect();
assert_eq!(caps.len(), 1);
assert_eq!(&caps[0][1], "repo");
}
#[test]
fn test_mention_bracket_re_no_match_plain_text() {
let re = crate::service::mention_bracket_re();
let caps: Vec<_> = re.captures_iter("Hello world").collect();
assert_eq!(caps.len(), 0);
}
#[test]
fn test_mention_multiple_in_same_message() {
let re = crate::service::mention_bracket_re();
let content = "@[ai:uuid1:Model1] and @[user:uuid2:User2]";
let caps: Vec<_> = re.captures_iter(content).collect();
assert_eq!(caps.len(), 2);
}
#[test]
fn test_mention_tag_re_legacy_format() {
let re = crate::service::mention_tag_re();
let content = r#"<mention type="ai" id="model-uuid">GPT-4</mention>"#;
let caps: Vec<_> = re.captures_iter(content).collect();
assert_eq!(caps.len(), 1);
assert_eq!(&caps[0][1], "ai");
assert_eq!(&caps[0][2], "model-uuid");
}
#[test]
fn test_mention_combined_brackets_and_tags() {
let bracket_re = crate::service::mention_bracket_re();
let tag_re = crate::service::mention_tag_re();
let content = r#"@[ai:uuid1:A] <mention type="ai" id="uuid2">B</mention>"#;
assert_eq!(bracket_re.captures_iter(content).count(), 1);
assert_eq!(tag_re.captures_iter(content).count(), 1);
}
}