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:
@@ -14,8 +14,9 @@ import (
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
pool := testdb.CreateTestDatabase("crussell_test_handlers_today")
|
||||
db.DB = pool
|
||||
db.Conn = db.NewPoolProxy(pool)
|
||||
jwt.Init()
|
||||
testdb.SeedBaseline(pool)
|
||||
code := m.Run()
|
||||
testdb.DestroyTestDatabase(pool, "crussell_test_handlers_today")
|
||||
os.Exit(code)
|
||||
|
||||
@@ -9,16 +9,17 @@ import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"crussell/db"
|
||||
"crussell/testutils"
|
||||
"crussell/testutils/fixtures"
|
||||
)
|
||||
|
||||
func createTodayService(t *testing.T) string {
|
||||
func createTodayService(t *testing.T, ctx context.Context, q db.Querier) string {
|
||||
t.Helper()
|
||||
var svcID string
|
||||
err := db.DB.QueryRow(context.Background(), `
|
||||
err := q.QueryRow(ctx, `
|
||||
INSERT INTO services (name, description, price, duration_minutes, is_active, minimum_age_required)
|
||||
VALUES ('Test Service', 'Description', 50.00, 60, true, 16)
|
||||
RETURNING id
|
||||
@@ -29,9 +30,9 @@ func createTodayService(t *testing.T) string {
|
||||
return svcID
|
||||
}
|
||||
|
||||
func addBookingService(t *testing.T, bookingID, serviceID string) {
|
||||
func addBookingService(t *testing.T, ctx context.Context, q db.Querier, bookingID, serviceID string) {
|
||||
t.Helper()
|
||||
_, err := db.DB.Exec(context.Background(), `
|
||||
_, err := q.Exec(ctx, `
|
||||
INSERT INTO booking_services (booking_id, service_id)
|
||||
VALUES ($1, $2)
|
||||
`, bookingID, serviceID)
|
||||
@@ -41,20 +42,21 @@ func addBookingService(t *testing.T, bookingID, serviceID string) {
|
||||
}
|
||||
|
||||
func TestGetTodayAppointments_ShowsPreviousNameInAppointment(t *testing.T) {
|
||||
testutils.SetupTestDB(t)
|
||||
t.Parallel()
|
||||
ctx, tx := testutils.SetupTestTx(t)
|
||||
|
||||
userID, err := fixtures.CreateTestUser(db.DB)
|
||||
userID, err := fixtures.CreateTestUser(tx)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create user: %v", err)
|
||||
}
|
||||
|
||||
var origFirstName, origLastName string
|
||||
err = db.DB.QueryRow(context.Background(), `SELECT n_first_name, n_last_name FROM users WHERE id = $1`, userID).Scan(&origFirstName, &origLastName)
|
||||
err = tx.QueryRow(ctx, `SELECT n_first_name, n_last_name FROM users WHERE id = $1`, userID).Scan(&origFirstName, &origLastName)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to query user name: %v", err)
|
||||
}
|
||||
|
||||
_, err = db.DB.Exec(context.Background(), `
|
||||
_, err = tx.Exec(ctx, `
|
||||
INSERT INTO name_history (user_id, previous_first_name, previous_last_name)
|
||||
VALUES ($1, 'OldFirst', 'OldLast')
|
||||
`, userID)
|
||||
@@ -62,20 +64,23 @@ func TestGetTodayAppointments_ShowsPreviousNameInAppointment(t *testing.T) {
|
||||
t.Fatalf("failed to insert name_history: %v", err)
|
||||
}
|
||||
|
||||
svcID := createTodayService(t)
|
||||
svcID := createTodayService(t, ctx, tx)
|
||||
|
||||
var bookingID string
|
||||
err = db.DB.QueryRow(context.Background(), `
|
||||
now := time.Now()
|
||||
bookingStart := time.Date(now.Year(), now.Month(), now.Day(), 10, 0, 0, 0, now.Location())
|
||||
err = tx.QueryRow(ctx, `
|
||||
INSERT INTO bookings (user_id, start_time, status)
|
||||
VALUES ($1, NOW() + INTERVAL '5 minutes', 'in_progress')
|
||||
VALUES ($1, $2, 'in_progress')
|
||||
RETURNING id
|
||||
`, userID).Scan(&bookingID)
|
||||
`, userID, bookingStart).Scan(&bookingID)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create booking: %v", err)
|
||||
}
|
||||
addBookingService(t, bookingID, svcID)
|
||||
addBookingService(t, ctx, tx, bookingID, svcID)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/admin/today/appointments", nil)
|
||||
req = req.WithContext(ctx)
|
||||
rr := httptest.NewRecorder()
|
||||
GetTodayAppointmentsHandler(rr, req)
|
||||
|
||||
@@ -110,23 +115,25 @@ func TestGetTodayAppointments_ShowsPreviousNameInAppointment(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetTodayAppointments_OmitsPreviousNameWhenNoHistory(t *testing.T) {
|
||||
testutils.SetupTestDB(t)
|
||||
t.Parallel()
|
||||
ctx, tx := testutils.SetupTestTx(t)
|
||||
|
||||
userID, err := fixtures.CreateTestUser(db.DB)
|
||||
userID, err := fixtures.CreateTestUser(tx)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create user: %v", err)
|
||||
}
|
||||
|
||||
svcID := createTodayService(t)
|
||||
svcID := createTodayService(t, ctx, tx)
|
||||
var bookingID string
|
||||
err = db.DB.QueryRow(context.Background(), `
|
||||
err = tx.QueryRow(ctx, `
|
||||
INSERT INTO bookings (user_id, start_time, status)
|
||||
VALUES ($1, NOW() + INTERVAL '5 minutes', 'in_progress')
|
||||
RETURNING id
|
||||
`, userID).Scan(&bookingID)
|
||||
addBookingService(t, bookingID, svcID)
|
||||
addBookingService(t, ctx, tx, bookingID, svcID)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/admin/today/appointments", nil)
|
||||
req = req.WithContext(ctx)
|
||||
rr := httptest.NewRecorder()
|
||||
GetTodayAppointmentsHandler(rr, req)
|
||||
|
||||
@@ -152,9 +159,11 @@ func TestGetTodayAppointments_OmitsPreviousNameWhenNoHistory(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetTodayAppointments_Empty(t *testing.T) {
|
||||
testutils.SetupTestDB(t)
|
||||
t.Parallel()
|
||||
ctx, _ := testutils.SetupTestTx(t)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/admin/today/appointments", nil)
|
||||
req = req.WithContext(ctx)
|
||||
rr := httptest.NewRecorder()
|
||||
GetTodayAppointmentsHandler(rr, req)
|
||||
|
||||
@@ -176,20 +185,21 @@ func TestGetTodayAppointments_Empty(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetPendingApprovals_ShowsPreviousName(t *testing.T) {
|
||||
testutils.SetupTestDB(t)
|
||||
t.Parallel()
|
||||
ctx, tx := testutils.SetupTestTx(t)
|
||||
|
||||
userID, err := fixtures.CreateTestUser(db.DB)
|
||||
userID, err := fixtures.CreateTestUser(tx)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create user: %v", err)
|
||||
}
|
||||
|
||||
var origFirstName, origLastName string
|
||||
err = db.DB.QueryRow(context.Background(), `SELECT n_first_name, n_last_name FROM users WHERE id = $1`, userID).Scan(&origFirstName, &origLastName)
|
||||
err = tx.QueryRow(ctx, `SELECT n_first_name, n_last_name FROM users WHERE id = $1`, userID).Scan(&origFirstName, &origLastName)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to query user name: %v", err)
|
||||
}
|
||||
|
||||
_, err = db.DB.Exec(context.Background(), `
|
||||
_, err = tx.Exec(ctx, `
|
||||
INSERT INTO name_history (user_id, previous_first_name, previous_last_name)
|
||||
VALUES ($1, 'OldFirst', 'OldLast')
|
||||
`, userID)
|
||||
@@ -197,9 +207,9 @@ func TestGetPendingApprovals_ShowsPreviousName(t *testing.T) {
|
||||
t.Fatalf("failed to insert name_history: %v", err)
|
||||
}
|
||||
|
||||
svcID := createTodayService(t)
|
||||
svcID := createTodayService(t, ctx, tx)
|
||||
var bookingID string
|
||||
err = db.DB.QueryRow(context.Background(), `
|
||||
err = tx.QueryRow(ctx, `
|
||||
INSERT INTO bookings (user_id, start_time, status)
|
||||
VALUES ($1, NOW() + INTERVAL '1 day', 'pending')
|
||||
RETURNING id
|
||||
@@ -207,9 +217,10 @@ func TestGetPendingApprovals_ShowsPreviousName(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create booking: %v", err)
|
||||
}
|
||||
addBookingService(t, bookingID, svcID)
|
||||
addBookingService(t, ctx, tx, bookingID, svcID)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/admin/today/pending-approvals", nil)
|
||||
req = req.WithContext(ctx)
|
||||
rr := httptest.NewRecorder()
|
||||
GetPendingApprovalsHandler(rr, req)
|
||||
|
||||
@@ -244,23 +255,25 @@ func TestGetPendingApprovals_ShowsPreviousName(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetPendingApprovals_OmitsPreviousNameWhenNoHistory(t *testing.T) {
|
||||
testutils.SetupTestDB(t)
|
||||
t.Parallel()
|
||||
ctx, tx := testutils.SetupTestTx(t)
|
||||
|
||||
userID, err := fixtures.CreateTestUser(db.DB)
|
||||
userID, err := fixtures.CreateTestUser(tx)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create user: %v", err)
|
||||
}
|
||||
|
||||
svcID := createTodayService(t)
|
||||
svcID := createTodayService(t, ctx, tx)
|
||||
var bookingID string
|
||||
err = db.DB.QueryRow(context.Background(), `
|
||||
err = tx.QueryRow(ctx, `
|
||||
INSERT INTO bookings (user_id, start_time, status)
|
||||
VALUES ($1, NOW() + INTERVAL '1 day', 'pending')
|
||||
RETURNING id
|
||||
`, userID).Scan(&bookingID)
|
||||
addBookingService(t, bookingID, svcID)
|
||||
addBookingService(t, ctx, tx, bookingID, svcID)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/admin/today/pending-approvals", nil)
|
||||
req = req.WithContext(ctx)
|
||||
rr := httptest.NewRecorder()
|
||||
GetPendingApprovalsHandler(rr, req)
|
||||
|
||||
@@ -286,9 +299,11 @@ func TestGetPendingApprovals_OmitsPreviousNameWhenNoHistory(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetPendingApprovals_Empty(t *testing.T) {
|
||||
testutils.SetupTestDB(t)
|
||||
t.Parallel()
|
||||
ctx, _ := testutils.SetupTestTx(t)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/admin/today/pending-approvals", nil)
|
||||
req = req.WithContext(ctx)
|
||||
rr := httptest.NewRecorder()
|
||||
GetPendingApprovalsHandler(rr, req)
|
||||
|
||||
@@ -307,14 +322,15 @@ func TestGetPendingApprovals_Empty(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetCurrentNext_ShowsPreviousNameInAppointment(t *testing.T) {
|
||||
testutils.SetupTestDB(t)
|
||||
t.Parallel()
|
||||
ctx, tx := testutils.SetupTestTx(t)
|
||||
|
||||
userID, err := fixtures.CreateTestUser(db.DB)
|
||||
userID, err := fixtures.CreateTestUser(tx)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create user: %v", err)
|
||||
}
|
||||
|
||||
_, err = db.DB.Exec(context.Background(), `
|
||||
_, err = tx.Exec(ctx, `
|
||||
INSERT INTO name_history (user_id, previous_first_name, previous_last_name)
|
||||
VALUES ($1, 'OldFirst', 'OldLast')
|
||||
`, userID)
|
||||
@@ -322,11 +338,11 @@ func TestGetCurrentNext_ShowsPreviousNameInAppointment(t *testing.T) {
|
||||
t.Fatalf("failed to insert name_history: %v", err)
|
||||
}
|
||||
|
||||
svcID := createTodayService(t)
|
||||
svcID := createTodayService(t, ctx, tx)
|
||||
|
||||
// Ensure working hours for all weekdays
|
||||
for wd := 0; wd <= 6; wd++ {
|
||||
db.DB.Exec(context.Background(), `
|
||||
tx.Exec(ctx, `
|
||||
INSERT INTO working_hours (weekday, start_time, end_time, is_open)
|
||||
VALUES ($1, '09:00', '17:00', true)
|
||||
ON CONFLICT (weekday) DO UPDATE SET start_time = '09:00', end_time = '17:00', is_open = true
|
||||
@@ -334,7 +350,7 @@ func TestGetCurrentNext_ShowsPreviousNameInAppointment(t *testing.T) {
|
||||
}
|
||||
|
||||
var bookingID2 string
|
||||
err = db.DB.QueryRow(context.Background(), `
|
||||
err = tx.QueryRow(ctx, `
|
||||
INSERT INTO bookings (user_id, start_time, status)
|
||||
VALUES ($1, NOW(), 'confirmed')
|
||||
RETURNING id
|
||||
@@ -342,9 +358,10 @@ func TestGetCurrentNext_ShowsPreviousNameInAppointment(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create booking: %v", err)
|
||||
}
|
||||
addBookingService(t, bookingID2, svcID)
|
||||
addBookingService(t, ctx, tx, bookingID2, svcID)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/admin/today/current-next", nil)
|
||||
req = req.WithContext(ctx)
|
||||
rr := httptest.NewRecorder()
|
||||
GetCurrentAndNextHandler(rr, req)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user