Skip to content
quarry Artifact [600ce1f905]
Login

Artifact [600ce1f905]

Artifact 600ce1f9059fb0e30613e7d97a27363c44478ab03feb7697f36ed415e3faa0c3:


package web

import (
	"encoding/json"
	"strings"
	"testing"
)

// #381: a stack whose middle rung conflicts lands the rungs below it,
// and the strip says so instead of "nothing in this stack lands".
func TestAStoppedStackSaysWhatLandingLands(t *testing.T) {
	render := func(landCount int) string {
		var stack stackView
		if err := json.Unmarshal([]byte(`{"segments":[
			{"id":"r1aaaaaaaaaa","number":1,"position":1,"state":"open"},
			{"id":"r2aaaaaaaaaa","number":2,"position":2,"state":"open","preflight":"conflict","preflightConflicts":["s2.txt"]},
			{"id":"r3aaaaaaaaaa","number":3,"position":3,"state":"open"}],
			"preflight":"stops","stopsAt":2,"landTo":"r1aaaaaaaaaa","landCount":`+itoa(landCount)+`}`), &stack); err != nil {
			t.Fatal(err)
		}
		var buf strings.Builder
		if err := noHooks.template(landingPage).ExecuteTemplate(&buf, "landing-body", pageData{Repo: "quarry",
			Landing: &landingDetail{landingRow: landingRow{ID: "r3aaaaaaaaaa", Branch: "s3", Target: "s2", State: "open"},
				Position: 3, Stack: stack}}); err != nil {
			t.Fatal(err)
		}
		return buf.String()
	}
	got := render(1)
	if !strings.Contains(got, `data-hook="stack-stops-lands" data-count="1"`) || strings.Contains(got, "Nothing in this stack lands") {
		t.Error("FAIL: a stack that lands its bottom rung says nothing in it lands")
	}
	// The middle rung's conflict is with the target plus the rung below
	// it, not the target alone (jva, ^4016).
	if !strings.Contains(got, "plus the rung below it") {
		t.Error("FAIL: a stacked rung's conflict is named as one with the target alone")
	}
	if got := render(0); !strings.Contains(got, `data-hook="stack-stops-lands" data-count="0"`) {
		t.Error("FAIL: a stack stopped at its base does not say nothing lands")
	}
}

// #382: a comment shown as text decodes its character references, as
// the body does, and the page escapes it once.
func TestCommentTextDecodesCharacterReferences(t *testing.T) {
	if got := commentText("0.0&lt;B&lt;1.0 and AT&amp;T &#8212; [/wiki?name=X | a &amp; b]"); got != "0.0<B<1.0 and AT&T — a & b" {
		t.Errorf("FAIL: commentText = %q", got)
	}
}

// #382's leftover: a landing title whose "<b>" was written as
// "&lt;b&gt;" keeps it as text; firstLine's tag stripping dropped it.
func TestALandingTitleKeepsTagShapedText(t *testing.T) {
	if got := titleLine("entities & <b> — done\nmore"); got != "entities & <b> — done" {
		t.Errorf("FAIL: titleLine = %q", got)
	}
	var buf strings.Builder
	if err := noHooks.template(landingPage).ExecuteTemplate(&buf, "landing-body", pageData{Repo: "quarry", OwnH1: true,
		Landing: &landingDetail{landingRow: landingRow{ID: "aa11bb22cc33", Branch: "b", Target: "trunk", State: "open",
			Title: "entities & <b> — done"}}}); err != nil {
		t.Fatal(err)
	}
	if got := buf.String(); !strings.Contains(got, "entities &amp; &lt;b&gt; — done") {
		t.Error("FAIL: the landing h1 lost the title's tag-shaped text")
	}
}

