use mesk::net::http_package::HTTPPackage; use mesk::pkgtoolkit::pkgtools::{Archs, Package}; use std::fs; mod shared; use shared::create_test_config; use std::collections::HashMap; use tempfile::TempDir; use tokio; use log::{debug, info}; #[cfg(test)] mod http_package_tests { use super::*; fn init_logger() { let _ = env_logger::builder().is_test(true).try_init(); } use std::time::Duration; use tokio::time::timeout; #[tokio::test] async fn test_http_fetch_index_success() -> Result<(), Box> { init_logger(); // Initialize logger info!("Starting test_http_fetch_index_success"); let mut server = mockito::Server::new_async().await; let index_toml_content = r#" [[packages]] name = "test-pkg" version = "1.0.0" arch = "X86_64" url = "/repo/test-pkg.mesk" descr = "A test package from index" license = "MIT" "#; let temp_dir = TempDir::new()?; let index_toml_path = temp_dir.path().join("INDEX.toml"); fs::write(&index_toml_path, index_toml_content)?; let archive_path = temp_dir.path().join("INDEX.tar.gz"); let file = fs::File::create(&archive_path)?; let gz_encoder = flate2::write::GzEncoder::new(file, flate2::Compression::default()); let mut tar_builder = tar::Builder::new(gz_encoder); tar_builder.append_path_with_name(&index_toml_path, "INDEX.toml")?; tar_builder.into_inner()?.finish()?; let mock_body = fs::read(&archive_path)?; let _mock = server .mock("GET", "/INDEX.tar.gz") .with_status(200) .with_header("content-length", &mock_body.len().to_string()) .with_body(mock_body) .create_async() .await; let temp_config_dir = TempDir::new()?; let config = create_test_config(temp_config_dir.path().to_str().unwrap()); let mut config_with_mock_url = config.clone(); config_with_mock_url.repo.repo_http_url = Some(server.url()); config_with_mock_url.repo.repo_url = server.url(); let mut http_pkg = HTTPPackage::new(config_with_mock_url); debug!("Attempting to fetch index via HTTP"); let result = timeout(Duration::from_secs(10), http_pkg.fetch_index_http()).await; match result { Ok(Ok(true)) => { info!("Checking if index_packages is populated"); assert!( http_pkg.index_packages.is_some(), "index_packages should not be None after successful fetch" ); let packages = http_pkg.index_packages.as_ref().unwrap(); info!("Checking number of packages in the index"); assert_eq!( packages.len(), 1, "There should be exactly one package in the index" ); info!("Checking if 'test-pkg' exists in the index"); assert!( packages.contains_key("test-pkg"), "The package 'test-pkg' should be present in the index" ); let pkg_info = packages.get("test-pkg").unwrap(); info!("Checking if package URL is correctly formed"); assert!( pkg_info.url.starts_with(&server.url()), "Package URL should be prefixed with the server URL" ); } Ok(Ok(false)) => panic!("fetch_index_http should indicate success"), Ok(Err(e)) => panic!("fetch_index_http failed: {:?}", e), Err(_) => panic!("fetch_index_http timed out"), } Ok(()) } #[tokio::test] async fn test_http_fetch_index_http_error() -> Result<(), Box> { init_logger(); info!("Starting test_http_fetch_index_http_error"); let mut server = mockito::Server::new_async().await; let _mock = server .mock("GET", "/INDEX.tar.gz") .with_status(404) .create_async() .await; let temp_config_dir = TempDir::new()?; let config = create_test_config(temp_config_dir.path().to_str().unwrap()); let mut config_with_mock_url = config.clone(); config_with_mock_url.repo.repo_http_url = Some(server.url()); config_with_mock_url.repo.repo_url = server.url(); let mut http_pkg = HTTPPackage::new(config_with_mock_url); debug!("Attempting to fetch index with expected 404 error"); let result = http_pkg.fetch_index_http().await; info!("Checking if fetch_index_http resulted in an error as expected"); assert!( result.is_err(), "fetch_index_http should return an Err for a 404 response" ); let err_msg = result.unwrap_err().to_string(); info!("Verifying error message contains 'HTTP Error: 404'"); assert!( err_msg.contains("HTTP Error: 404"), "Error message should contain 'HTTP Error: 404', got: {}", err_msg ); Ok(()) } #[tokio::test] async fn test_http_fetch_package_info_success() -> Result<(), Box> { init_logger(); info!("Starting test_http_fetch_package_info_success"); let temp_config_dir = TempDir::new()?; let config = create_test_config(temp_config_dir.path().to_str().unwrap()); let mut http_pkg = HTTPPackage::new(config); let mut packages_map = HashMap::new(); let pkg = Package { name: "test-pkg".to_string(), version: "1.0.0".to_string(), arch: Archs::X86_64, descr: Some("Test".to_string()), license: Some("MIT".to_string()), url: "http://example.com/repo/test-pkg.mesk".to_string(), }; packages_map.insert("test-pkg".to_string(), pkg); http_pkg.index_packages = Some(packages_map); debug!("Fetching package info for 'test-pkg'"); let pkg_info = http_pkg.fetch_package_info("test-pkg"); info!("Checking if fetch_package_info returned successfully"); assert!( pkg_info.is_ok(), "fetch_package_info should return Ok for an existing package" ); info!("Checking the retrieved package name"); assert_eq!( pkg_info.unwrap().name, "test-pkg", "Retrieved package name should be 'test-pkg'" ); Ok(()) } #[tokio::test] async fn test_http_fetch_package_info_not_found() -> Result<(), Box> { init_logger(); info!("Starting test_http_fetch_package_info_not_found"); let temp_config_dir = TempDir::new()?; let config = create_test_config(temp_config_dir.path().to_str().unwrap()); let http_pkg = HTTPPackage::new(config.clone()); debug!("Attempting to fetch package info before index load"); let result = http_pkg.fetch_package_info("nonexistent-pkg"); info!("Checking if fetch_package_info failed due to unloaded index"); assert!( result.is_err(), "fetch_package_info should fail when index is not loaded" ); let err_msg = result.unwrap_err().to_string(); info!("Verifying error message contains 'Index not loaded'"); assert!( err_msg.contains("Index not loaded"), "Error message should contain 'Index not loaded', got: {}", err_msg ); let mut http_pkg_empty_index = HTTPPackage::new(config); http_pkg_empty_index.index_packages = Some(HashMap::new()); debug!("Attempting to fetch package info from an empty index"); let result_empty = http_pkg_empty_index.fetch_package_info("nonexistent-pkg"); info!("Checking if fetch_package_info failed due to missing package in index"); assert!( result_empty.is_err(), "fetch_package_info should fail for a package not in the index" ); let err_msg_empty = result_empty.unwrap_err().to_string(); info!("Verifying error message contains 'not found in index'"); assert!( err_msg_empty.contains("not found in index"), "Error message should contain 'not found in index', got: {}", err_msg_empty ); Ok(()) } }