fix: add hours validation to user edit requests (was M8/L5 stubs)
RequestEditHandler had empty M8/L5 placeholder comments where hours validation was planned. Implemented full validation: staged-hours-aware closing time check via getClosingTimeForDate, closed-day check, and closing-hours boundary check using the booking's total_duration_minutes. Removed placeholder comments. Updated test to propose an open-day time that doesn't extend past closing.
This commit is contained in:
@@ -425,7 +425,14 @@ func TestRequestEditHandler_NoticePeriod_AllowsWhenEnoughNotice(t *testing.T) {
|
||||
}
|
||||
|
||||
token := jwt.GenerateUserToken(userID)
|
||||
newTime := bookingTime.Add(48 * time.Hour)
|
||||
// Set the new time to 10:00 London time on a weekday that's clearly within
|
||||
// working hours. Compute from the current time to avoid DST boundary issues.
|
||||
londonNow := clock.Now().In(clock.London)
|
||||
nextWeekday := londonNow.AddDate(0, 0, 1)
|
||||
for nextWeekday.Weekday() == time.Sunday || nextWeekday.Weekday() == time.Monday {
|
||||
nextWeekday = nextWeekday.AddDate(0, 0, 1)
|
||||
}
|
||||
newTime := time.Date(nextWeekday.Year(), nextWeekday.Month(), nextWeekday.Day(), 10, 0, 0, 0, clock.London).UTC()
|
||||
|
||||
handler := http.HandlerFunc(RequestEditHandler)
|
||||
w := makeRequest(handler, "POST", "/api/bookings/"+bookingID+"/edit-request", map[string]interface{}{
|
||||
|
||||
@@ -1310,9 +1310,6 @@ func RequestEditHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// M8
|
||||
// L5
|
||||
|
||||
// Validate: at least one of new_start_time, new_services, or notes must be provided
|
||||
if req.NewStartTime == nil && len(req.NewServices) == 0 && req.Notes == nil {
|
||||
http.Error(w, "At least one of new_start_time, new_services, or notes is required", http.StatusBadRequest)
|
||||
@@ -1340,8 +1337,9 @@ func RequestEditHandler(w http.ResponseWriter, r *http.Request) {
|
||||
// Check booking is not already completed/cancelled
|
||||
var currentStatus string
|
||||
var currentStartTime time.Time
|
||||
var currentDuration int
|
||||
var depositRequired bool
|
||||
err = db.Conn.QueryRow(r.Context(), "SELECT status, start_time, deposit_required FROM bookings WHERE id = $1", bookingID).Scan(¤tStatus, ¤tStartTime, &depositRequired)
|
||||
err = db.Conn.QueryRow(r.Context(), "SELECT status, start_time, total_duration_minutes, deposit_required FROM bookings WHERE id = $1", bookingID).Scan(¤tStatus, ¤tStartTime, ¤tDuration, &depositRequired)
|
||||
if err != nil {
|
||||
log.Printf("Failed to get booking status %s: %v", bookingID, err)
|
||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||
@@ -1409,6 +1407,32 @@ func RequestEditHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
// Validate proposed time is within working hours (including staged hours changes)
|
||||
if req.NewStartTime != nil {
|
||||
newTime := req.NewStartTime.In(londonLocation)
|
||||
weekday := int((newTime.Weekday() + 6) % 7)
|
||||
|
||||
// Get closing time (respects staged default hours changes)
|
||||
closeStr, err := getClosingTimeForDate(r.Context(), db.Conn, weekday, newTime)
|
||||
if err != nil {
|
||||
log.Printf("Failed to get hours for edit request: %v", err)
|
||||
http.Error(w, "Could not verify hours", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if closeStr == "00:00" || closeStr == "00:00:00" {
|
||||
http.Error(w, "The salon is closed at this time on this day", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Check the proposed end time (based on the booking's service duration)
|
||||
// doesn't extend beyond closing hours.
|
||||
localEnd := newTime.Add(time.Duration(currentDuration) * time.Minute)
|
||||
if err := checkClosingHours(localEnd, closeStr); err != nil {
|
||||
http.Error(w, "This time would extend beyond closing hours", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
tx, err := db.Conn.Begin(r.Context())
|
||||
if err != nil {
|
||||
log.Printf("Failed to start transaction: %v", err)
|
||||
|
||||
Reference in New Issue
Block a user