// jva: the base rung of a stack offered "Accept and land" and "Land
// stack (3)" as two primary buttons with different scope. When the
// stack lands more than this rung, the whole stack is the one primary
// action and this rung alone is the quiet alternative.
func TestTheBaseRungHasOnePrimaryAction(t *testing.T) {
	render := func(landCount int) string {
		var stack stackView
		if err := json.Unmarshal([]byte(`{"segments":[
			{"id":"r1aaaaaaaaaa","number":1,"position":1,"state":"open"},
			{"id":"r2aaaaaaaaaa","number":2,"position":2,"state":"open"},
			{"id":"r3aaaaaaaaaa","number":3,"position":3,"state":"open"}],
			"landTo":"r3aaaaaaaaaa","landCount":`+itoa(landCount)+`}`), &stack); err != nil {
			t.Fatal(err)
		}
		var buf strings.Builder
		if err := noHooks.template(landingPage).ExecuteTemplate(&buf, "landing-decide", pageData{Repo: "quarry",
			Landing: &landingDetail{landingRow: landingRow{ID: "r1aaaaaaaaaa", Branch: "s1", Target: "trunk", State: "open"},
				CanAccept: true, Position: 1, Stack: stack}}); err != nil {
			t.Fatal(err)
		}
		return buf.String()
	}
	got := render(3)
	stack, only := strings.Index(got, `data-hook="land-stack"`), strings.Index(got, `data-hook="land-this-only"`)
	if stack < 0 || only < 0 || stack > only {
		t.Fatalf("FAIL: the base rung lacks land-stack then land-this-only: %s", got)
	}
	tag := got[strings.LastIndex(got[:only], "<button"):]
	tag = tag[:strings.Index(tag, ">")]
	if strings.Count(got, `class="btn-primary"`) != 1 || !strings.Contains(tag, "btn-quiet") {
		t.Errorf("FAIL: want exactly one primary (the stack) and a quiet single-rung control: %s", got)
	}
	// A stack that can land only this rung keeps the plain accept.
	if got := render(1); !strings.Contains(got, "Accept and land") || strings.Contains(got, `data-hook="land-this-only"`) {
		t.Errorf("FAIL: a one-rung land lost its plain accept")
	}
}

// A press of Land says what it did in a sentence (2026-10-30): a press
// that found the stack already landed says so, one that only armed a
// rung says nothing landed yet, and neither reads "0 rungs landed".
// While a stack land is merging, the strip says so and offers no
// control to press again.
func TestALandPressSaysWhatItDid(t *testing.T) {
	row := landingRow{ID: "aa11bb22cc33", Branch: "b", Target: "trunk", State: "open"}
	render := func(pd pageData) string {
		var buf strings.Builder
		if err := noHooks.template(landingPage).ExecuteTemplate(&buf, "landing-body", pd); err != nil {
			t.Fatal(err)
		}
		return buf.String()
	}
	for _, c := range []struct {
		pd        pageData
		want, not string
	}{
		{pageData{Landed: "0", LandSettled: "accepted"}, "Already landed", "0</strong>"},
		{pageData{Landed: "0", Stopped: "aa11bb22cc33", LandArmed: "1"}, `data-hook="land-armed"`, "0</strong> rung"},
		{pageData{Landed: "2"}, "Landed 2 rungs.", "stopped"},
	} {
		c.pd.Repo, c.pd.Landing = "quarry", &landingDetail{landingRow: row}
		got := render(c.pd)
		if !strings.Contains(got, c.want) || strings.Contains(got, c.not) {
			t.Errorf("FAIL: %+v renders %q, want %q and not %q", c.pd.Landed, got, c.want, c.not)
		}
	}
	got := render(pageData{Repo: "quarry", Landing: &landingDetail{landingRow: row, CanAccept: true, LandingNow: true}})
	if !strings.Contains(got, `data-hook="landing-now"`) || strings.Contains(got, `action="/r/quarry/landing/aa11bb22cc33/accept"`) {
		t.Error("FAIL: a stack mid-land does not say so, or still offers a control")
	}
}