Large manual tests corruption fix

This commit is contained in:
2026-03-02 18:07:13 +00:00
parent 817d5dd021
commit dd097c1022
14 changed files with 171 additions and 138 deletions
+16 -19
View File
@@ -1,6 +1,8 @@
//go:build test
// +build test
package admin
// Package admin contains tests for admin booking management endpoints.
//
// Test Coverage:
@@ -16,11 +18,6 @@
// - AdminRejectEditRequestHandler: POST /api/admin/bookings/{id}/reject-edit - Reject edit
//
// Authentication: All endpoints require admin role (403 for non-admins).
package admin
//go:build test
// +build test
package admin
import (
"context"
@@ -35,14 +32,15 @@ import (
"crussell/mw"
"crussell/testutils/fixtures"
"github.com/lib/pq"
)
"context"
"fmt"
"net/http"
"testing"
"time"
"github.com/go-chi/chi/v5"
"github.com/lib/pq"
"crussell/db"
"crussell/handlers/bookings"
"crussell/mw"
@@ -57,6 +55,7 @@ import (
// TestAdminBookings_List verifies that an admin can list all bookings in the
// system with pagination support.
func TestAdminBookings_List(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
@@ -113,6 +112,7 @@ import (
// TestAdminBookings_List_FilterByStatus tests that an admin can filter
// bookings by status (e.g., pending, confirmed, completed).
func TestAdminBookings_List_FilterByStatus(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
@@ -177,6 +177,7 @@ import (
// TestAdminBookings_Create verifies that an admin can create a booking
// on behalf of a user. The booking is created with 'confirmed' status.
func TestAdminBookings_Create(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
@@ -235,6 +236,7 @@ import (
// TestAdminBookings_Create_InvalidInput verifies that admin booking
// creation fails with HTTP 400 when required fields (userID, startTime, serviceIDs)
// are missing or invalid.
func TestAdminBookings_Create_InvalidInput(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
@@ -303,6 +305,7 @@ import (
// TestAdminBookings_Search tests that an admin can search bookings by
// notes, customer name, or other text fields.
func TestAdminBookings_Search(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
@@ -355,6 +358,7 @@ import (
// TestAdminBookings_Search_MissingQuery verifies that searching without
// a query parameter returns HTTP 400 Bad Request.
func TestAdminBookings_Search_MissingQuery(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
@@ -1167,6 +1171,7 @@ func TestAdminBookings_Search_MultipleResults(t *testing.T) {
t.Errorf("expected total 2, got %d", resp.Total)
}
}
// =============================================================================
// Admin List Edit Requests Tests
// =============================================================================
@@ -1208,7 +1213,7 @@ func TestAdminBookings_ListEditRequests(t *testing.T) {
t.Fatalf("failed to update booking status: %v", err)
}
// Clean up ALL existing edit requests in DB to ensure clean state (handler doesn't filter by booking_id)
// Clean up ALL existing edit requests in DB to ensure clean state
_, err = db.DB.Exec(context.Background(), "DELETE FROM booking_edit_requests")
if err != nil {
t.Fatalf("failed to clean up edit requests: %v", err)
@@ -1258,7 +1263,6 @@ func TestAdminBookings_ListEditRequests(t *testing.T) {
}
}
// =============================================================================
// Admin Deny Edit Request Tests
// =============================================================================
@@ -1320,14 +1324,12 @@ func TestAdminBookings_DenyEditRequest(t *testing.T) {
t.Fatalf("failed to create edit request: %v", err)
}
// Call admin deny endpoint - need to manually set chi context with both bookingID and request_id
// Call admin deny endpoint
handler := http.HandlerFunc(bookings.AdminRejectEditRequestHandler)
// Build request manually to include both bookingID and request_id in chi context
path := fmt.Sprintf("/api/admin/bookings/%s/edit-requests/%s/deny", bookingID, editRequestID)
req := httptest.NewRequest("POST", path, nil)
// Set up chi routing context with both params
rctx := chi.NewRouteContext()
rctx.URLParams.Add("id", bookingID)
rctx.URLParams.Add("request_id", editRequestID)
@@ -1339,19 +1341,17 @@ func TestAdminBookings_DenyEditRequest(t *testing.T) {
w := httptest.NewRecorder()
handler.ServeHTTP(w, req)
// Expect HTTP 200 OK
if w.Code != http.StatusOK && w.Code != http.StatusNoContent {
t.Errorf("expected status 200/204, got %d. body: %s", w.Code, w.Body.String())
}
// Verify edit request is handled (deleted in current implementation)
// Verify edit request is deleted
var erCount int
err = db.DB.QueryRow(context.Background(),
"SELECT COUNT(*) FROM booking_edit_requests WHERE id = $1", editRequestID).Scan(&erCount)
if err != nil {
t.Fatalf("failed to query edit requests: %v", err)
}
// Current implementation deletes the edit request
if erCount != 0 {
t.Errorf("expected edit request to be deleted after deny, got %d", erCount)
}
@@ -1445,14 +1445,12 @@ func TestAdminBookings_ApproveEditRequest(t *testing.T) {
t.Fatalf("failed to create admin notification: %v", err)
}
// Call admin approve endpoint using makeAdminRequest with manual chi context for two params
// Call admin approve endpoint
handler := http.HandlerFunc(bookings.AdminApproveEditRequestHandler)
// Build request manually to include both bookingID and request_id in chi context
path := fmt.Sprintf("/api/admin/bookings/%s/edit-requests/%s/approve", bookingID, editRequestID)
req := httptest.NewRequest("POST", path, nil)
// Set up chi routing context with both params
rctx := chi.NewRouteContext()
rctx.URLParams.Add("id", bookingID)
rctx.URLParams.Add("request_id", editRequestID)
@@ -1464,7 +1462,6 @@ func TestAdminBookings_ApproveEditRequest(t *testing.T) {
w := httptest.NewRecorder()
handler.ServeHTTP(w, req)
// Expect 204 NoContent
if w.Code != http.StatusNoContent {
t.Errorf("expected status 204, got %d. body: %s", w.Code, w.Body.String())
}
+13 -11
View File
@@ -1,6 +1,8 @@
//go:build test
// +build test
package admin
// Package admin contains tests for admin service management endpoints.
//
// Test Coverage:
@@ -10,11 +12,6 @@
// - DeleteServiceHandler: DELETE /api/admin/services/{id} - Soft delete service
//
// Authentication: All endpoints require admin role (403 for non-admins).
package admin
//go:build test
// +build test
package admin
import (
"context"
@@ -30,6 +27,7 @@ import (
// TestAdminServices_Create verifies that an admin can create a new service
// with name, description, price, duration, and minimum age requirements. The new
// service is active by default and stored in the database.
func TestAdminServices_Create(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
@@ -76,13 +74,14 @@ import (
// TestAdminServices_List tests that an admin can retrieve all services,
// including inactive ones. This is useful for managing the full service catalog.
func TestAdminServices_List(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
// Insert test services
_, err := db.DB.Exec(context.Background(), `
INSERT INTO services (name, description, price, duration_minutes, is_active, minimum_age_required)
VALUES
VALUES
('Manicure', 'Basic manicure', 25.00, 30, true, 0),
('Pedicure', 'Basic pedicure', 30.00, 45, false, 0),
('Gel Polish', 'Gel polish service', 40.00, 60, true, 16)
@@ -127,6 +126,7 @@ import (
// TestAdminServices_Toggle verifies that an admin can toggle a service's
// active status on/off. This is used to temporarily disable a service without
// deleting it from the system.
func TestAdminServices_Toggle(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
@@ -177,6 +177,7 @@ import (
// TestAdminServices_Delete tests that an admin can soft-delete a service
// by setting is_active to false. The service record remains but is hidden from
// customers.
func TestAdminServices_Delete(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
@@ -212,6 +213,7 @@ import (
// TestAdminServices_NonAdmin verifies that non-admin users receive HTTP 403
// Forbidden when attempting to create, list, toggle, or delete services. This
// ensures proper role-based access control.
func TestAdminServices_NonAdmin(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
@@ -227,11 +229,11 @@ import (
// Test CREATE - should get 403 when using middleware
createHandler := mw.RequireAdmin(http.HandlerFunc(services.CreateServiceHandler))
createReq := services.CreateServiceRequest{
Name: "Test Service",
Description: stringPtr("Test"),
Price: 50.00,
DurationMinutes: 60,
MinimumAgeRequired: 16,
Name: "Test Service",
Description: stringPtr("Test"),
Price: 50.00,
DurationMinutes: 60,
MinimumAgeRequired: 16,
}
w := makeUserRequest(createHandler, "POST", "/api/admin/services", createReq)
if w.Code != http.StatusForbidden {
+9 -6
View File
@@ -1,6 +1,8 @@
//go:build test
// +build test
package admin
// Package admin contains tests for admin dashboard "today" endpoints.
//
// Test Coverage:
@@ -11,12 +13,7 @@
// - AcknowledgeNotification: POST /api/admin/notifications/{id}/ack - Acknowledge (WIP - skipped)
//
// Authentication: All endpoints require admin role (403 for non-admins).
// WIP: Notification tests are skipped pending handler implementation.
package admin
//go:build test
// +build test
package admin
// WIP: Notification tests are skipped pending handler implementation.package admin
import (
"context"
@@ -32,6 +29,7 @@ import (
// TestAdminToday_CurrentNext verifies that an admin can retrieve the currently
// in-progress booking and the next upcoming booking for the dashboard.
func TestAdminToday_CurrentNext(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
@@ -107,6 +105,7 @@ import (
// 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) {
cleanup := setupTestDB(t)
defer cleanup()
@@ -182,6 +181,7 @@ import (
// TestAdminToday_PendingApprovals verifies that an admin can see all pending
// bookings that require approval/confirmation.
func TestAdminToday_PendingApprovals(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
@@ -257,16 +257,19 @@ import (
// TestAdminNotifications_List is skipped (WIP) - tests that an admin
// can list all their notifications.
func TestAdminNotifications_List(t *testing.T) {
t.Skip("Skipping - WIP handler")
}
// TestAdminNotifications_Acknowledge is skipped (WIP) - tests that an
// admin can acknowledge a notification.
func TestAdminNotifications_Acknowledge(t *testing.T) {
t.Skip("Skipping - WIP handler")
}
// TestAdminToday_NonAdmin verifies that non-admin users receive HTTP 403
// when accessing today's dashboard endpoints.
func TestAdminToday_NonAdmin(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
+12 -10
View File
@@ -1,6 +1,8 @@
//go:build test
// +build test
package admin
// Package admin contains tests for admin user management endpoints.
//
// Test Coverage:
@@ -11,11 +13,6 @@
// - RequireAdmin middleware: All endpoints require admin role (403 for non-admins)
//
// Database State: Tests create and clean up users in the users table.
package admin
//go:build test
// +build test
package admin
import (
"context"
@@ -30,13 +27,14 @@ import (
// TestAdminUsers_List verifies that an admin can list all users in the
// system with their details including account role and type.
func TestAdminUsers_List(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
// Create test users
_, err := db.DB.Exec(context.Background(), `
INSERT INTO users (n_first_name, n_last_name, email, phone, date_of_birth, password_hash, account_role, account_type)
VALUES
VALUES
('Alice', 'Smith', 'alice@test.com', '+447123456789', '1990-01-01', 'hash1', 'admin', 'email'),
('Bob', 'Jones', 'bob@test.com', '+447123456789', '1990-01-01', 'hash2', 'verified_email', 'email'),
('Charlie', 'Brown', 'charlie@test.com', '+447123456789', '1990-01-01', 'hash3', 'verified_email', 'email')
@@ -68,6 +66,7 @@ import (
// TestAdminUsers_Get tests that an admin can retrieve detailed information
// about a specific user including their profile and account settings.
func TestAdminUsers_Get(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
@@ -105,6 +104,7 @@ import (
// TestAdminUsers_Get_NotFound verifies that requesting details for a
// non-existent user returns HTTP 404 Not Found.
func TestAdminUsers_Get_NotFound(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
@@ -120,6 +120,7 @@ import (
// TestAdminUsers_PatchTests_Eligible tests that the system correctly
// identifies which services require patch tests and returns only those services
// the user is eligible for based on age requirements.
func TestAdminUsers_PatchTests_Eligible(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
@@ -137,7 +138,7 @@ import (
// Create services - some with patch test, some without
_, err = db.DB.Exec(context.Background(), `
INSERT INTO services (name, description, price, duration_minutes, is_active, minimum_age_required)
VALUES
VALUES
('Basic Manicure', 'Basic manicure', 25.00, 30, true, 0),
('Gel Polish Full Set', 'Gel polish service', 45.00, 60, true, 16),
('Luxury Gel Manicure', 'Luxury gel', 55.00, 75, true, 16),
@@ -196,6 +197,7 @@ import (
// TestAdminUsers_PatchTests_Eligible_WithExisting verifies that when a
// user already has a valid patch test on file, that service is filtered out
// from the eligible list (since they've already completed it).
func TestAdminUsers_PatchTests_Eligible_WithExisting(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
@@ -282,6 +284,7 @@ import (
// TestAdminUsers_AddPatchTest verifies that an admin can record a patch
// test completion for a user, creating a user_patch_tests record.
func TestAdminUsers_AddPatchTest(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
@@ -369,6 +372,7 @@ func TestAdminUsers_AddPatchTest_InvalidPatchTest(t *testing.T) {
// TestAdminUsers_NonAdmin verifies that non-admin users receive HTTP 403
// Forbidden when attempting to list users, get user details, or manage patch tests.
func TestAdminUsers_NonAdmin(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
@@ -421,10 +425,9 @@ func TestAdminUsers_AddPatchTest_InvalidPatchTest(t *testing.T) {
}
}
// TestAdminUsers_Get_Success is an additional test verifying admin can
// retrieve user details including ID, name, email, and account role.
func TestAdminUsers_Get_Success(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
@@ -470,4 +473,3 @@ func TestAdminUsers_AddPatchTest_InvalidPatchTest(t *testing.T) {
t.Errorf("expected account_role 'verified_email', got '%s'", resp.AccountRole)
}
}