internal/store/milestones_test.go

9df917e73a67d15adecc3f45976690f6fcd4e47a
gitbay/internal/store/milestones_test.go history · blame · raw

117 lines · 4005 bytes

  1package store
  2
  3import (
  4	"errors"
  5	"testing"
  6)
  7
  8func TestOrgMilestoneSpansRepos(t *testing.T) {
  9	f := newAcme(t)
 10	id, folded, err := f.s.CreateOrgMilestone(f.org, "v1", "first", "2027-01-01")
 11	if err != nil || folded != 0 || id == 0 {
 12		t.Fatalf("CreateOrgMilestone: %d, %d, %v", id, folded, err)
 13	}
 14	// Resolves from either repo, not from alice/app.
 15	m, err := f.s.MilestoneByTitle(f.core, "v1")
 16	if err != nil || m.OrgID != f.org || m.RepoID != 0 {
 17		t.Fatalf("core resolves v1 = %+v, %v", m, err)
 18	}
 19	if _, err := f.s.MilestoneByTitle(f.app, "v1"); !errors.Is(err, ErrNotFound) {
 20		t.Fatalf("app resolves v1: %v", err)
 21	}
 22	if err := f.s.SetIssueMilestone(f.coreIssue, id); err != nil {
 23		t.Fatal(err)
 24	}
 25	if err := f.s.SetIssueMilestone(f.siteIssue, id); err != nil {
 26		t.Fatal(err)
 27	}
 28	if err := f.s.SetIssueState(f.siteIssue, "closed"); err != nil {
 29		t.Fatal(err)
 30	}
 31	ms, err := f.s.ListOrgMilestones(f.org, "open", f.orgRepos())
 32	if err != nil || len(ms) != 1 || ms[0].OpenItems != 1 || ms[0].ClosedItems != 1 {
 33		t.Fatalf("org list = %+v, %v", ms, err)
 34	}
 35	// Counts stop at what the caller can read.
 36	ms, _ = f.s.ListOrgMilestones(f.org, "open", []int64{f.core.ID})
 37	if ms[0].OpenItems != 1 || ms[0].ClosedItems != 0 {
 38		t.Fatalf("org list over core = %+v", ms)
 39	}
 40	// A repo's list shows the org milestone first, then its own.
 41	if _, err := f.s.CreateMilestone(f.core, "core-only", "", ""); err != nil {
 42		t.Fatal(err)
 43	}
 44	ms, _ = f.s.ListMilestones(f.core, "open", f.orgRepos())
 45	if len(ms) != 2 || ms[0].Title != "v1" || ms[0].OrgID != f.org || ms[1].Title != "core-only" || ms[1].RepoID != f.core.ID {
 46		t.Fatalf("core list = %+v", ms)
 47	}
 48	if _, err := f.s.OrgMilestoneByTitle(f.org, "core-only"); !errors.Is(err, ErrNotFound) {
 49		t.Fatalf("org resolves a repo milestone: %v", err)
 50	}
 51}
 52
 53func TestRepoMilestoneRefusedWhenOrgHoldsTitle(t *testing.T) {
 54	f := newAcme(t)
 55	if _, _, err := f.s.CreateOrgMilestone(f.org, "v1", "", ""); err != nil {
 56		t.Fatal(err)
 57	}
 58	if _, err := f.s.CreateMilestone(f.core, "v1", "", ""); !errors.Is(err, ErrOrgScoped) {
 59		t.Fatalf("CreateMilestone over org title: %v", err)
 60	}
 61	if _, err := f.s.CreateMilestone(f.app, "v1", "", ""); err != nil {
 62		t.Fatalf("user repo unaffected: %v", err)
 63	}
 64	if _, _, err := f.s.CreateOrgMilestone(f.org, "v1", "", ""); err == nil {
 65		t.Fatal("duplicate org milestone accepted")
 66	}
 67}
 68
 69func TestCreateOrgMilestonePromotes(t *testing.T) {
 70	f := newAcme(t)
 71	cid, err := f.s.CreateMilestone(f.core, "v1", "", "")
 72	if err != nil {
 73		t.Fatal(err)
 74	}
 75	sid, err := f.s.CreateMilestone(f.site, "v1", "", "")
 76	if err != nil {
 77		t.Fatal(err)
 78	}
 79	if err := f.s.SetIssueMilestone(f.coreIssue, cid); err != nil {
 80		t.Fatal(err)
 81	}
 82	n, err := f.s.CreateMR(f.site.ID, f.alice, f.site.ID, "feat", "main", "t", "", "abc", "md", false)
 83	if err != nil {
 84		t.Fatal(err)
 85	}
 86	// CreateMR returns the per-repo MR number, not the merge_requests.id
 87	// row that milestone_id references; resolve it the way SetMRMilestone
 88	// callers must.
 89	mr, err := f.s.MRByNumber(f.site.ID, n)
 90	if err != nil {
 91		t.Fatal(err)
 92	}
 93	if err := f.s.SetMRMilestone(mr.ID, sid); err != nil {
 94		t.Fatal(err)
 95	}
 96	id, folded, err := f.s.CreateOrgMilestone(f.org, "v1", "org wide", "2027-06-01")
 97	if err != nil || folded != 2 {
 98		t.Fatalf("promote: folded %d, %v", folded, err)
 99	}
100	var count int
101	f.s.DB.QueryRow("SELECT COUNT(*) FROM milestones WHERE title = 'v1'").Scan(&count)
102	if count != 1 {
103		t.Fatalf("milestones named v1: %d", count)
104	}
105	f.s.DB.QueryRow("SELECT COUNT(*) FROM issues WHERE milestone_id = ?", id).Scan(&count)
106	if count != 1 {
107		t.Fatalf("issues on org milestone: %d", count)
108	}
109	f.s.DB.QueryRow("SELECT COUNT(*) FROM merge_requests WHERE milestone_id = ?", id).Scan(&count)
110	if count != 1 {
111		t.Fatalf("mrs on org milestone: %d", count)
112	}
113	ms, _ := f.s.ListOrgMilestones(f.org, "open", f.orgRepos())
114	if len(ms) != 1 || ms[0].OpenItems != 2 || ms[0].Description != "org wide" || ms[0].DueDate != "2027-06-01" {
115		t.Fatalf("after promote: %+v", ms)
116	}
117}