I've been saying "PDSes seem easy enough, they're what, some CRUD to a db? I can do that in my sleep". well i'm sleeping rn so let's go
at main 5.2 kB view raw
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}