use netspeed_cli::common;
use netspeed_cli::download::{build_test_url, download_test, extract_base_url};
use netspeed_cli::progress::SpeedProgress;
use netspeed_cli::servers::{ping_test, select_best_server};
use netspeed_cli::types::Server;
use netspeed_cli::upload::upload_test;
use reqwest::Client;
use std::sync::Arc;
use wiremock::matchers::{method, path_regex};
use wiremock::{Mock, MockServer, ResponseTemplate};
async fn create_mock_speedtest_server() -> MockServer {
let mock = MockServer::start().await;
Mock::given(method("GET"))
.and(path_regex(".*latency\\.txt.*"))
.respond_with(ResponseTemplate::new(200).set_body_string("OK"))
.mount(&mock)
.await;
Mock::given(method("GET"))
.and(path_regex(".*random.*"))
.respond_with(ResponseTemplate::new(200).set_body_bytes(vec![0u8; 1024 * 256]))
.mount(&mock)
.await;
Mock::given(method("POST"))
.and(path_regex(".*upload\\.php.*"))
.respond_with(ResponseTemplate::new(200).set_body_string("OK"))
.mount(&mock)
.await;
mock
}
#[tokio::test]
async fn test_e2e_full_speedtest_flow() {
let mock = create_mock_speedtest_server().await;
let mock_url = mock.uri();
let server = Server {
id: "9999".to_string(),
url: format!("{mock_url}/upload.php"),
name: "E2E Test Server".to_string(),
sponsor: "Test ISP".to_string(),
country: "US".to_string(),
lat: 40.0,
lon: -74.0,
distance: 50.0,
};
let servers = vec![server.clone()];
let selected = select_best_server(&servers).expect("Should select server");
assert_eq!(selected.id, "9999");
let client = Client::builder()
.timeout(std::time::Duration::from_secs(10))
.build()
.expect("Should create client");
let ping_result = ping_test(&client, &selected)
.await
.expect("Ping should succeed");
let (avg_latency, _jitter, _packet_loss, _samples) = ping_result;
assert!(avg_latency > 0.0, "Latency should be positive");
assert!(avg_latency < 1000.0, "Local latency should be reasonable");
let progress = Arc::new(SpeedProgress::with_target(
"Download",
indicatif::ProgressDrawTarget::hidden(),
));
let dl_result = download_test(&client, &selected, true, progress.clone())
.await
.expect("Download should succeed");
let (avg_dl, peak_dl, total_dl_bytes, dl_samples) = dl_result;
assert!(avg_dl > 0.0, "Download speed should be positive");
assert!(total_dl_bytes > 0, "Should have downloaded some bytes");
assert!(!dl_samples.is_empty(), "Should have speed samples");
let _ = peak_dl;
let progress = Arc::new(SpeedProgress::with_target(
"Upload",
indicatif::ProgressDrawTarget::hidden(),
));
let ul_result = upload_test(&client, &selected, true, progress.clone())
.await
.expect("Upload should succeed");
let (avg_ul, peak_ul, total_ul_bytes, ul_samples) = ul_result;
assert!(avg_ul > 0.0, "Upload speed should be positive");
assert!(total_ul_bytes > 0, "Should have uploaded some bytes");
assert!(!ul_samples.is_empty(), "Should have speed samples");
let _ = peak_ul;
}
#[tokio::test]
async fn test_e2e_download_only() {
let mock = create_mock_speedtest_server().await;
let server = Server {
id: "1".to_string(),
url: format!("{}/upload.php", mock.uri()),
name: "Test".to_string(),
sponsor: "Test".to_string(),
country: "US".to_string(),
lat: 0.0,
lon: 0.0,
distance: 0.0,
};
let client = Client::builder()
.timeout(std::time::Duration::from_secs(10))
.build()
.expect("Should create client");
let progress = Arc::new(SpeedProgress::with_target(
"Download",
indicatif::ProgressDrawTarget::hidden(),
));
let result = download_test(&client, &server, true, progress).await;
assert!(result.is_ok());
let (avg, _peak, bytes, samples) = result.unwrap();
assert!(avg > 0.0);
assert!(bytes > 0);
assert!(!samples.is_empty());
}
#[tokio::test]
async fn test_e2e_upload_only() {
let mock = create_mock_speedtest_server().await;
let server = Server {
id: "1".to_string(),
url: format!("{}/upload.php", mock.uri()),
name: "Test".to_string(),
sponsor: "Test".to_string(),
country: "US".to_string(),
lat: 0.0,
lon: 0.0,
distance: 0.0,
};
let client = Client::builder()
.timeout(std::time::Duration::from_secs(10))
.build()
.expect("Should create client");
let progress = Arc::new(SpeedProgress::with_target(
"Upload",
indicatif::ProgressDrawTarget::hidden(),
));
let result = upload_test(&client, &server, true, progress).await;
assert!(result.is_ok());
let (avg, _peak, bytes, samples) = result.unwrap();
assert!(avg > 0.0);
assert!(bytes > 0);
assert!(!samples.is_empty());
}
#[test]
fn test_url_construction_e2e() {
let server_url = "http://localhost:8080/upload.php";
let base = extract_base_url(server_url);
assert_eq!(base, "http://localhost:8080");
let url0 = build_test_url(server_url, 0);
assert!(url0.ends_with("/random0.txt") || url0.starts_with("http://localhost:8080"));
}
#[test]
fn test_bandwidth_calculation_e2e() {
let bytes = 1_000_000u64;
let secs = 1.0f64;
let bps = common::calculate_bandwidth(bytes, secs);
assert_eq!(bps, 8_000_000.0); }