feat(cli): upgrade command, rich status, and version cache
- Replace `upgrade` stub with real command (alias for `self-update`) - Also register `update` as alias: `unarr update` works too - Rewrite `status` to show full config, disk usage, daemon state, and update availability with colored sections - Add version check cache (1h TTL) so `status` is instant on repeat runs - Guard against division by zero on empty filesystems - Guard against negative durations from clock skew - Guard against stale PID via heartbeat recency check (2 min) - Add comprehensive test coverage across agent, engine, upgrade, usenet, arr, library, mediaserver, and UI packages - Improve Makefile coverage target to exclude cmd/ glue code - Fix stream handler resource cleanup and ffprobe error handling
This commit is contained in:
parent
01d62ffa13
commit
3e0f3a5a64
33 changed files with 7084 additions and 65 deletions
122
internal/ui/table_test.go
Normal file
122
internal/ui/table_test.go
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
package ui
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
tc "github.com/torrentclaw/go-client"
|
||||
)
|
||||
|
||||
func TestNewCleanTable(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
tbl := newCleanTable(&buf)
|
||||
tbl.Header([]string{"A", "B"})
|
||||
tbl.Append([]string{"1", "2"})
|
||||
tbl.Render()
|
||||
|
||||
out := buf.String()
|
||||
if !strings.Contains(out, "A") || !strings.Contains(out, "B") {
|
||||
t.Errorf("expected headers in output, got: %s", out)
|
||||
}
|
||||
if !strings.Contains(out, "1") || !strings.Contains(out, "2") {
|
||||
t.Errorf("expected row data in output, got: %s", out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrintSearchResultEntry(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
year := 2010
|
||||
rating := "8.8"
|
||||
quality := "1080p"
|
||||
codec := "x265"
|
||||
size := int64(4294967296)
|
||||
score := 85
|
||||
|
||||
r := tc.SearchResult{
|
||||
Title: "Inception",
|
||||
Year: &year,
|
||||
ContentType: "movie",
|
||||
RatingIMDb: &rating,
|
||||
Genres: []string{"Sci-Fi", "Action"},
|
||||
Torrents: []tc.TorrentInfo{
|
||||
{
|
||||
Quality: &quality,
|
||||
SizeBytes: &size,
|
||||
Seeders: 150,
|
||||
Leechers: 10,
|
||||
Source: "YTS",
|
||||
Codec: &codec,
|
||||
Languages: []string{"en", "es"},
|
||||
QualityScore: &score,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
printSearchResultEntry(&buf, r)
|
||||
out := buf.String()
|
||||
|
||||
if !strings.Contains(out, "Inception") {
|
||||
t.Error("expected title in output")
|
||||
}
|
||||
if !strings.Contains(out, "2010") {
|
||||
t.Error("expected year in output")
|
||||
}
|
||||
if !strings.Contains(out, "8.8") {
|
||||
t.Error("expected rating in output")
|
||||
}
|
||||
if !strings.Contains(out, "1080p") {
|
||||
t.Error("expected quality in output")
|
||||
}
|
||||
if !strings.Contains(out, "YTS") {
|
||||
t.Error("expected source in output")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrintSearchResultEntryNoTorrents(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
year := 2020
|
||||
|
||||
r := tc.SearchResult{
|
||||
Title: "No Torrents Movie",
|
||||
Year: &year,
|
||||
ContentType: "movie",
|
||||
Torrents: nil,
|
||||
}
|
||||
|
||||
printSearchResultEntry(&buf, r)
|
||||
out := buf.String()
|
||||
|
||||
if !strings.Contains(out, "No Torrents Movie") {
|
||||
t.Error("expected title in output")
|
||||
}
|
||||
if !strings.Contains(out, "No torrents available") {
|
||||
t.Error("expected no-torrents message")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrintSearchResultEntryNilFields(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
|
||||
r := tc.SearchResult{
|
||||
Title: "Minimal",
|
||||
ContentType: "movie",
|
||||
Torrents: []tc.TorrentInfo{
|
||||
{
|
||||
Seeders: 5,
|
||||
Leechers: 3,
|
||||
Source: "RARBG",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
printSearchResultEntry(&buf, r)
|
||||
out := buf.String()
|
||||
|
||||
if !strings.Contains(out, "Minimal") {
|
||||
t.Error("expected title in output")
|
||||
}
|
||||
if !strings.Contains(out, "-") {
|
||||
t.Error("expected dash for nil fields")
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue