mod common; use axum::http::StatusCode; use serde_json::json; use sqlx::PgPool; use tower::ServiceExt; #[sqlx::test(migrations = "./migrations")] async fn list_is_empty_initially(pool: PgPool) { let h = common::harness(pool); let resp = h.app.oneshot(common::get("/api/mangas")).await.unwrap(); assert_eq!(resp.status(), StatusCode::OK); assert_eq!(common::body_json(resp).await, json!([])); } #[sqlx::test(migrations = "./migrations")] async fn create_then_list_roundtrip(pool: PgPool) { let h = common::harness(pool); let created = h.app.clone().oneshot(common::post_json( "/api/mangas", json!({ "title": "Berserk", "author": "Kentaro Miura", "description": null }), )).await.unwrap(); assert_eq!(created.status(), StatusCode::OK); let body = common::body_json(created).await; assert_eq!(body["title"], "Berserk"); assert_eq!(body["author"], "Kentaro Miura"); assert!(body["id"].as_str().is_some()); let listed = h.app.oneshot(common::get("/api/mangas")).await.unwrap(); let listed_body = common::body_json(listed).await; assert_eq!(listed_body.as_array().unwrap().len(), 1); assert_eq!(listed_body[0]["title"], "Berserk"); } #[sqlx::test(migrations = "./migrations")] async fn search_filters_by_title_and_author(pool: PgPool) { let h = common::harness(pool); for (title, author) in [ ("One Piece", "Eiichiro Oda"), ("Berserk", "Kentaro Miura"), ("Vinland Saga", "Makoto Yukimura"), ] { let _ = h.app.clone().oneshot(common::post_json( "/api/mangas", json!({ "title": title, "author": author }), )).await.unwrap(); } let resp = h.app.clone().oneshot(common::get("/api/mangas?search=miura")).await.unwrap(); let body = common::body_json(resp).await; let titles: Vec<&str> = body.as_array().unwrap().iter().map(|m| m["title"].as_str().unwrap()).collect(); assert_eq!(titles, vec!["Berserk"]); let resp = h.app.oneshot(common::get("/api/mangas?search=saga")).await.unwrap(); let body = common::body_json(resp).await; let titles: Vec<&str> = body.as_array().unwrap().iter().map(|m| m["title"].as_str().unwrap()).collect(); assert_eq!(titles, vec!["Vinland Saga"]); } #[sqlx::test(migrations = "./migrations")] async fn create_rejects_empty_title(pool: PgPool) { let h = common::harness(pool); let resp = h.app.oneshot(common::post_json( "/api/mangas", json!({ "title": " ", "author": null }), )).await.unwrap(); assert_eq!(resp.status(), StatusCode::BAD_REQUEST); } #[sqlx::test(migrations = "./migrations")] async fn get_unknown_id_is_404(pool: PgPool) { let h = common::harness(pool); let resp = h.app.oneshot(common::get("/api/mangas/00000000-0000-0000-0000-000000000000")).await.unwrap(); assert_eq!(resp.status(), StatusCode::NOT_FOUND); }