read_integration_test.go
1//go:build integration
2
3package main
4
5import (
6 "io"
7 "os"
8 "os/exec"
9 "strings"
10 "testing"
11)
12
13// TestReadCommand_Integration tests the read command functionality
14func TestReadCommand_Integration(t *testing.T) {
15 // Create a temporary directory for our test repo
16 tmpDir := t.TempDir()
17
18 // Initialize a git repo
19 initCmd := exec.Command("git", "init")
20 initCmd.Dir = tmpDir
21 if err := initCmd.Run(); err != nil {
22 t.Fatalf("failed to init git repo: %v", err)
23 }
24 // Add origin remote for bug init
25 remoteCmd := exec.Command("git", "remote", "add", "origin", "[email protected]:test/repo.git")
26 remoteCmd.Dir = tmpDir
27 if err := remoteCmd.Run(); err != nil {
28 t.Fatalf("failed to add origin remote: %v", err)
29 }
30
31 // Initialize bug identities
32 if err := runInitWithReader(tmpDir, strings.NewReader("Test User\[email protected]\n")); err != nil {
33 t.Fatalf("Failed to init bug: %v", err)
34 }
35
36 // Create a bug with a title and description
37 title := "Test Issue for Read Command"
38 message := "This is a test description for the read command."
39 if err := runNew(tmpDir, title, message, ""); err != nil {
40 t.Fatalf("Failed to create bug: %v", err)
41 }
42
43 // Load bugs to get the ID
44 issues, err := LoadBugs(tmpDir)
45 if err != nil {
46 t.Fatalf("Failed to load bugs: %v", err)
47 }
48
49 if len(issues) == 0 {
50 t.Fatal("No issues found after creating bug")
51 }
52
53 bugID := issues[0].ShortID
54
55 // Add a comment to the bug
56 commentMsg := "This is a test comment."
57 if err := runComment(tmpDir, bugID, commentMsg); err != nil {
58 t.Fatalf("Failed to add comment: %v", err)
59 }
60
61 // Test read command - this should not error
62 // We can't easily capture stdout, but we can verify it doesn't panic or error
63 // For a more complete test, we could refactor runRead to return a string
64 err = runRead(tmpDir, bugID)
65 if err != nil {
66 t.Fatalf("runRead failed: %v", err)
67 }
68}
69
70func captureRunRead(t *testing.T, repoPath, bugID string) string {
71 t.Helper()
72 old := os.Stdout
73 r, w, _ := os.Pipe()
74 os.Stdout = w
75 defer func() { os.Stdout = old }()
76 if err := runRead(repoPath, bugID); err != nil {
77 t.Fatalf("runRead: %v", err)
78 }
79 w.Close()
80 data, _ := io.ReadAll(r)
81 return string(data)
82}
83
84func TestReadCommand_ShowsIDLine(t *testing.T) {
85 tmpDir := t.TempDir()
86 initCmd := exec.Command("git", "init")
87 initCmd.Dir = tmpDir
88 if err := initCmd.Run(); err != nil {
89 t.Fatalf("init: %v", err)
90 }
91 remoteCmd := exec.Command("git", "remote", "add", "origin", "[email protected]:test/repo.git")
92 remoteCmd.Dir = tmpDir
93 if err := remoteCmd.Run(); err != nil {
94 t.Fatalf("remote: %v", err)
95 }
96 if err := runInitWithReader(tmpDir, strings.NewReader("Test User\[email protected]\n")); err != nil {
97 t.Fatalf("init bug: %v", err)
98 }
99 if err := runNew(tmpDir, "ID Test", "desc", ""); err != nil {
100 t.Fatalf("new: %v", err)
101 }
102 issues, _ := LoadBugs(tmpDir)
103 bugID := issues[0].ShortID
104 fullID := issues[0].FullID
105 wantID := fullID
106 if len(wantID) > 7 {
107 wantID = wantID[:7]
108 }
109 out := captureRunRead(t, tmpDir, bugID)
110 if !strings.Contains(out, "ID: "+wantID) {
111 t.Errorf("read output missing %q\ngot:\n%s", "ID: "+wantID, out)
112 }
113 titleIdx := strings.Index(out, "Title:")
114 idIdx := strings.Index(out, "ID: ")
115 authorIdx := strings.Index(out, "Author:")
116 if !(titleIdx >= 0 && idIdx > titleIdx && authorIdx > idIdx) {
117 t.Errorf("want Title -> ID -> Author order\ngot:\n%s", out)
118 }
119}
120
121func TestReadCommand_ShowsParentLine(t *testing.T) {
122 tmpDir := setupParentTestRepo(t)
123 if err := runNew(tmpDir, "Parent Bug", "p desc", ""); err != nil {
124 t.Fatalf("new parent: %v", err)
125 }
126 parent := findIssueByTitle(t, tmpDir, "Parent Bug")
127 if err := runNew(tmpDir, "Child Bug", "c desc", parent.ShortID); err != nil {
128 t.Fatalf("new child: %v", err)
129 }
130 child := findIssueByTitle(t, tmpDir, "Child Bug")
131 out := captureRunRead(t, tmpDir, child.ShortID)
132 wantParentShort := parent.FullID
133 if len(wantParentShort) > 7 {
134 wantParentShort = wantParentShort[:7]
135 }
136 want := "Parent: " + wantParentShort + " - Parent Bug"
137 if !strings.Contains(out, want) {
138 t.Errorf("want %q\ngot:\n%s", want, out)
139 }
140}
141
142func TestReadCommand_OmitsParentWhenNone(t *testing.T) {
143 tmpDir := setupParentTestRepo(t)
144 if err := runNew(tmpDir, "Lonely", "desc", ""); err != nil {
145 t.Fatalf("new: %v", err)
146 }
147 lonely := findIssueByTitle(t, tmpDir, "Lonely")
148 out := captureRunRead(t, tmpDir, lonely.ShortID)
149 if strings.Contains(out, "Parent:") {
150 t.Errorf("want no Parent line\ngot:\n%s", out)
151 }
152}