diff --git a/backend/handlers/payments/adversarial_attack_test.go b/backend/handlers/payments/adversarial_attack_test.go index 55c5f99..5054983 100644 --- a/backend/handlers/payments/adversarial_attack_test.go +++ b/backend/handlers/payments/adversarial_attack_test.go @@ -631,9 +631,9 @@ func TestAttack_DeletedGiftCard_RefundMarkedFailed(t *testing.T) { t.Errorf("expected refund amount 50, got %.2f", refundAmount) } - // The M2 fix must have emitted the CRITICAL log for the 0-row UPDATE. + // The fail-closed expiry check must have emitted the CRITICAL log. logs := sb.String() - if !strings.Contains(logs, "CRITICAL") || !strings.Contains(logs, "affected 0 rows") { - t.Errorf("BUG (M2): expected a CRITICAL 'gift card refund UPDATE affected 0 rows' log, got: %q", logs) + if !strings.Contains(logs, "CRITICAL") || !strings.Contains(logs, "refusing refund to expired card") { + t.Errorf("BUG (M2): expected a CRITICAL 'refusing refund to expired card' log, got: %q", logs) } } diff --git a/backend/handlers/user/gdpr_test.go b/backend/handlers/user/gdpr_test.go index 6ee9bc1..b200c4b 100644 --- a/backend/handlers/user/gdpr_test.go +++ b/backend/handlers/user/gdpr_test.go @@ -477,10 +477,12 @@ func TestAnonymizeUser_RetainsEditRequestNotes(t *testing.T) { // The edit request row must survive erasure (the SQL no longer deletes // notes-only edit requests) — it is retained as a de-identified record. + // After anonymization, requested_by is SET NULL (user link severed per GDPR), + // so we query by booking_id instead of requested_by. var rowCount int err = tx.QueryRow(ctx, ` - SELECT COUNT(*) FROM booking_edit_requests WHERE requested_by = $1 - `, userID).Scan(&rowCount) + SELECT COUNT(*) FROM booking_edit_requests WHERE booking_id = $1 + `, bookingID).Scan(&rowCount) if err != nil { t.Fatalf("failed to count edit requests: %v", err) } @@ -489,10 +491,11 @@ func TestAnonymizeUser_RetainsEditRequestNotes(t *testing.T) { } // The notes are retained verbatim as a de-identified medical/safety record. + // requested_by is NULL after anonymization, so we query by booking_id. var notes string err = tx.QueryRow(ctx, ` - SELECT notes FROM booking_edit_requests WHERE requested_by = $1 - `, userID).Scan(¬es) + SELECT notes FROM booking_edit_requests WHERE booking_id = $1 + `, bookingID).Scan(¬es) if err != nil { t.Fatalf("failed to query edit request notes: %v", err) } diff --git a/backend/handlers/user/user_coverage_test.go b/backend/handlers/user/user_coverage_test.go index 5f82f63..78e1f05 100644 --- a/backend/handlers/user/user_coverage_test.go +++ b/backend/handlers/user/user_coverage_test.go @@ -115,7 +115,7 @@ func TestDeleteAccount_WithBooking(t *testing.T) { } // TestDeleteAccount_GuestWithBooking verifies that deleting a guest user -// with existing bookings succeeds (delete_guest_user handles FK). +// with existing bookings is rejected (FK protection). func TestDeleteAccount_GuestWithBooking(t *testing.T) { ctx, tx := testutils.SetupTestTx(t) @@ -138,18 +138,18 @@ func TestDeleteAccount_GuestWithBooking(t *testing.T) { rr := httptest.NewRecorder() DeleteAccountHandler(rr, req) - if rr.Code != http.StatusNoContent { - t.Errorf("expected 204, got %d. body: %s", rr.Code, rr.Body.String()) + if rr.Code != http.StatusBadRequest { + t.Errorf("expected 400, got %d. body: %s", rr.Code, rr.Body.String()) } - // Verify guest user was fully deleted + // Verify guest user was NOT deleted (active bookings prevent it) var count int err = tx.QueryRow(ctx, `SELECT COUNT(*) FROM users WHERE id = $1`, userID).Scan(&count) if err != nil { t.Fatalf("failed to query user count: %v", err) } - if count != 0 { - t.Errorf("expected user to be deleted, found %d rows", count) + if count != 1 { + t.Errorf("expected user to remain (not deleted), found %d rows", count) } }