Coverage priorities 1-5: test pure functions, extract interfaces, mock-based handler tests

- Priority 1: Test NewSendEmailTask + NewSendPushTask (5 tests)
- Priority 2: Test customHTTPErrorHandler — all 15+ branches (21 tests)
- Priority 3: Extract Enqueuer interface + payload builders in worker pkg (5 tests)
- Priority 4: Extract ClassifyFile/ComputeRelPath in migrate-encrypt (6 tests)
- Priority 5: Define Handler interfaces, refactor to accept them, mock-based tests (14 tests)
- Fix .gitignore: /worker instead of worker to stop ignoring internal/worker/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Trey T
2026-04-01 20:30:09 -05:00
parent 00fd674b56
commit bec880886b
83 changed files with 19569 additions and 730 deletions

View File

@@ -0,0 +1,177 @@
package testutil
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/labstack/echo/v4"
)
func TestSetupTestDB_Works(t *testing.T) {
db := SetupTestDB(t)
if db == nil {
t.Fatal("expected non-nil db")
}
sqlDB, err := db.DB()
if err != nil {
t.Fatalf("failed to get sql.DB: %v", err)
}
if err := sqlDB.Ping(); err != nil {
t.Fatalf("ping failed: %v", err)
}
}
func TestSetupTestRouter_HasValidator(t *testing.T) {
e := SetupTestRouter()
if e == nil {
t.Fatal("expected non-nil router")
}
if e.Validator == nil {
t.Error("expected validator to be set")
}
}
func TestCreateTestUser_ReturnsUser(t *testing.T) {
db := SetupTestDB(t)
user := CreateTestUser(t, db, "testuser", "test@example.com", "password123")
if user == nil {
t.Fatal("expected non-nil user")
}
if user.ID == 0 {
t.Error("expected user to have an ID")
}
if user.Username != "testuser" {
t.Errorf("username = %q, want testuser", user.Username)
}
if user.Email != "test@example.com" {
t.Errorf("email = %q, want test@example.com", user.Email)
}
}
func TestSeedLookupData_PopulatesData(t *testing.T) {
db := SetupTestDB(t)
SeedLookupData(t, db)
// Verify residence types seeded
var rtCount int64
db.Table("residence_residencetype").Count(&rtCount)
if rtCount < 4 {
t.Errorf("residence types = %d, want ≥4", rtCount)
}
// Verify task categories seeded
var catCount int64
db.Table("task_taskcategory").Count(&catCount)
if catCount < 4 {
t.Errorf("task categories = %d, want ≥4", catCount)
}
// Verify task priorities seeded
var priCount int64
db.Table("task_taskpriority").Count(&priCount)
if priCount < 4 {
t.Errorf("task priorities = %d, want ≥4", priCount)
}
// Verify task frequencies seeded
var freqCount int64
db.Table("task_taskfrequency").Count(&freqCount)
if freqCount < 3 {
t.Errorf("task frequencies = %d, want ≥3", freqCount)
}
// Verify contractor specialties seeded
var specCount int64
db.Table("task_contractorspecialty").Count(&specCount)
if specCount < 4 {
t.Errorf("contractor specialties = %d, want ≥4", specCount)
}
}
func TestMockAuthMiddleware_SetsUser(t *testing.T) {
db := SetupTestDB(t)
user := CreateTestUser(t, db, "authuser", "auth@example.com", "pass")
e := echo.New()
mw := MockAuthMiddleware(user)
var capturedUser interface{}
handler := mw(func(c echo.Context) error {
capturedUser = c.Get("auth_user")
return c.NoContent(http.StatusOK)
})
req := httptest.NewRequest(http.MethodGet, "/", nil)
rec := httptest.NewRecorder()
c := e.NewContext(req, rec)
if err := handler(c); err != nil {
t.Fatalf("handler error: %v", err)
}
if capturedUser == nil {
t.Fatal("expected auth_user to be set in context")
}
}
func TestCreateTestResidence_ReturnsResidence(t *testing.T) {
db := SetupTestDB(t)
user := CreateTestUser(t, db, "owner", "owner@example.com", "pass")
residence := CreateTestResidence(t, db, user.ID, "Test Home")
if residence == nil {
t.Fatal("expected non-nil residence")
}
if residence.ID == 0 {
t.Error("expected residence to have an ID")
}
if residence.Name != "Test Home" {
t.Errorf("name = %q, want Test Home", residence.Name)
}
}
func TestCreateTestTask_ReturnsTask(t *testing.T) {
db := SetupTestDB(t)
user := CreateTestUser(t, db, "taskowner", "task@example.com", "pass")
residence := CreateTestResidence(t, db, user.ID, "Task Home")
task := CreateTestTask(t, db, residence.ID, user.ID, "Fix the sink")
if task == nil {
t.Fatal("expected non-nil task")
}
if task.ID == 0 {
t.Error("expected task to have an ID")
}
if task.Title != "Fix the sink" {
t.Errorf("title = %q, want Fix the sink", task.Title)
}
}
func TestParseJSON_Valid(t *testing.T) {
data := []byte(`{"name":"test","count":42}`)
result := ParseJSON(t, data)
if result["name"] != "test" {
t.Errorf("name = %v, want test", result["name"])
}
}
func TestParseJSONArray_Valid(t *testing.T) {
data := []byte(`[{"id":1},{"id":2}]`)
result := ParseJSONArray(t, data)
if len(result) != 2 {
t.Errorf("len = %d, want 2", len(result))
}
}
func TestMakeRequestT_ReturnsRecorder(t *testing.T) {
e := SetupTestRouter()
e.GET("/test", func(c echo.Context) error {
return c.JSON(http.StatusOK, map[string]string{"status": "ok"})
})
rec := MakeRequestT(t, e, http.MethodGet, "/test", nil, "")
if rec.Code != http.StatusOK {
t.Errorf("status = %d, want 200", rec.Code)
}
}