zlsrs 0.1.6

Rust 标准库扩展工具集,提供更便捷的使用方式
Documentation
use super::*;
use std::time::Duration;

/// 测试 HTTP 方法的字符串转换
#[test]
fn test_http_methods() {
    assert_eq!(Method::GET.as_str(), "GET");
    assert_eq!(Method::POST.as_str(), "POST");
    assert_eq!(Method::PUT.as_str(), "PUT");
    assert_eq!(Method::DELETE.as_str(), "DELETE");
    assert_eq!(Method::HEAD.as_str(), "HEAD");
    assert_eq!(Method::OPTIONS.as_str(), "OPTIONS");
    assert_eq!(Method::PATCH.as_str(), "PATCH");
}

/// 测试 URL 解析
#[test]
fn test_url_parsing() {
    let test_cases = [
        ("http://example.com", "/", None),
        ("http://example.com/", "/", None),
        ("http://example.com/path", "/path", None),
        ("http://example.com/path?query=1", "/path", Some("query=1")),
    ];

    for (url_str, expected_path, expected_query) in test_cases {
        let url = url::Url::parse(url_str).unwrap();
        assert_eq!(url.path(), expected_path);
        assert_eq!(url.query(), expected_query);
    }
}

/// 测试无效 URL
#[test]
fn test_invalid_url() {
    let client = default();
    let result = client.get("not_a_valid_url").send();
    assert!(result.is_err());
    assert!(result
        .unwrap_err()
        .to_string()
        .contains("relative URL without a base"));
}

/// 测试 URL 端口解析
#[test]
fn test_url_port() {
    let urls = [
        ("http://example.com", 80),
        ("http://example.com:8080", 8080),
        ("https://example.com", 443),
        ("https://example.com:8443", 8443),
    ];

    for (url_str, expected_port) in urls {
        let url = url::Url::parse(url_str).unwrap();
        let port = url
            .port()
            .unwrap_or(if url.scheme() == "https" { 443 } else { 80 });
        assert_eq!(port, expected_port, "URL: {}", url_str);
    }
}

/// 测试请求头配置
#[test]
fn test_request_builder() {
    let client = Client::default();

    // 测试 GET 请求构建器
    let builder = client
        .get("http://httpbin.org/get")
        .header("X-Custom-Header", "custom-value")
        .header("Accept", "application/json");

    assert_eq!(builder.method.as_str(), "GET");
    assert_eq!(builder.url, "http://httpbin.org/get");
    assert_eq!(
        builder.headers.get("X-Custom-Header").unwrap(),
        "custom-value"
    );
    assert_eq!(builder.headers.get("Accept").unwrap(), "application/json");

    // 测试 POST 请求构建器
    let body = b"test-body".to_vec();
    let builder = client
        .post("http://httpbin.org/post")
        .header("Content-Type", "application/json")
        .body(body.clone());

    assert_eq!(builder.method.as_str(), "POST");
    assert_eq!(builder.url, "http://httpbin.org/post");
    assert_eq!(
        builder.headers.get("Content-Type").unwrap(),
        "application/json"
    );
    assert_eq!(builder.body.unwrap(), body);
}

/// 测试自定义配置
#[test]
fn test_custom_config() {
    let config = ClientConfig {
        timeout: Duration::from_secs(5),
        user_agent: "Custom Agent".to_string(),
        max_retries: 2,
        retry_interval: Duration::from_millis(500),
        allow_redirects: true,
        max_redirects: 5,
        verify_ssl: false,
        ..Default::default()
    };

    let client = Client::new(config.clone());
    assert_eq!(client.config.timeout, Duration::from_secs(5));
    assert_eq!(client.config.max_retries, 2);
    assert_eq!(client.config.user_agent, "Custom Agent");
    assert_eq!(client.config.retry_interval, Duration::from_millis(500));
    assert_eq!(client.config.allow_redirects, true);
    assert_eq!(client.config.max_redirects, 5);
    assert_eq!(client.config.verify_ssl, false);
}

