Skip to content
quarry Artifact [37859acd24]
Login

Artifact [37859acd24]

Artifact 37859acd2464e3019f23750f1efb7c260b210ce662ede5b7bf46aeff0380ef0e:


package web

import (
	"strings"
	"testing"
)

// The check-in page offers to propose a branch only where the offer is
// true: at the tip, on a branch that is not the target, with nothing
// already proposing it. Anywhere else the link would name work the
// reader is not looking at, or duplicate a landing that exists.
func TestProposeLinkAppearsOnlyWhenItIsTrue(t *testing.T) {
	render := func(d pageData) string {
		t.Helper()
		var sb strings.Builder
		d.Repo, d.Checkin.Hash = "alpha", strings.Repeat("a", 64)
		d.Checkin.Branch = "feature"
		if err := checkinPage.Execute(&sb, d); err != nil {
			t.Fatal(err)
		}
		return sb.String()
	}

	offered := render(pageData{ProposeBranch: "feature", ProposeTarget: "trunk"})
	if !strings.Contains(offered, `href="/r/alpha/landing-new?branch=feature"`) {
		t.Error("a branch tip with nothing proposing it offers no way to propose it")
	}
	// The form is linked, not submitted: the title and the reasoning are
	// what everyone reads afterwards.
	if strings.Contains(offered, `action="/r/alpha/landing-new"`) {
		t.Error("the page opens a landing directly instead of linking the form")
	}

	// Nothing to propose: no link at all, not a disabled one.
	if got := render(pageData{}); strings.Contains(got, "landing-new") {
		t.Error("a check-in with nothing to propose still offers it")
	}

	// Already proposed: the landing is named instead of a second button.
	taken := render(pageData{OpenLanding: &landingRow{
		ID: strings.Repeat("b", 64), Branch: "feature", Target: "trunk", Title: "the work"}})
	if strings.Contains(taken, "landing-new") {
		t.Error("a branch that is already proposed is offered a second landing")
	}
	if !strings.Contains(taken, `href="/r/alpha/landing/bbbbbbbbbbbb"`) {
		t.Errorf("the open landing is not linked:\n%s", taken)
	}
	if !strings.Contains(taken, "the work") {
		t.Error("the open landing is named without saying what it proposes")
	}
}

// The offer is built from four facts, and each one on its own can make
// it a lie. This pins the reasons rather than the wording: a closed
// branch is the author saying it is done, and offering to propose one
// is how a branch that had already landed was offered a second, empty
// landing.
func TestProposeAsksTheQuestionsThatMakeTheOfferTrue(t *testing.T) {
	tip := strings.Repeat("a", 64)
	cases := []struct {
		name         string
		branch, deft string
		branchTip    string
		open         bool
		landing      *landingRow
		want         bool
	}{
		{"the tip of an open unproposed branch", "feature", "trunk", tip, true, nil, true},
		{"not the tip", "feature", "trunk", strings.Repeat("b", 64), true, nil, false},
		{"the target itself", "trunk", "trunk", tip, true, nil, false},
		{"a closed branch", "feature", "trunk", tip, false, nil, false},
		{"already proposed", "feature", "trunk", tip, true, &landingRow{Branch: "feature"}, false},
		{"no branch at all", "", "trunk", tip, true, nil, false},
	}
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			got := proposable(tc.branch, tip, tc.branchTip, tc.deft, tc.open, tc.landing)
			if got != tc.want {
				t.Errorf("offered=%v, want %v", got, tc.want)
			}
		})
	}
}