Monorepo for Tangled
tangled.org
1package db_test
2
3import (
4 "context"
5 "path/filepath"
6 "testing"
7
8 "github.com/bluesky-social/indigo/atproto/syntax"
9 appviewdb "tangled.org/core/appview/db"
10 "tangled.org/core/appview/models"
11 notifydb "tangled.org/core/appview/notify/db"
12)
13
14func TestNewIssue_DeliversWithNullRkeyCollaborator(t *testing.T) {
15 d := setupNotifyTestDB(t)
16
17 ownerDid := "did:plc:boltless"
18 repoDid := "did:plc:anemone"
19 collabDid := "did:plc:limpet"
20 authorDid := "did:plc:akshay"
21
22 repo := seedNotifyRepo(t, d, ownerDid, repoDid)
23 insertNullRkeyCollaborator(t, d, ownerDid, collabDid, repoDid)
24
25 issue := seedIssue(t, d, authorDid, repoDid, repo)
26
27 notifier := notifydb.NewDatabaseNotifier(d, nil)
28 notifier.NewIssue(context.Background(), issue, nil)
29
30 if got := notificationCount(t, d, ownerDid); got != 1 {
31 t.Errorf("repo owner %s: want 1 notification, got %d", ownerDid, got)
32 }
33 if got := notificationCount(t, d, collabDid); got != 1 {
34 t.Errorf("null-rkey collaborator %s: want 1 notification, got %d", collabDid, got)
35 }
36 if got := notificationCount(t, d, authorDid); got != 0 {
37 t.Errorf("issue author %s: want 0 notifications, got %d", authorDid, got)
38 }
39}
40
41func TestNewPull_DeliversWithNullRkeyCollaborator(t *testing.T) {
42 d := setupNotifyTestDB(t)
43
44 ownerDid := "did:plc:boltless"
45 repoDid := "did:plc:anemone"
46 collabDid := "did:plc:limpet"
47 authorDid := "did:plc:akshay"
48
49 seedNotifyRepo(t, d, ownerDid, repoDid)
50 insertNullRkeyCollaborator(t, d, ownerDid, collabDid, repoDid)
51
52 pull := seedPull(t, d, authorDid, repoDid)
53
54 notifier := notifydb.NewDatabaseNotifier(d, nil)
55 notifier.NewPull(context.Background(), pull)
56
57 if got := notificationCount(t, d, ownerDid); got != 1 {
58 t.Errorf("repo owner %s: want 1 notification, got %d", ownerDid, got)
59 }
60 if got := notificationCount(t, d, collabDid); got != 1 {
61 t.Errorf("null-rkey collaborator %s: want 1 notification, got %d", collabDid, got)
62 }
63 if got := notificationCount(t, d, authorDid); got != 0 {
64 t.Errorf("pull author %s: want 0 notifications, got %d", authorDid, got)
65 }
66}
67
68func setupNotifyTestDB(t *testing.T) *appviewdb.DB {
69 t.Helper()
70 path := filepath.Join(t.TempDir(), "test.db")
71 d, err := appviewdb.Make(context.Background(), path)
72 if err != nil {
73 t.Fatalf("Make: %v", err)
74 }
75 t.Cleanup(func() { d.Close() })
76 return d
77}
78
79func seedNotifyRepo(t *testing.T, d *appviewdb.DB, ownerDid, repoDid string) *models.Repo {
80 t.Helper()
81 tx, err := d.Begin()
82 if err != nil {
83 t.Fatalf("Begin: %v", err)
84 }
85 repo := &models.Repo{
86 Did: ownerDid,
87 Name: "shell",
88 Knot: "knot.example",
89 Rkey: "shellrkey",
90 RepoDid: repoDid,
91 }
92 if err := appviewdb.AddRepo(tx, repo); err != nil {
93 t.Fatalf("AddRepo: %v", err)
94 }
95 if err := tx.Commit(); err != nil {
96 t.Fatalf("Commit: %v", err)
97 }
98 return repo
99}
100
101func seedIssue(t *testing.T, d *appviewdb.DB, authorDid, repoDid string, repo *models.Repo) *models.Issue {
102 t.Helper()
103 issue := &models.Issue{
104 Did: authorDid,
105 Rkey: "issuerkey",
106 RepoDid: syntax.DID(repoDid),
107 IssueId: 1,
108 Title: "test",
109 Body: "body",
110 Open: true,
111 Repo: repo,
112 }
113 result, err := d.Exec(
114 `insert into issues (did, rkey, repo_did, issue_id, title, body, open) values (?, ?, ?, ?, ?, ?, 1)`,
115 issue.Did, issue.Rkey, string(issue.RepoDid), issue.IssueId, issue.Title, issue.Body,
116 )
117 if err != nil {
118 t.Fatalf("insert issue: %v", err)
119 }
120 id, err := result.LastInsertId()
121 if err != nil {
122 t.Fatalf("LastInsertId: %v", err)
123 }
124 issue.Id = id
125 return issue
126}
127
128func seedPull(t *testing.T, d *appviewdb.DB, authorDid, repoDid string) *models.Pull {
129 t.Helper()
130 pull := &models.Pull{
131 RepoDid: syntax.DID(repoDid),
132 OwnerDid: authorDid,
133 Rkey: "pullrkey",
134 Title: "test",
135 Body: "body",
136 TargetBranch: "main",
137 State: models.PullOpen,
138 }
139 tx, err := d.Begin()
140 if err != nil {
141 t.Fatalf("Begin: %v", err)
142 }
143 if err := appviewdb.PutPull(tx, pull); err != nil {
144 t.Fatalf("PutPull: %v", err)
145 }
146 if err := tx.Commit(); err != nil {
147 t.Fatalf("Commit: %v", err)
148 }
149 return pull
150}
151
152func insertNullRkeyCollaborator(t *testing.T, d *appviewdb.DB, issuerDid, subjectDid, repoDid string) {
153 t.Helper()
154 if _, err := d.Exec(
155 `insert into collaborators (did, rkey, subject_did, repo_did) values (?, NULL, ?, ?)`,
156 issuerDid, subjectDid, repoDid,
157 ); err != nil {
158 t.Fatalf("insert null-rkey collaborator: %v", err)
159 }
160}
161
162func notificationCount(t *testing.T, d *appviewdb.DB, recipientDid string) int {
163 t.Helper()
164 var count int
165 if err := d.QueryRow(
166 `select count(*) from notifications where recipient_did = ?`,
167 recipientDid,
168 ).Scan(&count); err != nil {
169 t.Fatalf("count notifications for %s: %v", recipientDid, err)
170 }
171 return count
172}