Add dashboard / description page
This commit is contained in:
138
tui_test.go
138
tui_test.go
@@ -166,6 +166,142 @@ func TestPaneFocusAndNavigation(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOpeningPullRequestShowsDashboardBeforeThreads(t *testing.T) {
|
||||
settings := defaultAppSettings()
|
||||
settings.DashboardMode = "intermediate"
|
||||
m := NewAppWithSettings(nil, "o", "r", false, 50, 10*time.Second, settings)
|
||||
m.prs = []PullRequest{{
|
||||
ID: "pr", Owner: "owner", Repository: "repo", RepoWithOwner: "owner/repo", Number: 9,
|
||||
}}
|
||||
updated, command := m.Update(tea.KeyMsg{Type: tea.KeyEnter})
|
||||
m = updated.(App)
|
||||
if m.screen != dashboardScreen || m.details.Number != 9 || command == nil {
|
||||
t.Fatalf("opening PR produced screen=%d number=%d command=%v", m.screen, m.details.Number, command)
|
||||
}
|
||||
|
||||
updated, _ = m.Update(tea.KeyMsg{Type: tea.KeyEnter})
|
||||
m = updated.(App)
|
||||
if m.screen != threadScreen {
|
||||
t.Fatal("enter did not open review threads from dashboard")
|
||||
}
|
||||
updated, _ = m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("b")})
|
||||
m = updated.(App)
|
||||
if m.screen != dashboardScreen {
|
||||
t.Fatal("b did not return from threads to dashboard")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDashboardHotkeyModeIsDefault(t *testing.T) {
|
||||
if got := defaultAppSettings().DashboardMode; got != "hotkey" {
|
||||
t.Fatalf("default dashboard mode = %q, want hotkey", got)
|
||||
}
|
||||
if got := defaultConfig().Display.DashboardMode; got != "hotkey" {
|
||||
t.Fatalf("default config dashboard mode = %q, want hotkey", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHotkeyDashboardModeOpensThreadsDirectly(t *testing.T) {
|
||||
settings := defaultAppSettings()
|
||||
settings.DashboardMode = "hotkey"
|
||||
m := NewAppWithSettings(nil, "o", "r", false, 50, 10*time.Second, settings)
|
||||
m.prs = []PullRequest{{
|
||||
ID: "pr", Owner: "owner", Repository: "repo", RepoWithOwner: "owner/repo", Number: 9,
|
||||
}}
|
||||
|
||||
updated, command := m.Update(tea.KeyMsg{Type: tea.KeyEnter})
|
||||
m = updated.(App)
|
||||
if m.screen != threadScreen || command == nil {
|
||||
t.Fatalf("hotkey mode opened screen=%d command=%v", m.screen, command)
|
||||
}
|
||||
updated, _ = m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("d")})
|
||||
m = updated.(App)
|
||||
if m.screen != dashboardScreen || m.dashboardReturn != threadScreen {
|
||||
t.Fatal("d did not open a dashboard that returns to threads")
|
||||
}
|
||||
updated, _ = m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("b")})
|
||||
m = updated.(App)
|
||||
if m.screen != threadScreen {
|
||||
t.Fatal("dashboard did not return to the invoking thread screen")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDashboardHotkeyWorksFromPicker(t *testing.T) {
|
||||
settings := defaultAppSettings()
|
||||
settings.DashboardMode = "hotkey"
|
||||
m := NewAppWithSettings(nil, "o", "r", false, 50, 10*time.Second, settings)
|
||||
m.prs = []PullRequest{{
|
||||
ID: "pr", Owner: "owner", Repository: "repo", RepoWithOwner: "owner/repo", Number: 9,
|
||||
}}
|
||||
|
||||
updated, command := m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("d")})
|
||||
m = updated.(App)
|
||||
if m.screen != dashboardScreen || m.dashboardReturn != prScreen || command == nil {
|
||||
t.Fatalf("picker dashboard hotkey produced screen=%d return=%d", m.screen, m.dashboardReturn)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDashboardRendersDescriptionAndMetadata(t *testing.T) {
|
||||
m := NewApp(nil, "o", "r", false, 50, 10*time.Second)
|
||||
m.screen = dashboardScreen
|
||||
m.width, m.height = 100, 40
|
||||
m.details = PRDetails{
|
||||
PullRequest: PullRequest{
|
||||
RepoWithOwner: "owner/repo", Number: 9, Title: "Improve dashboard",
|
||||
Author: "alice", URL: "https://github.com/owner/repo/pull/9",
|
||||
UpdatedAt: time.Date(2026, 7, 1, 12, 0, 0, 0, time.UTC),
|
||||
},
|
||||
Body: "> Existing behavior\n\nUse `new_behavior` instead.",
|
||||
CreatedAt: time.Date(2026, 6, 1, 12, 0, 0, 0, time.UTC),
|
||||
BaseRef: "main",
|
||||
HeadRef: "feature",
|
||||
ReviewDecision: "REVIEW_REQUIRED",
|
||||
CheckState: "SUCCESS",
|
||||
MergeState: "CLEAN",
|
||||
Assignees: []string{"bob"},
|
||||
Reviewers: []Reviewer{{Login: "carol", State: "APPROVED"}},
|
||||
Labels: []string{"ui", "review"},
|
||||
Milestone: "v2",
|
||||
Additions: 20,
|
||||
Deletions: 4,
|
||||
ChangedFiles: 3,
|
||||
CommitCount: 2,
|
||||
CommentCount: 5,
|
||||
Threads: []ReviewThread{
|
||||
{ID: "open"},
|
||||
{ID: "old", IsOutdated: true},
|
||||
{ID: "done", IsResolved: true, IsOutdated: true},
|
||||
},
|
||||
}
|
||||
plain := ansi.Strip(m.View())
|
||||
for _, wanted := range []string{
|
||||
"Improve dashboard", "@alice", "feature → main", "@bob", "@carol",
|
||||
"ui, review", "v2", "+20", "-4", "3 files", "2 commits",
|
||||
"1 open", "1 outdated", "1 resolved", "Description",
|
||||
"Existing behavior", "new_behavior",
|
||||
} {
|
||||
if !strings.Contains(plain, wanted) {
|
||||
t.Fatalf("dashboard is missing %q:\n%s", wanted, plain)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDashboardDescriptionScrolls(t *testing.T) {
|
||||
m := NewApp(nil, "o", "r", false, 50, 10*time.Second)
|
||||
m.screen = dashboardScreen
|
||||
m.width, m.height = 60, 10
|
||||
m.details = PRDetails{
|
||||
PullRequest: PullRequest{RepoWithOwner: "owner/repo", Number: 1, Title: "Long", Author: "alice"},
|
||||
BaseRef: "main",
|
||||
HeadRef: "feature",
|
||||
Body: strings.Repeat("A long description line.\n\n", 20),
|
||||
}
|
||||
updated, _ := m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("G")})
|
||||
m = updated.(App)
|
||||
if m.scroll == 0 || m.scroll != m.dashboardMaxScroll() {
|
||||
t.Fatalf("dashboard scroll = %d, max = %d", m.scroll, m.dashboardMaxScroll())
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextualHelpOpensAndClosesWithoutLeavingScreen(t *testing.T) {
|
||||
m := NewApp(nil, "o", "r", false, 50, 10*time.Second)
|
||||
m.screen = threadScreen
|
||||
@@ -179,7 +315,7 @@ func TestContextualHelpOpensAndClosesWithoutLeavingScreen(t *testing.T) {
|
||||
plain := ansi.Strip(m.View())
|
||||
if !strings.Contains(plain, "Review thread keys") ||
|
||||
!strings.Contains(plain, "Fuzzy-search file paths") ||
|
||||
strings.Contains(plain, "Open pull request") {
|
||||
strings.Contains(plain, "Next pull request") {
|
||||
t.Fatalf("help was not contextual:\n%s", plain)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user