this repo has no description
1mod common;
2use tranquil_pds::comms::{SendError, is_valid_phone_number, sanitize_header_value};
3use tranquil_pds::image::{ImageError, ImageProcessor};
4
5#[test]
6fn test_header_injection_sanitization() {
7 let malicious = "Injected\r\nBcc: attacker@evil.com";
8 let sanitized = sanitize_header_value(malicious);
9 assert!(!sanitized.contains('\r') && !sanitized.contains('\n'));
10 assert!(sanitized.contains("Injected") && sanitized.contains("Bcc:"));
11
12 let normal = "Normal Subject Line";
13 assert_eq!(sanitize_header_value(normal), "Normal Subject Line");
14
15 let padded = " Subject ";
16 assert_eq!(sanitize_header_value(padded), "Subject");
17
18 let multi_newline = "Line1\r\nLine2\nLine3\rLine4";
19 let sanitized = sanitize_header_value(multi_newline);
20 assert!(!sanitized.contains('\r') && !sanitized.contains('\n'));
21 assert!(sanitized.contains("Line1") && sanitized.contains("Line4"));
22
23 let header_injection = "Normal Subject\r\nBcc: attacker@evil.com\r\nX-Injected: value";
24 let sanitized = sanitize_header_value(header_injection);
25 assert_eq!(sanitized.split("\r\n").count(), 1);
26 assert!(
27 sanitized.contains("Normal Subject")
28 && sanitized.contains("Bcc:")
29 && sanitized.contains("X-Injected:")
30 );
31
32 let with_null = "client\0id";
33 assert!(sanitize_header_value(with_null).contains("client"));
34
35 let long_input = "x".repeat(10000);
36 assert!(!sanitize_header_value(&long_input).is_empty());
37}
38
39#[test]
40fn test_phone_number_validation() {
41 assert!(is_valid_phone_number("+1234567890"));
42 assert!(is_valid_phone_number("+12025551234"));
43 assert!(is_valid_phone_number("+442071234567"));
44 assert!(is_valid_phone_number("+4915123456789"));
45 assert!(is_valid_phone_number("+1"));
46
47 assert!(!is_valid_phone_number("1234567890"));
48 assert!(!is_valid_phone_number("12025551234"));
49 assert!(!is_valid_phone_number(""));
50 assert!(!is_valid_phone_number("+"));
51 assert!(!is_valid_phone_number("+12345678901234567890123"));
52
53 assert!(!is_valid_phone_number("+abc123"));
54 assert!(!is_valid_phone_number("+1234abc"));
55 assert!(!is_valid_phone_number("+a"));
56
57 assert!(!is_valid_phone_number("+1234 5678"));
58 assert!(!is_valid_phone_number("+ 1234567890"));
59 assert!(!is_valid_phone_number("+1 "));
60
61 assert!(!is_valid_phone_number("+123-456-7890"));
62 assert!(!is_valid_phone_number("+1(234)567890"));
63 assert!(!is_valid_phone_number("+1.234.567.890"));
64
65 for malicious in [
66 "+123; rm -rf /",
67 "+123 && cat /etc/passwd",
68 "+123`id`",
69 "+123$(whoami)",
70 "+123|cat /etc/shadow",
71 "+123\n--help",
72 "+123\r\n--version",
73 "+123--help",
74 ] {
75 assert!(
76 !is_valid_phone_number(malicious),
77 "Command injection '{}' should be rejected",
78 malicious
79 );
80 }
81}
82
83#[test]
84fn test_image_file_size_limits() {
85 let processor = ImageProcessor::new();
86 let oversized_data: Vec<u8> = vec![0u8; 11 * 1024 * 1024];
87 let result = processor.process(&oversized_data, "image/jpeg");
88 match result {
89 Err(ImageError::FileTooLarge { .. }) => {}
90 Err(other) => {
91 let msg = format!("{:?}", other);
92 if !msg.to_lowercase().contains("size") && !msg.to_lowercase().contains("large") {
93 panic!("Expected FileTooLarge error, got: {:?}", other);
94 }
95 }
96 Ok(_) => panic!("Should reject files over size limit"),
97 }
98
99 let processor = ImageProcessor::new().with_max_file_size(1024);
100 let data: Vec<u8> = vec![0u8; 2048];
101 assert!(processor.process(&data, "image/jpeg").is_err());
102}
103
104#[test]
105fn test_send_error_display() {
106 let timeout = SendError::Timeout;
107 assert!(!format!("{}", timeout).is_empty());
108 assert!(format!("{}", timeout).to_lowercase().contains("timeout"));
109
110 let max_retries = SendError::MaxRetriesExceeded("Server returned 503".to_string());
111 let msg = format!("{}", max_retries);
112 assert!(!msg.is_empty());
113 assert!(msg.contains("503") || msg.contains("retries"));
114
115 let invalid = SendError::InvalidRecipient("bad recipient".to_string());
116 assert!(!format!("{}", invalid).is_empty());
117}
118
119#[tokio::test]
120async fn test_signup_queue_authentication() {
121 use common::{base_url, client, create_account_and_login};
122 let base = base_url().await;
123 let http_client = client();
124
125 let res = http_client
126 .get(format!("{}/xrpc/com.atproto.temp.checkSignupQueue", base))
127 .send()
128 .await
129 .unwrap();
130 assert_eq!(res.status(), reqwest::StatusCode::OK);
131 let body: serde_json::Value = res.json().await.unwrap();
132 assert_eq!(body["activated"], true);
133
134 let (token, _did) = create_account_and_login(&http_client).await;
135 let res = http_client
136 .get(format!("{}/xrpc/com.atproto.temp.checkSignupQueue", base))
137 .header("Authorization", format!("Bearer {}", token))
138 .send()
139 .await
140 .unwrap();
141 assert_eq!(res.status(), reqwest::StatusCode::OK);
142 let body: serde_json::Value = res.json().await.unwrap();
143 assert_eq!(body["activated"], true);
144}