agent_edit_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// TestAgentEditCommand_EditIssue edits an issue as the agent
16func TestAgentEditCommand_EditIssue(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 // Add origin remote for bug init
26 remoteCmd := exec.Command("git", "remote", "add", "origin", "[email protected]:test/repo.git")
27 remoteCmd.Dir = tmpDir
28 if err := remoteCmd.Run(); err != nil {
29 t.Fatalf("failed to add origin remote: %v", err)
30 }
31
32 // Initialize git-bug identities (creates both user and agent)
33 if err := runInitWithReader(tmpDir, strings.NewReader("Test User\[email protected]\n")); err != nil {
34 t.Fatalf("runInit failed: %v", err)
35 }
36
37 // Create a bug as agent
38 if err := runAgentNew(tmpDir, "Original Title", "Original description", "", "", false); err != nil {
39 t.Fatalf("runAgentNew failed: %v", err)
40 }
41
42 // Get the bug ID
43 repo, err := repository.OpenGoGitRepo(tmpDir, "", nil)
44 if err != nil {
45 t.Fatalf("failed to open repo: %v", err)
46 }
47
48 var bugID string
49 for streamedBug := range bug.ReadAll(repo) {
50 if streamedBug.Err != nil {
51 t.Fatalf("failed to read bug: %v", streamedBug.Err)
52 }
53 b := streamedBug.Entity
54 snap := b.Compile()
55 if snap.Title == "Original Title" {
56 bugID = b.Id().String()
57 break
58 }
59 }
60 repo.Close()
61
62 if bugID == "" {
63 t.Fatal("could not find created bug")
64 }
65
66 // Edit as agent
67 newTitle := "Agent Updated Title"
68 newMessage := "Agent updated description"
69 if err := runAgentEdit(tmpDir, bugID, newTitle, newMessage, "", false, ""); err != nil {
70 t.Fatalf("runAgentEdit failed: %v", err)
71 }
72
73 // Verify both were updated
74 repo, err = repository.OpenGoGitRepo(tmpDir, "", nil)
75 if err != nil {
76 t.Fatalf("failed to open repo: %v", err)
77 }
78 defer repo.Close()
79
80 b, err := bug.Read(repo, entity.Id(bugID))
81 if err != nil {
82 t.Fatalf("failed to read bug: %v", err)
83 }
84
85 snap := b.Compile()
86 if snap.Title != newTitle {
87 t.Errorf("title = %q, want %q", snap.Title, newTitle)
88 }
89 if len(snap.Comments) == 0 || snap.Comments[0].Message != newMessage {
90 t.Errorf("description = %q, want %q", snap.Comments[0].Message, newMessage)
91 }
92}
93
94// TestAgentEditCommand_EditComment edits a comment as the agent
95func TestAgentEditCommand_EditComment(t *testing.T) {
96 tmpDir := t.TempDir()
97
98 // Initialize a git repo
99 initCmd := exec.Command("git", "init")
100 initCmd.Dir = tmpDir
101 if err := initCmd.Run(); err != nil {
102 t.Fatalf("failed to init git repo: %v", err)
103 }
104 // Add origin remote for bug init
105 remoteCmd := exec.Command("git", "remote", "add", "origin", "[email protected]:test/repo.git")
106 remoteCmd.Dir = tmpDir
107 if err := remoteCmd.Run(); err != nil {
108 t.Fatalf("failed to add origin remote: %v", err)
109 }
110
111 // Initialize git-bug identities
112 if err := runInitWithReader(tmpDir, strings.NewReader("Test User\[email protected]\n")); err != nil {
113 t.Fatalf("runInit failed: %v", err)
114 }
115
116 // Create a bug as agent
117 if err := runAgentNew(tmpDir, "Test Bug", "Description", "", "", false); err != nil {
118 t.Fatalf("runAgentNew failed: %v", err)
119 }
120
121 // Get the bug ID
122 repo, err := repository.OpenGoGitRepo(tmpDir, "", nil)
123 if err != nil {
124 t.Fatalf("failed to open repo: %v", err)
125 }
126
127 var bugID string
128 for streamedBug := range bug.ReadAll(repo) {
129 if streamedBug.Err != nil {
130 t.Fatalf("failed to read bug: %v", streamedBug.Err)
131 }
132 b := streamedBug.Entity
133 snap := b.Compile()
134 if snap.Title == "Test Bug" {
135 bugID = b.Id().String()
136 break
137 }
138 }
139 repo.Close()
140
141 // Add a comment as agent
142 originalComment := "Original agent comment"
143 if err := runAgentComment(tmpDir, bugID, originalComment, "", false); err != nil {
144 t.Fatalf("runAgentComment failed: %v", err)
145 }
146
147 // Get the comment ID
148 repo, err = repository.OpenGoGitRepo(tmpDir, "", nil)
149 if err != nil {
150 t.Fatalf("failed to open repo: %v", err)
151 }
152
153 b, err := bug.Read(repo, entity.Id(bugID))
154 if err != nil {
155 t.Fatalf("failed to read bug: %v", err)
156 }
157 snap := b.Compile()
158 if len(snap.Comments) < 2 {
159 t.Fatal("expected at least 2 comments")
160 }
161 commentID := snap.Comments[1].CombinedId().String()
162 repo.Close()
163
164 // Edit the comment as agent
165 newComment := "Updated agent comment"
166 if err := runAgentEdit(tmpDir, commentID, "", newComment, "", false, ""); err != nil {
167 t.Fatalf("runAgentEdit failed: %v", err)
168 }
169
170 // Verify comment was updated
171 repo, err = repository.OpenGoGitRepo(tmpDir, "", nil)
172 if err != nil {
173 t.Fatalf("failed to open repo: %v", err)
174 }
175 defer repo.Close()
176
177 b, err = bug.Read(repo, entity.Id(bugID))
178 if err != nil {
179 t.Fatalf("failed to read bug: %v", err)
180 }
181
182 snap = b.Compile()
183 if len(snap.Comments) < 2 {
184 t.Fatal("expected at least 2 comments")
185 }
186 if snap.Comments[1].Message != newComment {
187 t.Errorf("comment = %q, want %q", snap.Comments[1].Message, newComment)
188 }
189}
190
191// TestAgentEditCommand_RequiresMessage tests that agent edit requires at least one field
192func TestAgentEditCommand_RequiresMessage(t *testing.T) {
193 tmpDir := t.TempDir()
194
195 // Initialize a git repo
196 initCmd := exec.Command("git", "init")
197 initCmd.Dir = tmpDir
198 if err := initCmd.Run(); err != nil {
199 t.Fatalf("failed to init git repo: %v", err)
200 }
201 // Add origin remote for bug init
202 remoteCmd := exec.Command("git", "remote", "add", "origin", "[email protected]:test/repo.git")
203 remoteCmd.Dir = tmpDir
204 if err := remoteCmd.Run(); err != nil {
205 t.Fatalf("failed to add origin remote: %v", err)
206 }
207
208 // Initialize git-bug identities
209 if err := runInitWithReader(tmpDir, strings.NewReader("Test User\[email protected]\n")); err != nil {
210 t.Fatalf("runInit failed: %v", err)
211 }
212
213 // Create a bug as agent
214 if err := runAgentNew(tmpDir, "Test Bug", "Description", "", "", false); err != nil {
215 t.Fatalf("runAgentNew failed: %v", err)
216 }
217
218 // Get the bug ID
219 repo, err := repository.OpenGoGitRepo(tmpDir, "", nil)
220 if err != nil {
221 t.Fatalf("failed to open repo: %v", err)
222 }
223
224 var bugID string
225 for streamedBug := range bug.ReadAll(repo) {
226 if streamedBug.Err != nil {
227 t.Fatalf("failed to read bug: %v", streamedBug.Err)
228 }
229 b := streamedBug.Entity
230 snap := b.Compile()
231 if snap.Title == "Test Bug" {
232 bugID = b.Id().String()
233 break
234 }
235 }
236 repo.Close()
237
238 // Add a comment as agent
239 if err := runAgentComment(tmpDir, bugID, "Original comment", "", false); err != nil {
240 t.Fatalf("runAgentComment failed: %v", err)
241 }
242
243 // Get the comment ID
244 repo, err = repository.OpenGoGitRepo(tmpDir, "", nil)
245 if err != nil {
246 t.Fatalf("failed to open repo: %v", err)
247 }
248
249 b, err := bug.Read(repo, entity.Id(bugID))
250 if err != nil {
251 t.Fatalf("failed to read bug: %v", err)
252 }
253 snap := b.Compile()
254 commentID := snap.Comments[1].CombinedId().String()
255 repo.Close()
256
257 // Try to edit comment without message
258 err = runAgentEdit(tmpDir, commentID, "", "", "", false, "")
259 if err == nil {
260 t.Error("expected error when editing comment without message, got nil")
261 }
262
263 if !strings.Contains(err.Error(), "either --title or --message") {
264 t.Errorf("expected 'either --title or --message' error, got: %v", err)
265 }
266}
267
268// TestAgentEditCommand_RequiresAtLeastOneField tests that agent edit requires at least one field
269func TestAgentEditCommand_RequiresAtLeastOneField(t *testing.T) {
270 tmpDir := t.TempDir()
271
272 // Initialize a git repo
273 initCmd := exec.Command("git", "init")
274 initCmd.Dir = tmpDir
275 if err := initCmd.Run(); err != nil {
276 t.Fatalf("failed to init git repo: %v", err)
277 }
278 // Add origin remote for bug init
279 remoteCmd := exec.Command("git", "remote", "add", "origin", "[email protected]:test/repo.git")
280 remoteCmd.Dir = tmpDir
281 if err := remoteCmd.Run(); err != nil {
282 t.Fatalf("failed to add origin remote: %v", err)
283 }
284
285 // Initialize git-bug identities
286 if err := runInitWithReader(tmpDir, strings.NewReader("Test User\[email protected]\n")); err != nil {
287 t.Fatalf("runInit failed: %v", err)
288 }
289
290 // Create a bug as agent
291 if err := runAgentNew(tmpDir, "Test Bug", "Description", "", "", false); err != nil {
292 t.Fatalf("runAgentNew failed: %v", err)
293 }
294
295 // Get the bug ID
296 repo, err := repository.OpenGoGitRepo(tmpDir, "", nil)
297 if err != nil {
298 t.Fatalf("failed to open repo: %v", err)
299 }
300
301 var bugID string
302 for streamedBug := range bug.ReadAll(repo) {
303 if streamedBug.Err != nil {
304 t.Fatalf("failed to read bug: %v", streamedBug.Err)
305 }
306 b := streamedBug.Entity
307 snap := b.Compile()
308 if snap.Title == "Test Bug" {
309 bugID = b.Id().String()
310 break
311 }
312 }
313 repo.Close()
314
315 // Try to edit without any flags
316 err = runAgentEdit(tmpDir, bugID, "", "", "", false, "")
317 if err == nil {
318 t.Error("expected error when editing without any fields, got nil")
319 }
320
321 if !strings.Contains(err.Error(), "at least one of --title, --message, or --parent") {
322 t.Errorf("expected 'at least one of --title, --message, or --parent' error, got: %v", err)
323 }
324}
325
326// TestAgentEditCommand_OnlyTitle edits only the title as agent
327func TestAgentEditCommand_OnlyTitle(t *testing.T) {
328 tmpDir := t.TempDir()
329
330 // Initialize a git repo
331 initCmd := exec.Command("git", "init")
332 initCmd.Dir = tmpDir
333 if err := initCmd.Run(); err != nil {
334 t.Fatalf("failed to init git repo: %v", err)
335 }
336 // Add origin remote for bug init
337 remoteCmd := exec.Command("git", "remote", "add", "origin", "[email protected]:test/repo.git")
338 remoteCmd.Dir = tmpDir
339 if err := remoteCmd.Run(); err != nil {
340 t.Fatalf("failed to add origin remote: %v", err)
341 }
342
343 // Initialize git-bug identities
344 if err := runInitWithReader(tmpDir, strings.NewReader("Test User\[email protected]\n")); err != nil {
345 t.Fatalf("runInit failed: %v", err)
346 }
347
348 // Create a bug as agent
349 originalTitle := "Original Title"
350 originalDesc := "Original description"
351 if err := runAgentNew(tmpDir, originalTitle, originalDesc, "", "", false); err != nil {
352 t.Fatalf("runAgentNew failed: %v", err)
353 }
354
355 // Get the bug ID
356 repo, err := repository.OpenGoGitRepo(tmpDir, "", nil)
357 if err != nil {
358 t.Fatalf("failed to open repo: %v", err)
359 }
360
361 var bugID string
362 for streamedBug := range bug.ReadAll(repo) {
363 if streamedBug.Err != nil {
364 t.Fatalf("failed to read bug: %v", streamedBug.Err)
365 }
366 b := streamedBug.Entity
367 snap := b.Compile()
368 if snap.Title == originalTitle {
369 bugID = b.Id().String()
370 break
371 }
372 }
373 repo.Close()
374
375 // Edit only title as agent
376 newTitle := "New Title"
377 if err := runAgentEdit(tmpDir, bugID, newTitle, "", "", false, ""); err != nil {
378 t.Fatalf("runAgentEdit failed: %v", err)
379 }
380
381 // Verify only title changed
382 repo, err = repository.OpenGoGitRepo(tmpDir, "", nil)
383 if err != nil {
384 t.Fatalf("failed to open repo: %v", err)
385 }
386 defer repo.Close()
387
388 b, err := bug.Read(repo, entity.Id(bugID))
389 if err != nil {
390 t.Fatalf("failed to read bug: %v", err)
391 }
392
393 snap := b.Compile()
394 if snap.Title != newTitle {
395 t.Errorf("title = %q, want %q", snap.Title, newTitle)
396 }
397 if len(snap.Comments) == 0 || snap.Comments[0].Message != originalDesc {
398 t.Errorf("description was changed unexpectedly")
399 }
400}