comment_integration_test.go
1//go:build integration
2
3package main
4
5import (
6 "os/exec"
7 "strings"
8 "testing"
9
10 "github.com/git-bug/git-bug/entities/bug"
11 "github.com/git-bug/git-bug/entity"
12 "github.com/git-bug/git-bug/repository"
13)
14
15// TestCommentCommand_WithFlag adds a comment using the message flag
16func TestCommentCommand_WithFlag(t *testing.T) {
17 tmpDir := t.TempDir()
18
19 // Initialize a git repo
20 initCmd := exec.Command("git", "init")
21 initCmd.Dir = tmpDir
22 if err := initCmd.Run(); err != nil {
23 t.Fatalf("failed to init git repo: %v", err)
24 }
25
26 // Initialize git-bug identities
27 if err := createIdentity(tmpDir, "Test User", "[email protected]", true); err != nil {
28 t.Fatalf("failed to create identity: %v", err)
29 }
30
31 // Create a bug first
32 title := "Test Bug for Comment"
33 message := "Initial bug description"
34 if err := runNew(tmpDir, title, message, ""); err != nil {
35 t.Fatalf("runNew failed: %v", err)
36 }
37
38 // Get the bug ID
39 repo, err := repository.OpenGoGitRepo(tmpDir, "", nil)
40 if err != nil {
41 t.Fatalf("failed to open repo: %v", err)
42 }
43
44 var bugID string
45 for streamedBug := range bug.ReadAll(repo) {
46 if streamedBug.Err != nil {
47 t.Fatalf("failed to read bug: %v", streamedBug.Err)
48 }
49 b := streamedBug.Entity
50 snap := b.Compile()
51 if snap.Title == title {
52 bugID = b.Id().String()
53 break
54 }
55 }
56 repo.Close()
57
58 if bugID == "" {
59 t.Fatal("could not find created bug")
60 }
61
62 // Add a comment using the flag
63 commentText := "This is a test comment"
64 if err := runComment(tmpDir, bugID, commentText); err != nil {
65 t.Fatalf("runComment failed: %v", err)
66 }
67
68 // Verify comment was added
69 repo, err = repository.OpenGoGitRepo(tmpDir, "", nil)
70 if err != nil {
71 t.Fatalf("failed to open repo: %v", err)
72 }
73 defer repo.Close()
74
75 b, err := bug.Read(repo, entity.Id(bugID))
76 if err != nil {
77 t.Fatalf("failed to read bug: %v", err)
78 }
79
80 snap := b.Compile()
81 if len(snap.Comments) != 2 {
82 t.Errorf("expected 2 comments (original + new), got %d", len(snap.Comments))
83 }
84
85 // Check the second comment (index 1) is our new comment
86 if snap.Comments[1].Message != commentText {
87 t.Errorf("comment message = %q, want %q", snap.Comments[1].Message, commentText)
88 }
89
90 if snap.Comments[1].Author.Name() != "Test User" {
91 t.Errorf("comment author = %q, want %q", snap.Comments[1].Author.Name(), "Test User")
92 }
93}
94
95// TestCommentCommand_WithShortID adds a comment using a short bug ID
96func TestCommentCommand_WithShortID(t *testing.T) {
97 tmpDir := t.TempDir()
98
99 // Initialize a git repo
100 initCmd := exec.Command("git", "init")
101 initCmd.Dir = tmpDir
102 if err := initCmd.Run(); err != nil {
103 t.Fatalf("failed to init git repo: %v", err)
104 }
105
106 // Initialize git-bug identities
107 if err := createIdentity(tmpDir, "Test User", "[email protected]", true); err != nil {
108 t.Fatalf("failed to create identity: %v", err)
109 }
110
111 // Create a bug
112 title := "Test Bug for Short ID"
113 if err := runNew(tmpDir, title, "", ""); err != nil {
114 t.Fatalf("runNew failed: %v", err)
115 }
116
117 // Get the bug ID and short ID
118 repo, err := repository.OpenGoGitRepo(tmpDir, "", nil)
119 if err != nil {
120 t.Fatalf("failed to open repo: %v", err)
121 }
122
123 var bugID, shortID string
124 for streamedBug := range bug.ReadAll(repo) {
125 if streamedBug.Err != nil {
126 t.Fatalf("failed to read bug: %v", streamedBug.Err)
127 }
128 b := streamedBug.Entity
129 snap := b.Compile()
130 if snap.Title == title {
131 bugID = b.Id().String()
132 // Use first 7 chars as short ID
133 if len(bugID) > 7 {
134 shortID = bugID[:7]
135 } else {
136 shortID = bugID
137 }
138 break
139 }
140 }
141 repo.Close()
142
143 if shortID == "" {
144 t.Fatal("could not find created bug")
145 }
146
147 // Add a comment using short ID
148 commentText := "Comment added via short ID"
149 if err := runComment(tmpDir, shortID, commentText); err != nil {
150 t.Fatalf("runComment with short ID failed: %v", err)
151 }
152
153 // Verify comment was added
154 repo, err = repository.OpenGoGitRepo(tmpDir, "", nil)
155 if err != nil {
156 t.Fatalf("failed to open repo: %v", err)
157 }
158 defer repo.Close()
159
160 b, err := bug.Read(repo, entity.Id(bugID))
161 if err != nil {
162 t.Fatalf("failed to read bug: %v", err)
163 }
164
165 snap := b.Compile()
166 if len(snap.Comments) != 2 {
167 t.Errorf("expected 2 comments, got %d", len(snap.Comments))
168 }
169
170 if snap.Comments[1].Message != commentText {
171 t.Errorf("comment message = %q, want %q", snap.Comments[1].Message, commentText)
172 }
173}
174
175// TestCommentCommand_NoIdentityError tests error when identity not set
176func TestCommentCommand_NoIdentityError(t *testing.T) {
177 tmpDir := t.TempDir()
178
179 // Initialize a git repo (but no git-bug identities)
180 initCmd := exec.Command("git", "init")
181 initCmd.Dir = tmpDir
182 if err := initCmd.Run(); err != nil {
183 t.Fatalf("failed to init git repo: %v", err)
184 }
185
186 // Don't create any identities - try to add a comment to non-existent bug
187 // Bug ID resolution happens before identity check, so we should get ID error first
188 err := runComment(tmpDir, "nonexistent123", "Test comment")
189 if err == nil {
190 t.Error("expected error, got nil")
191 }
192
193 // Since no bugs exist at all, we should get an ID resolution error
194 if !strings.Contains(err.Error(), "failed to resolve bug ID") {
195 t.Errorf("expected 'failed to resolve bug ID' error, got: %v", err)
196 }
197}
198
199// TestCommentCommand_EmptyMessageError tests error for empty message
200func TestCommentCommand_EmptyMessageError(t *testing.T) {
201 tmpDir := t.TempDir()
202
203 // Initialize a git repo
204 initCmd := exec.Command("git", "init")
205 initCmd.Dir = tmpDir
206 if err := initCmd.Run(); err != nil {
207 t.Fatalf("failed to init git repo: %v", err)
208 }
209
210 // Initialize git-bug identities
211 if err := createIdentity(tmpDir, "Test User", "[email protected]", true); err != nil {
212 t.Fatalf("failed to create identity: %v", err)
213 }
214
215 // Create a bug first
216 title := "Test Bug"
217 if err := runNew(tmpDir, title, "", ""); err != nil {
218 t.Fatalf("runNew failed: %v", err)
219 }
220
221 // Get the bug ID
222 repo, err := repository.OpenGoGitRepo(tmpDir, "", nil)
223 if err != nil {
224 t.Fatalf("failed to open repo: %v", err)
225 }
226
227 var bugID string
228 for streamedBug := range bug.ReadAll(repo) {
229 if streamedBug.Err != nil {
230 t.Fatalf("failed to read bug: %v", streamedBug.Err)
231 }
232 b := streamedBug.Entity
233 snap := b.Compile()
234 if snap.Title == title {
235 bugID = b.Id().String()
236 break
237 }
238 }
239 repo.Close()
240
241 // Try to add a comment with empty message (whitespace only)
242 // This triggers the editor path, which returns "no comment provided"
243 err = runComment(tmpDir, bugID, " ")
244 if err == nil {
245 t.Error("expected error for empty message, got nil")
246 }
247
248 // When empty message is provided, editor opens and returns "no comment provided"
249 if !strings.Contains(err.Error(), "no comment provided") {
250 t.Errorf("expected 'no comment provided' error, got: %v", err)
251 }
252}
253
254// TestCommentCommand_InvalidBugID tests error for invalid bug ID
255func TestCommentCommand_InvalidBugID(t *testing.T) {
256 tmpDir := t.TempDir()
257
258 // Initialize a git repo
259 initCmd := exec.Command("git", "init")
260 initCmd.Dir = tmpDir
261 if err := initCmd.Run(); err != nil {
262 t.Fatalf("failed to init git repo: %v", err)
263 }
264
265 // Initialize git-bug identities
266 if err := createIdentity(tmpDir, "Test User", "[email protected]", true); err != nil {
267 t.Fatalf("failed to create identity: %v", err)
268 }
269
270 // Try to add a comment to non-existent bug
271 err := runComment(tmpDir, "nonexistent", "Test comment")
272 if err == nil {
273 t.Error("expected error for invalid bug ID, got nil")
274 }
275
276 if !strings.Contains(err.Error(), "failed to resolve bug ID") {
277 t.Errorf("expected 'failed to resolve bug ID' error, got: %v", err)
278 }
279}
280
281// TestCommentCommand_MultipleComments tests adding multiple comments
282func TestCommentCommand_MultipleComments(t *testing.T) {
283 tmpDir := t.TempDir()
284
285 // Initialize a git repo
286 initCmd := exec.Command("git", "init")
287 initCmd.Dir = tmpDir
288 if err := initCmd.Run(); err != nil {
289 t.Fatalf("failed to init git repo: %v", err)
290 }
291
292 // Initialize git-bug identities
293 if err := createIdentity(tmpDir, "Test User", "[email protected]", true); err != nil {
294 t.Fatalf("failed to create identity: %v", err)
295 }
296
297 // Create a bug
298 title := "Test Bug for Multiple Comments"
299 if err := runNew(tmpDir, title, "", ""); err != nil {
300 t.Fatalf("runNew failed: %v", err)
301 }
302
303 // Get the bug ID
304 repo, err := repository.OpenGoGitRepo(tmpDir, "", nil)
305 if err != nil {
306 t.Fatalf("failed to open repo: %v", err)
307 }
308
309 var bugID string
310 for streamedBug := range bug.ReadAll(repo) {
311 if streamedBug.Err != nil {
312 t.Fatalf("failed to read bug: %v", streamedBug.Err)
313 }
314 b := streamedBug.Entity
315 snap := b.Compile()
316 if snap.Title == title {
317 bugID = b.Id().String()
318 break
319 }
320 }
321 repo.Close()
322
323 // Add multiple comments
324 comments := []string{
325 "First comment",
326 "Second comment",
327 "Third comment with **markdown**",
328 }
329
330 for _, comment := range comments {
331 if err := runComment(tmpDir, bugID, comment); err != nil {
332 t.Fatalf("runComment failed: %v", err)
333 }
334 }
335
336 // Verify all comments were added
337 repo, err = repository.OpenGoGitRepo(tmpDir, "", nil)
338 if err != nil {
339 t.Fatalf("failed to open repo: %v", err)
340 }
341 defer repo.Close()
342
343 b, err := bug.Read(repo, entity.Id(bugID))
344 if err != nil {
345 t.Fatalf("failed to read bug: %v", err)
346 }
347
348 snap := b.Compile()
349 // Original + 3 comments = 4 total
350 if len(snap.Comments) != 4 {
351 t.Errorf("expected 4 comments, got %d", len(snap.Comments))
352 }
353
354 // Verify each comment (index 1-3 are our added comments)
355 for i, expected := range comments {
356 if snap.Comments[i+1].Message != expected {
357 t.Errorf("comment %d message = %q, want %q", i+1, snap.Comments[i+1].Message, expected)
358 }
359 }
360}