d15afda9b2
Wire best-effort Meilisearch index sync into the admin write paths (create/update/delete/set_fields/set_visibility). Adds SearchClient::sync_object (reindex if the object exists, remove if gone — one uniform path), an optional AppState.search client, and a reindex helper that logs failures via tracing without failing the committed write. Server gains MEILI_URL/MEILI_MASTER_KEY/MEILI_INDEX config; search stays disabled (no-op) when unset. reindex_all remains the recovery path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
74 lines
2.1 KiB
Rust
74 lines
2.1 KiB
Rust
use api::{AppState, build_app};
|
|
use axum::body::Body;
|
|
use axum::http::{Request, StatusCode};
|
|
use http_body_util::BodyExt;
|
|
use sqlx::PgPool;
|
|
use tower::ServiceExt; // for `oneshot`
|
|
|
|
fn state(pool: PgPool, app_name: &str) -> AppState {
|
|
AppState {
|
|
db: db::Db::from_pool(pool),
|
|
app_name: app_name.to_string(),
|
|
cookie_secure: false,
|
|
search: None,
|
|
}
|
|
}
|
|
|
|
#[sqlx::test]
|
|
async fn live_returns_ok(pool: PgPool) {
|
|
let app = build_app(state(pool, "Test"));
|
|
let resp = app
|
|
.oneshot(
|
|
Request::builder()
|
|
.uri("/health/live")
|
|
.body(Body::empty())
|
|
.unwrap(),
|
|
)
|
|
.await
|
|
.unwrap();
|
|
|
|
assert_eq!(resp.status(), StatusCode::OK);
|
|
let bytes = resp.into_body().collect().await.unwrap().to_bytes();
|
|
let json: serde_json::Value = serde_json::from_slice(&bytes).unwrap();
|
|
assert_eq!(json["status"], "ok");
|
|
}
|
|
|
|
#[sqlx::test]
|
|
async fn ready_reports_database_true(pool: PgPool) {
|
|
let app = build_app(state(pool, "Test"));
|
|
let resp = app
|
|
.oneshot(
|
|
Request::builder()
|
|
.uri("/health/ready")
|
|
.body(Body::empty())
|
|
.unwrap(),
|
|
)
|
|
.await
|
|
.unwrap();
|
|
|
|
assert_eq!(resp.status(), StatusCode::OK);
|
|
let bytes = resp.into_body().collect().await.unwrap().to_bytes();
|
|
let json: serde_json::Value = serde_json::from_slice(&bytes).unwrap();
|
|
assert_eq!(json["database"], true);
|
|
assert_eq!(json["status"], "ok");
|
|
}
|
|
|
|
#[sqlx::test]
|
|
async fn openapi_doc_uses_configured_title(pool: PgPool) {
|
|
let app = build_app(state(pool, "My Museum CMS"));
|
|
let resp = app
|
|
.oneshot(
|
|
Request::builder()
|
|
.uri("/api-docs/openapi.json")
|
|
.body(Body::empty())
|
|
.unwrap(),
|
|
)
|
|
.await
|
|
.unwrap();
|
|
|
|
assert_eq!(resp.status(), StatusCode::OK);
|
|
let bytes = resp.into_body().collect().await.unwrap().to_bytes();
|
|
let json: serde_json::Value = serde_json::from_slice(&bytes).unwrap();
|
|
assert_eq!(json["info"]["title"], "My Museum CMS");
|
|
}
|