test: update tests to reflect current behavior changes

UPDATED TEST FILES:

1. backend/handlers/bookings/bookings_test.go (added 6 new tests):
   - TestBookings_Create_MinimumAdvance: Renamed from 48h check, now tests 1h requirement
   - TestBookings_Create_WithNotes_StatusPending: NEW - verifies notes cause 'pending' status
   - TestBookings_Create_WithoutNotes_StatusConfirmed: NEW - verifies auto-approval without notes
   - TestBookings_Create_Within1Hour_ShouldFail: NEW - verifies < 1h bookings are rejected
   - TestBookings_Delete_NoShow24hThreshold: NEW - tests 24h no-show rule & deposit penalty
   - TestBookings_Delete_NoShow_WithForgiveness: NEW - tests forgive_no_show parameter

2. backend/handlers/admin/bookings_test.go (added 2 new tests):
   - TestAdminBookings_Create_EnforceDeposits_Bypass: NEW - admin can bypass deposit checks
   - TestAdminBookings_Create_EnforceDeposits_Enforced: NEW - default enforcement behavior

3. backend/handlers/scheduling/time_blockers_test.go (added 1 new test):
   - TestCleanupOldReservations: NEW - verifies 1h+ old reservations are cleaned up

TEST COVERAGE FOR NEW FEATURES:

✓ 1h minimum advance requirement (universal, not deposit-dependent)
✓ Notes → 'pending' status (auto-approval workflow)
✓ No notes → 'confirmed' status (auto-approved)
✓ 24h no-show threshold (< 24h = penalty, >= 24h = late cancellation)
✓ forgive_no_show parameter (admin can forgive no-shows)
✓ Deposit penalty: set to 3 (not +=3, prevents escalation)
✓ enforce_deposits parameter (admin can bypass checks)
✓ Reservation cleanup (auto-delete > 1h old reservations)

VERIFICATION:
✓ All test code compiles (go build -tags test ./handlers/bookings)
✓ All test code compiles (go build -tags test ./handlers/admin)
✓ All test code compiles (go build -tags test ./handlers/scheduling)
✓ Main build still works (go build -tags dev ./main.go)

TEST EXECUTION (to run):
go test -tags test -v ./handlers/bookings -run TestBookings_Create_WithNotes
go test -tags test -v ./handlers/bookings -run TestBookings_Delete_NoShow
go test -tags test -v ./handlers/admin -run TestAdminBookings_Create_EnforceDeposits
go test -tags test -v ./handlers/scheduling -run TestCleanupOldReservations
This commit is contained in:
2026-03-07 18:02:13 +00:00
parent f9610c8392
commit 99ab43eefb
3 changed files with 493 additions and 31 deletions
+111
View File
@@ -1826,3 +1826,114 @@ func TestAdminBookings_Edit_OverlappingBlocker_WithWarning(t *testing.T) {
}
}
}
// TestAdminBookings_Create_EnforceDeposits_Bypass tests that admin can create bookings
// for users with outstanding deposits by setting enforce_deposits=false.
func TestAdminBookings_Create_EnforceDeposits_Bypass(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
t.Fatalf("failed to create admin user: %v", err)
}
defer fixtures.DeleteUser(db.DB, adminID)
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)
// Set user to have outstanding deposits (deposits_required = 3)
_, err = db.DB.Exec(context.Background(), "UPDATE users SET deposits_required = 3 WHERE id = $1", userID)
if err != nil {
t.Fatalf("failed to set deposits_required: %v", err)
}
futureTime := time.Now().Add(72 * time.Hour).Truncate(time.Second)
falseVal := false
req := bookings.AdminCreateBookingForUserRequest{
UserID: userID,
StartTime: futureTime,
ServiceIDs: []string{serviceID},
EnforceDeposits: &falseVal, // Bypass deposit check
}
handler := http.HandlerFunc(bookings.AdminCreateBookingForUserHandler)
w := makeAdminRequest(handler, "POST", "/api/admin/bookings", req)
// Should succeed (not 409 Conflict) because deposits check was bypassed
if w.Code != http.StatusCreated {
t.Errorf("expected status 201 when enforce_deposits=false, got %d. body: %s", w.Code, w.Body.String())
}
}
// TestAdminBookings_Create_EnforceDeposits_Enforced tests that by default (or when enforce_deposits=true),
// admin bookings respect the deposit requirement rules.
func TestAdminBookings_Create_EnforceDeposits_Enforced(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
t.Fatalf("failed to create admin user: %v", err)
}
defer fixtures.DeleteUser(db.DB, adminID)
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)
// Set user to have outstanding deposits
_, err = db.DB.Exec(context.Background(), "UPDATE users SET deposits_required = 3 WHERE id = $1", userID)
if err != nil {
t.Fatalf("failed to set deposits_required: %v", err)
}
// Create first booking for user (will have it active)
firstTime := time.Now().Add(72 * time.Hour).Truncate(time.Second)
firstReq := bookings.AdminCreateBookingForUserRequest{
UserID: userID,
StartTime: firstTime,
ServiceIDs: []string{serviceID},
EnforceDeposits: nil, // Default: enforce deposits
}
handler := http.HandlerFunc(bookings.AdminCreateBookingForUserHandler)
w := makeAdminRequest(handler, "POST", "/api/admin/bookings", firstReq)
if w.Code != http.StatusCreated {
t.Fatalf("failed to create first booking: %d. body: %s", w.Code, w.Body.String())
}
// Try to create second booking (should fail due to one-active-booking limit)
secondTime := time.Now().Add(96 * time.Hour).Truncate(time.Second)
secondReq := bookings.AdminCreateBookingForUserRequest{
UserID: userID,
StartTime: secondTime,
ServiceIDs: []string{serviceID},
EnforceDeposits: nil, // Default: enforce (deposits_required > 0 still active)
}
w = makeAdminRequest(handler, "POST", "/api/admin/bookings", secondReq)
// Should get 409 Conflict because user has active booking and deposits outstanding
if w.Code != http.StatusConflict {
t.Errorf("expected status 409 when enforce_deposits is enforced, got %d. body: %s", w.Code, w.Body.String())
}
}