package web
import (
"context"
"io"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
"craftdesign.group/quarry/internal/api"
"craftdesign.group/quarry/internal/ops"
)
type acceptStubIn struct {
Repo string `json:"repo" path:"repo"`
ID string `json:"id" path:"id"`
Message string `json:"message"`
Override string `json:"override"`
}
type acceptStubOut struct {
Hash string `json:"hash"`
}
// An accept refused because the branch moved since it was checked, or
// in premerge mode because the target moved since the pair was judged,
// comes back as a refusal page carrying the code, with a way back to
// the landing to review the new tip.
func TestAMovedBranchAcceptRendersItsRefusalHook(t *testing.T) {
for _, code := range []string{api.RefusalBranchMoved, api.RefusalTargetMoved} {
t.Run(code, func(t *testing.T) { movedAcceptRendersItsHook(t, code) })
}
}
func movedAcceptRendersItsHook(t *testing.T, code string) {
r := viewRegistry(t, nil)
if err := ops.Register(r, ops.Op[acceptStubIn, acceptStubOut]{
Name: "landing.accept", Caps: "i", Doc: "test stub", Kind: ops.Command, Auth: ops.Token,
Route: "POST /api/v1/r/{repo}/landing/{id}/accept",
Run: func(context.Context, acceptStubIn) (acceptStubOut, error) {
return acceptStubOut{}, &ops.Refusal{Code: code, Message: "moved",
Fields: map[string]string{"expected": "aaa", "current": "bbb"}}
},
}); err != nil {
t.Fatal(err)
}
srv := httptest.NewServer(HandlerWith(r, nil, nil, nil))
defer srv.Close()
c := srv.Client()
c.CheckRedirect = func(*http.Request, []*http.Request) error { return http.ErrUseLastResponse }
resp, err := c.PostForm(srv.URL+"/r/alpha/landing/a1a1a1a1a1a1/accept", url.Values{})
if err != nil {
t.Fatal(err)
}
defer resp.Body.Close()
b, _ := io.ReadAll(resp.Body)
html := string(b)
if resp.StatusCode != http.StatusBadRequest {
t.Fatalf("FAIL: status %d, want 400:\n%.600s", resp.StatusCode, html)
}
if !strings.Contains(html, `data-refusal="`+code+`"`) {
t.Fatalf("FAIL: no data-refusal hook for %s:\n%.1200s", code, html)
}
if !strings.Contains(html, `data-hook="refusal-back" href="/r/alpha/landing/a1a1a1a1a1a1"`) {
t.Fatalf("FAIL: no way back to the landing to review the new tip:\n%.1200s", html)
}
t.Log("ok")
}