/// 测试不同的请求体格式
#[test]
fn test_body_formats() {
    // 测试 JSON 格式
    assert_eq!(BodyFormat::Json.content_type(), "application/json");

    // 测试 Form 格式
    assert_eq!(
        BodyFormat::FormUrlEncoded.content_type(),
        "application/x-www-form-urlencoded"
    );

    // 测试文本格式
    assert_eq!(BodyFormat::Text.content_type(), "text/plain");

    // 测试 FormData 格式
    let boundary = "boundary123";
    assert_eq!(
        BodyFormat::FormData(boundary.to_string()).content_type(),
        format!("multipart/form-data; boundary={}", boundary)
    );

    // 测试自定义格式
    assert_eq!(
        BodyFormat::Custom("application/xml".to_string()).content_type(),
        "application/xml"
    );
}

/// 测试所有 HTTP 方法
#[test]
fn test_all_http_methods() {
    let client = default();
    let url = "http://example.com";

    let methods = [
        (client.get(url), "GET"),
        (client.post(url), "POST"),
        (client.put(url), "PUT"),
        (client.delete(url), "DELETE"),
        (client.head(url), "HEAD"),
        (client.options(url), "OPTIONS"),
        (client.patch(url), "PATCH"),
    ];

    for (builder, expected_method) in methods {
        assert_eq!(builder.method.as_str(), expected_method);
        assert_eq!(builder.url, url);
    }
}

/// 测试请求构建器的所有配置选项
#[test]
fn test_request_builder_options() {
    let client = default();
    let builder = client
        .post("http://example.com")
        .header("X-Custom", "value")
        .body("data".as_bytes().to_vec())
        .body_format(BodyFormat::Json)
        .timeout(Duration::from_secs(5))
        .retries(2);

    assert_eq!(builder.method.as_str(), "POST");
    assert_eq!(builder.headers.get("X-Custom").unwrap(), "value");
    assert_eq!(builder.body.as_ref().unwrap(), b"data");
    assert!(matches!(builder.body_format.unwrap(), BodyFormat::Json));
    assert_eq!(builder.timeout.unwrap(), Duration::from_secs(5));
    assert_eq!(builder.retries.unwrap(), 2);
}

/// 测试实际的 HTTP 请求(需要网络连接)
#[test]
#[ignore]
fn test_http_requests() {
    let client = default();

    // 测试 GET 请求
    let response = client
        .get("http://httpbin.org/get")
        .header("X-Test-Header", "test-value")
        .timeout(Duration::from_secs(5))
        .retries(2)
        .send()
        .unwrap();
    assert_eq!(response.status, 200);
    println!("GET Response: {}", String::from_utf8_lossy(&response.body));

    // 测试 POST 请求(JSON)
    let json_data = r#"{"key": "value"}"#;
    let response = client
        .post("http://httpbin.org/post")
        .body(json_data.as_bytes().to_vec())
        .body_format(BodyFormat::Json)
        .send()
        .unwrap();
    assert_eq!(response.status, 200);
    println!("POST Response: {}", String::from_utf8_lossy(&response.body));

    // 测试 PUT 请求
    let response = client
        .put("http://httpbin.org/put")
        .body(b"test data".to_vec())
        .body_format(BodyFormat::Text)
        .send()
        .unwrap();
    assert_eq!(response.status, 200);
    println!("PUT Response: {}", String::from_utf8_lossy(&response.body));

    // 测试 DELETE 请求
    let response = client.delete("http://httpbin.org/delete").send().unwrap();
    assert_eq!(response.status, 200);
    println!(
        "DELETE Response: {}",
        String::from_utf8_lossy(&response.body)
    );
}

#[test]
#[ignore]
fn test_redirects() {
    let client = default();
    let response = client
        .get("http://httpbin.org/redirect/1")
        .follow_redirects(true) // 显式启用重定向
        .send()
        .unwrap();

    assert_eq!(response.status, 200);
    let body = String::from_utf8_lossy(&response.body);
    assert!(body.contains("httpbin.org/get"));

    // 测试禁用重定向
    let response = client
        .get("http://httpbin.org/redirect/1")
        .follow_redirects(false) // 禁用重定向
        .send()
        .unwrap();

    assert_eq!(response.status, 302);
    assert!(response.header("Location").is_some());
}

#[test]
#[ignore]
fn test_save_to_file() {
    let client = default();
    let response = client.get("http://httpbin.org/get").send().unwrap();
    let file = response.save_to_file("test.json").unwrap();
    assert_eq!(file.exists(), true);
    crate::zfile::remove("test.json", false).unwrap();
}