Files
arr-tui/internal/ui/discover_test.go
T
nilsandClaude Opus 5.5 9b8d59bd48 Trakt lists: right-align the numbers
The grey number of every entry ("1.2k watching", "on 18k lists") stood
right after its title, so they did not line up. The rows are now padded
to the list's width on every draw where it changed, putting the numbers
against the right edge; a title too long for that keeps the number right
after it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 23:20:59 +02:00

131 lines
4.6 KiB
Go

package ui
import (
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
"github.com/gdamore/tcell/v2"
"git.stinnesbeck.com/nils/arr-tui/internal/radarr"
)
func TestTraktListsInTheSearchView(t *testing.T) {
traktSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`[
{"watchers":1234,"movie":{"title":"Dune","year":2021,"ids":{"trakt":1,"tmdb":438631}}},
{"watchers":900,"movie":{"title":"Unknown To Radarr","year":2020,"ids":{"trakt":2,"tmdb":1}}},
{"watchers":7,"movie":{"title":"No Ids","year":2019,"ids":{"trakt":3}}},
{"watchers":5,"movie":{"title":"Heat","year":1995,"ids":{"trakt":4,"tmdb":949}}}]`))
}))
defer traktSrv.Close()
radarrSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Query().Get("term") {
case "tmdb:438631":
w.Write([]byte(`[{"id":5,"title":"Dune","year":2021,"tmdbId":438631}]`))
case "tmdb:949":
w.Write([]byte(`[{"title":"Heat","year":1995,"tmdbId":949}]`))
default:
w.Write([]byte(`[]`))
}
}))
defer radarrSrv.Close()
a := newTestApp(t)
v := a.searches[0]
// Without a client ID the list says how to get one.
v.activate()
if !v.browsing || !strings.Contains(v.placeholder, "Trakt client ID") {
t.Fatalf("unconfigured: browsing %v, placeholder %q", v.browsing, v.placeholder)
}
a.radarr.Reconfigure(radarrSrv.URL, "k")
a.trakt.Reconfigure("id")
a.trakt.SetBaseURL(traktSrv.URL)
d := v.fetchList(v.lists[0])
if d.err != nil || len(d.results) != 2 {
t.Fatalf("fetched %d results, err %v", len(d.results), d.err)
}
// In the list's order; titles Radarr does not know, or without ids, are left out.
if d.results[0].title() != "Dune" || d.results[1].title() != "Heat" || !d.results[0].inLibrary() || d.results[1].inLibrary() {
t.Errorf("results %v %v", d.results[0].title(), d.results[1].title())
}
if strings.Join(d.notes, "|") != "1.2k watching|5 watching" {
t.Errorf("notes %q", d.notes)
}
// A fresh list is shown from memory, with its numbers and its name in the title.
v.discover[0] = d
v.showList()
if main, _ := v.list.GetItemText(0); !strings.Contains(main, "Dune") || !strings.Contains(main, "1.2k watching") {
t.Errorf("first row %q", main)
}
if title := v.list.GetTitle(); !strings.Contains(title, "Trending now") {
t.Errorf("title %q", title)
}
// ] and [ switch lists while browsing.
v.discover[1] = &discovered{at: time.Now()}
v.list.GetInputCapture()(tcell.NewEventKey(tcell.KeyRune, ']', 0))
if v.listIdx != 1 || !strings.Contains(v.list.GetTitle(), "Most watched") || v.placeholder != "Nothing on this list right now." {
t.Errorf("after ]: list %d, title %q, placeholder %q", v.listIdx, v.list.GetTitle(), v.placeholder)
}
v.list.GetInputCapture()(tcell.NewEventKey(tcell.KeyRune, '[', 0))
// From the empty search box too (where the cursor is when the view opens).
v.input.GetInputCapture()(tcell.NewEventKey(tcell.KeyRune, '[', 0))
if v.listIdx != len(v.lists)-1 || v.input.GetText() != "" {
t.Errorf("[ wraps around: list %d, search box %q", v.listIdx, v.input.GetText())
}
// Search results replace the list; their rows have no numbers.
v.setResults(d.results)
if v.browsing || v.notes != nil || strings.Contains(v.list.GetTitle(), "lists") {
t.Errorf("search results: browsing %v, title %q", v.browsing, v.list.GetTitle())
}
if main, _ := v.list.GetItemText(0); strings.Contains(main, "watching") {
t.Errorf("search row %q", main)
}
}
func TestListNumbersAreRightAligned(t *testing.T) {
sim := tcell.NewSimulationScreen("")
if err := sim.Init(); err != nil {
t.Fatal(err)
}
defer sim.Fini()
sim.SetSize(60, 6)
a := newTestApp(t)
v := a.searches[0]
a.trakt.Reconfigure("id")
v.discover[0] = &discovered{at: time.Now(),
results: []result{movieResult{Movie: radarr.Movie{Title: "Dune", Year: 2021}}, movieResult{Movie: radarr.Movie{Title: "A Much Longer Title", Year: 2024}}},
notes: []string{"1.2k watching", "5 watching"}}
v.showList()
ends := func(width int) []int {
sim.Clear()
l := notesList{v.list, v}
l.SetRect(0, 0, width, 6)
l.Draw(sim)
var out []int
for y := 1; y <= 2; y++ {
row := strings.TrimRight(rowText(sim, y, 0, width), " │")
out = append(out, len([]rune(row)))
if !strings.HasSuffix(row, "watching") {
t.Errorf("row %d does not end with its number: %q", y, row)
}
}
return out
}
if e := ends(60); e[0] != e[1] {
t.Errorf("numbers end in columns %v, want the same", e)
}
// After a resize they line up at the new edge.
if e := ends(44); e[0] != e[1] || e[0] > 44 {
t.Errorf("after resize: numbers end in columns %v", e)
}
}