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

@@ -567,3 +567,164 @@ func TestResidenceHandler_CreateResidence_NegativeBedrooms_Returns400(t *testing
testutil.AssertStatusCode(t, w, http.StatusCreated)
})
}
func TestResidenceHandler_GetMyResidences(t *testing.T) {
handler, e, db := setupResidenceHandler(t)
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
testutil.CreateTestResidence(t, db, user.ID, "House 1")
testutil.CreateTestResidence(t, db, user.ID, "House 2")
authGroup := e.Group("/api/residences")
authGroup.Use(testutil.MockAuthMiddleware(user))
authGroup.GET("/my-residences/", handler.GetMyResidences)
t.Run("successful my residences", func(t *testing.T) {
w := testutil.MakeRequest(e, "GET", "/api/residences/my-residences/", nil, "test-token")
testutil.AssertStatusCode(t, w, http.StatusOK)
// GetMyResidences returns MyResidencesResponse: {"residences": [...]}
var response map[string]interface{}
err := json.Unmarshal(w.Body.Bytes(), &response)
require.NoError(t, err)
residences := response["residences"].([]interface{})
assert.Len(t, residences, 2)
})
t.Run("user with no residences returns empty", func(t *testing.T) {
noResUser := testutil.CreateTestUser(t, db, "nores", "nores@test.com", "Password123")
e2 := testutil.SetupTestRouter()
authGroup2 := e2.Group("/api/residences")
authGroup2.Use(testutil.MockAuthMiddleware(noResUser))
authGroup2.GET("/my-residences/", handler.GetMyResidences)
w := testutil.MakeRequest(e2, "GET", "/api/residences/my-residences/", nil, "test-token")
testutil.AssertStatusCode(t, w, http.StatusOK)
// GetMyResidences returns MyResidencesResponse: {"residences": [...] or null}
var response map[string]interface{}
err := json.Unmarshal(w.Body.Bytes(), &response)
require.NoError(t, err)
if response["residences"] == nil {
// null residences means no residences
} else {
residences := response["residences"].([]interface{})
assert.Len(t, residences, 0)
}
})
}
func TestResidenceHandler_GetSummary(t *testing.T) {
handler, e, db := setupResidenceHandler(t)
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
testutil.CreateTestResidence(t, db, user.ID, "House 1")
authGroup := e.Group("/api/residences")
authGroup.Use(testutil.MockAuthMiddleware(user))
authGroup.GET("/summary/", handler.GetSummary)
t.Run("successful summary", func(t *testing.T) {
w := testutil.MakeRequest(e, "GET", "/api/residences/summary/", nil, "test-token")
testutil.AssertStatusCode(t, w, http.StatusOK)
var response map[string]interface{}
err := json.Unmarshal(w.Body.Bytes(), &response)
require.NoError(t, err)
assert.Contains(t, response, "total_residences")
assert.Contains(t, response, "total_tasks")
})
}
func TestResidenceHandler_UpdateResidence_InvalidID(t *testing.T) {
handler, e, db := setupResidenceHandler(t)
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
authGroup := e.Group("/api/residences")
authGroup.Use(testutil.MockAuthMiddleware(user))
authGroup.PUT("/:id/", handler.UpdateResidence)
t.Run("invalid id returns 400", func(t *testing.T) {
newName := "Updated"
req := requests.UpdateResidenceRequest{Name: &newName}
w := testutil.MakeRequest(e, "PUT", "/api/residences/invalid/", req, "test-token")
testutil.AssertStatusCode(t, w, http.StatusBadRequest)
})
t.Run("non-existent id returns 403", func(t *testing.T) {
newName := "Updated"
req := requests.UpdateResidenceRequest{Name: &newName}
w := testutil.MakeRequest(e, "PUT", "/api/residences/9999/", req, "test-token")
testutil.AssertStatusCode(t, w, http.StatusForbidden)
})
}
func TestResidenceHandler_DeleteResidence_InvalidID(t *testing.T) {
handler, e, db := setupResidenceHandler(t)
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
authGroup := e.Group("/api/residences")
authGroup.Use(testutil.MockAuthMiddleware(user))
authGroup.DELETE("/:id/", handler.DeleteResidence)
t.Run("invalid id returns 400", func(t *testing.T) {
w := testutil.MakeRequest(e, "DELETE", "/api/residences/invalid/", nil, "test-token")
testutil.AssertStatusCode(t, w, http.StatusBadRequest)
})
t.Run("non-existent id returns 403", func(t *testing.T) {
w := testutil.MakeRequest(e, "DELETE", "/api/residences/9999/", nil, "test-token")
testutil.AssertStatusCode(t, w, http.StatusForbidden)
})
}
func TestResidenceHandler_GetShareCode(t *testing.T) {
handler, e, db := setupResidenceHandler(t)
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
residence := testutil.CreateTestResidence(t, db, user.ID, "Share Code Test")
authGroup := e.Group("/api/residences")
authGroup.Use(testutil.MockAuthMiddleware(user))
authGroup.GET("/:id/share-code/", handler.GetShareCode)
t.Run("no share code returns null", func(t *testing.T) {
w := testutil.MakeRequest(e, "GET", fmt.Sprintf("/api/residences/%d/share-code/", residence.ID), nil, "test-token")
testutil.AssertStatusCode(t, w, http.StatusOK)
var response map[string]interface{}
err := json.Unmarshal(w.Body.Bytes(), &response)
require.NoError(t, err)
assert.Nil(t, response["share_code"])
})
t.Run("invalid id returns 400", func(t *testing.T) {
w := testutil.MakeRequest(e, "GET", "/api/residences/invalid/share-code/", nil, "test-token")
testutil.AssertStatusCode(t, w, http.StatusBadRequest)
})
}
func TestResidenceHandler_GenerateSharePackage(t *testing.T) {
handler, e, db := setupResidenceHandler(t)
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
residence := testutil.CreateTestResidence(t, db, user.ID, "Package Test")
authGroup := e.Group("/api/residences")
authGroup.Use(testutil.MockAuthMiddleware(user))
authGroup.POST("/:id/generate-share-package/", handler.GenerateSharePackage)
t.Run("generate share package", func(t *testing.T) {
w := testutil.MakeRequest(e, "POST", fmt.Sprintf("/api/residences/%d/generate-share-package/", residence.ID), nil, "test-token")
testutil.AssertStatusCode(t, w, http.StatusOK)
var response map[string]interface{}
err := json.Unmarshal(w.Body.Bytes(), &response)
require.NoError(t, err)
assert.Contains(t, response, "share_code")
})
}