fix: reject a malformed reenqueue body instead of running the full scope

Option<Json<T>> collapses a malformed body to None, so a bad reenqueue body
silently ran the default full "All" scope (audit). Parse raw bytes: empty =
default All, malformed = 422. Tested both.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-07-13 21:37:16 +02:00
parent 4f085f228a
commit cc8ae2566f
6 changed files with 75 additions and 5 deletions

View File

@@ -189,6 +189,51 @@ async fn reenqueue_returns_503_when_analysis_disabled(pool: PgPool) {
assert_eq!(resp.status(), StatusCode::SERVICE_UNAVAILABLE);
}
#[sqlx::test(migrations = "./migrations")]
async fn reenqueue_rejects_a_malformed_body(pool: PgPool) {
// A present-but-malformed JSON body must be a 422 — NOT silently coerced to
// an absent body, which would run the default full "All" scope the caller
// never asked for and enqueue jobs across the whole library.
let h = common::harness_with_analysis(pool.clone());
let cookie = seed_admin(&pool, &h.app).await;
seed_pages(&pool, 2).await;
let resp = h
.app
.clone()
.oneshot(common::post_raw_with_cookie(
"/api/v1/admin/analysis/reenqueue",
"{ not valid json",
&cookie,
))
.await
.unwrap();
assert_eq!(resp.status(), StatusCode::UNPROCESSABLE_ENTITY);
assert_eq!(analyze_job_count(&pool).await, 0, "a rejected body enqueues nothing");
}
#[sqlx::test(migrations = "./migrations")]
async fn reenqueue_treats_empty_body_as_default_all_scope(pool: PgPool) {
// An absent/empty body is still valid: it means the default "All" scope.
let h = common::harness_with_analysis(pool.clone());
let cookie = seed_admin(&pool, &h.app).await;
seed_pages(&pool, 2).await;
let resp = h
.app
.clone()
.oneshot(common::post_raw_with_cookie(
"/api/v1/admin/analysis/reenqueue",
"",
&cookie,
))
.await
.unwrap();
assert_eq!(resp.status(), StatusCode::OK);
let body = common::body_json(resp).await;
assert_eq!(body["enqueued"], 2, "empty body backfills the whole library");
}
#[sqlx::test(migrations = "./migrations")]
async fn reenqueue_backfills_existing_pages(pool: PgPool) {
let h = common::harness_with_analysis(pool.clone());