From d0bcbd1ed060c3780438e9f9e77571c0470b2d1f Mon Sep 17 00:00:00 2001 From: agent-company Date: Mon, 18 May 2026 21:39:34 +0000 Subject: [PATCH] feat: add POST /pulls/{owner}/{repo}/{index}/assignees route Register the PR assignees route pointing to the existing AssignIssue handler, which works for both issues and PRs via the Gitea API. Add integration tests covering valid, HTMX, and missing assignee cases. Closes leeworks-agents/gitea-mobile#228 Co-Authored-By: Claude Opus 4.6 (1M context) --- internal/handlers/handlers.go | 1 + internal/handlers/integration_test.go | 60 +++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/internal/handlers/handlers.go b/internal/handlers/handlers.go index 1134c72..8fe1d1c 100644 --- a/internal/handlers/handlers.go +++ b/internal/handlers/handlers.go @@ -56,6 +56,7 @@ func (h *Handler) RegisterRoutes(mux *http.ServeMux) { mux.HandleFunc("GET /pulls/{owner}/{repo}/{index}", h.PullDetail) mux.HandleFunc("POST /pulls/{owner}/{repo}/{index}/review", h.SubmitReview) mux.HandleFunc("POST /pulls/{owner}/{repo}/{index}/state", h.SetPullState) + mux.HandleFunc("POST /pulls/{owner}/{repo}/{index}/assignees", h.AssignIssue) // Settings (handled separately for auth bypass). settingsHandler := &SettingsHandler{ diff --git a/internal/handlers/integration_test.go b/internal/handlers/integration_test.go index b5dcd3e..f8c4dbc 100644 --- a/internal/handlers/integration_test.go +++ b/internal/handlers/integration_test.go @@ -726,6 +726,66 @@ func TestIntegration_AssignIssue_MissingAssignee(t *testing.T) { } } +// --- Issue #228: Integration tests for POST /pulls/{owner}/{repo}/{index}/assignees --- + +func TestIntegration_AssignPull_Valid(t *testing.T) { + h, srv := newTestHandlerWithMock(t) + defer srv.Close() + + mux := http.NewServeMux() + mux.HandleFunc("POST /pulls/{owner}/{repo}/{index}/assignees", h.AssignIssue) + + form := url.Values{"assignee": {"user1"}} + req := reqWithToken(http.MethodPost, "/pulls/test-org/repo1/1/assignees", form.Encode()) + w := httptest.NewRecorder() + + mux.ServeHTTP(w, req) + + if w.Code != http.StatusSeeOther { + t.Errorf("status = %d, want %d", w.Code, http.StatusSeeOther) + } +} + +func TestIntegration_AssignPull_HTMX(t *testing.T) { + h, srv := newTestHandlerWithMock(t) + defer srv.Close() + + mux := http.NewServeMux() + mux.HandleFunc("POST /pulls/{owner}/{repo}/{index}/assignees", h.AssignIssue) + + form := url.Values{"assignee": {"user1"}} + req := reqWithToken(http.MethodPost, "/pulls/test-org/repo1/1/assignees", form.Encode()) + req.Header.Set("HX-Request", "true") + w := httptest.NewRecorder() + + mux.ServeHTTP(w, req) + + if w.Code != http.StatusOK { + t.Errorf("status = %d, want %d", w.Code, http.StatusOK) + } + body := w.Body.String() + if !contains(body, "Assigned to user1") { + t.Errorf("expected 'Assigned to user1' in HTMX response, got: %s", body) + } +} + +func TestIntegration_AssignPull_MissingAssignee(t *testing.T) { + h, srv := newTestHandlerWithMock(t) + defer srv.Close() + + mux := http.NewServeMux() + mux.HandleFunc("POST /pulls/{owner}/{repo}/{index}/assignees", h.AssignIssue) + + req := reqWithToken(http.MethodPost, "/pulls/test-org/repo1/1/assignees", "") + w := httptest.NewRecorder() + + mux.ServeHTTP(w, req) + + if w.Code != http.StatusBadRequest { + t.Errorf("status = %d, want %d", w.Code, http.StatusBadRequest) + } +} + // --- Issue #118: Integration tests for CloseIssue and AddComment --- func TestIntegration_CloseIssue(t *testing.T) {