feat: edit request time blockers, today closing time, UI polish, and test fixes

- Add time blocker management for booking edit requests
- Add closing_time field to admin today/current-next endpoint
- Update UserBookingModal and CurrentAppointment UI components
- Fix fmt import in bookings_test.go (was missing)
- Fix created_by FK in TestAdminApproveEditRequest_TimeBlockerOverlap
- Update test coverage for edit request time blocker overlap
- Update gap backlog documentation
This commit is contained in:
2026-05-10 16:53:17 +01:00
parent f3fb44f401
commit 83c62ffb97
10 changed files with 950 additions and 37 deletions
+46
View File
@@ -19,6 +19,7 @@ import (
"encoding/json"
"net/http"
"testing"
"time"
"crussell/db"
"crussell/handlers/notifications"
@@ -102,6 +103,51 @@ func TestAdminToday_CurrentNext(t *testing.T) {
}
}
// TestAdminToday_CurrentNext_ClosingTime verifies that the current-next endpoint
// returns the closing time for today.
func TestAdminToday_CurrentNext_ClosingTime(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
// Seed working hours for today (query uses current weekday)
todayWeekday := int(time.Now().Weekday())
if todayWeekday == 0 {
todayWeekday = 7
}
_, err := db.DB.Exec(context.Background(), `
INSERT INTO working_hours (weekday, start_time, end_time, is_open)
VALUES ($1, '09:00', '18:00', true)
ON CONFLICT (weekday) DO UPDATE SET start_time = '09:00', end_time = '18:00', is_open = true
`, todayWeekday)
if err != nil {
t.Fatalf("failed to seed working hours: %v", err)
}
handler := http.HandlerFunc(today.GetCurrentAndNextHandler)
w := makeAdminRequest(handler, "GET", "/api/admin/today/current-next", nil)
if w.Code != http.StatusOK {
t.Errorf("expected status 200, got %d. body: %s", w.Code, w.Body.String())
}
var response today.CurrentNextResponse
if err := json.Unmarshal(w.Body.Bytes(), &response); err != nil {
t.Fatalf("failed to unmarshal response: %v", err)
}
if response.ClosingTime == nil {
t.Errorf("expected closing_time in response, got nil")
}
if response.ClosingTime != nil && *response.ClosingTime == "" {
t.Error("expected closing_time to be non-empty string")
}
if response.ClosingTime != nil && *response.ClosingTime != "18:00:00" && *response.ClosingTime != "18:00" {
t.Logf("got closing_time: %s", *response.ClosingTime)
}
}
// TestAdminToday_Appointments tests that an admin can get a list of all
// bookings scheduled for today with their details.
func TestAdminToday_Appointments(t *testing.T) {