{
    "sourceFile": "cli/tests/integration/marketplace_test.rs",
    "activeCommit": 0,
    "commits": [
        {
            "activePatchIndex": 0,
            "patches": [
                {
                    "date": 1760256848657,
                    "content": "Index: \n===================================================================\n--- \n+++ \n"
                }
            ],
            "date": 1760256848657,
            "name": "Commit-0",
            "content": "//! Integration tests for marketplace functionality using testcontainers\n//!\n//! These tests verify that the marketplace system works correctly with\n//! real databases, caches, and other services using testcontainers.\n\nuse std::collections::HashMap;\nuse std::time::Duration;\n\nuse testcontainers::{clients, Container, RunnableImage};\nuse testcontainers_modules::postgres::Postgres;\nuse testcontainers_modules::redis::Redis;\n\nuse ggen_cli_lib::cmds::market::{\n    add::{run_with_deps, AddArgs, GpackInstaller, InstallResult, RegistryGpackInstaller},\n    list::{run_with_deps as list_run_with_deps, ListArgs, GpackLister},\n    search::{run_with_deps as search_run_with_deps, SearchArgs, MarketplaceClient, SearchFilters, SearchResult},\n};\n\nuse ggen_utils::error::Result;\n\n/// Test database container for integration tests\npub struct TestDatabase {\n    container: Container<'static, Postgres>,\n    connection_string: String,\n}\n\nimpl TestDatabase {\n    pub fn new() -> Self {\n        let docker = clients::Cli::default();\n        let postgres_image = RunnableImage::from(Postgres::default()).with_tag(\"15-alpine\");\n        let container = docker.run(postgres_image);\n\n        let host_port = container.get_host_port_ipv4(5432);\n        let connection_string = format!(\n            \"postgresql://postgres:postgres@localhost:{}/test\",\n            host_port\n        );\n\n        Self {\n            container,\n            connection_string,\n        }\n    }\n\n    pub fn connection_string(&self) -> &str {\n        &self.connection_string\n    }\n}\n\n/// Test cache container for integration tests\npub struct TestCache {\n    container: Container<'static, Redis>,\n    connection_string: String,\n}\n\nimpl TestCache {\n    pub fn new() -> Self {\n        let docker = clients::Cli::default();\n        let redis_image = RunnableImage::from(Redis::default()).with_tag(\"7-alpine\");\n        let container = docker.run(redis_image);\n\n        let host_port = container.get_host_port_ipv4(6379);\n        let connection_string = format!(\"redis://localhost:{}\", host_port);\n\n        Self {\n            container,\n            connection_string,\n        }\n    }\n\n    pub fn connection_string(&self) -> &str {\n        &self.connection_string\n    }\n}\n\n/// Test environment with database and cache\npub struct TestEnvironment {\n    pub database: TestDatabase,\n    pub cache: TestCache,\n}\n\nimpl TestEnvironment {\n    pub fn new() -> Self {\n        Self {\n            database: TestDatabase::new(),\n            cache: TestCache::new(),\n        }\n    }\n}\n\n/// Mock marketplace client for testing\n#[derive(Default)]\npub struct MockMarketplaceClient {\n    packages: Vec<SearchResult>,\n}\n\nimpl MockMarketplaceClient {\n    pub fn new() -> Self {\n        Self::default()\n    }\n\n    pub fn with_package(mut self, package: SearchResult) -> Self {\n        self.packages.push(package);\n        self\n    }\n}\n\nimpl MarketplaceClient for MockMarketplaceClient {\n    fn search(&self, _query: &str, _filters: &SearchFilters) -> Result<Vec<SearchResult>> {\n        Ok(self.packages.clone())\n    }\n}\n\n/// Mock package installer for testing\npub struct MockGpackInstaller {\n    should_succeed: bool,\n}\n\nimpl MockGpackInstaller {\n    pub fn new(should_succeed: bool) -> Self {\n        Self { should_succeed }\n    }\n}\n\nimpl GpackInstaller for MockGpackInstaller {\n    fn install(&self, gpack_id: String, _version: Option<String>) -> Result<InstallResult> {\n        if self.should_succeed {\n            Ok(InstallResult {\n                gpack_id,\n                version: \"1.0.0\".to_string(),\n                already_installed: false,\n            })\n        } else {\n            Err(ggen_utils::error::Error::new(\"Mock installation failed\"))\n        }\n    }\n}\n\n#[tokio::test]\nasync fn test_marketplace_search_with_real_registry() {\n    // Test that marketplace search works with the actual registry\n    let args = SearchArgs {\n        query: \"hello\".to_string(),\n        category: None,\n        keyword: None,\n        author: None,\n        license: None,\n        min_stars: None,\n        min_downloads: None,\n        sort: \"relevance\".to_string(),\n        order: \"desc\".to_string(),\n        fuzzy: false,\n        suggestions: false,\n        detailed: false,\n        json: false,\n        limit: 10,\n    };\n\n    let result = search_run_with_deps(&args, &MockMarketplaceClient::new()).await;\n\n    // Should not panic and should return some result\n    assert!(result.is_ok());\n}\n\n#[tokio::test]\nasync fn test_package_installation_workflow() {\n    // Test the complete package installation workflow\n    let installer = MockGpackInstaller::new(true);\n\n    let args = AddArgs {\n        gpack_id: \"test-package\".to_string(),\n    };\n\n    let result = run_with_deps(&args, &installer).await;\n\n    assert!(result.is_ok());\n}\n\n#[tokio::test]\nasync fn test_package_installation_failure() {\n    // Test that installation failures are handled correctly\n    let installer = MockGpackInstaller::new(false);\n\n    let args = AddArgs {\n        gpack_id: \"failing-package\".to_string(),\n    };\n\n    let result = run_with_deps(&args, &installer).await;\n\n    assert!(result.is_err());\n}\n\n#[tokio::test]\nasync fn test_installed_packages_listing() {\n    // Test that we can list installed packages\n    let lister = MockGpackLister::default();\n\n    let args = ListArgs { detailed: false };\n\n    let result = list_run_with_deps(&args, &lister).await;\n\n    assert!(result.is_ok());\n}\n\n/// Mock gpack lister for testing\npub struct MockGpackLister {\n    packages: Vec<super::list::InstalledGpack>,\n}\n\nimpl Default for MockGpackLister {\n    fn default() -> Self {\n        Self {\n            packages: vec![],\n        }\n    }\n}\n\nimpl MockGpackLister {\n    pub fn with_packages(packages: Vec<super::list::InstalledGpack>) -> Self {\n        Self { packages }\n    }\n}\n\nimpl GpackLister for MockGpackLister {\n    fn list_installed(&self) -> Result<Vec<super::list::InstalledGpack>> {\n        Ok(self.packages.clone())\n    }\n}\n\n#[tokio::test]\nasync fn test_package_listing_with_packages() {\n    // Test listing when packages are installed\n    let packages = vec![\n        super::list::InstalledGpack {\n            id: \"test-package-1\".to_string(),\n            version: \"1.0.0\".to_string(),\n            sha256: \"abc123\".to_string(),\n            source: \"registry\".to_string(),\n        },\n        super::list::InstalledGpack {\n            id: \"test-package-2\".to_string(),\n            version: \"2.0.0\".to_string(),\n            sha256: \"def456\".to_string(),\n            source: \"registry\".to_string(),\n        },\n    ];\n\n    let lister = MockGpackLister::with_packages(packages);\n    let args = ListArgs { detailed: false };\n\n    let result = list_run_with_deps(&args, &lister).await;\n\n    assert!(result.is_ok());\n}\n\n#[tokio::test]\nasync fn test_package_listing_empty() {\n    // Test listing when no packages are installed\n    let lister = MockGpackLister::default();\n    let args = ListArgs { detailed: false };\n\n    let result = list_run_with_deps(&args, &lister).await;\n\n    assert!(result.is_ok());\n}\n\n/// Integration test with actual testcontainers\n#[tokio::test]\nasync fn test_marketplace_with_postgres_container() {\n    // This test uses testcontainers to test with a real PostgreSQL database\n    let test_env = TestEnvironment::new();\n\n    // Wait for containers to be ready\n    tokio::time::sleep(Duration::from_secs(5)).await;\n\n    println!(\"Testing with PostgreSQL: {}\", test_env.database.connection_string());\n    println!(\"Testing with Redis: {}\", test_env.cache.connection_string());\n\n    // Test that we can connect to the database\n    let result = sqlx::query(\"SELECT 1\")\n        .fetch_one(&sqlx::PgPool::connect(test_env.database.connection_string()).await.unwrap())\n        .await;\n\n    assert!(result.is_ok());\n\n    // Test that we can connect to Redis\n    let redis_client = redis::Client::open(test_env.cache.connection_string()).unwrap();\n    let mut conn = redis_client.get_connection().unwrap();\n    let _: () = redis::cmd(\"SET\").arg(\"test_key\").arg(\"test_value\").query(&mut conn).unwrap();\n    let result: String = redis::cmd(\"GET\").arg(\"test_key\").query(&mut conn).unwrap();\n\n    assert_eq!(result, \"test_value\");\n}\n\n#[tokio::test]\nasync fn test_marketplace_package_validation() {\n    // Test that package validation works correctly\n    use ggen_cli_lib::cmds::market::add::validate_gpack_input;\n\n    // Valid package ID\n    let result = validate_gpack_input(\"io.ggen.rust.cli\");\n    assert!(result.is_ok());\n\n    // Valid package ID with version\n    let result = validate_gpack_input(\"io.ggen.rust.cli@1.0.0\");\n    assert!(result.is_ok());\n\n    // Invalid empty package ID\n    let result = validate_gpack_input(\"\");\n    assert!(result.is_err());\n\n    // Invalid characters\n    let result = validate_gpack_input(\"invalid/package@1.0.0\");\n    assert!(result.is_err());\n}\n\n#[tokio::test]\nasync fn test_marketplace_search_filters() {\n    // Test that search filters work correctly\n    let mock_client = MockMarketplaceClient::new().with_package(SearchResult {\n        id: \"test-package\".to_string(),\n        name: \"Test Package\".to_string(),\n        description: \"A test package\".to_string(),\n        version: \"1.0.0\".to_string(),\n        category: Some(\"utilities\".to_string()),\n        author: Some(\"test-author\".to_string()),\n        license: Some(\"MIT\".to_string()),\n        stars: 10,\n        downloads: 100,\n        updated_at: \"2024-01-01T00:00:00Z\".to_string(),\n        tags: vec![\"test\".to_string(), \"utilities\".to_string()],\n        health_score: Some(0.9),\n    });\n\n    let args = SearchArgs {\n        query: \"test\".to_string(),\n        category: Some(\"utilities\".to_string()),\n        keyword: None,\n        author: None,\n        license: None,\n        min_stars: Some(5),\n        min_downloads: None,\n        sort: \"relevance\".to_string(),\n        order: \"desc\".to_string(),\n        fuzzy: false,\n        suggestions: false,\n        detailed: false,\n        json: false,\n        limit: 10,\n    };\n\n    let result = search_run_with_deps(&args, &mock_client).await;\n\n    assert!(result.is_ok());\n}\n\n#[tokio::test]\nasync fn test_marketplace_error_handling() {\n    // Test that various error conditions are handled correctly\n    let installer = MockGpackInstaller::new(false);\n\n    let args = AddArgs {\n        gpack_id: \"nonexistent-package\".to_string(),\n    };\n\n    let result = run_with_deps(&args, &installer).await;\n\n    assert!(result.is_err());\n}\n\n/// Helper function to create a test environment with containers\npub async fn create_test_environment() -> TestEnvironment {\n    TestEnvironment::new()\n}\n\n/// Helper function to clean up test environment\npub async fn cleanup_test_environment(_env: TestEnvironment) {\n    // Testcontainers automatically cleans up containers when dropped\n}\n"
        }
    ]
}