refactor: optimize test DB setup — TestMain per package, truncate-only between tests

- Add TestMain to all 10 test packages (schema DROP+CREATE runs once per package)
- Convert per-test setupTestDB to resetTestData (TRUNCATE only, ~60% faster)
- Add 3 missing tables to TruncateTables (booking_edit_requests, exceptional_group_applications, business_settings)
- Remove dead truncateDiscountTables helper
- Consolidate discount_test.go into package bookings (was external test package)
- Update testutils.SetupTestDB to truncate-only
- Fix unused imports across user, bookings, and handlers packages
- Verify: 286 passing, 2 skipped, 0 failures with -count=2 (no state leakage)
This commit is contained in:
2026-05-10 17:27:51 +01:00
parent 83c62ffb97
commit e73c96b653
26 changed files with 554 additions and 920 deletions
+42 -84
View File
@@ -77,8 +77,7 @@ func seedDefaultWorkingHours(t *testing.T) {
// 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()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -134,8 +133,7 @@ func TestAdminBookings_List(t *testing.T) {
// 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()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -199,8 +197,7 @@ func TestAdminBookings_List_FilterByStatus(t *testing.T) {
// 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()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -268,8 +265,7 @@ func TestAdminBookings_Create(t *testing.T) {
// 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()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -337,8 +333,7 @@ func TestAdminBookings_Create_InvalidInput(t *testing.T) {
// 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()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -390,8 +385,7 @@ func TestAdminBookings_Search(t *testing.T) {
// 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()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -414,8 +408,7 @@ func TestAdminBookings_Search_MissingQuery(t *testing.T) {
// TestAdminBookings_Get verifies that an admin can retrieve a single booking by ID and that
// the response includes populated user and services relationships.
func TestAdminBookings_Get(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -468,8 +461,7 @@ func TestAdminBookings_Get(t *testing.T) {
// TestAdminBookings_Get_NotFound verifies that requesting a non-existent booking returns 404.
func TestAdminBookings_Get_NotFound(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -491,8 +483,7 @@ func TestAdminBookings_Get_NotFound(t *testing.T) {
// TestAdminBookings_GetUserBookings verifies that an admin can retrieve all bookings for a specific user.
func TestAdminBookings_GetUserBookings(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -552,8 +543,7 @@ func TestAdminBookings_GetUserBookings(t *testing.T) {
// TestAdminBookings_Progress verifies that an admin can change a booking's status (e.g., pending to confirmed),
// and that the status is correctly updated in both the response and database.
func TestAdminBookings_Progress(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -612,8 +602,7 @@ func TestAdminBookings_Progress(t *testing.T) {
// TestAdminBookings_Progress_InvalidStatus verifies that providing an invalid status value returns 400 Bad Request.
func TestAdminBookings_Progress_InvalidStatus(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -653,8 +642,7 @@ func TestAdminBookings_Progress_InvalidStatus(t *testing.T) {
// TestAdminBookings_Progress_NotFound verifies that attempting to progress a non-existent booking returns 404.
func TestAdminBookings_Progress_NotFound(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -680,8 +668,7 @@ func TestAdminBookings_Progress_NotFound(t *testing.T) {
// TestAdminBookings_Confirm verifies that an admin can confirm a pending booking, updating its status to 'confirmed'.
func TestAdminBookings_Confirm(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -729,8 +716,7 @@ func TestAdminBookings_Confirm(t *testing.T) {
// TestAdminBookings_Confirm_AlreadyConfirmed verifies idempotency - attempting to confirm
// an already-confirmed booking returns 404 Not Found.
func TestAdminBookings_Confirm_AlreadyConfirmed(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -778,8 +764,7 @@ func TestAdminBookings_Confirm_AlreadyConfirmed(t *testing.T) {
// TestAdminBookings_Cancel verifies that an admin can cancel a booking, updating its status to 'we_cancelled'.
func TestAdminBookings_Cancel(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -831,8 +816,7 @@ func TestAdminBookings_Cancel(t *testing.T) {
// TestAdminBookings_Cancel_NotFound verifies that attempting to cancel a non-existent booking returns 404.
func TestAdminBookings_Cancel_NotFound(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -851,8 +835,7 @@ func TestAdminBookings_Cancel_NotFound(t *testing.T) {
// TestAdminBookings_Cancel_PendingStatus verifies that admin cancellations of pending bookings
// do NOT create admin notifications (pending cancellations don't require staff attention).
func TestAdminBookings_Cancel_PendingStatus(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -915,8 +898,7 @@ func TestAdminBookings_Cancel_PendingStatus(t *testing.T) {
// TestAdminBookings_Cancel_ConfirmedCreatesNotification verifies that cancelling a confirmed
// booking creates an admin notification for staff awareness.
func TestAdminBookings_Cancel_ConfirmedCreatesNotification(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -982,8 +964,7 @@ func TestAdminBookings_Cancel_ConfirmedCreatesNotification(t *testing.T) {
// TestAdminBookings_Cancel_InProgressStatus verifies cancellation of in-progress bookings.
func TestAdminBookings_Cancel_InProgressStatus(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -1038,8 +1019,7 @@ func TestAdminBookings_Cancel_InProgressStatus(t *testing.T) {
// TestAdminBookings_Cancel_AlreadyCancelledRejectsCancellation verifies that attempting to
// cancel an already-cancelled booking returns 404 Not Found (idempotency guard).
func TestAdminBookings_Cancel_AlreadyCancelledRejectsCancellation(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -1084,8 +1064,7 @@ func TestAdminBookings_Cancel_AlreadyCancelledRejectsCancellation(t *testing.T)
// TestAdminBookings_Cancel_CompletedRejectsCancellation verifies that attempting to cancel
// a completed booking returns 404 Not Found (cannot cancel finished appointments).
func TestAdminBookings_Cancel_CompletedRejectsCancellation(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -1134,8 +1113,7 @@ func TestAdminBookings_Cancel_CompletedRejectsCancellation(t *testing.T) {
// TestAdminBookings_NonAdmin verifies that regular users receive 403 Forbidden when attempting
// to access any admin booking endpoints (list, get, create, progress, confirm, cancel, search).
func TestAdminBookings_NonAdmin(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
_, err := fixtures.CreateTestUser(db.DB)
if err != nil {
@@ -1210,8 +1188,7 @@ func TestAdminBookings_NonAdmin(t *testing.T) {
// TestAdminBookings_Create_DuringHolidayHours_Rejected verifies that an admin cannot create a booking
// during hours marked as closed in the exceptional working hours (holiday) system.
func TestAdminBookings_Create_DuringHolidayHours_Rejected(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -1294,8 +1271,7 @@ func TestAdminBookings_Create_DuringHolidayHours_Rejected(t *testing.T) {
// TestAdminBookings_Search_CaseInsensitive verifies that the admin booking search is case-insensitive,
// matching booking notes regardless of uppercase/lowercase differences.
func TestAdminBookings_Search_CaseInsensitive(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -1359,8 +1335,7 @@ func TestAdminBookings_Search_CaseInsensitive(t *testing.T) {
// TestAdminBookings_Search_NoResults verifies that searching with a query that matches no bookings
// returns an empty list with total count of 0.
func TestAdminBookings_Search_NoResults(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -1412,8 +1387,7 @@ func TestAdminBookings_Search_NoResults(t *testing.T) {
// TestAdminBookings_Search_MultipleResults verifies that search returns all bookings whose notes
// contain the search query, with correct total count.
func TestAdminBookings_Search_MultipleResults(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -1489,8 +1463,7 @@ func TestAdminBookings_Search_MultipleResults(t *testing.T) {
// TestAdminBookings_ListEditRequests verifies that an admin can list all pending edit requests
// for a specific booking, and that the response includes the correct count and request details.
func TestAdminBookings_ListEditRequests(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -1580,8 +1553,7 @@ func TestAdminBookings_ListEditRequests(t *testing.T) {
// TestAdminBookings_DenyEditRequest verifies that denying an edit request deletes the request
// while keeping the original booking time unchanged, and returns success.
func TestAdminBookings_DenyEditRequest(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -1681,8 +1653,7 @@ func TestAdminBookings_DenyEditRequest(t *testing.T) {
// TestAdminBookings_ApproveEditRequest verifies that approving an edit request updates the booking's
// start_time to the requested time, deletes the edit request, and acknowledges the admin notification.
func TestAdminBookings_ApproveEditRequest(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
// Create admin user
adminID, err := fixtures.CreateTestAdminUser(db.DB)
@@ -1820,8 +1791,7 @@ func TestAdminBookings_ApproveEditRequest(t *testing.T) {
// deposit-related fields (deposit_required, deposit_amount, deposit_paid, deposit_deadline)
// for bookings that have deposit_required=true.
func TestAdminBookings_Get_DepositFields(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -1892,8 +1862,7 @@ func TestAdminBookings_Get_DepositFields(t *testing.T) {
// TestAdminBookings_List_DepositFields verifies that admin booking list returns
// deposit-related fields for each booking.
func TestAdminBookings_List_DepositFields(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -1970,8 +1939,7 @@ func TestAdminBookings_List_DepositFields(t *testing.T) {
// create bookings that overlap with time blockers, but receive a warning.
// The booking is still created (201 Created), unlike regular users who get 409.
func TestAdminBookings_Create_OverlappingBlocker_WithWarning(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -2051,8 +2019,7 @@ func TestAdminBookings_Create_OverlappingBlocker_WithWarning(t *testing.T) {
// edit bookings to overlap with time blockers, but receive a warning.
// The booking is still updated (200 OK with warnings), unlike regular users who get 409.
func TestAdminBookings_Edit_OverlappingBlocker_WithWarning(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -2141,8 +2108,7 @@ func TestAdminBookings_Edit_OverlappingBlocker_WithWarning(t *testing.T) {
// TestAdminBookings_Create_EnforceDeposits_Bypass tests that admin can create bookings
// for users with outstanding deposits by setting enforce_deposits=false.
func TestAdminBookings_Create_EnforceDeposits_Bypass(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -2189,8 +2155,7 @@ func TestAdminBookings_Create_EnforceDeposits_Bypass(t *testing.T) {
// TestAdminBookings_Create_EnforceDeposits_Enforced tests that by default (or when enforce_deposits=true),
// admin bookings respect the deposit requirement rules.
func TestAdminBookings_Create_EnforceDeposits_Enforced(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -2252,8 +2217,7 @@ func TestAdminBookings_Create_EnforceDeposits_Enforced(t *testing.T) {
// TestAdminBookings_Create_WalkIn tests that admins can create walk-in bookings
// (no advance time requirement), including immediate/past times if needed.
func TestAdminBookings_Create_WalkIn(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -2299,8 +2263,7 @@ func TestAdminBookings_Create_WalkIn(t *testing.T) {
// TestAdminBookings_Create_WalkInWithDeposits tests that admins can create walk-ins
// even when user has outstanding deposits and enforce_deposits=false.
func TestAdminBookings_Create_WalkInWithDeposits(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -2358,8 +2321,7 @@ func TestAdminBookings_Create_WalkInWithDeposits(t *testing.T) {
// confirmed booking is progressed to completed with at least one payment, the user's
// deposits_required is reduced by 1.
func TestAdminBookings_Confirm_CompletesWithPayment_ReducesDeposits(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -2444,8 +2406,7 @@ func TestAdminBookings_Confirm_CompletesWithPayment_ReducesDeposits(t *testing.T
// TestAdminBookings_Confirm_CompletesWithoutPayment_NoReduction verifies that when a
// booking is completed without any payments, the user's deposits_required is NOT reduced.
func TestAdminBookings_Confirm_CompletesWithoutPayment_NoReduction(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -2524,8 +2485,7 @@ func TestAdminBookings_Confirm_CompletesWithoutPayment_NoReduction(t *testing.T)
// enforce_deposits is set to false, the admin can create a second booking for a user
// who already has an active booking, bypassing the one-active-booking limit.
func TestAdminBookings_Create_EnforceDepositsFalse_BypassesLimit(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -2590,8 +2550,7 @@ func TestAdminBookings_Create_EnforceDepositsFalse_BypassesLimit(t *testing.T) {
// enforce_deposits is set to false, the admin can create a booking within 24 hours
// for a user with outstanding deposits.
func TestAdminBookings_Create_EnforceDepositsFalse_Within24h(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
@@ -2648,8 +2607,7 @@ func TestAdminBookings_Create_EnforceDepositsFalse_Within24h(t *testing.T) {
// TestAdminBookings_Create_WalkInGuestUser verifies that an admin can create a booking
// for a guest user (created via fixtures.CreateTestGuestUser).
func TestAdminBookings_Create_WalkInGuestUser(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
adminID, err := fixtures.CreateTestAdminUser(db.DB)
if err != nil {
+5 -10
View File
@@ -28,8 +28,7 @@ import (
// 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()
resetTestData(t)
// Create admin user in DB first
_, err := db.DB.Exec(context.Background(), `
@@ -75,8 +74,7 @@ func TestAdminServices_Create(t *testing.T) {
// 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()
resetTestData(t)
// Insert test services
_, err := db.DB.Exec(context.Background(), `
@@ -127,8 +125,7 @@ func TestAdminServices_List(t *testing.T) {
// 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()
resetTestData(t)
// Create a service
var serviceID string
@@ -178,8 +175,7 @@ func TestAdminServices_Toggle(t *testing.T) {
// 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()
resetTestData(t)
// Create a service
var serviceID string
@@ -214,8 +210,7 @@ func TestAdminServices_Delete(t *testing.T) {
// 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()
resetTestData(t)
// Create regular user in DB
_, err := db.DB.Exec(context.Background(), `
+3 -32
View File
@@ -9,48 +9,19 @@ import (
"encoding/json"
"net/http"
"net/http/httptest"
"os"
"testing"
"crussell/db"
"crussell/mw"
"crussell/testutils/jwt"
"crussell/testutils/testdb"
"github.com/go-chi/chi/v5"
)
// TestMain initializes test environment variables before any tests run
func TestMain(m *testing.M) {
// Set database environment variables for test database
os.Setenv("POSTGRES_USER", "myuser")
os.Setenv("POSTGRES_PASSWORD", "mypassword")
os.Setenv("POSTGRES_HOST", "localhost")
os.Setenv("POSTGRES_DB", "crussell_test")
os.Setenv("GO_TESTING", "true")
// Run the tests
code := m.Run()
os.Exit(code)
}
// setupTestDB replaces the global db.DB with a test pool and returns a cleanup function
func setupTestDB(t *testing.T) func() {
// resetTestData truncates tables to clean up data between tests
func resetTestData(t *testing.T) {
t.Helper()
pool := testdb.Pool(t)
testdb.Migrate(t, pool)
testdb.TruncateTables(t, pool) // Clear data between tests
originalDB := db.DB
db.DB = pool
jwt.Init()
return func() {
db.DB = originalDB
pool.Close()
}
testdb.TruncateTables(t, db.DB)
}
// makeAdminRequest creates a request with admin context
+26
View File
@@ -0,0 +1,26 @@
//go:build test
// +build test
package admin
import (
"os"
"testing"
"crussell/db"
"crussell/testutils/testdb"
"crussell/testutils/jwt"
)
func TestMain(m *testing.M) {
pool, err := testdb.NewPool("")
if err != nil {
panic(err)
}
testdb.Migrate(&testing.T{}, pool)
db.DB = pool
jwt.Init()
code := m.Run()
pool.Close()
os.Exit(code)
}
+9 -18
View File
@@ -30,8 +30,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()
resetTestData(t)
// Create test user
var userID string
@@ -106,8 +105,7 @@ 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()
resetTestData(t)
// Seed working hours for today (query uses current weekday)
todayWeekday := int(time.Now().Weekday())
@@ -151,8 +149,7 @@ func TestAdminToday_CurrentNext_ClosingTime(t *testing.T) {
// 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()
resetTestData(t)
// Create test user
var userID string
@@ -227,8 +224,7 @@ func TestAdminToday_Appointments(t *testing.T) {
// 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()
resetTestData(t)
// Create test user
var userID string
@@ -310,8 +306,7 @@ func TestAdminToday_PendingApprovals(t *testing.T) {
//
// The transition happens silently in the background during GET requests, not via cron.
func TestAdminToday_AutoTransition_ConfirmedToInProgress(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
// Create test user
var userID string
@@ -384,8 +379,7 @@ func TestAdminToday_AutoTransition_ConfirmedToInProgress(t *testing.T) {
//
// The transition happens silently in the background during GET requests, not via cron.
func TestAdminToday_AutoTransition_InProgressToCompleted(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
// Create test user
var userID string
@@ -455,8 +449,7 @@ func TestAdminToday_AutoTransition_InProgressToCompleted(t *testing.T) {
// TestAdminToday_NoAutoTransition_BeforeStartTime verifies that a confirmed
// booking that hasn't started yet is NOT transitioned to in_progress.
func TestAdminToday_NoAutoTransition_BeforeStartTime(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
// Create test user
var userID string
@@ -525,8 +518,7 @@ func TestAdminToday_NoAutoTransition_BeforeStartTime(t *testing.T) {
// TestAdminToday_AutoTransition_CurrentNextHandler verifies that auto-transition
// also works when calling GetCurrentAndNextHandler (not just appointments handler)
func TestAdminToday_AutoTransition_CurrentNextHandler(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
// Create test user
var userID string
@@ -619,8 +611,7 @@ func TestAdminNotifications_Acknowledge(t *testing.T) {
// 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()
resetTestData(t)
// Test current-next endpoint
currentNextHandler := mw.RequireAdmin(http.HandlerFunc(today.GetCurrentAndNextHandler))
+10 -20
View File
@@ -29,8 +29,7 @@ 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()
resetTestData(t)
// Create test users
_, err := db.DB.Exec(context.Background(), `
@@ -68,8 +67,7 @@ func TestAdminUsers_List(t *testing.T) {
// 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()
resetTestData(t)
// Create test user
var userID string
@@ -106,8 +104,7 @@ func TestAdminUsers_Get(t *testing.T) {
// 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()
resetTestData(t)
handler := http.HandlerFunc(user.GetAdminUserHandler)
// Use 12-char or less ID to avoid CHAR(12) constraint error
@@ -122,8 +119,7 @@ func TestAdminUsers_Get_NotFound(t *testing.T) {
// 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()
resetTestData(t)
// Create test user
var userID string
@@ -199,8 +195,7 @@ func TestAdminUsers_PatchTests_Eligible(t *testing.T) {
// 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()
resetTestData(t)
// Create test user
var userID string
@@ -286,8 +281,7 @@ func TestAdminUsers_PatchTests_Eligible_WithExisting(t *testing.T) {
// 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()
resetTestData(t)
// Create test user
var userID string
@@ -346,8 +340,7 @@ func TestAdminUsers_AddPatchTest(t *testing.T) {
}
func TestAdminUsers_AddPatchTest_InvalidPatchTest(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
// Create test user
var userID string
@@ -374,8 +367,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()
resetTestData(t)
// Create regular user in DB
_, err := db.DB.Exec(context.Background(), `
@@ -429,8 +421,7 @@ func TestAdminUsers_NonAdmin(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()
resetTestData(t)
// Create a test user
var userID string
@@ -478,8 +469,7 @@ func TestAdminUsers_Get_Success(t *testing.T) {
// TestAdminUsers_AddPatchTest_Duplicate verifies that recording the same patch test
// twice updates the tested_at timestamp (upsert behavior).
func TestAdminUsers_AddPatchTest_Duplicate(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
resetTestData(t)
// Create test user
var userID string