diff --git a/crates/db/tests/audit_immutability.rs b/crates/db/tests/audit_immutability.rs index 3cf66ef..abd973f 100644 --- a/crates/db/tests/audit_immutability.rs +++ b/crates/db/tests/audit_immutability.rs @@ -29,23 +29,37 @@ async fn update_delete_truncate_are_rejected(pool: PgPool) { // Each failing statement poisons its connection (Postgres enters aborted-transaction // state). Acquire a fresh connection per statement so later assertions are independent. - let updated = sqlx::query("UPDATE audit_log SET action = 'deleted'") + let update_err = sqlx::query("UPDATE audit_log SET action = 'deleted'") .execute(db.pool()) - .await; - - assert!(updated.is_err(), "UPDATE must be rejected by the trigger"); - - let deleted = sqlx::query("DELETE FROM audit_log") - .execute(db.pool()) - .await; - - assert!(deleted.is_err(), "DELETE must be rejected by the trigger"); - - let truncated = sqlx::query("TRUNCATE audit_log").execute(db.pool()).await; + .await + .unwrap_err() + .to_string(); assert!( - truncated.is_err(), - "TRUNCATE must be rejected by the trigger" + update_err.contains("audit_log is append-only"), + "UPDATE must be rejected by the trigger, got: {update_err}" + ); + + let delete_err = sqlx::query("DELETE FROM audit_log") + .execute(db.pool()) + .await + .unwrap_err() + .to_string(); + + assert!( + delete_err.contains("audit_log is append-only"), + "DELETE must be rejected by the trigger, got: {delete_err}" + ); + + let truncate_err = sqlx::query("TRUNCATE audit_log") + .execute(db.pool()) + .await + .unwrap_err() + .to_string(); + + assert!( + truncate_err.contains("audit_log is append-only"), + "TRUNCATE must be rejected by the trigger, got: {truncate_err}" ); assert_eq!(count(db.pool()).await, 1, "the row is still there");