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}