Artifact 2bab54a3222573364afb30f31cb098af878b62b0e9d0dc30e8f0638fb93cd3a2:
- File
internal/web/strata_test.go
— part of check-in
[6469f151c4]
at
2026-08-28 01:21:32
on branch trunk
— landings: headings scale instead of clipping; the decision row abbreviates
The h1 had no rule at all, so it drew at the browser's 2em on every screen. A real subject line then became three lines of shouting on a phone, which made clipping look necessary — it was not. The clip only hid words: 'permissions without a…' with the rest nowhere. Headings now clamp between 1.35rem and 2rem and wrap, so a long one fits and says the whole thing. The pathological case — no subject line at all, the title IS the body — already drops the visible heading, so nothing depends on the clip any more.
The decision row gains a second step at 22rem: measured at 320, five abbreviated buttons want 364px against 302 of room, and Comment is the widest word left. It has an icon and destroys nothing, so it is the one that loses its label. 'Land the strata (N rungs)' is now 'Land strata (N)' at every width — it was too many words wide as well as narrow.
The strata test pinned that sentence, so a wording change read as a missing control. It now asserts the formaction, which is the contract, and the rung count rather than the sentence around it. (user: dmestas, size: 7516) [annotate] [blame] [check-ins using]
package web import ( "strings" "testing" "craftdesign.group/quarry/internal/api" "craftdesign.group/quarry/internal/artifact" "craftdesign.group/quarry/internal/index" "craftdesign.group/quarry/internal/ops" "net/http/httptest" "path/filepath" ) // Three landings chained feat-c → feat-b → feat-a → trunk, all open, // plus one standalone. Four open landings; two decisions. func strataIndex(t *testing.T) *index.Index { t.Helper() ix, err := index.Open(filepath.Join(t.TempDir(), "index.db")) if err != nil { t.Fatal(err) } t.Cleanup(func() { ix.Close() }) root := func(hash, branch, target, title, date string) index.Parsed { return index.Parsed{Hash: hash, Art: &artifact.Artifact{Type: artifact.Forum, ThreadTitle: title, Date: date, User: "dan", Mimetype: "text/x-markdown", Body: []byte("zit-landing: 1\nbranch: " + branch + "\ntarget: " + target + "\n\n" + title + "\n")}} } if err := ix.FoldNow([]index.Parsed{ // A tip on the top branch with a passing verdict: the strata's. {Hash: strings.Repeat("00", 20), Art: &artifact.Artifact{Type: artifact.Manifest, Date: "2026-08-19T09:00:00", User: "dan", Comment: "base"}}, {Hash: strings.Repeat("cc", 20), Art: &artifact.Artifact{Type: artifact.Manifest, Date: "2026-08-20T09:25:00", User: "dan", Comment: "top of the stack", Parents: []string{strings.Repeat("00", 20)}, Tags: []artifact.Tag{{Name: "*branch", Target: "*", Value: "feat-c"}, {Name: "*sym-feat-c", Target: "*"}, {Name: "+ci-pass", Target: "*"}}}}, root(strings.Repeat("a1", 20), "feat-a", "trunk", "phase one", "2026-08-20T09:00:00"), root(strings.Repeat("b2", 20), "feat-b", "feat-a", "phase two", "2026-08-20T09:10:00"), root(strings.Repeat("c3", 20), "feat-c", "feat-b", "phase three", "2026-08-20T09:20:00"), root(strings.Repeat("d4", 20), "lone", "trunk", "a loner", "2026-08-20T09:30:00"), }); err != nil { t.Fatal(err) } if err := ix.RecomputeBranches(); err != nil { t.Fatal(err) } return ix } func strataServer(t *testing.T, ix *index.Index) *httptest.Server { t.Helper() r := ops.NewRegistry() if err := api.RegisterAll(r, api.Deps{Version: "v", Repos: api.NewRepos(map[string]*api.Repo{"alpha": {Index: ix}})}); err != nil { t.Fatal(err) } srv := httptest.NewServer(HandlerWith(r, nil, nil, []Option{WithSessions(fakeSessions{user: "dan"}), WithCaps(stubCaps{letters: "i"})})) t.Cleanup(srv.Close) return srv } // RFC 0006: a strata that looks like three landings is worse than no // strata feature. The open queue shows it as ONE row, counts it as one // decision, and folds the rungs under it with their positions. func TestStrataListsAsOneDecision(t *testing.T) { srv := strataServer(t, strataIndex(t)) html := asDan(t, srv, "/r/alpha/landing") if strings.Count(html, `<li class="t-row`) != 2 { t.Fatalf("want 2 rows (the stack and the loner), got %d:\n%.1200s", strings.Count(html, `<li class="t-row`), html) } if !strings.Contains(html, `t-strata`) || !strings.Contains(html, "3 segments") { t.Errorf("the stack row is not marked as a strata of 3") } if !strings.Contains(html, `title="2">2</span> Open<`) { i := strings.Index(html, "Open</a>") if i < 0 { i = len(html) } t.Errorf("the count chip does not count decisions (want 2 Open): %q", html[max(0, i-160):min(len(html), i+12)]) } for _, badge := range []string{">1/3<", ">2/3<", ">3/3<"} { if !strings.Contains(html, badge) { t.Errorf("rung badge %s missing", badge) } } if !strings.Contains(html, "<details class=\"strata\">") { t.Error("the rungs are not folded under the base without script") } // The top rung passed CI, and its tip contains everything below: // that is the strata's verdict, on the row. if !strings.Contains(html, "stack <span class=\"tl-badge ci-pass\"") { t.Errorf("the stack's verdict is not on the row:\n%.900s", html) } // The settled views stay flat: nothing to group. if all := asDan(t, srv, "/r/alpha/landing?state=all"); strings.Contains(all, "t-strata") { t.Error("the flat view grouped") } } // The record page: a map with this rung marked and the landable one // named; above the bottom, the accept control is disabled and says why. func TestStrataMapOnTheRecord(t *testing.T) { srv := strataServer(t, strataIndex(t)) top := asDan(t, srv, "/r/alpha/landing/"+strings.Repeat("c3", 6)) if !strings.Contains(top, `class="strata-map"`) || !strings.Contains(top, "3 segments") { t.Fatalf("no stack map on the top rung:\n%.1200s", top) } if !strings.Contains(top, `aria-current="true"`) { t.Error("the current rung is not marked") } if !strings.Contains(top, "stack <span class=\"tl-badge ci-pass\"") { t.Error("the map does not carry the strata's verdict") } if !strings.Contains(top, "phase one</a>") || !strings.Contains(top, "· landable") { t.Error("the landable base is not named in the map") } if !strings.Contains(top, "stacked — the segment below lands first") { t.Error("the accept control above the bottom is not disabled with the reason") } base := asDan(t, srv, "/r/alpha/landing/"+strings.Repeat("a1", 6)) if !strings.Contains(base, `formaction="/r/alpha/landing/a1a1a1a1a1a1/accept"`) { t.Error("the base's accept control is missing") } // Landing the whole strata is offered at the base, aimed at the top; // landing up to a rung is offered on that rung. // The FORMACTION is the contract — it names the top rung, which is // what "land the whole strata" means. The rung COUNT must reach the // reader too, but its wording is display text and changes with the // viewport, so the assertion is on the number, not the sentence. if !strings.Contains(base, `formaction="/r/alpha/landing/c3c3c3c3c3c3/land"`) || !strings.Contains(base, "3") { t.Error("the base does not offer to land the strata") } if !strings.Contains(top, `formaction="/r/alpha/landing/c3c3c3c3c3c3/land"`) || !strings.Contains(top, "Land up to here (3 rungs)") { t.Error("the top rung does not offer to land up to itself") } // A standalone landing has no map. if lone := asDan(t, srv, "/r/alpha/landing/"+strings.Repeat("d4", 6)); strings.Contains(lone, `class="strata-map"`) { t.Error("a standalone landing drew a stack map") } } // Past twenty rungs the folded list and the map stop helping and start // scrolling (GitLab's cap). The chain is still read and landable; the // page says how tall it is and points at the base. func TestTooTallStrataIsNotDrawn(t *testing.T) { var g landingGroup g.ID, g.Title, g.Branch, g.Target, g.State = strings.Repeat("a1", 20), "base", "r1", "trunk", "open" g.Stack, g.Position, g.Depth = g.ID, 1, index.MaxDrawnRungs+1 for i := 1; i <= index.MaxDrawnRungs+1; i++ { g.Segments = append(g.Segments, landingRow{ID: strings.Repeat("b2", 20), Title: "rung", State: "open", Stack: g.ID, Position: i, Depth: index.MaxDrawnRungs + 1}) } if !g.TooTall() { t.Fatal("21 rungs is not too tall") } var buf strings.Builder if err := landingListPage.ExecuteTemplate(&buf, "content", pageData{Repo: "alpha", LandingGroups: []landingGroup{g}, LandingOpen: 1, Nav: ticketNav{Repo: "alpha"}}); err != nil { t.Fatal(err) } html := buf.String() if strings.Contains(html, `<details class="strata">`) { t.Error("a too-tall strata was folded anyway") } if !strings.Contains(html, "too tall to fold here") { t.Error("the page does not say the strata is too tall") } g.Segments = g.Segments[:index.MaxDrawnRungs] if g.TooTall() { t.Error("exactly the cap counts as too tall") } }