refactor(backend): update test files for PoolProxy and per-test transactions
Migrate all test files from SetupTestDB/db.DB pattern to per-test transactions: - Replace SetupTestDB(t) with SetupTestTx(t) for context + transaction - Replace db.DB.Query/QueryRow/Exec with tx.Query/QueryRow/Exec - Replace context.Background() with context from SetupTestTx - Replace defer rows.Close() pattern with explicit rows.Close() - Add testdb.SeedBaseline(pool) to all TestMain functions - Wire db.Conn = db.NewPoolProxy(pool) in all TestMain functions Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -28,50 +28,17 @@ import (
|
||||
|
||||
"crussell/db"
|
||||
"crussell/mw"
|
||||
"crussell/testutils"
|
||||
"crussell/testutils/jwt"
|
||||
"crussell/testutils/testdb"
|
||||
)
|
||||
|
||||
func resetTestData(t *testing.T) {
|
||||
func resetTestData(t *testing.T) (context.Context, db.Querier) {
|
||||
t.Helper()
|
||||
testdb.TruncateTables(t, db.DB)
|
||||
// Also truncate financial_aggregates which is not in the default truncation list
|
||||
db.DB.Exec(context.Background(), "TRUNCATE financial_aggregates CASCADE")
|
||||
seedDefaultWorkingHours(t)
|
||||
ctx, tx := testutils.SetupTestTx(t)
|
||||
return ctx, tx
|
||||
}
|
||||
|
||||
func seedDefaultWorkingHours(t *testing.T) {
|
||||
t.Helper()
|
||||
|
||||
// Seed 7 days of working hours (Monday=0 to Sunday=6)
|
||||
hours := []struct {
|
||||
weekday int
|
||||
startTime string
|
||||
endTime string
|
||||
isOpen bool
|
||||
}{
|
||||
{0, "09:00", "17:00", true}, // Monday
|
||||
{1, "09:00", "17:00", true}, // Tuesday
|
||||
{2, "09:00", "17:00", true}, // Wednesday
|
||||
{3, "09:00", "17:00", true}, // Thursday
|
||||
{4, "09:00", "17:00", true}, // Friday
|
||||
{5, "10:00", "16:00", true}, // Saturday
|
||||
{6, "00:00", "00:00", false}, // Sunday
|
||||
}
|
||||
|
||||
for _, h := range hours {
|
||||
_, err := db.DB.Exec(context.Background(), `
|
||||
INSERT INTO working_hours (weekday, start_time, end_time, is_open)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
ON CONFLICT (weekday) DO UPDATE SET start_time = $2, end_time = $3, is_open = $4
|
||||
`, h.weekday, h.startTime, h.endTime, h.isOpen)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to seed working hours: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func makeRequest(handler http.HandlerFunc, method, path string, body interface{}) *httptest.ResponseRecorder {
|
||||
func makeRequest(handler http.HandlerFunc, method, path string, body interface{}, ctx context.Context) *httptest.ResponseRecorder {
|
||||
var req *http.Request
|
||||
if body != nil {
|
||||
bodyBytes, _ := json.Marshal(body)
|
||||
@@ -80,12 +47,13 @@ func makeRequest(handler http.HandlerFunc, method, path string, body interface{}
|
||||
} else {
|
||||
req = httptest.NewRequest(method, path, nil)
|
||||
}
|
||||
req = req.WithContext(ctx)
|
||||
w := httptest.NewRecorder()
|
||||
handler.ServeHTTP(w, req)
|
||||
return w
|
||||
}
|
||||
|
||||
func makeAuthRequest(handler http.Handler, method, path, token string, body interface{}) *httptest.ResponseRecorder {
|
||||
func makeAuthRequest(handler http.Handler, method, path, token string, body interface{}, ctx context.Context) *httptest.ResponseRecorder {
|
||||
var req *http.Request
|
||||
if body != nil {
|
||||
bodyBytes, _ := json.Marshal(body)
|
||||
@@ -97,6 +65,7 @@ func makeAuthRequest(handler http.Handler, method, path, token string, body inte
|
||||
if token != "" {
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
}
|
||||
req = req.WithContext(ctx)
|
||||
w := httptest.NewRecorder()
|
||||
handler.ServeHTTP(w, req)
|
||||
return w
|
||||
@@ -108,10 +77,11 @@ func makeAuthRequest(handler http.Handler, method, path, token string, body inte
|
||||
// can be retrieved. The test checks that all 7 days are returned with correct
|
||||
// opening times, closing times, and is_open status.
|
||||
func TestScheduling_GetDefaultHours(t *testing.T) {
|
||||
resetTestData(t)
|
||||
t.Parallel()
|
||||
ctx, _ := resetTestData(t)
|
||||
|
||||
handler := http.HandlerFunc(GetDefaultHours)
|
||||
w := makeRequest(handler, "GET", "/api/scheduling/default-hours", nil)
|
||||
w := makeRequest(handler, "GET", "/api/scheduling/default-hours", nil, ctx)
|
||||
|
||||
if w.Code != http.StatusOK {
|
||||
t.Errorf("expected status 200, got %d. body: %s", w.Code, w.Body.String())
|
||||
@@ -155,7 +125,8 @@ func TestScheduling_GetDefaultHours(t *testing.T) {
|
||||
// the default weekly working hours. The new schedule is persisted to the
|
||||
// database and returned on subsequent requests.
|
||||
func TestScheduling_UpdateDefaultHours_Admin(t *testing.T) {
|
||||
resetTestData(t)
|
||||
t.Parallel()
|
||||
ctx, tx := resetTestData(t)
|
||||
|
||||
adminToken := jwt.GenerateAdminToken()
|
||||
handler := http.HandlerFunc(UpdateDefaultHours)
|
||||
@@ -170,7 +141,7 @@ func TestScheduling_UpdateDefaultHours_Admin(t *testing.T) {
|
||||
{Weekday: 6, StartTime: "00:00", EndTime: "00:00", IsOpen: false},
|
||||
}
|
||||
|
||||
w := makeAuthRequest(handler, "PUT", "/api/scheduling/default-hours", adminToken, newHours)
|
||||
w := makeAuthRequest(handler, "PUT", "/api/scheduling/default-hours", adminToken, newHours, ctx)
|
||||
|
||||
if w.Code != http.StatusNoContent {
|
||||
t.Errorf("expected status 204, got %d. body: %s", w.Code, w.Body.String())
|
||||
@@ -178,7 +149,7 @@ func TestScheduling_UpdateDefaultHours_Admin(t *testing.T) {
|
||||
|
||||
// Verify the update persisted
|
||||
var hours []DefaultHours
|
||||
rows, err := db.DB.Query(context.Background(), `SELECT weekday, start_time::text, end_time::text, is_open FROM working_hours ORDER BY weekday`)
|
||||
rows, err := tx.Query(ctx, `SELECT weekday, start_time::text, end_time::text, is_open FROM working_hours ORDER BY weekday`)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to query hours: %v", err)
|
||||
}
|
||||
@@ -200,7 +171,8 @@ func TestScheduling_UpdateDefaultHours_Admin(t *testing.T) {
|
||||
// TestScheduling_UpdateDefaultHours_NonAdmin verifies that non-admin users
|
||||
// receive HTTP 403 Forbidden when attempting to update default hours.
|
||||
func TestScheduling_UpdateDefaultHours_NonAdmin(t *testing.T) {
|
||||
resetTestData(t)
|
||||
t.Parallel()
|
||||
ctx, _ := resetTestData(t)
|
||||
|
||||
userToken := jwt.GenerateUserToken("user-123")
|
||||
|
||||
@@ -215,7 +187,7 @@ func TestScheduling_UpdateDefaultHours_NonAdmin(t *testing.T) {
|
||||
}
|
||||
|
||||
// Wrap handler with RequireAuth + RequireAdmin middleware (auth first to populate context)
|
||||
w := makeAuthRequest(mw.RequireAuth(mw.RequireAdmin(http.HandlerFunc(UpdateDefaultHours))), "PUT", "/api/scheduling/default-hours", userToken, newHours)
|
||||
w := makeAuthRequest(mw.RequireAuth(mw.RequireAdmin(http.HandlerFunc(UpdateDefaultHours))), "PUT", "/api/scheduling/default-hours", userToken, newHours, ctx)
|
||||
|
||||
if w.Code != http.StatusForbidden {
|
||||
t.Errorf("expected status 403, got %d. body: %s", w.Code, w.Body.String())
|
||||
@@ -227,10 +199,11 @@ func TestScheduling_UpdateDefaultHours_NonAdmin(t *testing.T) {
|
||||
// TestScheduling_ListExceptionalGroups verifies that admins can list all
|
||||
// exceptional working hours groups (holidays, special events).
|
||||
func TestScheduling_ListExceptionalGroups(t *testing.T) {
|
||||
resetTestData(t)
|
||||
t.Parallel()
|
||||
ctx, tx := resetTestData(t)
|
||||
|
||||
// Create an exceptional group
|
||||
_, err := db.DB.Exec(context.Background(), `
|
||||
_, err := tx.Exec(ctx, `
|
||||
INSERT INTO exceptional_working_hours_groups (name, description)
|
||||
VALUES ('Holiday Hours', 'Christmas holiday schedule')
|
||||
`)
|
||||
@@ -239,7 +212,7 @@ func TestScheduling_ListExceptionalGroups(t *testing.T) {
|
||||
}
|
||||
|
||||
handler := http.HandlerFunc(ListExceptionalGroups)
|
||||
w := makeRequest(handler, "GET", "/api/scheduling/exceptional-groups", nil)
|
||||
w := makeRequest(handler, "GET", "/api/scheduling/exceptional-groups", nil, ctx)
|
||||
|
||||
if w.Code != http.StatusOK {
|
||||
t.Errorf("expected status 200, got %d. body: %s", w.Code, w.Body.String())
|
||||
@@ -264,7 +237,8 @@ func TestScheduling_ListExceptionalGroups(t *testing.T) {
|
||||
// TestScheduling_CreateExceptionalGroup_Admin tests that an admin can
|
||||
// create a new exceptional working hours group with specific hours for each day.
|
||||
func TestScheduling_CreateExceptionalGroup_Admin(t *testing.T) {
|
||||
resetTestData(t)
|
||||
t.Parallel()
|
||||
ctx, _ := resetTestData(t)
|
||||
|
||||
adminToken := jwt.GenerateAdminToken()
|
||||
handler := http.HandlerFunc(CreateExceptionalGroup)
|
||||
@@ -284,7 +258,7 @@ func TestScheduling_CreateExceptionalGroup_Admin(t *testing.T) {
|
||||
WeekStarts: []string{"2026-06-01"},
|
||||
}
|
||||
|
||||
w := makeAuthRequest(handler, "POST", "/api/scheduling/exceptional-groups", adminToken, newGroup)
|
||||
w := makeAuthRequest(handler, "POST", "/api/scheduling/exceptional-groups", adminToken, newGroup, ctx)
|
||||
|
||||
if w.Code != http.StatusCreated {
|
||||
t.Errorf("expected status 201, got %d. body: %s", w.Code, w.Body.String())
|
||||
@@ -306,7 +280,8 @@ func TestScheduling_CreateExceptionalGroup_Admin(t *testing.T) {
|
||||
// TestScheduling_CreateExceptionalGroup_NonAdmin verifies that non-admin
|
||||
// users receive HTTP 403 when attempting to create exceptional groups.
|
||||
func TestScheduling_CreateExceptionalGroup_NonAdmin(t *testing.T) {
|
||||
resetTestData(t)
|
||||
t.Parallel()
|
||||
ctx, _ := resetTestData(t)
|
||||
|
||||
userToken := jwt.GenerateUserToken("user-123")
|
||||
|
||||
@@ -325,7 +300,7 @@ func TestScheduling_CreateExceptionalGroup_NonAdmin(t *testing.T) {
|
||||
WeekStarts: []string{"2026-06-01"},
|
||||
}
|
||||
|
||||
w := makeAuthRequest(mw.RequireAuth(mw.RequireAdmin(http.HandlerFunc(CreateExceptionalGroup))), "POST", "/api/scheduling/exceptional-groups", userToken, newGroup)
|
||||
w := makeAuthRequest(mw.RequireAuth(mw.RequireAdmin(http.HandlerFunc(CreateExceptionalGroup))), "POST", "/api/scheduling/exceptional-groups", userToken, newGroup, ctx)
|
||||
|
||||
if w.Code != http.StatusForbidden {
|
||||
t.Errorf("expected status 403, got %d. body: %s", w.Code, w.Body.String())
|
||||
@@ -363,8 +338,9 @@ func TestScheduling_UpdateDefaultHours_InvalidTimes(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
resetTestData(t)
|
||||
w := makeAuthRequest(handler, "PUT", "/api/scheduling/default-hours", adminToken, tt.hours)
|
||||
t.Parallel()
|
||||
ctx, _ := resetTestData(t)
|
||||
w := makeAuthRequest(handler, "PUT", "/api/scheduling/default-hours", adminToken, tt.hours, ctx)
|
||||
if w.Code != tt.wantStatus {
|
||||
t.Errorf("expected status %d, got %d. body: %s", tt.wantStatus, w.Code, w.Body.String())
|
||||
}
|
||||
@@ -418,7 +394,8 @@ func TestScheduling_CreateExceptionalGroup_InvalidTimes(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
resetTestData(t)
|
||||
t.Parallel()
|
||||
ctx, _ := resetTestData(t)
|
||||
hours := tt.modify(baseHours())
|
||||
group := ExceptionalGroup{
|
||||
Name: "Test Group",
|
||||
@@ -426,7 +403,7 @@ func TestScheduling_CreateExceptionalGroup_InvalidTimes(t *testing.T) {
|
||||
Hours: hours,
|
||||
WeekStarts: []string{"2026-06-01"},
|
||||
}
|
||||
w := makeAuthRequest(handler, "POST", "/api/scheduling/exceptional-groups", adminToken, group)
|
||||
w := makeAuthRequest(handler, "POST", "/api/scheduling/exceptional-groups", adminToken, group, ctx)
|
||||
if w.Code != tt.wantStatus {
|
||||
t.Errorf("expected status %d, got %d. body: %s", tt.wantStatus, w.Code, w.Body.String())
|
||||
}
|
||||
@@ -440,13 +417,14 @@ func TestScheduling_CreateExceptionalGroup_InvalidTimes(t *testing.T) {
|
||||
// an exceptional working hours group. This removes the group and its associated
|
||||
// hours from the system.
|
||||
func TestScheduling_DeleteExceptionalGroup_Admin(t *testing.T) {
|
||||
resetTestData(t)
|
||||
t.Parallel()
|
||||
ctx, tx := resetTestData(t)
|
||||
|
||||
adminToken := jwt.GenerateAdminToken()
|
||||
|
||||
// Create a group to delete
|
||||
var groupID int
|
||||
err := db.DB.QueryRow(context.Background(), `
|
||||
err := tx.QueryRow(ctx, `
|
||||
INSERT INTO exceptional_working_hours_groups (name, description)
|
||||
VALUES ('To Delete', 'Will be deleted')
|
||||
RETURNING id
|
||||
@@ -459,6 +437,7 @@ func TestScheduling_DeleteExceptionalGroup_Admin(t *testing.T) {
|
||||
// Use proper URL query with strconv.Itoa
|
||||
req := httptest.NewRequest("DELETE", "/api/scheduling/exceptional-groups?id="+strconv.Itoa(groupID), nil)
|
||||
req.Header.Set("Authorization", "Bearer "+adminToken)
|
||||
req = req.WithContext(ctx)
|
||||
w := httptest.NewRecorder()
|
||||
handler.ServeHTTP(w, req)
|
||||
|
||||
@@ -468,7 +447,7 @@ func TestScheduling_DeleteExceptionalGroup_Admin(t *testing.T) {
|
||||
|
||||
// Verify group was deleted
|
||||
var count int
|
||||
err = db.DB.QueryRow(context.Background(), `SELECT COUNT(*) FROM exceptional_working_hours_groups WHERE id = $1`, groupID).Scan(&count)
|
||||
err = tx.QueryRow(ctx, `SELECT COUNT(*) FROM exceptional_working_hours_groups WHERE id = $1`, groupID).Scan(&count)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to check group: %v", err)
|
||||
}
|
||||
@@ -480,7 +459,8 @@ func TestScheduling_DeleteExceptionalGroup_Admin(t *testing.T) {
|
||||
// TestScheduling_DeleteExceptionalGroup_NonAdmin verifies that non-admin
|
||||
// users receive HTTP 403 when attempting to delete exceptional groups.
|
||||
func TestScheduling_DeleteExceptionalGroup_NonAdmin(t *testing.T) {
|
||||
resetTestData(t)
|
||||
t.Parallel()
|
||||
_, _ = resetTestData(t)
|
||||
|
||||
userToken := jwt.GenerateUserToken("user-123")
|
||||
|
||||
@@ -501,7 +481,8 @@ func TestScheduling_DeleteExceptionalGroup_NonAdmin(t *testing.T) {
|
||||
// retrieved for a given date range. The response includes whether hours come
|
||||
// from default schedule or exceptional groups.
|
||||
func TestScheduling_GetWorkingHours(t *testing.T) {
|
||||
resetTestData(t)
|
||||
t.Parallel()
|
||||
_, _ = resetTestData(t)
|
||||
|
||||
handler := http.HandlerFunc(GetWorkingHours)
|
||||
req := httptest.NewRequest("GET", "/api/scheduling/working-hours?start=2026-02-16&end=2026-02-22", nil)
|
||||
@@ -536,7 +517,8 @@ func TestScheduling_GetWorkingHours(t *testing.T) {
|
||||
// slots can be calculated for a date range based on working hours and service
|
||||
// durations.
|
||||
func TestScheduling_GetAvailableHours(t *testing.T) {
|
||||
resetTestData(t)
|
||||
t.Parallel()
|
||||
_, _ = resetTestData(t)
|
||||
|
||||
handler := http.HandlerFunc(GetAvailableHours)
|
||||
req := httptest.NewRequest("GET", "/api/scheduling/available-hours?start=2026-02-16&end=2026-02-22", nil)
|
||||
@@ -573,13 +555,14 @@ func TestScheduling_GetAvailableHours(t *testing.T) {
|
||||
// admin can apply an exceptional hours group to specific weeks, activating
|
||||
// holiday schedules for those periods.
|
||||
func TestScheduling_UpdateExceptionalApplications_Admin(t *testing.T) {
|
||||
resetTestData(t)
|
||||
t.Parallel()
|
||||
ctx, tx := resetTestData(t)
|
||||
|
||||
adminToken := jwt.GenerateAdminToken()
|
||||
|
||||
// Create a group
|
||||
var groupID int
|
||||
err := db.DB.QueryRow(context.Background(), `
|
||||
err := tx.QueryRow(ctx, `
|
||||
INSERT INTO exceptional_working_hours_groups (name, description)
|
||||
VALUES ('Test Group', 'Test')
|
||||
RETURNING id
|
||||
@@ -595,7 +578,7 @@ func TestScheduling_UpdateExceptionalApplications_Admin(t *testing.T) {
|
||||
"weekStarts": []string{"2026-03-02", "2026-03-09"},
|
||||
}
|
||||
|
||||
w := makeAuthRequest(handler, "PUT", "/api/scheduling/exceptional-applications", adminToken, reqBody)
|
||||
w := makeAuthRequest(handler, "PUT", "/api/scheduling/exceptional-applications", adminToken, reqBody, ctx)
|
||||
|
||||
if w.Code != http.StatusNoContent {
|
||||
t.Errorf("expected status 204, got %d. body: %s", w.Code, w.Body.String())
|
||||
@@ -603,7 +586,7 @@ func TestScheduling_UpdateExceptionalApplications_Admin(t *testing.T) {
|
||||
|
||||
// Verify applications were created
|
||||
var count int
|
||||
err = db.DB.QueryRow(context.Background(), `
|
||||
err = tx.QueryRow(ctx, `
|
||||
SELECT COUNT(*) FROM exceptional_group_applications WHERE group_id = $1
|
||||
`, groupID).Scan(&count)
|
||||
if err != nil {
|
||||
@@ -617,7 +600,8 @@ func TestScheduling_UpdateExceptionalApplications_Admin(t *testing.T) {
|
||||
// TestScheduling_UpdateExceptionalApplications_NonAdmin verifies that
|
||||
// non-admin users receive HTTP 403 when attempting to apply exceptional hours.
|
||||
func TestScheduling_UpdateExceptionalApplications_NonAdmin(t *testing.T) {
|
||||
resetTestData(t)
|
||||
t.Parallel()
|
||||
ctx, _ := resetTestData(t)
|
||||
|
||||
userToken := jwt.GenerateUserToken("user-123")
|
||||
handler := mw.RequireAuth(mw.RequireAdmin(http.HandlerFunc(UpdateExceptionalApplications)))
|
||||
@@ -627,7 +611,7 @@ func TestScheduling_UpdateExceptionalApplications_NonAdmin(t *testing.T) {
|
||||
"weekStarts": []string{"2026-03-02"},
|
||||
}
|
||||
|
||||
w := makeAuthRequest(handler, "PUT", "/api/scheduling/exceptional-applications", userToken, reqBody)
|
||||
w := makeAuthRequest(handler, "PUT", "/api/scheduling/exceptional-applications", userToken, reqBody, ctx)
|
||||
|
||||
if w.Code != http.StatusForbidden {
|
||||
t.Errorf("expected status 403, got %d. body: %s", w.Code, w.Body.String())
|
||||
@@ -641,12 +625,13 @@ func TestScheduling_UpdateExceptionalApplications_NonAdmin(t *testing.T) {
|
||||
// TestScheduling_GetAvailableHours_WithBlocker_NonAdmin verifies that non-admin
|
||||
// users do NOT see blocked time slots in their available hours.
|
||||
func TestScheduling_GetAvailableHours_WithBlocker_NonAdmin(t *testing.T) {
|
||||
resetTestData(t)
|
||||
t.Parallel()
|
||||
ctx, tx := resetTestData(t)
|
||||
|
||||
// Create a time blocker for 2026-03-16 10:00-11:00 (Monday - an open day)
|
||||
ukLocation, _ := time.LoadLocation("Europe/London")
|
||||
blockerTime := time.Date(2026, 3, 16, 10, 0, 0, 0, ukLocation)
|
||||
_, err := db.DB.Exec(context.Background(), `
|
||||
_, err := tx.Exec(ctx, `
|
||||
INSERT INTO time_blockers (start_time, duration_minutes, description, created_by)
|
||||
VALUES ($1, 60, 'Staff Meeting', NULL)
|
||||
`, blockerTime)
|
||||
@@ -659,9 +644,9 @@ func TestScheduling_GetAvailableHours_WithBlocker_NonAdmin(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/api/scheduling/available-hours?start=2026-03-16&end=2026-03-16", nil)
|
||||
|
||||
// Set non-admin context
|
||||
ctx := context.WithValue(req.Context(), mw.UserIDKey, "user001")
|
||||
ctx = context.WithValue(ctx, mw.UserRoleKey, "verified_email")
|
||||
req = req.WithContext(ctx)
|
||||
reqCtx := context.WithValue(ctx, mw.UserIDKey, "user001")
|
||||
reqCtx = context.WithValue(reqCtx, mw.UserRoleKey, "verified_email")
|
||||
req = req.WithContext(reqCtx)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
handler.ServeHTTP(w, req)
|
||||
@@ -708,12 +693,13 @@ func TestScheduling_GetAvailableHours_WithBlocker_NonAdmin(t *testing.T) {
|
||||
// TestScheduling_GetAvailableHours_WithBlocker_Admin verifies that admin users
|
||||
// CAN see blocked time slots in the blockers field.
|
||||
func TestScheduling_GetAvailableHours_WithBlocker_Admin(t *testing.T) {
|
||||
resetTestData(t)
|
||||
t.Parallel()
|
||||
ctx, tx := resetTestData(t)
|
||||
|
||||
// Create a time blocker for 2026-03-16 10:00-11:00 (Monday - open day)
|
||||
ukLocation, _ := time.LoadLocation("Europe/London")
|
||||
blockerTime := time.Date(2026, 3, 16, 10, 0, 0, 0, ukLocation)
|
||||
_, err := db.DB.Exec(context.Background(), `
|
||||
_, err := tx.Exec(ctx, `
|
||||
INSERT INTO time_blockers (start_time, duration_minutes, description, created_by)
|
||||
VALUES ($1, 60, 'Staff Meeting', NULL)
|
||||
`, blockerTime)
|
||||
@@ -726,9 +712,9 @@ func TestScheduling_GetAvailableHours_WithBlocker_Admin(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/api/scheduling/available-hours?start=2026-03-16&end=2026-03-16", nil)
|
||||
|
||||
// Set admin context
|
||||
ctx := context.WithValue(req.Context(), mw.UserIDKey, "admin001")
|
||||
ctx = context.WithValue(ctx, mw.UserRoleKey, "admin")
|
||||
req = req.WithContext(ctx)
|
||||
reqCtx := context.WithValue(ctx, mw.UserIDKey, "admin001")
|
||||
reqCtx = context.WithValue(reqCtx, mw.UserRoleKey, "admin")
|
||||
req = req.WithContext(reqCtx)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
handler.ServeHTTP(w, req)
|
||||
@@ -782,6 +768,7 @@ func TestScheduling_GetAvailableHours_WithBlocker_Admin(t *testing.T) {
|
||||
// TestIsValidTime15Min tests the time validation helper directly for all
|
||||
// supported formats (HH:MM, HH:MM:SS) and edge cases.
|
||||
func TestIsValidTime15Min(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
time string
|
||||
|
||||
@@ -14,8 +14,9 @@ import (
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
pool := testdb.CreateTestDatabase("crussell_test_handlers_scheduling")
|
||||
db.DB = pool
|
||||
db.Conn = db.NewPoolProxy(pool)
|
||||
jwt.Init()
|
||||
testdb.SeedBaselineScheduling(pool)
|
||||
code := m.Run()
|
||||
testdb.DestroyTestDatabase(pool, "crussell_test_handlers_scheduling")
|
||||
os.Exit(code)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user