#![allow(clippy::unwrap_used, clippy::expect_used, unused_results)]
use std::collections::HashMap;
use std::time::Duration;
use liburlx::{Response, TransferInfo};
#[test]
fn response_new_basic() {
let resp = Response::new(200, HashMap::new(), Vec::new(), String::new());
assert_eq!(resp.status(), 200);
assert!(resp.body().is_empty());
assert_eq!(resp.effective_url(), "");
}
#[test]
fn response_new_with_body() {
let body = b"hello world".to_vec();
let resp = Response::new(200, HashMap::new(), body, "http://example.com".to_string());
assert_eq!(resp.body_str().unwrap(), "hello world");
assert_eq!(resp.effective_url(), "http://example.com");
assert_eq!(resp.size_download(), 11);
}
#[test]
fn response_new_with_headers() {
let mut headers = HashMap::new();
headers.insert("content-type".to_string(), "text/html".to_string());
headers.insert("x-custom".to_string(), "value".to_string());
let resp = Response::new(200, headers, Vec::new(), String::new());
assert_eq!(resp.header("content-type"), Some("text/html"));
assert_eq!(resp.header("x-custom"), Some("value"));
}
#[test]
fn response_with_info() {
let info = TransferInfo {
time_connect: Duration::from_millis(50),
time_total: Duration::from_millis(100),
num_redirects: 2,
..TransferInfo::default()
};
let resp = Response::with_info(200, HashMap::new(), Vec::new(), String::new(), info);
assert_eq!(resp.status(), 200);
assert_eq!(resp.transfer_info().time_connect, Duration::from_millis(50));
assert_eq!(resp.transfer_info().time_total, Duration::from_millis(100));
assert_eq!(resp.transfer_info().num_redirects, 2);
}
#[test]
fn set_transfer_info() {
let mut resp = Response::new(200, HashMap::new(), Vec::new(), String::new());
let info = TransferInfo {
time_connect: Duration::from_millis(25),
time_total: Duration::from_millis(75),
num_redirects: 1,
..TransferInfo::default()
};
resp.set_transfer_info(info);
assert_eq!(resp.transfer_info().num_redirects, 1);
}
#[test]
fn header_lookup_case_insensitive() {
let mut headers = HashMap::new();
headers.insert("content-type".to_string(), "application/json".to_string());
let resp = Response::new(200, headers, Vec::new(), String::new());
assert_eq!(resp.header("Content-Type"), Some("application/json"));
assert_eq!(resp.header("CONTENT-TYPE"), Some("application/json"));
assert_eq!(resp.header("content-type"), Some("application/json"));
}
#[test]
fn header_lookup_missing() {
let resp = Response::new(200, HashMap::new(), Vec::new(), String::new());
assert_eq!(resp.header("x-missing"), None);
}
#[test]
fn body_str_valid_utf8() {
let resp = Response::new(200, HashMap::new(), "valid utf8".into(), String::new());
assert_eq!(resp.body_str().unwrap(), "valid utf8");
}
#[test]
fn body_str_invalid_utf8() {
let resp = Response::new(200, HashMap::new(), vec![0xFF, 0xFE], String::new());
assert!(resp.body_str().is_err());
}
#[test]
fn body_str_empty() {
let resp = Response::new(200, HashMap::new(), Vec::new(), String::new());
assert_eq!(resp.body_str().unwrap(), "");
}
#[test]
fn is_redirect_301_with_location() {
let mut headers = HashMap::new();
headers.insert("location".to_string(), "/new".to_string());
let resp = Response::new(301, headers, Vec::new(), String::new());
assert!(resp.is_redirect());
}
#[test]
fn is_redirect_302_with_location() {
let mut headers = HashMap::new();
headers.insert("location".to_string(), "/new".to_string());
let resp = Response::new(302, headers, Vec::new(), String::new());
assert!(resp.is_redirect());
}
#[test]
fn is_redirect_301_without_location() {
let resp = Response::new(301, HashMap::new(), Vec::new(), String::new());
assert!(!resp.is_redirect());
}
#[test]
fn is_redirect_200_not_redirect() {
let resp = Response::new(200, HashMap::new(), Vec::new(), String::new());
assert!(!resp.is_redirect());
}
#[test]
fn content_type_present() {
let mut headers = HashMap::new();
headers.insert("content-type".to_string(), "text/plain".to_string());
let resp = Response::new(200, headers, Vec::new(), String::new());
assert_eq!(resp.content_type(), Some("text/plain"));
}
#[test]
fn content_type_absent() {
let resp = Response::new(200, HashMap::new(), Vec::new(), String::new());
assert_eq!(resp.content_type(), None);
}
#[test]
fn size_download_empty() {
let resp = Response::new(200, HashMap::new(), Vec::new(), String::new());
assert_eq!(resp.size_download(), 0);
}
#[test]
fn size_download_with_body() {
let body = vec![0u8; 1024];
let resp = Response::new(200, HashMap::new(), body, String::new());
assert_eq!(resp.size_download(), 1024);
}
#[test]
fn transfer_info_default() {
let info = TransferInfo::default();
assert_eq!(info.time_connect, Duration::ZERO);
assert_eq!(info.time_total, Duration::ZERO);
assert_eq!(info.num_redirects, 0);
}
#[test]
fn transfer_info_clone() {
let info = TransferInfo {
time_connect: Duration::from_millis(10),
time_total: Duration::from_millis(20),
num_redirects: 3,
..TransferInfo::default()
};
let cloned = info.clone();
assert_eq!(info.time_connect, Duration::from_millis(10));
assert_eq!(cloned.time_connect, Duration::from_millis(10));
assert_eq!(cloned.num_redirects, 3);
}
#[test]
fn transfer_info_debug() {
let info = TransferInfo::default();
let debug = format!("{info:?}");
assert!(debug.contains("TransferInfo"));
}
#[test]
fn response_clone_independent() {
let mut headers = HashMap::new();
headers.insert("x-key".to_string(), "value".to_string());
let resp = Response::new(200, headers, b"body".to_vec(), "http://example.com".to_string());
let cloned = resp.clone();
assert_eq!(resp.status(), 200);
assert_eq!(cloned.status(), 200);
assert_eq!(cloned.header("x-key"), Some("value"));
assert_eq!(cloned.body_str().unwrap(), "body");
assert_eq!(cloned.effective_url(), "http://example.com");
}
#[test]
fn status_1xx() {
let resp = Response::new(100, HashMap::new(), Vec::new(), String::new());
assert_eq!(resp.status(), 100);
}
#[test]
fn status_3xx() {
let resp = Response::new(307, HashMap::new(), Vec::new(), String::new());
assert_eq!(resp.status(), 307);
}
#[test]
fn headers_returns_all() {
let mut headers = HashMap::new();
headers.insert("a".to_string(), "1".to_string());
headers.insert("b".to_string(), "2".to_string());
let resp = Response::new(200, headers, Vec::new(), String::new());
assert_eq!(resp.headers().len(), 2);
}