aboutsummaryrefslogtreecommitdiffstats
path: root/tui/tui_test.go
diff options
context:
space:
mode:
authorAdam Mathes <adam@adammathes.com>2026-02-13 18:43:03 -0800
committerAdam Mathes <adam@adammathes.com>2026-02-13 18:43:03 -0800
commit21b4eec6c1e096573bcd5f2079bc21e23a960621 (patch)
tree58c8fe2e86aef9859debd05344084e9060dc38c9 /tui/tui_test.go
parent01d4bbe4b2842cb8c2e4319b6cf03d3050f38d06 (diff)
downloadneko-21b4eec6c1e096573bcd5f2079bc21e23a960621.tar.gz
neko-21b4eec6c1e096573bcd5f2079bc21e23a960621.tar.bz2
neko-21b4eec6c1e096573bcd5f2079bc21e23a960621.zip
refactor(backend): improve testability and add tests (NK-6q9nyg)
Diffstat (limited to 'tui/tui_test.go')
-rw-r--r--tui/tui_test.go108
1 files changed, 108 insertions, 0 deletions
diff --git a/tui/tui_test.go b/tui/tui_test.go
index f34707f..764dd28 100644
--- a/tui/tui_test.go
+++ b/tui/tui_test.go
@@ -1,6 +1,7 @@
package tui
import (
+ "fmt"
"path/filepath"
"strings"
"testing"
@@ -9,6 +10,7 @@ import (
"adammathes.com/neko/models"
"adammathes.com/neko/models/feed"
"adammathes.com/neko/models/item"
+ "github.com/charmbracelet/bubbles/list"
tea "github.com/charmbracelet/bubbletea"
)
@@ -158,3 +160,109 @@ func TestItemString(t *testing.T) {
t.Errorf("Expected 'hello', got %s", is.FilterValue())
}
}
+func TestUpdateError(t *testing.T) {
+ m := NewModel()
+ msg := errMsg(fmt.Errorf("test error"))
+ newModel, cmd := m.Update(msg)
+ tm := newModel.(Model)
+ if tm.err == nil {
+ t.Error("Expected error to be set in model")
+ }
+ if cmd == nil {
+ t.Error("Expected tea.Quit command (non-nil)")
+ }
+}
+
+func TestUpdateCtrlC(t *testing.T) {
+ m := NewModel()
+ msg := tea.KeyMsg{Type: tea.KeyCtrlC}
+ _, cmd := m.Update(msg)
+ if cmd == nil {
+ t.Error("Expected tea.Quit command")
+ }
+}
+
+func TestViewError(t *testing.T) {
+ m := NewModel()
+ m.err = fmt.Errorf("fatal error")
+ v := m.View()
+ if !strings.Contains(v, "Error: fatal error") {
+ t.Errorf("Expected view to show error, got %q", v)
+ }
+}
+
+func TestUpdateEscNotFeeds(t *testing.T) {
+ m := NewModel()
+ m.state = viewItems
+ m1, _ := m.Update(tea.KeyMsg{Type: tea.KeyEsc})
+ if m1.(Model).state != viewFeeds {
+ t.Error("Esc in viewItems should go to viewFeeds")
+ }
+}
+
+func TestLoadFeedsError(t *testing.T) {
+ setupTestDB(t)
+ models.DB.Close()
+ msg := loadFeeds()
+ if _, ok := msg.(errMsg); !ok {
+ t.Errorf("Expected errMsg on DB close, got %T", msg)
+ }
+}
+
+func TestLoadItemsError(t *testing.T) {
+ setupTestDB(t)
+ models.DB.Close()
+ msg := loadItems(1)()
+ if _, ok := msg.(errMsg); !ok {
+ t.Errorf("Expected errMsg on DB close, got %T", msg)
+ }
+}
+
+func TestUpdateItemsMsg(t *testing.T) {
+ m := NewModel()
+ msg := itemsMsg([]*item.Item{{Title: "Test Item"}})
+ m1, _ := m.Update(msg)
+ tm := m1.(Model)
+ if tm.state != viewItems {
+ t.Errorf("Expected state viewItems, got %v", tm.state)
+ }
+ if len(tm.items) != 1 {
+ t.Errorf("Expected 1 item, got %d", len(tm.items))
+ }
+}
+
+func TestUpdateEnterItems(t *testing.T) {
+ m := NewModel()
+ m.state = viewItems
+ m.items = []*item.Item{{Title: "Test Item", Description: "Content"}}
+ m.itemList = list.New([]list.Item{itemString("Test Item")}, list.NewDefaultDelegate(), 0, 0)
+
+ m1, _ := m.Update(tea.KeyMsg{Type: tea.KeyEnter})
+ tm := m1.(Model)
+ if tm.state != viewContent {
+ t.Errorf("Expected state viewContent, got %v", tm.state)
+ }
+}
+
+func TestUpdateTuiMoreKeys(t *testing.T) {
+ m := NewModel()
+
+ // Test 'q'
+ _, cmd := m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("q")})
+ if cmd == nil {
+ t.Error("Expected Quit command for 'q'")
+ }
+
+ // Test 'r'
+ _, cmd = m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("r")})
+ if cmd == nil {
+ t.Error("Expected loadFeeds command for 'r'")
+ }
+
+ // Test 'esc' when already at viewFeeds
+ m.state = viewFeeds
+ m3, _ := m.Update(tea.KeyMsg{Type: tea.KeyEsc})
+ if m3.(Model).state != viewFeeds {
+ t.Error("Esc at viewFeeds should keep viewFeeds")
+ }
+}