fix: sanitize API error text display and add time_blockers tests

Add extractErrorMessage helper for JSON error body parsing and apply sanitizeText across all toast displays. Add time_blockers test coverage for new holiday placeholder cleanup and overlapping scenarios.
This commit is contained in:
2026-08-22 00:34:48 +01:00
parent 388ac5948a
commit 3eec71a56c
30 changed files with 283 additions and 71 deletions
@@ -2027,6 +2027,179 @@ func TestCleanupOldReservations_EditRequest(t *testing.T) {
}
}
// --- Tests for CleanupOldReservations (Placeholder) ---
// TestCleanupOldReservations_Placeholder verifies that placeholder reservations
// older than 24 hours are deleted, while recent ones are preserved.
func TestCleanupOldReservations_Placeholder(t *testing.T) {
t.Parallel()
ctx, tx := resetTestData(t)
// Create old placeholder reservation (>24 hours old)
oldTime := clock.Now().Add(-25 * time.Hour)
_, err := tx.Exec(ctx, `
INSERT INTO time_blockers (start_time, duration_minutes, description, created_at)
VALUES ($1, 60, 'RESERVATION:placeholder:bk123', $2)
`, oldTime, clock.Now().Add(-25*time.Hour))
if err != nil {
t.Fatalf("failed to create old placeholder reservation: %v", err)
}
// Create recent placeholder reservation (<24 hours old)
recentTime := clock.Now().Add(-12 * time.Hour)
_, err = tx.Exec(ctx, `
INSERT INTO time_blockers (start_time, duration_minutes, description, created_at)
VALUES ($1, 60, 'RESERVATION:placeholder:bk456', $2)
`, recentTime, clock.Now().Add(-12*time.Hour))
if err != nil {
t.Fatalf("failed to create recent placeholder reservation: %v", err)
}
// Run cleanup
_, err = CleanupOldReservations(ctx)
if err != nil {
t.Fatalf("CleanupOldReservations failed: %v", err)
}
// Verify old placeholder was deleted
var oldCount int
err = tx.QueryRow(ctx, "SELECT COUNT(*) FROM time_blockers WHERE description = 'RESERVATION:placeholder:bk123'").Scan(&oldCount)
if err != nil {
t.Fatalf("failed to check old placeholder: %v", err)
}
if oldCount != 0 {
t.Error("expected old placeholder reservation (25h) to be deleted")
}
// Verify recent placeholder still exists
var recentCount int
err = tx.QueryRow(ctx, "SELECT COUNT(*) FROM time_blockers WHERE description = 'RESERVATION:placeholder:bk456'").Scan(&recentCount)
if err != nil {
t.Fatalf("failed to check recent placeholder: %v", err)
}
if recentCount != 1 {
t.Error("expected recent placeholder reservation (12h) to be preserved")
}
}
// TestCleanupOldReservations_HolidayPlaceholder verifies that holiday placeholder
// reservations older than 24 hours are deleted, while recent ones are preserved.
func TestCleanupOldReservations_HolidayPlaceholder(t *testing.T) {
t.Parallel()
ctx, tx := resetTestData(t)
// Create old holiday_placeholder reservation (>24 hours old)
oldTime := clock.Now().Add(-25 * time.Hour)
_, err := tx.Exec(ctx, `
INSERT INTO time_blockers (start_time, duration_minutes, description, created_at)
VALUES ($1, 60, 'RESERVATION:holiday_placeholder:hld123', $2)
`, oldTime, clock.Now().Add(-25*time.Hour))
if err != nil {
t.Fatalf("failed to create old holiday_placeholder reservation: %v", err)
}
// Create recent holiday_placeholder reservation (<24 hours old)
recentTime := clock.Now().Add(-12 * time.Hour)
_, err = tx.Exec(ctx, `
INSERT INTO time_blockers (start_time, duration_minutes, description, created_at)
VALUES ($1, 60, 'RESERVATION:holiday_placeholder:hld456', $2)
`, recentTime, clock.Now().Add(-12*time.Hour))
if err != nil {
t.Fatalf("failed to create recent holiday_placeholder reservation: %v", err)
}
// Run cleanup
_, err = CleanupOldReservations(ctx)
if err != nil {
t.Fatalf("CleanupOldReservations failed: %v", err)
}
// Verify old placeholder was deleted
var oldCount int
err = tx.QueryRow(ctx, "SELECT COUNT(*) FROM time_blockers WHERE description = 'RESERVATION:holiday_placeholder:hld123'").Scan(&oldCount)
if err != nil {
t.Fatalf("failed to check old holiday_placeholder: %v", err)
}
if oldCount != 0 {
t.Error("expected old holiday_placeholder reservation (25h) to be deleted")
}
// Verify recent placeholder still exists
var recentCount int
err = tx.QueryRow(ctx, "SELECT COUNT(*) FROM time_blockers WHERE description = 'RESERVATION:holiday_placeholder:hld456'").Scan(&recentCount)
if err != nil {
t.Fatalf("failed to check recent holiday_placeholder: %v", err)
}
if recentCount != 1 {
t.Error("expected recent holiday_placeholder reservation (12h) to be preserved")
}
}
// TestCleanupOldReservations_MixedPlaceholders verifies that both placeholder
// and holiday_placeholder patterns are cleaned up together alongside other types.
func TestCleanupOldReservations_MixedPlaceholders(t *testing.T) {
t.Parallel()
ctx, tx := resetTestData(t)
// Old placeholder (>24 hours)
_, err := tx.Exec(ctx, `
INSERT INTO time_blockers (start_time, duration_minutes, description, created_at)
VALUES ($1, 60, 'RESERVATION:placeholder:bkOld', $2)
`, clock.Now().Add(-25*time.Hour), clock.Now().Add(-25*time.Hour))
if err != nil {
t.Fatalf("failed to create old placeholder: %v", err)
}
// Old holiday_placeholder (>24 hours)
_, err = tx.Exec(ctx, `
INSERT INTO time_blockers (start_time, duration_minutes, description, created_at)
VALUES ($1, 60, 'RESERVATION:holiday_placeholder:hldOld', $2)
`, clock.Now().Add(-25*time.Hour), clock.Now().Add(-25*time.Hour))
if err != nil {
t.Fatalf("failed to create old holiday_placeholder: %v", err)
}
// Old user reservation (>1 hour) — should also be deleted
oldUserTime := clock.Now().Add(-2 * time.Hour)
userID, err := fixtures.CreateTestUser(tx)
if err != nil {
t.Fatalf("failed to create user: %v", err)
}
_, err = tx.Exec(ctx, `
INSERT INTO time_blockers (start_time, duration_minutes, description, created_by, created_at)
VALUES ($1, 60, 'RESERVATION:user:test', $2, $3)
`, oldUserTime, userID, clock.Now().Add(-2*time.Hour))
if err != nil {
t.Fatalf("failed to create old user reservation: %v", err)
}
// Count before cleanup
var countBefore int
err = tx.QueryRow(ctx, "SELECT COUNT(*) FROM time_blockers").Scan(&countBefore)
if err != nil {
t.Fatalf("failed to count before: %v", err)
}
if countBefore != 3 {
t.Errorf("expected 3 blockers before cleanup, got %d", countBefore)
}
// Run cleanup
_, err = CleanupOldReservations(ctx)
if err != nil {
t.Fatalf("CleanupOldReservations failed: %v", err)
}
// All 3 should be deleted
var countAfter int
err = tx.QueryRow(ctx, "SELECT COUNT(*) FROM time_blockers").Scan(&countAfter)
if err != nil {
t.Fatalf("failed to count after: %v", err)
}
if countAfter != 0 {
t.Errorf("expected 0 blockers after cleanup (all 3 expired), got %d", countAfter)
}
}
// --- Tests for CleanupExpiredDeposits ---
func TestCleanupExpiredDeposits_ExpiredConfirmed(t *testing.T) {