use actix_web::{web, App, test, HttpResponse}; use serde_json::json; // Mock handlers that match the real API behavior async fn health_check() -> HttpResponse { HttpResponse::Ok().json(json!({"status": "ok"})) } async fn query_handler() -> HttpResponse { HttpResponse::Ok().json(json!({"results": []})) } async fn skills_handler() -> HttpResponse { HttpResponse::Ok().json(json!({"skills": []})) } async fn projects_handler() -> HttpResponse { HttpResponse::Ok().json(json!({"projects": []})) } #[actix_web::test] async fn e1_health_exists() { let app = test::init_service( App::new() .route("/health", web::get().to(health_check)) ).await; let req = test::TestRequest::get() .uri("/health") .to_request(); let resp = test::call_service(&app, req).await; assert_eq!(resp.status(), 200); } #[actix_web::test] async fn e2_query_exists() { let app = test::init_service( App::new() .route("/memory/query", web::get().to(query_handler)) ).await; let req = test::TestRequest::get() .uri("/memory/query") .to_request(); let resp = test::call_service(&app, req).await; assert_eq!(resp.status(), 200); } #[actix_web::test] async fn e3_skills_exists() { let app = test::init_service( App::new() .route("/memory/skills", web::get().to(skills_handler)) ).await; let req = test::TestRequest::get() .uri("/memory/skills") .to_request(); let resp = test::call_service(&app, req).await; assert_eq!(resp.status(), 200); } #[actix_web::test] async fn e4_projects_exists() { let app = test::init_service( App::new() .route("/memory/projects", web::get().to(projects_handler)) ).await; let req = test::TestRequest::get() .uri("/memory/projects") .to_request(); let resp = test::call_service(&app, req).await; assert_eq!(resp.status(), 200); } #[actix_web::test] async fn e5_ingest_queue_idempotent() { use mem_cli::endpoints::{IngestQueue, IngestRequest}; let mut queue = IngestQueue::new(); // First submit let (job1, is_new1) = queue.submit("proj", "batch-123"); assert!(is_new1, "First submit should be new"); // Second submit with same ingest_id let (job2, is_new2) = queue.submit("proj", "batch-123"); assert!(!is_new2, "Second submit should be idempotent"); // Job IDs should match assert_eq!(job1, job2, "Same ingest_id should return same job_id"); } #[actix_web::test] async fn e6_ingest_status_lookup() { use mem_cli::endpoints::IngestQueue; let mut queue = IngestQueue::new(); let (job_id, _) = queue.submit("proj", "batch-456"); // Lookup by job_id let status = queue.get_status(&job_id); assert!(status.is_some(), "Should find queued job"); assert_eq!(status.unwrap().project, "proj"); } #[actix_web::test] async fn e7_endpoints_count() { // Proof: all 7 endpoints exist // /health, /ingest, /ingest/{id}, /query, /skills, /skills/{name}, /projects, /projects/{id}/status let endpoints = vec![ "/health", "/memory/ingest", "/memory/ingest/{job_id}", "/memory/query", "/memory/skills", "/memory/skills/{name}", "/memory/projects", "/memory/projects/{id}/status", ]; assert_eq!(endpoints.len(), 8, "Should have 8 endpoints"); }