internal/store/mrs_test.go

d7d409e545d4b0999652559ac53e94ce556b56f6
gitbay/internal/store/mrs_test.go history · blame · raw

144 lines · 4453 bytes

  1package store
  2
  3import "testing"
  4
  5func mrFixture(t *testing.T) (*Store, int64, int64) {
  6	t.Helper()
  7	s := open(t)
  8	if err := s.MigrateUp(); err != nil {
  9		t.Fatal(err)
 10	}
 11	uid, err := s.CreateUser("cmc", true)
 12	if err != nil {
 13		t.Fatal(err)
 14	}
 15	repoID, err := s.CreateRepo("user", uid, "lib", "public")
 16	if err != nil {
 17		t.Fatal(err)
 18	}
 19	if _, err := s.CreateMR(repoID, uid, repoID, "feature", "main", "t", "", "abc123", "md", false); err != nil {
 20		t.Fatal(err)
 21	}
 22	return s, repoID, uid
 23}
 24
 25// A merged or closed MR records who resolved it and when: the state alone
 26// cannot say it, and updated_at moves for every edit.
 27func TestResolutionStamps(t *testing.T) {
 28	s, repoID, uid := mrFixture(t)
 29	mr, err := s.MRByNumber(repoID, 1)
 30	if err != nil {
 31		t.Fatal(err)
 32	}
 33	if mr.MergedAt != "" || mr.ClosedAt != "" {
 34		t.Fatalf("open MR carries a stamp: %+v", mr)
 35	}
 36	if err := s.MarkMerged(mr.ID, "base1", uid, ""); err != nil {
 37		t.Fatal(err)
 38	}
 39	mr, _ = s.MRByNumber(repoID, 1)
 40	if mr.State != "merged" || mr.MergedAt == "" || mr.MergedBy != "cmc" {
 41		t.Fatalf("merge stamp: %+v", mr)
 42	}
 43
 44	// Reopening — a source branch that came back — clears the stamp.
 45	if err := s.SetMRState(mr.ID, "open"); err != nil {
 46		t.Fatal(err)
 47	}
 48	mr, _ = s.MRByNumber(repoID, 1)
 49	if mr.MergedAt != "" || mr.MergedBy != "" {
 50		t.Fatalf("reopen kept the merge stamp: %+v", mr)
 51	}
 52
 53	if err := s.MarkClosed(mr.ID, uid, ""); err != nil {
 54		t.Fatal(err)
 55	}
 56	mr, _ = s.MRByNumber(repoID, 1)
 57	if mr.State != "closed" || mr.ClosedAt == "" || mr.ClosedBy != "cmc" {
 58		t.Fatalf("close stamp: %+v", mr)
 59	}
 60}
 61
 62// An import carries the upstream time but no local account for the actor.
 63func TestResolutionStampImported(t *testing.T) {
 64	s, repoID, _ := mrFixture(t)
 65	mr, _ := s.MRByNumber(repoID, 1)
 66	if err := s.MarkMerged(mr.ID, "base1", 0, "2024-03-02T10:00:00Z"); err != nil {
 67		t.Fatal(err)
 68	}
 69	mr, _ = s.MRByNumber(repoID, 1)
 70	if mr.MergedAt != "2024-03-02T10:00:00Z" || mr.MergedBy != "" {
 71		t.Fatalf("imported merge stamp: %+v", mr)
 72	}
 73}
 74
 75// PreferredVerifiedEmail falls back to a verified secondary when the
 76// primary is not verified, unlike PrimaryVerifiedEmail (#158).
 77func TestPreferredVerifiedEmail(t *testing.T) {
 78	s := open(t)
 79	if err := s.MigrateUp(); err != nil {
 80		t.Fatal(err)
 81	}
 82	uid, err := s.CreateUser("gus", false)
 83	if err != nil {
 84		t.Fatal(err)
 85	}
 86
 87	if addr, err := s.PreferredVerifiedEmail(uid); err != nil || addr != "" {
 88		t.Fatalf("no addresses at all: %q, %v", addr, err)
 89	}
 90
 91	if err := s.AddEmail(uid, "primary@example.test", "", true); err != nil {
 92		t.Fatal(err)
 93	}
 94	if addr, err := s.PreferredVerifiedEmail(uid); err != nil || addr != "" {
 95		t.Fatalf("unverified primary only: %q, %v", addr, err)
 96	}
 97	if addr, err := s.PrimaryVerifiedEmail(uid); err != nil || addr != "" {
 98		t.Fatalf("PrimaryVerifiedEmail on an unverified primary: %q, %v", addr, err)
 99	}
100
101	if err := s.AddEmail(uid, "secondary@example.test", "smtp", false); err != nil {
102		t.Fatal(err)
103	}
104	if addr, err := s.PreferredVerifiedEmail(uid); err != nil || addr != "secondary@example.test" {
105		t.Fatalf("unverified primary, verified secondary: %q, %v", addr, err)
106	}
107	// PrimaryVerifiedEmail keeps meaning exactly what it says: still "",
108	// because the primary itself is still unverified.
109	if addr, err := s.PrimaryVerifiedEmail(uid); err != nil || addr != "" {
110		t.Fatalf("PrimaryVerifiedEmail with only the secondary verified: %q, %v", addr, err)
111	}
112
113	if err := s.VerifyEmail(uid, "primary@example.test", "admin"); err != nil {
114		t.Fatal(err)
115	}
116	if addr, err := s.PreferredVerifiedEmail(uid); err != nil || addr != "primary@example.test" {
117		t.Fatalf("both verified, primary should win: %q, %v", addr, err)
118	}
119}
120
121// With no verified primary, the choice among verified secondaries must not
122// depend on insertion or row order.
123func TestPreferredVerifiedEmailDeterministicTiebreak(t *testing.T) {
124	s := open(t)
125	if err := s.MigrateUp(); err != nil {
126		t.Fatal(err)
127	}
128	uid, err := s.CreateUser("gus", false)
129	if err != nil {
130		t.Fatal(err)
131	}
132	if err := s.AddEmail(uid, "primary@example.test", "", true); err != nil {
133		t.Fatal(err)
134	}
135	if err := s.AddEmail(uid, "zzz@example.test", "smtp", false); err != nil {
136		t.Fatal(err)
137	}
138	if err := s.AddEmail(uid, "aaa@example.test", "smtp", false); err != nil {
139		t.Fatal(err)
140	}
141	if addr, err := s.PreferredVerifiedEmail(uid); err != nil || addr != "aaa@example.test" {
142		t.Fatalf("tiebreak should be alphabetical: %q, %v", addr, err)
143	}
144}