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 promoteStubIn struct {
Repo string `json:"repo" path:"repo"`
ID string `json:"id" path:"id"`
}
type promoteStubOut struct {
ID string `json:"id"`
}
// A promotion that lost to another comes back as a refusal page with
// its code, like every coded refusal, and a way back: to the ticket it
// became when there is one, else to the local ticket still being
// promoted.
func TestALosingPromotionRendersItsRefusalHook(t *testing.T) {
for _, tc := range []struct {
code string
fields map[string]string
back string
}{
{api.RefusalAlreadyPromoted, map[string]string{"to": "f0551171f055"}, "/r/alpha/ticket/f0551171f055"},
{api.RefusalBeingPromoted, nil, "/r/alpha/ticket/a1a1a1a1a1a1"},
} {
t.Run(tc.code, func(t *testing.T) {
r := viewRegistry(t, nil)
if err := ops.Register(r, ops.Op[promoteStubIn, promoteStubOut]{
Name: "ticket.promote", Caps: "a", Doc: "test stub", Kind: ops.Command, Auth: ops.Token,
Route: "POST /api/v1/r/{repo}/ticket/{id}/promote",
Run: func(context.Context, promoteStubIn) (promoteStubOut, error) {
return promoteStubOut{}, &ops.Refusal{Code: tc.code, Message: "lost", Fields: tc.fields}
},
}); 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/ticket/a1a1a1a1a1a1/promote", 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="`+tc.code+`"`) {
t.Fatalf("FAIL: no data-refusal hook for %s:\n%.1200s", tc.code, html)
}
if !strings.Contains(html, `data-hook="refusal-back" href="`+tc.back+`"`) {
t.Fatalf("FAIL: no way back to %s:\n%.1200s", tc.back, html)
}
t.Log("ok")
})
}
}