Skip to content
quarry Artifact [51d0cf04be]
Login

Artifact [51d0cf04be]

Artifact 51d0cf04beba702e550dc7ee5876701ae8b3f63df3fc865e9ba9d173364f1762:


package web

import (
	"strings"
	"testing"
)

// RFC 0028: requests live on a page of their own. Waiting ones answer
// with two POSTed buttons that return to the list (never a link, so
// nothing runs from a GET); decided ones fold into History, filterable
// by agent; and /me no longer draws them.
func TestRequestsHaveAPageOfTheirOwn(t *testing.T) {
	render := func(v requestsView) string {
		var b strings.Builder
		if err := noHooks.template(requestsPageTmpl).ExecuteTemplate(&b, "content", pageData{Title: "Requests", Requests: &v}); err != nil {
			t.Fatal(err)
		}
		return b.String()
	}
	waiting := render(requestsView{Tab: "waiting",
		Waiting: []meSignOff{{ID: "abc", Agent: "zeitgeist", Summary: "agent.new for rajeev", Reason: "a QA tester", State: "pending", Requested: "2026-11-08T10:00:00Z"}}})
	for what, want := range map[string]string{
		"approve posts back to the list": `<form method="post" action="/me/signoffs/abc"><input type="hidden" name="approve" value="true"><input type="hidden" name="back" value="list">`,
		"deny posts back to the list":    `<form method="post" action="/me/signoffs/abc"><input type="hidden" name="approve" value="false"><input type="hidden" name="back" value="list">`,
		"each row opens its request":     `href="/me/requests/abc"`,
		"the waiting tab is current":     `data-hook="requests-tab-waiting">`,
	} {
		if !strings.Contains(waiting, want) {
			t.Errorf("FAIL: %s (%q)", what, want)
		}
	}
	history := render(requestsView{Tab: "history", Agent: "zeitgeist", Agents: []string{"zeitgeist", "jva-bot"},
		History: []meSignOff{{ID: "def", Agent: "zeitgeist", Summary: "x", State: "denied", Requested: "2026-11-07T10:00:00Z"}}})
	if !strings.Contains(history, `data-hook="request" data-state="denied"`) || strings.Contains(history, `action="/me/signoffs/def"`) {
		t.Error("FAIL: a decided request is not in History, or can still be answered")
	}
	if !strings.Contains(history, `agent=jva-bot`) {
		t.Error("FAIL: History cannot be narrowed to one agent")
	}
	if empty := render(requestsView{Tab: "waiting"}); !strings.Contains(empty, `data-hook="requests-none"`) {
		t.Error("FAIL: an empty Waiting tab says nothing")
	}
	var me strings.Builder
	if err := noHooks.template(mePageTmpl).ExecuteTemplate(&me, "content", pageData{Title: "ann", User: "ann", Me: &meView{Name: "ann", Notify: &prefsView{}}}); err != nil {
		t.Fatal(err)
	}
	if strings.Contains(me.String(), `id="signoffs"`) {
		t.Error("FAIL: /me still draws a sign-off section")
	}
	if h := requestsBadgeHTML(3); !strings.Contains(h, `id="requests-btn"`) || !strings.Contains(h, `data-count="3"`) || !strings.Contains(h, `href="/me/requests"`) {
		t.Errorf("FAIL: the bar's badge: %s", h)
	}
}

// RFC 0027: the page an email links to shows one request, who asks and
// why, and answers it with two posted buttons that return to it; a
// decided request has no buttons left.
func TestASignOffHasAPageOfItsOwn(t *testing.T) {
	render := func(s meSignOff) string {
		var b strings.Builder
		if err := noHooks.template(signOffPageTmpl).ExecuteTemplate(&b, "content", pageData{Title: "Approve?", SignOff: &s}); err != nil {
			t.Fatal(err)
		}
		return b.String()
	}
	got := render(meSignOff{ID: "abc", Agent: "zeitgeist", Summary: "agent.new for rajeev", Reason: "a QA tester", State: "pending", Requested: "2026-11-08T10:00:00Z"})
	for what, want := range map[string]string{
		"who asks":          `data-hook="signoff-agent">zeitgeist<`,
		"what runs":         `data-hook="signoff-summary">agent.new for rajeev<`,
		"why":               `data-hook="signoff-reason"`,
		"approve posts":     `<form method="post" action="/me/signoffs/abc"><input type="hidden" name="approve" value="true"><input type="hidden" name="back" value="page">`,
		"deny posts":        `<form method="post" action="/me/signoffs/abc"><input type="hidden" name="approve" value="false"><input type="hidden" name="back" value="page">`,
		"its state is read": `data-hook="signoff-page" data-state="pending"`,
	} {
		if !strings.Contains(got, want) {
			t.Errorf("FAIL: %s (%q)", what, want)
		}
	}
	if done := render(meSignOff{ID: "abc", Agent: "zeitgeist", Summary: "x", State: "approved", Requested: "2026-11-08T10:00:00Z"}); strings.Contains(done, "<form") {
		t.Errorf("FAIL: an approved request can still be answered")
	}
}