11
This commit is contained in:
@@ -0,0 +1,214 @@
|
||||
package webhook_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"superwork-tui/internal/webhook"
|
||||
)
|
||||
|
||||
func post(t *testing.T, srv *webhook.Server, path, eventHeader, body string) *httptest.ResponseRecorder {
|
||||
t.Helper()
|
||||
req := httptest.NewRequest(http.MethodPost, path, bytes.NewBufferString(body))
|
||||
req.Header.Set("X-Gitea-Event", eventHeader)
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
w := httptest.NewRecorder()
|
||||
srv.ServeHTTP(w, req)
|
||||
return w
|
||||
}
|
||||
|
||||
func TestServer_PREvent(t *testing.T) {
|
||||
var got webhook.Event
|
||||
srv := webhook.NewServer(func(e webhook.Event) { got = e })
|
||||
|
||||
payload := `{"action":"opened","pull_request":{"number":7,"html_url":"http://x/pr/7","head":{"ref":"feat/my-branch"},"title":"My PR","body":"Closes #3"}}`
|
||||
w := post(t, srv, "/webhook", "pull_request", payload)
|
||||
|
||||
if w.Code != 200 {
|
||||
t.Fatalf("want 200, got %d", w.Code)
|
||||
}
|
||||
pr, ok := got.(webhook.PrEvent)
|
||||
if !ok {
|
||||
t.Fatalf("want PrEvent, got %T", got)
|
||||
}
|
||||
if pr.Action != "opened" {
|
||||
t.Errorf("action: want opened, got %q", pr.Action)
|
||||
}
|
||||
if pr.PR != "7" {
|
||||
t.Errorf("pr: want 7, got %q", pr.PR)
|
||||
}
|
||||
if pr.Branch != "feat/my-branch" {
|
||||
t.Errorf("branch: %q", pr.Branch)
|
||||
}
|
||||
if pr.HTMLUrl != "http://x/pr/7" {
|
||||
t.Errorf("htmlUrl: %q", pr.HTMLUrl)
|
||||
}
|
||||
if pr.Title != "My PR" {
|
||||
t.Errorf("title: %q", pr.Title)
|
||||
}
|
||||
if pr.Body != "Closes #3" {
|
||||
t.Errorf("body: %q", pr.Body)
|
||||
}
|
||||
if pr.IssueNumber != 0 {
|
||||
t.Errorf("issueNumber should be 0 on canonical route, got %d", pr.IssueNumber)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer_PREventLegacyRoute(t *testing.T) {
|
||||
var got webhook.Event
|
||||
srv := webhook.NewServer(func(e webhook.Event) { got = e })
|
||||
payload := `{"action":"opened","pull_request":{"number":7,"html_url":"http://x/pr/7","head":{"ref":"feat/x"},"title":"T","body":""}}`
|
||||
w := post(t, srv, "/webhook/42", "pull_request", payload)
|
||||
if w.Code != 200 {
|
||||
t.Fatalf("want 200, got %d", w.Code)
|
||||
}
|
||||
pr := got.(webhook.PrEvent)
|
||||
if pr.IssueNumber != 42 {
|
||||
t.Errorf("issueNumber: want 42, got %d", pr.IssueNumber)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer_IssueEvent(t *testing.T) {
|
||||
var got webhook.Event
|
||||
srv := webhook.NewServer(func(e webhook.Event) { got = e })
|
||||
payload := `{"action":"opened","issue":{"number":5,"html_url":"http://x/issues/5","title":"Issue title","body":"some body"}}`
|
||||
w := post(t, srv, "/webhook", "issues", payload)
|
||||
if w.Code != 200 {
|
||||
t.Fatalf("want 200, got %d", w.Code)
|
||||
}
|
||||
ev, ok := got.(webhook.IssueEvent)
|
||||
if !ok {
|
||||
t.Fatalf("want IssueEvent, got %T", got)
|
||||
}
|
||||
if ev.Action != "opened" {
|
||||
t.Errorf("action: %q", ev.Action)
|
||||
}
|
||||
if ev.IssueNumber != 5 {
|
||||
t.Errorf("issueNumber: %d", ev.IssueNumber)
|
||||
}
|
||||
if ev.Title != "Issue title" {
|
||||
t.Errorf("title: %q", ev.Title)
|
||||
}
|
||||
if ev.Body != "some body" {
|
||||
t.Errorf("body: %q", ev.Body)
|
||||
}
|
||||
if ev.HTMLUrl != "http://x/issues/5" {
|
||||
t.Errorf("htmlUrl: %q", ev.HTMLUrl)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer_IssueCommentEvent_OnPR(t *testing.T) {
|
||||
var got webhook.Event
|
||||
srv := webhook.NewServer(func(e webhook.Event) { got = e })
|
||||
// issue.pull_request non-null → prNumber = issue.number
|
||||
payload := `{"action":"created","issue":{"number":9,"pull_request":{"merged_at":null}},"comment":{"body":"<!-- spx:review=1 -->","html_url":"http://x/c/1"}}`
|
||||
w := post(t, srv, "/webhook", "issue_comment", payload)
|
||||
if w.Code != 200 {
|
||||
t.Fatalf("want 200, got %d", w.Code)
|
||||
}
|
||||
ev, ok := got.(webhook.IssueCommentEvent)
|
||||
if !ok {
|
||||
t.Fatalf("want IssueCommentEvent, got %T", got)
|
||||
}
|
||||
if ev.IssueNumber != 9 {
|
||||
t.Errorf("issueNumber: %d", ev.IssueNumber)
|
||||
}
|
||||
if ev.PRNumber != 9 {
|
||||
t.Errorf("prNumber: want 9 (PR comment), got %d", ev.PRNumber)
|
||||
}
|
||||
if ev.CommentBody != "<!-- spx:review=1 -->" {
|
||||
t.Errorf("commentBody: %q", ev.CommentBody)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer_IssueCommentEvent_NotOnPR(t *testing.T) {
|
||||
var got webhook.Event
|
||||
srv := webhook.NewServer(func(e webhook.Event) { got = e })
|
||||
payload := `{"action":"created","issue":{"number":9},"comment":{"body":"hello","html_url":"http://x/c/2"}}`
|
||||
w := post(t, srv, "/webhook", "issue_comment", payload)
|
||||
if w.Code != 200 {
|
||||
t.Fatalf("want 200, got %d", w.Code)
|
||||
}
|
||||
ev := got.(webhook.IssueCommentEvent)
|
||||
if ev.PRNumber != 0 {
|
||||
t.Errorf("prNumber: want 0 (not a PR), got %d", ev.PRNumber)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer_PushEvent(t *testing.T) {
|
||||
var got webhook.Event
|
||||
srv := webhook.NewServer(func(e webhook.Event) { got = e })
|
||||
payload := `{"ref":"refs/heads/main"}`
|
||||
w := post(t, srv, "/webhook", "push", payload)
|
||||
if w.Code != 200 {
|
||||
t.Fatalf("want 200, got %d", w.Code)
|
||||
}
|
||||
ev, ok := got.(webhook.PushEvent)
|
||||
if !ok {
|
||||
t.Fatalf("want PushEvent, got %T", got)
|
||||
}
|
||||
if ev.Branch != "main" {
|
||||
t.Errorf("branch: want main, got %q", ev.Branch)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer_MalformedJSON_Returns400(t *testing.T) {
|
||||
called := false
|
||||
srv := webhook.NewServer(func(e webhook.Event) { called = true })
|
||||
w := post(t, srv, "/webhook", "pull_request", "{bad json")
|
||||
if w.Code != 400 {
|
||||
t.Fatalf("want 400, got %d", w.Code)
|
||||
}
|
||||
if called {
|
||||
t.Error("OnEvent should not be called for malformed JSON")
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer_WrongMethod_Returns405(t *testing.T) {
|
||||
srv := webhook.NewServer(func(e webhook.Event) {})
|
||||
req := httptest.NewRequest(http.MethodGet, "/webhook", nil)
|
||||
w := httptest.NewRecorder()
|
||||
srv.ServeHTTP(w, req)
|
||||
if w.Code != 405 {
|
||||
t.Fatalf("want 405, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer_UnknownPath_Returns404(t *testing.T) {
|
||||
srv := webhook.NewServer(func(e webhook.Event) {})
|
||||
req := httptest.NewRequest(http.MethodPost, "/unknown", nil)
|
||||
w := httptest.NewRecorder()
|
||||
srv.ServeHTTP(w, req)
|
||||
if w.Code != 404 {
|
||||
t.Fatalf("want 404, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer_NonMatchingEventHeader_Returns200_NoEvent(t *testing.T) {
|
||||
called := false
|
||||
srv := webhook.NewServer(func(e webhook.Event) { called = true })
|
||||
// push event but missing ref → null parse → no event emitted, still 200
|
||||
w := post(t, srv, "/webhook", "push", `{"action":"opened"}`)
|
||||
if w.Code != 200 {
|
||||
t.Fatalf("want 200, got %d", w.Code)
|
||||
}
|
||||
if called {
|
||||
t.Error("OnEvent should not be called when event doesn't parse")
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer_ResponseBodyIsJSON(t *testing.T) {
|
||||
srv := webhook.NewServer(func(e webhook.Event) {})
|
||||
payload := `{"action":"opened","pull_request":{"number":1,"html_url":"http://x","head":{"ref":"x"},"title":"","body":""}}`
|
||||
w := post(t, srv, "/webhook", "pull_request", payload)
|
||||
var resp map[string]any
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
|
||||
t.Fatalf("response not JSON: %v", err)
|
||||
}
|
||||
if resp["ok"] != true {
|
||||
t.Errorf("want ok:true, got %v", resp["ok"])
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user