cli/pkg/jobrunner/handlers/publish_draft_test.go
Claude d32c51d816 feat(jobrunner): port from GitHub to Forgejo using pkg/forge
Replace all GitHub API and gh CLI dependencies with Forgejo SDK via
pkg/forge. The bash dispatcher burned a week of credit in a day due to
bugs — the jobrunner now talks directly to Forgejo.

- Add forge client methods: CreateIssueComment, CloseIssue, MergePullRequest,
  SetPRDraft, ListPRReviews, GetCombinedStatus, DismissReview
- Create ForgejoSource implementing JobSource (epic polling, checklist
  parsing, commit status via combined status API)
- Rewrite all 5 handlers to accept *forge.Client instead of shelling out
- Replace ResolveThreadsHandler with DismissReviewsHandler (Forgejo has
  no thread resolution API — dismiss stale REQUEST_CHANGES reviews instead)
- Delete pkg/jobrunner/github/ and handlers/exec.go entirely
- Update internal/core-ide/headless.go to wire Forgejo source and handlers
- All 33 tests pass with mock Forgejo HTTP servers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 00:40:49 +00:00

84 lines
2 KiB
Go

package handlers
import (
"context"
"io"
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/host-uk/core/pkg/jobrunner"
)
func TestPublishDraft_Match_Good(t *testing.T) {
h := NewPublishDraftHandler(nil)
sig := &jobrunner.PipelineSignal{
IsDraft: true,
PRState: "OPEN",
CheckStatus: "SUCCESS",
}
assert.True(t, h.Match(sig))
}
func TestPublishDraft_Match_Bad_NotDraft(t *testing.T) {
h := NewPublishDraftHandler(nil)
sig := &jobrunner.PipelineSignal{
IsDraft: false,
PRState: "OPEN",
CheckStatus: "SUCCESS",
}
assert.False(t, h.Match(sig))
}
func TestPublishDraft_Match_Bad_ChecksFailing(t *testing.T) {
h := NewPublishDraftHandler(nil)
sig := &jobrunner.PipelineSignal{
IsDraft: true,
PRState: "OPEN",
CheckStatus: "FAILURE",
}
assert.False(t, h.Match(sig))
}
func TestPublishDraft_Execute_Good(t *testing.T) {
var capturedMethod string
var capturedPath string
var capturedBody string
srv := httptest.NewServer(withVersion(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
capturedMethod = r.Method
capturedPath = r.URL.Path
b, _ := io.ReadAll(r.Body)
capturedBody = string(b)
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte(`{}`))
})))
defer srv.Close()
client := newTestForgeClient(t, srv.URL)
h := NewPublishDraftHandler(client)
sig := &jobrunner.PipelineSignal{
RepoOwner: "host-uk",
RepoName: "core-php",
PRNumber: 42,
IsDraft: true,
PRState: "OPEN",
}
result, err := h.Execute(context.Background(), sig)
require.NoError(t, err)
assert.Equal(t, http.MethodPatch, capturedMethod)
assert.Equal(t, "/api/v1/repos/host-uk/core-php/pulls/42", capturedPath)
assert.Contains(t, capturedBody, `"draft":false`)
assert.True(t, result.Success)
assert.Equal(t, "publish_draft", result.Action)
assert.Equal(t, "host-uk", result.RepoOwner)
assert.Equal(t, "core-php", result.RepoName)
assert.Equal(t, 42, result.PRNumber)
}