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:
@@ -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")
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user