Files
diple/user_completion_test.go
2026-07-29 13:12:39 +02:00

155 lines
5.1 KiB
Go

package main
import (
"slices"
"strings"
"testing"
"time"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/x/ansi"
)
func TestReviewerCompletionSupportsMultipleEligibleUsers(t *testing.T) {
m := NewApp(&recordingPRService{}, "o", "r", false, 50, time.Second)
m.width = 80
m.details = PRDetails{
PullRequest: PullRequest{Author: "author"},
ViewerLogin: "current",
}
m.prEditField = prEditReviewersField
m.prEditEditors[prEditReviewersField] = newTextEditor("alice, bo", false)
m.prEditUsers = []RepositoryUser{
{Login: "alice", Name: "Alice", CanReview: true},
{Login: "bob", Name: "Bob", CanReview: true},
{Login: "author", Name: "Author", CanReview: true},
{Login: "carol", Name: "Carol", CanAssign: true},
}
suggestions := m.userSuggestions()
if len(suggestions) != 1 || suggestions[0].user.Login != "bob" {
t.Fatalf("reviewer suggestions = %#v", suggestions)
}
if !m.completeUserSuggestion() ||
m.prEditEditors[prEditReviewersField].Text != "alice, bob" {
t.Fatalf("completed reviewers = %q", m.prEditEditors[prEditReviewersField].Text)
}
view := ansi.Strip(strings.Join(
m.prEditFieldLines("reviewers", prEditReviewersField, 80), "\n",
))
if !strings.Contains(view, "comma separates users") {
t.Fatalf("reviewer completion help missing:\n%s", view)
}
}
func TestReviewerSuggestionsPreferRecentRepositoryActivity(t *testing.T) {
now := time.Now()
m := NewApp(&recordingPRService{}, "o", "r", false, 50, time.Second)
m.details = PRDetails{PullRequest: PullRequest{Author: "author"}}
m.prEditField = prEditReviewersField
m.prEditEditors[prEditReviewersField] = newTextEditor("", false)
m.prEditUsers = []RepositoryUser{
{
Login: "old-contributor", CanReview: true, RecentCommits: 30,
LastContributionAt: now.AddDate(-2, 0, 0),
},
{
Login: "active-contributor", CanReview: true, RecentCommits: 3,
RecentAdditions: 50, LastContributionAt: now.Add(-24 * time.Hour),
},
{Login: "never-contributed", CanReview: true},
}
suggestions := m.userSuggestions()
if len(suggestions) != 3 || suggestions[0].user.Login != "active-contributor" {
t.Fatalf("activity-ranked reviewers = %#v", suggestions)
}
}
func TestPREditStartsWithCurrentRequestedReviewers(t *testing.T) {
m := NewApp(&recordingPRService{}, "o", "r", false, 50, time.Second)
m.loading = false
m.details = PRDetails{
PullRequest: PullRequest{
ID: "pr", Owner: "o", Repository: "r", Title: "Title",
},
BaseRef: "main", RequestedReviewers: []string{"alice", "bob"},
Assignees: []string{"carol"},
Permissions: ViewerPermissions{CanUpdatePR: true, CanAssign: true},
}
m.startPREdit()
if got := m.prEditEditors[prEditReviewersField].Text; got != "alice, bob" {
t.Fatalf("reviewer field = %q", got)
}
if got := m.prEditEditors[prEditAssigneesField].Text; got != "carol" {
t.Fatalf("assignee field = %q", got)
}
}
func TestPeopleOnlyPREditSkipsCoreMetadataMutation(t *testing.T) {
service := &recordingPRService{}
m := NewApp(service, "o", "r", false, 50, time.Second)
m.screen, m.loading, m.width, m.height = dashboardScreen, false, 80, 30
m.details = PRDetails{
PullRequest: PullRequest{
ID: "pr", Owner: "o", Repository: "r", Number: 4,
Title: "Title", Author: "author",
},
BaseRef: "main", RequestedReviewers: []string{"alice"},
Permissions: ViewerPermissions{CanUpdatePR: true, CanAssign: true},
}
m.startPREdit()
m.prEditUsers = []RepositoryUser{
{Login: "alice", CanReview: true},
{Login: "bob", CanReview: true, CanAssign: true},
}
m.prEditUsersLoading = false
m.prEditEditors[prEditReviewersField] = newTextEditor("alice, bob", false)
m.prEditEditors[prEditAssigneesField] = newTextEditor("bob", false)
if err := m.validatePREdit(); err != nil {
t.Fatal(err)
}
m.writeMode = writePREditConfirm
updated, command := m.updatePREditInput(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("y")})
m = updated.(App)
if command == nil {
t.Fatal("people update did not create a command")
}
msg := command().(pullRequestUpdatedMsg)
if msg.err != nil {
t.Fatal(msg.err)
}
if service.updateID != "" {
t.Fatalf("people-only edit rewrote core metadata for %q", service.updateID)
}
if !slices.Equal(service.people.Reviewers, []string{"alice", "bob"}) ||
!slices.Equal(service.people.Assignees, []string{"bob"}) {
t.Fatalf("people update = %#v", service.people)
}
}
func TestApplyingUserReviewersPreservesTeamRequestsAndCompletedReviews(t *testing.T) {
m := App{details: PRDetails{
RequestedReviewers: []string{"old-user"},
Reviewers: []Reviewer{
{Login: "old-user", State: "REVIEW_REQUESTED"},
{Login: "backend-team", State: "REVIEW_REQUESTED"},
{Login: "approved-user", State: "APPROVED"},
},
}}
m.applyPREditPeople(PullRequestPeople{
Reviewers: []string{"new-user"},
Assignees: []string{"assignee"},
})
got := make(map[string]string)
for _, reviewer := range m.details.Reviewers {
got[reviewer.Login] = reviewer.State
}
if len(got) != 3 || got["backend-team"] != "REVIEW_REQUESTED" ||
got["approved-user"] != "APPROVED" ||
got["new-user"] != "REVIEW_REQUESTED" {
t.Fatalf("reviewers after update = %#v", m.details.Reviewers)
}
}