Compare commits

..

1 Commits

Author SHA1 Message Date
agent-company c026d24d11 test: add HTMX fragment assertions to IssueDetail and PullDetail tests
Build and Push / test (pull_request) Successful in 18s
Build and Push / build (pull_request) Has been skipped
Verify that GET /issues/{owner}/{repo}/{index} and
GET /pulls/{owner}/{repo}/{index} with HX-Request: true return bare
content fragments without layout boilerplate (<html>, <!DOCTYPE>,
bottom-nav), while still containing the correct issue/PR-specific content.

Closes leeworks-agents/gitea-mobile#217

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-18 21:47:15 +00:00
2 changed files with 72 additions and 61 deletions
-1
View File
@@ -56,7 +56,6 @@ 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{
+72 -60
View File
@@ -489,6 +489,78 @@ func TestIntegration_PullDetail_InvalidIndex(t *testing.T) {
}
}
// --- Issue #217: HTMX fragment assertions for IssueDetail and PullDetail ---
func TestIntegration_IssueDetail_HTMX(t *testing.T) {
h, srv := newTestHandlerWithMock(t)
defer srv.Close()
mux := http.NewServeMux()
mux.HandleFunc("GET /issues/{owner}/{repo}/{index}", h.IssueDetail)
req := reqWithToken(http.MethodGet, "/issues/test-org/repo1/1", "")
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()
// HTMX response must NOT contain layout boilerplate.
if contains(body, "<html") {
t.Error("HTMX response should not contain <html tag")
}
if contains(body, "<!DOCTYPE") {
t.Error("HTMX response should not contain <!DOCTYPE")
}
if contains(body, `class="bottom-nav"`) {
t.Error("HTMX response should not contain bottom-nav")
}
// HTMX response MUST contain issue-specific content.
if !contains(body, "Test issue #1") {
t.Errorf("expected issue title 'Test issue #1' in HTMX fragment, got: %s", body[:min(300, len(body))])
}
}
func TestIntegration_PullDetail_HTMX(t *testing.T) {
h, srv := newTestHandlerWithMock(t)
defer srv.Close()
mux := http.NewServeMux()
mux.HandleFunc("GET /pulls/{owner}/{repo}/{index}", h.PullDetail)
req := reqWithToken(http.MethodGet, "/pulls/test-org/repo1/1", "")
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()
// HTMX response must NOT contain layout boilerplate.
if contains(body, "<html") {
t.Error("HTMX response should not contain <html tag")
}
if contains(body, "<!DOCTYPE") {
t.Error("HTMX response should not contain <!DOCTYPE")
}
if contains(body, `class="bottom-nav"`) {
t.Error("HTMX response should not contain bottom-nav")
}
// HTMX response MUST contain PR-specific content.
if !contains(body, "Test PR #1") {
t.Errorf("expected PR title 'Test PR #1' in HTMX fragment, got: %s", body[:min(300, len(body))])
}
}
// --- Issue #138: Integration tests for GET /issues/new and GET /issues/new/labels ---
func TestIntegration_NewIssue_WithToken(t *testing.T) {
@@ -726,66 +798,6 @@ 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) {