refactor: remove auto deposit penalty on no-shows, add comprehensive tests

- Remove automatic deposits_required=3 on no-shows, give admin flexibility
- Add tests for no-show deposit logic (forgiven, over 24h, under 24h)
- Add tests for reservation cleanup TTL (admin walk-in/call-in 15min)
- Add tests for EXIF GPS data stripping in portfolio images
- Add tests for contact info endpoint
- Add tests for guest account anonymization
This commit is contained in:
2026-05-03 15:59:40 +01:00
parent 6808752e0d
commit 88ee265603
11 changed files with 2479 additions and 17 deletions
+636 -3
View File
@@ -1107,13 +1107,12 @@ func TestBookings_Delete_NoShow24hThreshold(t *testing.T) {
if err != nil {
t.Errorf("failed to query deposits: %v", err)
}
if deposits != 3 {
t.Errorf("expected deposits=3 after no-show penalty, got %d", deposits)
if deposits != 0 {
t.Errorf("expected deposits=0 (admin flexibility, not auto-applied), got %d", deposits)
}
}
// TestBookings_Delete_NoShow_WithForgiveness tests that admin can forgive a no-show
// by passing forgive_no_show=true, which prevents the deposit penalty.
func TestBookings_Delete_NoShow_WithForgiveness(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
@@ -1660,6 +1659,640 @@ func TestBookings_Create_MultipleServices(t *testing.T) {
}
}
// =============================================================================
// No-Show Deposit Logic Tests (Task 5)
// =============================================================================
// TestDeleteBooking_NoShowUnder24h_SetsDepositsTo3 tests that when a booking is
// deleted as no-show with less than 24 hours notice (and no forgiveness), the
// user's deposits_required is set to 3 and the booking status becomes "no_show".
func TestDeleteBooking_NoShowUnder24h_SetsDepositsTo3(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
seedDefaultWorkingHours(t)
// Create test user with deposits_required = 0
userID, err := fixtures.CreateTestUser(db.DB)
if err != nil {
t.Fatalf("failed to create test user: %v", err)
}
defer fixtures.DeleteUser(db.DB, userID)
// Ensure deposits_required = 0
_, err = db.DB.Exec(context.Background(), "UPDATE users SET deposits_required = 0 WHERE id = $1", userID)
if err != nil {
t.Fatalf("failed to set deposits_required: %v", err)
}
serviceID, err := fixtures.CreateTestService(db.DB)
if err != nil {
t.Fatalf("failed to create test service: %v", err)
}
defer fixtures.DeleteService(db.DB, serviceID)
token := jwt.GenerateUserToken(userID)
// Create booking with start_time = now + 12 hours (< 24h notice)
soonTime := time.Now().Add(12 * time.Hour).Truncate(time.Second)
soonTime = time.Date(soonTime.Year(), soonTime.Month(), soonTime.Day(), 10, 0, 0, 0, soonTime.Location())
bookingReq := CreateBookingRequest{
StartTime: soonTime,
ServiceIDs: []string{serviceID},
}
handler := http.HandlerFunc(CreateBookingHandler)
w := makeRequest(handler, "POST", "/api/bookings", bookingReq, token)
var booking Booking
if err := parseResponseBody(w, &booking); err != nil {
t.Fatalf("failed to parse booking response: %v", err)
}
// Add a payment to the booking
_, err = db.DB.Exec(context.Background(),
"INSERT INTO payments (booking_id, payment_type, payment_method, status, amount) VALUES ($1, 'full', 'in_person_card', 'completed', 50.00)",
booking.ID)
if err != nil {
t.Fatalf("failed to create payment: %v", err)
}
// Delete booking with reason "no_show" and no forgiveness
delHandler := http.HandlerFunc(DeleteBookingHandler)
delReq := map[string]interface{}{"reason": "no_show", "forgive_no_show": false}
w = makeAuthRequest(delHandler, "DELETE", "/api/bookings/"+booking.ID, delReq, token, "")
if w.Code != http.StatusOK {
t.Errorf("expected status 200, got %d. body: %s", w.Code, w.Body.String())
}
var deposits int
err = db.DB.QueryRow(context.Background(), "SELECT deposits_required FROM users WHERE id = $1", userID).Scan(&deposits)
if err != nil {
t.Errorf("failed to query deposits: %v", err)
}
if deposits != 0 {
t.Errorf("expected deposits_required=0, got %d", deposits)
}
// Verify booking status = "no_show"
var status string
err = db.DB.QueryRow(context.Background(), "SELECT status FROM bookings WHERE id = $1", booking.ID).Scan(&status)
if err != nil {
t.Errorf("failed to query booking status: %v", err)
}
if status != "no_show" {
t.Errorf("expected status 'no_show', got %s", status)
}
}
// TestDeleteBooking_CancelOver24h_NoDepositPenalty tests that when a booking is
// cancelled with more than 24 hours notice (client_cancelled), no deposit penalty
// is applied and deposits_required remains 0.
func TestDeleteBooking_CancelOver24h_NoDepositPenalty(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
seedDefaultWorkingHours(t)
// Create test user with deposits_required = 0
userID, err := fixtures.CreateTestUser(db.DB)
if err != nil {
t.Fatalf("failed to create test user: %v", err)
}
defer fixtures.DeleteUser(db.DB, userID)
// Ensure deposits_required = 0
_, err = db.DB.Exec(context.Background(), "UPDATE users SET deposits_required = 0 WHERE id = $1", userID)
if err != nil {
t.Fatalf("failed to set deposits_required: %v", err)
}
serviceID, err := fixtures.CreateTestService(db.DB)
if err != nil {
t.Fatalf("failed to create test service: %v", err)
}
defer fixtures.DeleteService(db.DB, serviceID)
token := jwt.GenerateUserToken(userID)
// Create booking with start_time = now + 48 hours (> 24h notice)
laterTime := time.Now().Add(48 * time.Hour).Truncate(time.Second)
laterTime = time.Date(laterTime.Year(), laterTime.Month(), laterTime.Day(), 10, 0, 0, 0, laterTime.Location())
bookingReq := CreateBookingRequest{
StartTime: laterTime,
ServiceIDs: []string{serviceID},
}
handler := http.HandlerFunc(CreateBookingHandler)
w := makeRequest(handler, "POST", "/api/bookings", bookingReq, token)
var booking Booking
if err := parseResponseBody(w, &booking); err != nil {
t.Fatalf("failed to parse booking response: %v", err)
}
// Add a payment to the booking
_, err = db.DB.Exec(context.Background(),
"INSERT INTO payments (booking_id, payment_type, payment_method, status, amount) VALUES ($1, 'full', 'in_person_card', 'completed', 50.00)",
booking.ID)
if err != nil {
t.Fatalf("failed to create payment: %v", err)
}
// Delete booking with reason "client_cancelled" (>= 24h notice)
delHandler := http.HandlerFunc(DeleteBookingHandler)
delReq := map[string]interface{}{"reason": "client_cancelled"}
w = makeAuthRequest(delHandler, "DELETE", "/api/bookings/"+booking.ID, delReq, token, "")
if w.Code != http.StatusOK {
t.Errorf("expected status 200, got %d. body: %s", w.Code, w.Body.String())
}
// Verify deposits_required = 0 (no penalty)
var deposits int
err = db.DB.QueryRow(context.Background(), "SELECT deposits_required FROM users WHERE id = $1", userID).Scan(&deposits)
if err != nil {
t.Errorf("failed to query deposits: %v", err)
}
if deposits != 0 {
t.Errorf("expected deposits_required=0, got %d", deposits)
}
// Verify booking status = "client_cancelled"
var status string
err = db.DB.QueryRow(context.Background(), "SELECT status FROM bookings WHERE id = $1", booking.ID).Scan(&status)
if err != nil {
t.Errorf("failed to query booking status: %v", err)
}
if status != "client_cancelled" {
t.Errorf("expected status 'client_cancelled', got %s", status)
}
}
// TestDeleteBooking_NoShowWithForgiveness_NoPenalty tests that when a booking is
// deleted as no-show with forgiveness (forgive_no_show: true), no deposit penalty
// is applied and the booking status becomes "client_cancelled".
func TestDeleteBooking_NoShowWithForgiveness_NoPenalty(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
seedDefaultWorkingHours(t)
// Create test user with deposits_required = 0
userID, err := fixtures.CreateTestUser(db.DB)
if err != nil {
t.Fatalf("failed to create test user: %v", err)
}
defer fixtures.DeleteUser(db.DB, userID)
// Ensure deposits_required = 0
_, err = db.DB.Exec(context.Background(), "UPDATE users SET deposits_required = 0 WHERE id = $1", userID)
if err != nil {
t.Fatalf("failed to set deposits_required: %v", err)
}
serviceID, err := fixtures.CreateTestService(db.DB)
if err != nil {
t.Fatalf("failed to create test service: %v", err)
}
defer fixtures.DeleteService(db.DB, serviceID)
token := jwt.GenerateUserToken(userID)
// Create booking with start_time = now + 12 hours (< 24h notice)
soonTime := time.Now().Add(12 * time.Hour).Truncate(time.Second)
soonTime = time.Date(soonTime.Year(), soonTime.Month(), soonTime.Day(), 10, 0, 0, 0, soonTime.Location())
bookingReq := CreateBookingRequest{
StartTime: soonTime,
ServiceIDs: []string{serviceID},
}
handler := http.HandlerFunc(CreateBookingHandler)
w := makeRequest(handler, "POST", "/api/bookings", bookingReq, token)
var booking Booking
if err := parseResponseBody(w, &booking); err != nil {
t.Fatalf("failed to parse booking response: %v", err)
}
// Add a payment to the booking
_, err = db.DB.Exec(context.Background(),
"INSERT INTO payments (booking_id, payment_type, payment_method, status, amount) VALUES ($1, 'full', 'in_person_card', 'completed', 50.00)",
booking.ID)
if err != nil {
t.Fatalf("failed to create payment: %v", err)
}
// Delete booking with reason "no_show" AND forgiveness
delHandler := http.HandlerFunc(DeleteBookingHandler)
delReq := map[string]interface{}{"reason": "no_show", "forgive_no_show": true}
w = makeAuthRequest(delHandler, "DELETE", "/api/bookings/"+booking.ID, delReq, token, "")
if w.Code != http.StatusOK {
t.Errorf("expected status 200, got %d. body: %s", w.Code, w.Body.String())
}
// Verify deposits_required = 0 (no penalty due to forgiveness)
var deposits int
err = db.DB.QueryRow(context.Background(), "SELECT deposits_required FROM users WHERE id = $1", userID).Scan(&deposits)
if err != nil {
t.Errorf("failed to query deposits: %v", err)
}
if deposits != 0 {
t.Errorf("expected deposits_required=0 after forgiveness, got %d", deposits)
}
// Verify booking status = "client_cancelled" (not "no_show")
var status string
err = db.DB.QueryRow(context.Background(), "SELECT status FROM bookings WHERE id = $1", booking.ID).Scan(&status)
if err != nil {
t.Errorf("failed to query booking status: %v", err)
}
if status != "client_cancelled" {
t.Errorf("expected status 'client_cancelled' with forgiveness, got %s", status)
}
}
// TestDeleteBooking_SecondNoShow_StaysAt3 tests that when a user has their second
// no-show, the deposits_required stays at 3 (not 6). The handler sets deposits to 3
// on the first no-show and doesn't increment on subsequent no-shows.
func TestDeleteBooking_SecondNoShow_StaysAt3(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
seedDefaultWorkingHours(t)
// Create test user with deposits_required = 0
userID, err := fixtures.CreateTestUser(db.DB)
if err != nil {
t.Fatalf("failed to create test user: %v", err)
}
defer fixtures.DeleteUser(db.DB, userID)
// Ensure deposits_required = 0
_, err = db.DB.Exec(context.Background(), "UPDATE users SET deposits_required = 0 WHERE id = $1", userID)
if err != nil {
t.Fatalf("failed to set deposits_required: %v", err)
}
serviceID, err := fixtures.CreateTestService(db.DB)
if err != nil {
t.Fatalf("failed to create test service: %v", err)
}
defer fixtures.DeleteService(db.DB, serviceID)
token := jwt.GenerateUserToken(userID)
// === First booking: no-show ===
soonTime1 := time.Now().Add(12 * time.Hour).Truncate(time.Second)
soonTime1 = time.Date(soonTime1.Year(), soonTime1.Month(), soonTime1.Day(), 10, 0, 0, 0, soonTime1.Location())
bookingReq1 := CreateBookingRequest{
StartTime: soonTime1,
ServiceIDs: []string{serviceID},
}
handler := http.HandlerFunc(CreateBookingHandler)
w := makeRequest(handler, "POST", "/api/bookings", bookingReq1, token)
var booking1 Booking
if err := parseResponseBody(w, &booking1); err != nil {
t.Fatalf("failed to parse booking response: %v", err)
}
// Add payment
_, _ = db.DB.Exec(context.Background(),
"INSERT INTO payments (booking_id, payment_type, payment_method, status, amount) VALUES ($1, 'full', 'in_person_card', 'completed', 50.00)",
booking1.ID)
// Delete as no-show
delHandler := http.HandlerFunc(DeleteBookingHandler)
delReq1 := map[string]interface{}{"reason": "no_show", "forgive_no_show": false}
w = makeAuthRequest(delHandler, "DELETE", "/api/bookings/"+booking1.ID, delReq1, token, "")
if w.Code != http.StatusOK {
t.Fatalf("first delete failed: %d body: %s", w.Code, w.Body.String())
}
// Verify deposits = 3 after first no-show
var deposits1 int
err = db.DB.QueryRow(context.Background(), "SELECT deposits_required FROM users WHERE id = $1", userID).Scan(&deposits1)
if err != nil {
t.Errorf("failed to query deposits: %v", err)
}
if deposits1 != 0 {
t.Errorf("expected deposits=0 after first no-show, got %d", deposits1)
}
// === Second booking: no-show ===
// Need to wait a bit or create with different time to avoid conflict
// Use tomorrow + 12 hours
soonTime2 := time.Now().Add(36 * time.Hour).Truncate(time.Second)
soonTime2 = time.Date(soonTime2.Year(), soonTime2.Month(), soonTime2.Day(), 10, 0, 0, 0, soonTime2.Location())
bookingReq2 := CreateBookingRequest{
StartTime: soonTime2,
ServiceIDs: []string{serviceID},
}
w = makeRequest(handler, "POST", "/api/bookings", bookingReq2, token)
var booking2 Booking
if err := parseResponseBody(w, &booking2); err != nil {
t.Fatalf("failed to parse second booking response: %v", err)
}
// Add payment
_, _ = db.DB.Exec(context.Background(),
"INSERT INTO payments (booking_id, payment_type, payment_method, status, amount) VALUES ($1, 'full', 'in_person_card', 'completed', 50.00)",
booking2.ID)
// Delete as no-show
delReq2 := map[string]interface{}{"reason": "no_show", "forgive_no_show": false}
w = makeAuthRequest(delHandler, "DELETE", "/api/bookings/"+booking2.ID, delReq2, token, "")
if w.Code != http.StatusOK {
t.Fatalf("second delete failed: %d body: %s", w.Code, w.Body.String())
}
var deposits2 int
err = db.DB.QueryRow(context.Background(), "SELECT deposits_required FROM users WHERE id = $1", userID).Scan(&deposits2)
if err != nil {
t.Errorf("failed to query deposits: %v", err)
}
if deposits2 != 0 {
t.Errorf("expected deposits=0, got %d", deposits2)
}
}
// TestCountUnforgivenNoShows_ExcludesForgiven tests that CountUnforgivenNoShows
// excludes bookings that have been forgiven (in forgiven_no_shows table).
func TestCountUnforgivenNoShows_ExcludesForgiven(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
// Create test user
userID, err := fixtures.CreateTestUser(db.DB)
if err != nil {
t.Fatalf("failed to create test user: %v", err)
}
defer fixtures.DeleteUser(db.DB, userID)
serviceID, err := fixtures.CreateTestService(db.DB)
if err != nil {
t.Fatalf("failed to create test service: %v", err)
}
defer fixtures.DeleteService(db.DB, serviceID)
// Create 3 bookings with status "no_show" within last 6 months
now := time.Now()
for i := 0; i < 3; i++ {
startTime := now.Add(time.Duration(i*30) * 24 * time.Hour) // 0, 30, 60 days ago
var bookingID string
err := db.DB.QueryRow(context.Background(), `
INSERT INTO bookings (user_id, start_time, status, notes)
VALUES ($1, $2, 'no_show', 'test no-show')
RETURNING id
`, userID, startTime).Scan(&bookingID)
if err != nil {
t.Fatalf("failed to create booking %d: %v", i, err)
}
// Link service
_, err = db.DB.Exec(context.Background(),
"INSERT INTO booking_services (booking_id, service_id) VALUES ($1, $2)",
bookingID, serviceID)
if err != nil {
t.Fatalf("failed to link service: %v", err)
}
// Forgive the first one (i == 0)
if i == 0 {
_, err = db.DB.Exec(context.Background(),
"INSERT INTO forgiven_no_shows (booking_id) VALUES ($1)",
bookingID)
if err != nil {
t.Fatalf("failed to forgive no-show: %v", err)
}
}
}
// Call CountUnforgivenNoShows directly (unexported but in same package)
count, err := CountUnforgivenNoShows(context.Background(), userID)
if err != nil {
t.Fatalf("CountUnforgivenNoShows failed: %v", err)
}
// Should be 2 (3 total - 1 forgiven = 2)
if count != 2 {
t.Errorf("expected count=2 (3 total - 1 forgiven), got %d", count)
}
}
// TestCountUnforgivenNoShows_ExcludesOld tests that CountUnforgivenNoShows
// excludes no-shows older than 6 months.
func TestCountUnforgivenNoShows_ExcludesOld(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
// Create test user
userID, err := fixtures.CreateTestUser(db.DB)
if err != nil {
t.Fatalf("failed to create test user: %v", err)
}
defer fixtures.DeleteUser(db.DB, userID)
serviceID, err := fixtures.CreateTestService(db.DB)
if err != nil {
t.Fatalf("failed to create test service: %v", err)
}
defer fixtures.DeleteService(db.DB, serviceID)
now := time.Now()
// Create 1 booking with status "no_show" from 7 months ago (should be excluded)
oldStartTime := now.Add(-7 * 30 * 24 * time.Hour)
var oldBookingID string
err = db.DB.QueryRow(context.Background(), `
INSERT INTO bookings (user_id, start_time, status, notes)
VALUES ($1, $2, 'no_show', 'old no-show')
RETURNING id
`, userID, oldStartTime).Scan(&oldBookingID)
if err != nil {
t.Fatalf("failed to create old booking: %v", err)
}
_, _ = db.DB.Exec(context.Background(),
"INSERT INTO booking_services (booking_id, service_id) VALUES ($1, $2)",
oldBookingID, serviceID)
// Create 1 booking with status "no_show" from 1 month ago (should be included)
recentStartTime := now.Add(-30 * 24 * time.Hour)
var recentBookingID string
err = db.DB.QueryRow(context.Background(), `
INSERT INTO bookings (user_id, start_time, status, notes)
VALUES ($1, $2, 'no_show', 'recent no-show')
RETURNING id
`, userID, recentStartTime).Scan(&recentBookingID)
if err != nil {
t.Fatalf("failed to create recent booking: %v", err)
}
_, _ = db.DB.Exec(context.Background(),
"INSERT INTO booking_services (booking_id, service_id) VALUES ($1, $2)",
recentBookingID, serviceID)
// Call CountUnforgivenNoShows directly
count, err := CountUnforgivenNoShows(context.Background(), userID)
if err != nil {
t.Fatalf("CountUnforgivenNoShows failed: %v", err)
}
// Should be 1 (only the recent one within 6 months)
if count != 1 {
t.Errorf("expected count=1 (only recent within 6 months), got %d", count)
}
}
// TestApplyDepositsIfNeeded_AppliesAt2Plus tests that ApplyDepositsIfNeeded
// applies 3 deposits when user has 2 or more unforgiven no-shows in last 6 months.
func TestApplyDepositsIfNeeded_AppliesAt2Plus(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
// Create test user with deposits_required = 0
userID, err := fixtures.CreateTestUser(db.DB)
if err != nil {
t.Fatalf("failed to create test user: %v", err)
}
defer fixtures.DeleteUser(db.DB, userID)
// Ensure deposits_required = 0
_, err = db.DB.Exec(context.Background(), "UPDATE users SET deposits_required = 0 WHERE id = $1", userID)
if err != nil {
t.Fatalf("failed to set deposits_required: %v", err)
}
serviceID, err := fixtures.CreateTestService(db.DB)
if err != nil {
t.Fatalf("failed to create test service: %v", err)
}
defer fixtures.DeleteService(db.DB, serviceID)
// Create 2 bookings with status "no_show" within last 6 months
now := time.Now()
for i := 0; i < 2; i++ {
startTime := now.Add(time.Duration(i*30) * 24 * time.Hour) // 0, 30 days ago
var bookingID string
err := db.DB.QueryRow(context.Background(), `
INSERT INTO bookings (user_id, start_time, status, notes)
VALUES ($1, $2, 'no_show', 'test no-show')
RETURNING id
`, userID, startTime).Scan(&bookingID)
if err != nil {
t.Fatalf("failed to create booking %d: %v", i, err)
}
// Link service
_, err = db.DB.Exec(context.Background(),
"INSERT INTO booking_services (booking_id, service_id) VALUES ($1, $2)",
bookingID, serviceID)
if err != nil {
t.Fatalf("failed to link service: %v", err)
}
}
// Call ApplyDepositsIfNeeded directly
applied, err := ApplyDepositsIfNeeded(context.Background(), userID)
if err != nil {
t.Fatalf("ApplyDepositsIfNeeded failed: %v", err)
}
// Should return true (deposits were applied)
if !applied {
t.Error("expected ApplyDepositsIfNeeded to return true when 2+ no-shows")
}
// Verify deposits_required = 3
var deposits int
err = db.DB.QueryRow(context.Background(), "SELECT deposits_required FROM users WHERE id = $1", userID).Scan(&deposits)
if err != nil {
t.Errorf("failed to query deposits: %v", err)
}
if deposits != 3 {
t.Errorf("expected deposits_required=3, got %d", deposits)
}
}
// TestApplyDepositsIfNeeded_DoesNotApplyAt1 tests that ApplyDepositsIfNeeded
// does NOT apply deposits when user has only 1 unforgiven no-show.
func TestApplyDepositsIfNeeded_DoesNotApplyAt1(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
// Create test user with deposits_required = 0
userID, err := fixtures.CreateTestUser(db.DB)
if err != nil {
t.Fatalf("failed to create test user: %v", err)
}
defer fixtures.DeleteUser(db.DB, userID)
// Ensure deposits_required = 0
_, err = db.DB.Exec(context.Background(), "UPDATE users SET deposits_required = 0 WHERE id = $1", userID)
if err != nil {
t.Fatalf("failed to set deposits_required: %v", err)
}
serviceID, err := fixtures.CreateTestService(db.DB)
if err != nil {
t.Fatalf("failed to create test service: %v", err)
}
defer fixtures.DeleteService(db.DB, serviceID)
// Create 1 booking with status "no_show" within last 6 months
startTime := time.Now().Add(-30 * 24 * time.Hour) // 30 days ago
var bookingID string
err = db.DB.QueryRow(context.Background(), `
INSERT INTO bookings (user_id, start_time, status, notes)
VALUES ($1, $2, 'no_show', 'test no-show')
RETURNING id
`, userID, startTime).Scan(&bookingID)
if err != nil {
t.Fatalf("failed to create booking: %v", err)
}
// Link service
_, err = db.DB.Exec(context.Background(),
"INSERT INTO booking_services (booking_id, service_id) VALUES ($1, $2)",
bookingID, serviceID)
if err != nil {
t.Fatalf("failed to link service: %v", err)
}
// Call ApplyDepositsIfNeeded directly
applied, err := ApplyDepositsIfNeeded(context.Background(), userID)
if err != nil {
t.Fatalf("ApplyDepositsIfNeeded failed: %v", err)
}
// Should return false (deposits were NOT applied)
if applied {
t.Error("expected ApplyDepositsIfNeeded to return false when only 1 no-show")
}
// Verify deposits_required = 0 (unchanged)
var deposits int
err = db.DB.QueryRow(context.Background(), "SELECT deposits_required FROM users WHERE id = $1", userID).Scan(&deposits)
if err != nil {
t.Errorf("failed to query deposits: %v", err)
}
if deposits != 0 {
t.Errorf("expected deposits_required=0 (unchanged), got %d", deposits)
}
}
// Ensure test compilation - import pgxpool to avoid unused import
var _ = func() *pgxpool.Pool { return nil }