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:
@@ -20,6 +20,7 @@ import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
@@ -2709,6 +2710,94 @@ func TestCreateEditRequest(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestCreateEditRequest_WithTimeChange verifies that a user can request an edit to
|
||||
// change the booking time, and a time_blocker is created to reserve the new slot.
|
||||
func TestCreateEditRequest_WithTimeChange(t *testing.T) {
|
||||
cleanup := setupTestDB(t)
|
||||
defer cleanup()
|
||||
|
||||
seedDefaultWorkingHours(t)
|
||||
|
||||
userID, err := fixtures.CreateTestUser(db.DB)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create test user: %v", err)
|
||||
}
|
||||
defer fixtures.DeleteUser(db.DB, userID)
|
||||
|
||||
_, 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)
|
||||
|
||||
bookingID, err := fixtures.CreateTestBooking(db.DB, userID, serviceID)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create test booking: %v", err)
|
||||
}
|
||||
defer fixtures.DeleteBooking(db.DB, bookingID)
|
||||
|
||||
_, err = db.DB.Exec(context.Background(), "UPDATE bookings SET status = 'confirmed' WHERE id = $1", bookingID)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to confirm booking: %v", err)
|
||||
}
|
||||
|
||||
token := jwt.GenerateUserToken(userID)
|
||||
|
||||
newStartTime := time.Now().Add(24 * time.Hour).Truncate(time.Second)
|
||||
newStartTime = time.Date(newStartTime.Year(), newStartTime.Month(), newStartTime.Day(), 14, 0, 0, 0, newStartTime.Location())
|
||||
|
||||
handler := http.HandlerFunc(RequestEditHandler)
|
||||
reqBody := map[string]interface{}{
|
||||
"new_start_time": newStartTime.Format(time.RFC3339),
|
||||
}
|
||||
w := makeRequest(handler, "POST", "/api/bookings/"+bookingID+"/edit-request", reqBody, token)
|
||||
|
||||
if w.Code != http.StatusCreated && w.Code != http.StatusOK {
|
||||
t.Errorf("expected status 200/201, got %d. body: %s", w.Code, w.Body.String())
|
||||
}
|
||||
|
||||
var erNewTime time.Time
|
||||
err = db.DB.QueryRow(context.Background(),
|
||||
"SELECT new_start_time FROM booking_edit_requests WHERE booking_id = $1", bookingID).Scan(&erNewTime)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to query edit request: %v", err)
|
||||
}
|
||||
if !erNewTime.Truncate(time.Second).Equal(newStartTime) {
|
||||
t.Errorf("expected new_start_time %v, got %v", newStartTime, erNewTime)
|
||||
}
|
||||
|
||||
var blockerCount int
|
||||
err = db.DB.QueryRow(context.Background(),
|
||||
"SELECT COUNT(*) FROM time_blockers WHERE description = $1",
|
||||
fmt.Sprintf("RESERVATION:edit_request:%s", bookingID)).Scan(&blockerCount)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to query time_blockers: %v", err)
|
||||
}
|
||||
if blockerCount != 1 {
|
||||
t.Errorf("expected 1 time_blocker for edit request, got %d", blockerCount)
|
||||
}
|
||||
|
||||
var blockerStart time.Time
|
||||
var blockerDuration int
|
||||
err = db.DB.QueryRow(context.Background(),
|
||||
"SELECT start_time, duration_minutes FROM time_blockers WHERE description = $1",
|
||||
fmt.Sprintf("RESERVATION:edit_request:%s", bookingID)).Scan(&blockerStart, &blockerDuration)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to query time_blocker details: %v", err)
|
||||
}
|
||||
if !blockerStart.Truncate(time.Second).Equal(newStartTime) {
|
||||
t.Errorf("expected blocker start_time %v, got %v", newStartTime, blockerStart)
|
||||
}
|
||||
if blockerDuration < 15 {
|
||||
t.Errorf("expected blocker duration >= 15, got %d", blockerDuration)
|
||||
}
|
||||
}
|
||||
|
||||
// TestDeleteEditRequest tests that user deleting their edit request deletes the admin notification
|
||||
func TestDeleteEditRequest(t *testing.T) {
|
||||
cleanup := setupTestDB(t)
|
||||
@@ -3029,6 +3118,360 @@ func TestAdminRejectEditRequest(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestAdminApproveEditRequest_DeletesTimeBlocker verifies that when admin approves
|
||||
// an edit request, the associated time_blocker reservation is deleted.
|
||||
func TestAdminApproveEditRequest_DeletesTimeBlocker(t *testing.T) {
|
||||
cleanup := setupTestDB(t)
|
||||
defer cleanup()
|
||||
|
||||
seedDefaultWorkingHours(t)
|
||||
|
||||
userID, err := fixtures.CreateTestUser(db.DB)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create test user: %v", err)
|
||||
}
|
||||
defer fixtures.DeleteUser(db.DB, userID)
|
||||
|
||||
_, 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)
|
||||
|
||||
bookingID, err := fixtures.CreateTestBooking(db.DB, userID, serviceID)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create test booking: %v", err)
|
||||
}
|
||||
defer fixtures.DeleteBooking(db.DB, bookingID)
|
||||
|
||||
_, err = db.DB.Exec(context.Background(), "UPDATE bookings SET status = 'confirmed' WHERE id = $1", bookingID)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to confirm booking: %v", err)
|
||||
}
|
||||
|
||||
userToken := jwt.GenerateUserToken(userID)
|
||||
|
||||
newStartTime := time.Now().Add(48 * time.Hour).Truncate(time.Second)
|
||||
newStartTime = time.Date(newStartTime.Year(), newStartTime.Month(), newStartTime.Day(), 14, 0, 0, 0, newStartTime.Location())
|
||||
|
||||
createReq := http.HandlerFunc(RequestEditHandler)
|
||||
createBody := map[string]interface{}{
|
||||
"new_start_time": newStartTime.Format(time.RFC3339),
|
||||
}
|
||||
w := makeRequest(createReq, "POST", "/api/bookings/"+bookingID+"/edit-request", createBody, userToken)
|
||||
if w.Code != http.StatusCreated && w.Code != http.StatusOK {
|
||||
t.Fatalf("failed to create edit request: %d %s", w.Code, w.Body.String())
|
||||
}
|
||||
|
||||
var blockerCountBefore int
|
||||
err = db.DB.QueryRow(context.Background(),
|
||||
"SELECT COUNT(*) FROM time_blockers WHERE description = $1",
|
||||
fmt.Sprintf("RESERVATION:edit_request:%s", bookingID)).Scan(&blockerCountBefore)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to query blockers: %v", err)
|
||||
}
|
||||
if blockerCountBefore != 1 {
|
||||
t.Fatalf("expected 1 blocker before approval, got %d", blockerCountBefore)
|
||||
}
|
||||
|
||||
var editRequestID string
|
||||
err = db.DB.QueryRow(context.Background(),
|
||||
"SELECT id FROM booking_edit_requests WHERE booking_id = $1", bookingID).Scan(&editRequestID)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get edit request ID: %v", err)
|
||||
}
|
||||
|
||||
r := chi.NewRouter()
|
||||
r.Post("/api/admin/bookings/{id}/edit-requests/{request_id}/approve", AdminApproveEditRequestHandler)
|
||||
req := httptest.NewRequest("POST", "/api/admin/bookings/"+bookingID+"/edit-requests/"+editRequestID+"/approve", nil)
|
||||
ctx := context.WithValue(req.Context(), mw.UserRoleKey, "admin")
|
||||
rctx := chi.NewRouteContext()
|
||||
rctx.URLParams.Add("id", bookingID)
|
||||
rctx.URLParams.Add("request_id", editRequestID)
|
||||
ctx = context.WithValue(ctx, chi.RouteCtxKey, rctx)
|
||||
req = req.WithContext(ctx)
|
||||
w = httptest.NewRecorder()
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusNoContent && w.Code != http.StatusOK {
|
||||
t.Errorf("expected status 200/204, got %d. body: %s", w.Code, w.Body.String())
|
||||
}
|
||||
|
||||
var blockerCountAfter int
|
||||
err = db.DB.QueryRow(context.Background(),
|
||||
"SELECT COUNT(*) FROM time_blockers WHERE description = $1",
|
||||
fmt.Sprintf("RESERVATION:edit_request:%s", bookingID)).Scan(&blockerCountAfter)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to query blockers after approval: %v", err)
|
||||
}
|
||||
if blockerCountAfter != 0 {
|
||||
t.Errorf("expected 0 blockers after approval, got %d", blockerCountAfter)
|
||||
}
|
||||
}
|
||||
|
||||
// TestAdminRejectEditRequest_DeletesTimeBlocker verifies that when admin rejects
|
||||
// an edit request, the associated time_blocker reservation is deleted.
|
||||
func TestAdminRejectEditRequest_DeletesTimeBlocker(t *testing.T) {
|
||||
cleanup := setupTestDB(t)
|
||||
defer cleanup()
|
||||
|
||||
seedDefaultWorkingHours(t)
|
||||
|
||||
userID, err := fixtures.CreateTestUser(db.DB)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create test user: %v", err)
|
||||
}
|
||||
defer fixtures.DeleteUser(db.DB, userID)
|
||||
|
||||
_, 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)
|
||||
|
||||
bookingID, err := fixtures.CreateTestBooking(db.DB, userID, serviceID)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create test booking: %v", err)
|
||||
}
|
||||
defer fixtures.DeleteBooking(db.DB, bookingID)
|
||||
|
||||
_, err = db.DB.Exec(context.Background(), "UPDATE bookings SET status = 'confirmed' WHERE id = $1", bookingID)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to confirm booking: %v", err)
|
||||
}
|
||||
|
||||
userToken := jwt.GenerateUserToken(userID)
|
||||
|
||||
newStartTime := time.Now().Add(48 * time.Hour).Truncate(time.Second)
|
||||
newStartTime = time.Date(newStartTime.Year(), newStartTime.Month(), newStartTime.Day(), 14, 0, 0, 0, newStartTime.Location())
|
||||
|
||||
createReq := http.HandlerFunc(RequestEditHandler)
|
||||
createBody := map[string]interface{}{
|
||||
"new_start_time": newStartTime.Format(time.RFC3339),
|
||||
}
|
||||
w := makeRequest(createReq, "POST", "/api/bookings/"+bookingID+"/edit-request", createBody, userToken)
|
||||
if w.Code != http.StatusCreated && w.Code != http.StatusOK {
|
||||
t.Fatalf("failed to create edit request: %d %s", w.Code, w.Body.String())
|
||||
}
|
||||
|
||||
var blockerCountBefore int
|
||||
err = db.DB.QueryRow(context.Background(),
|
||||
"SELECT COUNT(*) FROM time_blockers WHERE description = $1",
|
||||
fmt.Sprintf("RESERVATION:edit_request:%s", bookingID)).Scan(&blockerCountBefore)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to query blockers: %v", err)
|
||||
}
|
||||
if blockerCountBefore != 1 {
|
||||
t.Fatalf("expected 1 blocker before rejection, got %d", blockerCountBefore)
|
||||
}
|
||||
|
||||
var editRequestID string
|
||||
err = db.DB.QueryRow(context.Background(),
|
||||
"SELECT id FROM booking_edit_requests WHERE booking_id = $1", bookingID).Scan(&editRequestID)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get edit request ID: %v", err)
|
||||
}
|
||||
|
||||
r := chi.NewRouter()
|
||||
r.Post("/api/admin/bookings/{id}/edit-requests/{request_id}/deny", AdminRejectEditRequestHandler)
|
||||
req := httptest.NewRequest("POST", "/api/admin/bookings/"+bookingID+"/edit-requests/"+editRequestID+"/deny", nil)
|
||||
ctx := context.WithValue(req.Context(), mw.UserRoleKey, "admin")
|
||||
rctx := chi.NewRouteContext()
|
||||
rctx.URLParams.Add("id", bookingID)
|
||||
rctx.URLParams.Add("request_id", editRequestID)
|
||||
ctx = context.WithValue(ctx, chi.RouteCtxKey, rctx)
|
||||
req = req.WithContext(ctx)
|
||||
w = httptest.NewRecorder()
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusNoContent && w.Code != http.StatusOK {
|
||||
t.Errorf("expected status 200/204, got %d. body: %s", w.Code, w.Body.String())
|
||||
}
|
||||
|
||||
var blockerCountAfter int
|
||||
err = db.DB.QueryRow(context.Background(),
|
||||
"SELECT COUNT(*) FROM time_blockers WHERE description = $1",
|
||||
fmt.Sprintf("RESERVATION:edit_request:%s", bookingID)).Scan(&blockerCountAfter)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to query blockers after rejection: %v", err)
|
||||
}
|
||||
if blockerCountAfter != 0 {
|
||||
t.Errorf("expected 0 blockers after rejection, got %d", blockerCountAfter)
|
||||
}
|
||||
}
|
||||
|
||||
// TestDeleteEditRequest_DeletesTimeBlocker verifies that when user cancels their
|
||||
// own edit request, the associated time_blocker reservation is deleted.
|
||||
func TestDeleteEditRequest_DeletesTimeBlocker(t *testing.T) {
|
||||
cleanup := setupTestDB(t)
|
||||
defer cleanup()
|
||||
|
||||
seedDefaultWorkingHours(t)
|
||||
|
||||
userID, err := fixtures.CreateTestUser(db.DB)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create test user: %v", err)
|
||||
}
|
||||
defer fixtures.DeleteUser(db.DB, userID)
|
||||
|
||||
_, 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)
|
||||
|
||||
bookingID, err := fixtures.CreateTestBooking(db.DB, userID, serviceID)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create test booking: %v", err)
|
||||
}
|
||||
defer fixtures.DeleteBooking(db.DB, bookingID)
|
||||
|
||||
_, err = db.DB.Exec(context.Background(), "UPDATE bookings SET status = 'confirmed' WHERE id = $1", bookingID)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to confirm booking: %v", err)
|
||||
}
|
||||
|
||||
userToken := jwt.GenerateUserToken(userID)
|
||||
|
||||
newStartTime := time.Now().Add(48 * time.Hour).Truncate(time.Second)
|
||||
newStartTime = time.Date(newStartTime.Year(), newStartTime.Month(), newStartTime.Day(), 14, 0, 0, 0, newStartTime.Location())
|
||||
|
||||
createReq := http.HandlerFunc(RequestEditHandler)
|
||||
createBody := map[string]interface{}{
|
||||
"new_start_time": newStartTime.Format(time.RFC3339),
|
||||
}
|
||||
w := makeRequest(createReq, "POST", "/api/bookings/"+bookingID+"/edit-request", createBody, userToken)
|
||||
if w.Code != http.StatusCreated && w.Code != http.StatusOK {
|
||||
t.Fatalf("failed to create edit request: %d %s", w.Code, w.Body.String())
|
||||
}
|
||||
|
||||
var blockerCountBefore int
|
||||
err = db.DB.QueryRow(context.Background(),
|
||||
"SELECT COUNT(*) FROM time_blockers WHERE description = $1",
|
||||
fmt.Sprintf("RESERVATION:edit_request:%s", bookingID)).Scan(&blockerCountBefore)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to query blockers: %v", err)
|
||||
}
|
||||
if blockerCountBefore != 1 {
|
||||
t.Fatalf("expected 1 blocker before delete, got %d", blockerCountBefore)
|
||||
}
|
||||
|
||||
delHandler := http.HandlerFunc(DeleteEditRequestHandler)
|
||||
w = makeRequest(delHandler, "DELETE", "/api/bookings/"+bookingID+"/edit-request", nil, userToken)
|
||||
|
||||
if w.Code != http.StatusOK && w.Code != http.StatusNoContent {
|
||||
t.Errorf("expected status 200/204, got %d. body: %s", w.Code, w.Body.String())
|
||||
}
|
||||
|
||||
var blockerCountAfter int
|
||||
err = db.DB.QueryRow(context.Background(),
|
||||
"SELECT COUNT(*) FROM time_blockers WHERE description = $1",
|
||||
fmt.Sprintf("RESERVATION:edit_request:%s", bookingID)).Scan(&blockerCountAfter)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to query blockers after delete: %v", err)
|
||||
}
|
||||
if blockerCountAfter != 0 {
|
||||
t.Errorf("expected 0 blockers after user delete, got %d", blockerCountAfter)
|
||||
}
|
||||
}
|
||||
|
||||
// TestAdminApproveEditRequest_TimeBlockerOverlap tests that approving an edit
|
||||
// request fails when the new time conflicts with an existing time_blocker.
|
||||
func TestAdminApproveEditRequest_TimeBlockerOverlap(t *testing.T) {
|
||||
cleanup := setupTestDB(t)
|
||||
defer cleanup()
|
||||
|
||||
seedDefaultWorkingHours(t)
|
||||
|
||||
userID, err := fixtures.CreateTestUser(db.DB)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create test user: %v", err)
|
||||
}
|
||||
defer fixtures.DeleteUser(db.DB, userID)
|
||||
|
||||
_, 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)
|
||||
|
||||
bookingID, err := fixtures.CreateTestBooking(db.DB, userID, serviceID)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create test booking: %v", err)
|
||||
}
|
||||
defer fixtures.DeleteBooking(db.DB, bookingID)
|
||||
|
||||
_, err = db.DB.Exec(context.Background(), "UPDATE bookings SET status = 'confirmed' WHERE id = $1", bookingID)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to confirm booking: %v", err)
|
||||
}
|
||||
|
||||
userToken := jwt.GenerateUserToken(userID)
|
||||
|
||||
newStartTime := time.Now().Add(48 * time.Hour).Truncate(time.Second)
|
||||
newStartTime = time.Date(newStartTime.Year(), newStartTime.Month(), newStartTime.Day(), 14, 0, 0, 0, newStartTime.Location())
|
||||
|
||||
createReq := http.HandlerFunc(RequestEditHandler)
|
||||
createBody := map[string]interface{}{
|
||||
"new_start_time": newStartTime.Format(time.RFC3339),
|
||||
}
|
||||
w := makeRequest(createReq, "POST", "/api/bookings/"+bookingID+"/edit-request", createBody, userToken)
|
||||
if w.Code != http.StatusCreated && w.Code != http.StatusOK {
|
||||
t.Fatalf("failed to create edit request: %d %s", w.Code, w.Body.String())
|
||||
}
|
||||
|
||||
_, err = db.DB.Exec(context.Background(), `
|
||||
INSERT INTO time_blockers (start_time, duration_minutes, description, created_by)
|
||||
VALUES ($1, 60, 'Existing blocker', $2)
|
||||
`, newStartTime, userID)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create blocking time_blocker: %v", err)
|
||||
}
|
||||
|
||||
var editRequestID string
|
||||
err = db.DB.QueryRow(context.Background(),
|
||||
"SELECT id FROM booking_edit_requests WHERE booking_id = $1", bookingID).Scan(&editRequestID)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get edit request ID: %v", err)
|
||||
}
|
||||
|
||||
r := chi.NewRouter()
|
||||
r.Post("/api/admin/bookings/{id}/edit-requests/{request_id}/approve", AdminApproveEditRequestHandler)
|
||||
req := httptest.NewRequest("POST", "/api/admin/bookings/"+bookingID+"/edit-requests/"+editRequestID+"/approve", nil)
|
||||
ctx := context.WithValue(req.Context(), mw.UserRoleKey, "admin")
|
||||
rctx := chi.NewRouteContext()
|
||||
rctx.URLParams.Add("id", bookingID)
|
||||
rctx.URLParams.Add("request_id", editRequestID)
|
||||
ctx = context.WithValue(ctx, chi.RouteCtxKey, rctx)
|
||||
req = req.WithContext(ctx)
|
||||
w = httptest.NewRecorder()
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusConflict {
|
||||
t.Errorf("expected status 409 Conflict due to time_blocker overlap, got %d. body: %s", w.Code, w.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
// TestBookings_RequestEdit_BookingNotFound tests that requesting an edit for a non-existent booking returns 404
|
||||
func TestBookings_RequestEdit_BookingNotFound(t *testing.T) {
|
||||
cleanup := setupTestDB(t)
|
||||
|
||||
Reference in New Issue
Block a user