diff --git a/crates/db/src/catalog.rs b/crates/db/src/catalog.rs index f8a6efe..392e0ad 100644 --- a/crates/db/src/catalog.rs +++ b/crates/db/src/catalog.rs @@ -234,15 +234,15 @@ pub async fn delete_object( actor: AuditActor, id: ObjectId, ) -> Result { - if object_by_id(&mut *conn, id).await?.is_none() { - return Ok(false); - } - - sqlx::query("DELETE FROM object WHERE id = $1") + let result = sqlx::query("DELETE FROM object WHERE id = $1") .bind(id.to_uuid()) .execute(&mut *conn) .await?; + if result.rows_affected() == 0 { + return Ok(false); + } + audit::record( &mut *conn, &NewAuditEvent { diff --git a/crates/db/tests/catalog_mutations.rs b/crates/db/tests/catalog_mutations.rs index 59f8a10..ceb9498 100644 --- a/crates/db/tests/catalog_mutations.rs +++ b/crates/db/tests/catalog_mutations.rs @@ -81,17 +81,70 @@ async fn no_op_update_records_no_audit(pool: PgPool) { #[sqlx::test] async fn update_missing_returns_false(pool: PgPool) { let db = Db::from_pool(pool); + let missing = domain::ObjectId::new(); + let mut tx = db.pool().begin().await.unwrap(); - let updated = catalog::update_object( - &mut tx, - AuditActor::System, - domain::ObjectId::new(), - &base(), - ) - .await - .unwrap(); + let updated = catalog::update_object(&mut tx, AuditActor::System, missing, &base()) + .await + .unwrap(); tx.commit().await.unwrap(); assert!(!updated); + + let history = audit::history_for(db.pool(), "object", missing.to_uuid()) + .await + .unwrap(); + assert!( + history.is_empty(), + "updating a missing object records no audit" + ); +} + +#[sqlx::test] +async fn delete_missing_returns_false(pool: PgPool) { + let db = Db::from_pool(pool); + let mut tx = db.pool().begin().await.unwrap(); + let deleted = catalog::delete_object(&mut tx, AuditActor::System, domain::ObjectId::new()) + .await + .unwrap(); + tx.commit().await.unwrap(); + assert!(!deleted); +} + +#[sqlx::test] +async fn clearing_a_field_is_audited(pool: PgPool) { + let db = Db::from_pool(pool); + let mut tx = db.pool().begin().await.unwrap(); + let id = catalog::create_object(&mut tx, AuditActor::System, &base()) + .await + .unwrap(); + tx.commit().await.unwrap(); + + let mut cleared = base(); + cleared.current_location = None; + + let mut tx = db.pool().begin().await.unwrap(); + catalog::update_object(&mut tx, AuditActor::System, id, &cleared) + .await + .unwrap(); + tx.commit().await.unwrap(); + + let history = audit::history_for(db.pool(), "object", id.to_uuid()) + .await + .unwrap(); + let update = history.last().unwrap(); + let loc = update + .changes + .iter() + .find(|c| c.field == "current_location") + .expect("location change recorded"); + assert!( + loc.before.is_some(), + "cleared field should have before = Some" + ); + assert!( + loc.after.is_none(), + "cleared field should have after = None" + ); } #[sqlx::test]