use extension_registry::{build_routes, AppState, Config}; use axum::body::Body; use axum::http::{Request, StatusCode}; use tower::ServiceExt; #[tokio::test] async fn test_health_check() { let config = Config { server: extension_registry::config::ServerConfig::default(), gitea: None, oci: None, cache: extension_registry::config::CacheConfig::default(), }; let state = AppState::new(config).expect("Failed to create app state"); let app = build_routes(state); let response = app .oneshot( Request::builder() .uri("/api/v1/health") .body(Body::empty()) .unwrap(), ) .await .unwrap(); assert_eq!(response.status(), StatusCode::OK); let body = hyper::body::to_bytes(response.into_body()).await.unwrap(); let health: serde_json::Value = serde_json::from_slice(&body).unwrap(); assert!(health.get("status").is_some()); assert!(health.get("version").is_some()); assert!(health.get("uptime").is_some()); } #[tokio::test] async fn test_list_extensions_empty() { let config = Config { server: extension_registry::config::ServerConfig::default(), gitea: None, oci: None, cache: extension_registry::config::CacheConfig::default(), }; let state = AppState::new(config).expect("Failed to create app state"); let app = build_routes(state); let response = app .oneshot( Request::builder() .uri("/api/v1/extensions") .body(Body::empty()) .unwrap(), ) .await .unwrap(); assert_eq!(response.status(), StatusCode::OK); let body = hyper::body::to_bytes(response.into_body()).await.unwrap(); let extensions: Vec = serde_json::from_slice(&body).unwrap(); // Should be empty when no backends configured assert_eq!(extensions.len(), 0); } #[tokio::test] async fn test_get_nonexistent_extension() { let config = Config { server: extension_registry::config::ServerConfig::default(), gitea: None, oci: None, cache: extension_registry::config::CacheConfig::default(), }; let state = AppState::new(config).expect("Failed to create app state"); let app = build_routes(state); let response = app .oneshot( Request::builder() .uri("/api/v1/extensions/provider/nonexistent") .body(Body::empty()) .unwrap(), ) .await .unwrap(); assert_eq!(response.status(), StatusCode::NOT_FOUND); } #[tokio::test] async fn test_metrics_endpoint() { let config = Config { server: extension_registry::config::ServerConfig::default(), gitea: None, oci: None, cache: extension_registry::config::CacheConfig::default(), }; let state = AppState::new(config).expect("Failed to create app state"); let app = build_routes(state); let response = app .oneshot( Request::builder() .uri("/api/v1/metrics") .body(Body::empty()) .unwrap(), ) .await .unwrap(); assert_eq!(response.status(), StatusCode::OK); let body = hyper::body::to_bytes(response.into_body()).await.unwrap(); let metrics = String::from_utf8(body.to_vec()).unwrap(); assert!(metrics.contains("http_requests_total")); } #[tokio::test] async fn test_cache_stats_endpoint() { let config = Config { server: extension_registry::config::ServerConfig::default(), gitea: None, oci: None, cache: extension_registry::config::CacheConfig::default(), }; let state = AppState::new(config).expect("Failed to create app state"); let app = build_routes(state); let response = app .oneshot( Request::builder() .uri("/api/v1/cache/stats") .body(Body::empty()) .unwrap(), ) .await .unwrap(); assert_eq!(response.status(), StatusCode::OK); let body = hyper::body::to_bytes(response.into_body()).await.unwrap(); let stats: serde_json::Value = serde_json::from_slice(&body).unwrap(); assert!(stats.get("list_entries").is_some()); assert!(stats.get("metadata_entries").is_some()); assert!(stats.get("total_entries").is_some()); } #[tokio::test] async fn test_invalid_extension_type() { let config = Config { server: extension_registry::config::ServerConfig::default(), gitea: None, oci: None, cache: extension_registry::config::CacheConfig::default(), }; let state = AppState::new(config).expect("Failed to create app state"); let app = build_routes(state); let response = app .oneshot( Request::builder() .uri("/api/v1/extensions/invalid_type/test") .body(Body::empty()) .unwrap(), ) .await .unwrap(); assert_eq!(response.status(), StatusCode::BAD_REQUEST); }