internal/control/mrscreen_test.go

v1.43.1
gitbay/internal/control/mrscreen_test.go history · blame · raw

132 lines · 4255 bytes

  1package control
  2
  3import (
  4	"strings"
  5	"testing"
  6	"time"
  7
  8	"gitbay.org/gitbay/internal/gitutil"
  9	"gitbay.org/gitbay/internal/protocol"
 10	"gitbay.org/gitbay/internal/store"
 11)
 12
 13func TestMRShowPlainPinned(t *testing.T) {
 14	st, repo, owner := twoMRTestRepo(t)
 15	mr, err := st.MRByNumber(repo.ID, 1)
 16	if err != nil {
 17		t.Fatal(err)
 18	}
 19	if err := st.AddMRComment(mr.ID, owner.ID, "Looks right.", "md"); err != nil {
 20		t.Fatal(err)
 21	}
 22	for _, ctx := range []string{"test", "build"} {
 23		if err := st.SetCommitStatus(repo.ID, "abc111", ctx, "success", "", "", owner.ID); err != nil {
 24			t.Fatal(err)
 25		}
 26	}
 27	c, out, errOut := mrTestCtx(st, owner)
 28	if code := Dispatch(c, []string{"mr", "show", repo.Path(), "1"}); code != protocol.ExitOK {
 29		t.Fatalf("exit %d: %s", code, errOut)
 30	}
 31	pinPlain(t, "mr-show", out.String())
 32}
 33
 34func mrShowFixture() MRShow {
 35	d := MRShow{mrOut: mrOut{Number: 552, Title: "wire $PAGER through long views", State: "open",
 36		Author: "cmc", Source: "cli-pager", TargetRef: "main", Body: "Pages long views.", BodyFormat: "md",
 37		CreatedAt: "2026-10-01T11:40:00Z"}}
 38	d.Commits = []CommitOut{{"8f3a1c2aaaaaaaa", "cli: page long output"}, {"2b77e90bbbbbbbb", "control: mark views"}}
 39	d.Checks = []CheckOut{{Context: "test", State: "pending"}, {Context: "build", State: "success"}}
 40	d.Gates = &GatesOut{ApprovalsRequired: 1, FastForward: false, Unmet: []string{"needs 1 approval", "behind main"}}
 41	d.Comments = []commentOut{
 42		{ID: 1, Author: "alice", Body: "Looks right.", BodyFormat: "md", CreatedAt: "2026-10-01T11:50:00Z", Kind: "comment"},
 43		{ID: 2, Author: "cmc", Body: "marked ready", CreatedAt: "2026-10-01T11:51:00Z", Kind: "system"},
 44	}
 45	return d
 46}
 47
 48func actionArgvs(s screen, group string) [][]string {
 49	var out [][]string
 50	for _, a := range s.actions {
 51		if a.group == group {
 52			out = append(out, a.argv)
 53		}
 54	}
 55	return out
 56}
 57
 58func sectionCounts(s screen) map[string]int {
 59	m := map[string]int{}
 60	for _, sec := range s.sections {
 61		m[sec.title] = sec.n
 62	}
 63	return m
 64}
 65
 66var screenRepo = store.Repo{OwnerName: "krz", Name: "gitbay", DefaultBranch: "main"}
 67
 68func TestMRShowScreenBehind(t *testing.T) {
 69	c := screenCtx(100, false)
 70	s := mrShowScreen(c, screenRepo, mrShowFixture(), []gitutil.NumStat{{Path: "cmd/gitbay/ssh.go", Added: 41, Deleted: 6, Status: "M"}})
 71	if got := actionArgvs(s, "Unblock"); len(got) != 1 || got[0][1] != "rebase" {
 72		t.Errorf("Unblock = %q, want mr rebase", got)
 73	}
 74	if got := actionArgvs(s, "Merge"); len(got) != 0 {
 75		t.Errorf("Merge offered with unmet gates: %q", got)
 76	}
 77	if n := sectionCounts(s); n["Commits"] != 2 || n["Files"] != 1 || n["Discussion"] != 1 {
 78		t.Errorf("sections = %v", n)
 79	}
 80	checkActions(t, s)
 81}
 82
 83func TestMRShowScreenReady(t *testing.T) {
 84	c := screenCtx(100, false)
 85	d := mrShowFixture()
 86	d.Gates = &GatesOut{FastForward: true}
 87	s := mrShowScreen(c, screenRepo, d, nil)
 88	if len(actionArgvs(s, "Unblock")) != 0 {
 89		t.Error("Unblock offered when nothing blocks")
 90	}
 91	if got := actionArgvs(s, "Merge"); len(got) != 1 || got[0][1] != "merge" {
 92		t.Errorf("Merge = %q", got)
 93	}
 94	checkActions(t, s)
 95}
 96
 97func TestMRShowScreenMergedOffersOnlyReading(t *testing.T) {
 98	c := screenCtx(100, false)
 99	d := mrShowFixture()
100	d.State, d.Gates = "merged", nil
101	s := mrShowScreen(c, screenRepo, d, nil)
102	for _, a := range s.actions {
103		if a.group != "Read" {
104			t.Errorf("merged MR offers %q", a.argv)
105		}
106	}
107}
108
109func TestMRShowScreenRenders(t *testing.T) {
110	termNow = func() time.Time { return time.Date(2026, 10, 1, 12, 0, 0, 0, time.UTC) }
111	t.Cleanup(func() { termNow = time.Now })
112	c := screenCtx(100, false)
113	c.Term.Here = "krz/gitbay"
114	s := mrShowScreen(c, screenRepo, mrShowFixture(), []gitutil.NumStat{{Path: "cmd/gitbay/ssh.go", Added: 41, Deleted: 6, Status: "M"}})
115	out := renderString(c, s)
116	for _, want := range []string{
117		"Merge:   !552  wire $PAGER through long views\n",
118		"Gates:   ✗ needs 1 approval · ✗ behind main\n",
119		"Pages long views.\n",
120		"Files (1)  +41 −6\n",
121		"alice  10m ago\n  Looks right.\n",
122		"gitbay mr rebase 552",
123		"gitbay mr diff 552",
124	} {
125		if !strings.Contains(out, want) {
126			t.Errorf("missing %q in:\n%s", want, out)
127		}
128	}
129	if !strings.Contains(out, "Events (1)\n9m ago  marked ready\n") {
130		t.Errorf("system event not under Events:\n%s", out)
131	}
132}