Skip to content
quarry Artifact [b987aeb743]
Login

Artifact [b987aeb743]

Artifact b987aeb743e6af1d6f1b489b7b5c4ead9f780bfdc3376024bd47c5c37634a9cb:


package web

import (
	"strings"
	"testing"
)

// A landing settles from somewhere else — a reviewer accepts on the
// record page, or CI goes green under an armed one — and the reader
// watching this list has no reason to reload. Until this, the list was
// the one landing surface with no live wiring at all: the record page
// and the timeline both followed the repository, and the queue did not,
// so an accepted landing sat in the list and in the nav badge until
// somebody pressed reload.
func TestTheLandingsListFollowsTheRepository(t *testing.T) {
	var buf strings.Builder
	err := landingListPage.ExecuteTemplate(&buf, "content", pageData{
		Repo: "alpha", Live: true, Nav: ticketNav{Repo: "alpha"},
	})
	if err != nil {
		t.Fatal(err)
	}
	got := buf.String()
	for _, want := range []string{
		`data-signals="{tlRev: 0}"`,
		`data-init="@get('/r/alpha/timeline.rev')"`,
		`@get('/r/alpha/landing.frag')`,
		`@get('/r/alpha/nav.frag?s=landing')`,
		`<div id="l-list">`,
	} {
		if !strings.Contains(got, want) {
			t.Errorf("FAIL: the live list is missing %s", want)
		}
	}
	// data-init, never data-on:load — Datastar fires no load event, and
	// the wrong spelling is inert rather than an error.
	if strings.Contains(got, "data-on:load") {
		t.Error("FAIL: uses an event Datastar never fires")
	}
}

// The filter travels with the repaint. Without it a reader watching
// "Accepted" would have the list replaced with the open queue the
// moment anything in the repository moved.
func TestTheRepaintKeepsTheFilterThePageIsShowing(t *testing.T) {
	var buf strings.Builder
	if err := landingListPage.ExecuteTemplate(&buf, "content", pageData{
		Repo: "alpha", Live: true, Nav: ticketNav{Repo: "alpha", State: "accepted"},
	}); err != nil {
		t.Fatal(err)
	}
	if !strings.Contains(buf.String(), `landing.frag?state=accepted`) {
		t.Error("FAIL: the repaint drops the state filter and would show the open queue instead")
	}
}

// Without a notifier there is no revision stream to subscribe to, so
// the page carries no wiring — and is still a correct page.
func TestWithoutAStreamTheListIsPlain(t *testing.T) {
	var buf strings.Builder
	if err := landingListPage.ExecuteTemplate(&buf, "content", pageData{
		Repo: "alpha", Nav: ticketNav{Repo: "alpha"},
	}); err != nil {
		t.Fatal(err)
	}
	got := buf.String()
	if strings.Contains(got, "data-init") || strings.Contains(got, "data-effect") {
		t.Error("FAIL: a forge with no revision stream still subscribes to one")
	}
	// The listing itself is still there — the wiring is what is absent,
	// not the content.
	if !strings.Contains(got, `<div id="l-list">`) || !strings.Contains(got, "No branch is awaiting a decision") {
		t.Error("FAIL: the plain page lost its listing")
	}
}

// The fragment renders the same body the page does, wrapped in the
// element it replaces. Two renderings of one listing that could differ
// is the bug this shape exists to prevent.
func TestTheFragmentIsTheSameBodyThePageShows(t *testing.T) {
	data := pageData{Repo: "alpha", Nav: ticketNav{Repo: "alpha"}}
	var frag, page strings.Builder
	if err := landingListPage.ExecuteTemplate(&frag, "l-list-body", data); err != nil {
		t.Fatal(err)
	}
	if err := landingListPage.ExecuteTemplate(&page, "content", data); err != nil {
		t.Fatal(err)
	}
	if !strings.Contains(page.String(), strings.TrimSpace(frag.String())) {
		t.Error("FAIL: the fragment is not the body the page renders")
	}
}