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}