//go:build test package admin import ( "bytes" "context" "encoding/json" "net/http" "net/http/httptest" "strings" "crussell/mw" "github.com/go-chi/chi/v5" ) // makeAdminRequest creates a request with admin context // Note: Using 12-char IDs to match CHAR(12) columns in schema (e.g., created_by) func makeAdminRequest(handler http.Handler, method, path string, body interface{}, ctx context.Context) *httptest.ResponseRecorder { return makeRequestWithContext(handler, method, path, body, "admin001", "admin", ctx) } // makeUserRequest creates a request with regular user context // Note: Using 12-char IDs to match CHAR(12) columns in schema (e.g., created_by) func makeUserRequest(handler http.Handler, method, path string, body interface{}, ctx context.Context) *httptest.ResponseRecorder { return makeRequestWithContext(handler, method, path, body, "user001", "verified_email", ctx) } // makeRequestWithContext creates a request with specific user context func makeRequestWithContext(handler http.Handler, method, path string, body interface{}, userID, role string, ctx context.Context) *httptest.ResponseRecorder { var req *http.Request if body != nil { bodyBytes, _ := json.Marshal(body) req = httptest.NewRequest(method, path, bytes.NewReader(bodyBytes)) req.Header.Set("Content-Type", "application/json") } else { req = httptest.NewRequest(method, path, nil) } rctx := chi.NewRouteContext() if method == "GET" || method == "PUT" || method == "POST" || method == "DELETE" || method == "PATCH" { if id, paramName := extractIDFromPath(path); id != "" { rctx.URLParams.Add(paramName, id) } // Extract request_id for: /api/admin/bookings/{id}/edit-requests/{request_id}/approve if parts := strings.Split(path, "/"); len(parts) >= 8 && parts[5] == "edit-requests" { rctx.URLParams.Add("request_id", parts[6]) } } ctx = context.WithValue(ctx, chi.RouteCtxKey, rctx) ctx = context.WithValue(ctx, mw.UserIDKey, userID) ctx = context.WithValue(ctx, mw.UserRoleKey, role) req = req.WithContext(ctx) w := httptest.NewRecorder() handler.ServeHTTP(w, req) return w } func extractIDFromPath(path string) (string, string) { patterns := []struct { prefix string paramName string }{ {"/api/admin/bookings/user/", "user_id"}, {"/api/admin/users/", "id"}, {"/api/admin/bookings/", "id"}, {"/api/admin/services/", "id"}, {"/api/admin/patch-tests/", "id"}, {"/api/bookings/", "id"}, {"/api/services/eligible-for/", "userId"}, {"/api/services/", "id"}, } for _, p := range patterns { if strings.HasPrefix(path, p.prefix) { suffix := path[len(p.prefix):] if slashIdx := strings.Index(suffix, "/"); slashIdx >= 0 { return suffix[:slashIdx], p.paramName } return suffix, p.paramName } } return "", "" } func parseResponseBody(w *httptest.ResponseRecorder, dest interface{}) error { return json.Unmarshal(w.Body.Bytes(), dest) }