internal/store/dashboard_test.go
128 lines · 3428 bytes
2 symbols in this file
1package store
2
3import (
4 "reflect"
5 "testing"
6)
7
8// Rows sharing an updated_at (timestamps are milliseconds) come back
9// newest first, the same order distinct times give, so the dashboard does
10// not reshuffle depending on whether two writes landed in one millisecond.
11func TestDashboardEqualUpdatedAtStableOrder(t *testing.T) {
12 s := open(t)
13 if err := s.MigrateUp(); err != nil {
14 t.Fatal(err)
15 }
16 uid, err := s.CreateUser("cmc", false)
17 if err != nil {
18 t.Fatal(err)
19 }
20 other, err := s.CreateUser("alice", false)
21 if err != nil {
22 t.Fatal(err)
23 }
24 repoID, err := s.CreateRepo("user", uid, "gitbay", "public")
25 if err != nil {
26 t.Fatal(err)
27 }
28 for _, title := range []string{"first", "second", "third"} {
29 n, err := s.CreateIssue(repoID, uid, title, "", "markdown")
30 if err != nil {
31 t.Fatal(err)
32 }
33 issue, err := s.IssueByNumber(repoID, n)
34 if err != nil {
35 t.Fatal(err)
36 }
37 if err := s.SetIssueAssignee(issue.ID, other, true); err != nil {
38 t.Fatal(err)
39 }
40 if _, err := s.CreateMR(repoID, other, repoID, title, "main", title, "", "abc", "md", false); err != nil {
41 t.Fatal(err)
42 }
43 }
44 for _, table := range []string{"issues", "merge_requests"} {
45 if _, err := s.DB.Exec("UPDATE " + table + " SET updated_at = '2026-10-01T12:00:00.000Z'"); err != nil {
46 t.Fatal(err)
47 }
48 }
49
50 titles := func(items []DashboardItem, err error) []string {
51 t.Helper()
52 if err != nil {
53 t.Fatal(err)
54 }
55 var out []string
56 for _, d := range items {
57 out = append(out, d.Title)
58 }
59 return out
60 }
61 want := []string{"third", "second", "first"}
62 cases := []struct {
63 name string
64 got []string
65 }{
66 {"DashboardIssues", titles(s.DashboardIssues(uid))},
67 {"DashboardMRs", titles(s.DashboardMRs(uid))},
68 {"ReviewQueue", titles(s.ReviewQueue(uid))},
69 {"AssignedIssues", titles(s.AssignedIssues(other))},
70 }
71 for _, tc := range cases {
72 if !reflect.DeepEqual(tc.got, want) {
73 t.Errorf("%s = %v, want %v", tc.name, tc.got, want)
74 }
75 }
76}
77
78// An issue assigned to the user is not repeated under DashboardIssues:
79// AssignedIssues already covers it, and a repository the user can
80// otherwise reach (here, one they own) is the common case where the two
81// queries used to overlap (#265).
82func TestDashboardIssuesExcludesAssignedIssues(t *testing.T) {
83 s := open(t)
84 if err := s.MigrateUp(); err != nil {
85 t.Fatal(err)
86 }
87 uid, err := s.CreateUser("cmc", false)
88 if err != nil {
89 t.Fatal(err)
90 }
91 repoID, err := s.CreateRepo("user", uid, "gitbay", "public")
92 if err != nil {
93 t.Fatal(err)
94 }
95 repo, err := s.RepoByID(repoID)
96 if err != nil {
97 t.Fatal(err)
98 }
99 assignedNum, err := s.CreateIssue(repo.ID, uid, "assigned to me", "", "markdown")
100 if err != nil {
101 t.Fatal(err)
102 }
103 if _, err := s.CreateIssue(repo.ID, uid, "not assigned", "", "markdown"); err != nil {
104 t.Fatal(err)
105 }
106 assigned, err := s.IssueByNumber(repo.ID, assignedNum)
107 if err != nil {
108 t.Fatal(err)
109 }
110 if err := s.SetIssueAssignee(assigned.ID, uid, true); err != nil {
111 t.Fatal(err)
112 }
113
114 issues, err := s.DashboardIssues(uid)
115 if err != nil {
116 t.Fatal(err)
117 }
118 if len(issues) != 1 || issues[0].Title != "not assigned" {
119 t.Fatalf("DashboardIssues = %+v, want only the unassigned issue", issues)
120 }
121 assignedList, err := s.AssignedIssues(uid)
122 if err != nil {
123 t.Fatal(err)
124 }
125 if len(assignedList) != 1 || assignedList[0].Title != "assigned to me" {
126 t.Fatalf("AssignedIssues = %+v, want the assigned issue", assignedList)
127 }
128}