package web
import (
"strings"
"testing"
)
// The chip and the action read the SAME sentence, by the same parser.
// A reader who sees "closes X" is looking at the reference that will
// settle X — there is no way to write one that acts without appearing,
// or appears without acting.
func TestTheRecordShowsWhatItWillClose(t *testing.T) {
var buf strings.Builder
err := noHooks.template(landingPage).ExecuteTemplate(&buf, "landing-body", pageData{
Repo: "quarry",
Landing: &landingDetail{landingRow: landingRow{
ID: "aa11bb22cc33", Branch: "fix-it", Target: "trunk", State: "open",
Title: "zitcli: record every store subprocess. closes cafb1f21be",
}},
})
if err != nil {
t.Fatal(err)
}
got := buf.String()
if !strings.Contains(got, `href="/r/quarry/ticket/cafb1f21be"`) {
t.Error("FAIL: the record does not link the ticket it closes")
}
if !strings.Contains(got, ">closes\n") && !strings.Contains(got, "closes") {
t.Error("FAIL: the record does not say it closes anything")
}
}
// Past tense once settled: by then it has closed it.
func TestASettledRecordSaysItClosed(t *testing.T) {
var buf strings.Builder
if err := noHooks.template(landingPage).ExecuteTemplate(&buf, "landing-body", pageData{
Repo: "quarry",
Landing: &landingDetail{landingRow: landingRow{
ID: "aa11bb22cc33", Branch: "fix-it", Target: "trunk", State: "accepted",
Title: "closes cafb1f21be",
}},
}); err != nil {
t.Fatal(err)
}
if !strings.Contains(buf.String(), "closed") {
t.Error("FAIL: a settled record still speaks in the future tense")
}
}
// A landing that says nothing shows nothing — the ordinary case.
func TestAnOrdinaryRecordShowsNoClosingLine(t *testing.T) {
var buf strings.Builder
if err := noHooks.template(landingPage).ExecuteTemplate(&buf, "landing-body", pageData{
Repo: "quarry",
Landing: &landingDetail{landingRow: landingRow{
ID: "aa11bb22cc33", Branch: "b", Target: "trunk", State: "open",
Title: "csp: allow the page to state its own address",
}},
}); err != nil {
t.Fatal(err)
}
if strings.Contains(buf.String(), "l-closes") {
t.Error("FAIL: a record that closes nothing drew the closing line anyway")
}
}
// The queue says so too, so a reader scanning it can see which
// proposals carry tickets with them without opening each one.
func TestTheQueueShowsWhichRecordsCarryTickets(t *testing.T) {
var buf strings.Builder
err := noHooks.template(landingListPage).ExecuteTemplate(&buf, "l-list-body", pageData{
Repo: "quarry", Nav: ticketNav{Repo: "quarry"},
Landings: []landingRow{{
ID: "aa11bb22cc33", Branch: "fix-it", Target: "trunk", State: "open",
Title: "zitcli: record every store subprocess. closes cafb1f21be",
}},
})
if err != nil {
t.Fatal(err)
}
got := buf.String()
if !strings.Contains(got, "l-closes-chip") {
t.Error("FAIL: the queue does not mark a record that closes a ticket")
}
if !strings.Contains(got, "cafb1f21be") {
t.Error("FAIL: the chip does not name the ticket")
}
}
// A cross-repository reference is not acted on, so it is not advertised
// either: showing a chip for something that will not happen is worse
// than showing nothing.
func TestACrossRepositoryCloseIsNotAdvertised(t *testing.T) {
if got := closingIDs("closes other:ticket/cafb1f21be"); len(got) != 0 {
t.Errorf("FAIL: advertised %v for another repository's ticket", got)
}
if got := closingIDs("closes cafb1f21be"); len(got) != 1 || got[0] != "cafb1f21be" {
t.Errorf("FAIL: our own ticket gave %v", got)
}
}