Files
parasocial/internal/tui/model_test.go

146 lines
3.9 KiB
Go

package tui
import (
"testing"
"parasocial/internal/auth"
"parasocial/internal/twitch"
)
func TestViewDisplaysStreamers(t *testing.T) {
model := New(Options{
Streamers: []twitch.StreamerEntry{
{ConfigLogin: "alpha", Login: "alpha_live", ChannelID: "1", Live: true, Status: twitch.StreamerReady},
{ConfigLogin: "beta", Status: twitch.StreamerLoading},
},
})
model.mode = streamerView
model.viewer = &twitch.Viewer{ID: "7", Login: "viewer"}
got := model.View()
want := "Logged in as viewer (7)\n\nStreamers\n1. alpha_live \x1b[32m●\x1b[0m (1)\n2. beta [loading]\n\n"
if got != want {
t.Fatalf("View() = %q, want %q", got, want)
}
}
func TestAuthUpdateAppendsLogLine(t *testing.T) {
model := New(Options{Streamers: twitch.LoadingStreamerEntries([]string{"alpha"})})
updated, cmd := model.Update(AuthUpdate{Line: "Open page: https://www.twitch.tv/activate"})
if cmd != nil {
t.Fatal("expected nil cmd after auth update without channel")
}
next := updated.(Model)
got := next.View()
want := "Twitch Login\nOpen page: https://www.twitch.tv/activate\n\n"
if got != want {
t.Fatalf("View() = %q, want %q", got, want)
}
}
func TestAuthSuccessSwitchesToStreamerViewAndStartsResolution(t *testing.T) {
var started *auth.State
model := New(Options{
Streamers: twitch.LoadingStreamerEntries([]string{"alpha"}),
StartResolve: func(state *auth.State, ch chan<- StreamerUpdate) {
started = state
close(ch)
},
})
state := &auth.State{Login: "viewer", UserID: "7"}
updated, cmd := model.Update(AuthUpdate{
State: state,
Done: true,
})
if cmd == nil {
t.Fatal("expected streamer resolution command")
}
if _, ok := cmd().(streamerStartedMsg); !ok {
t.Fatalf("cmd() returned %T, want streamerStartedMsg", cmd())
}
if started != state {
t.Fatalf("started state = %#v, want %#v", started, state)
}
next := updated.(Model)
got := next.View()
want := "Logged in as viewer\nResolving viewer identity...\n\nStreamers\n1. alpha [loading]\n\n"
if got != want {
t.Fatalf("View() = %q, want %q", got, want)
}
}
func TestInitStartsResolutionWhenAlreadyAuthenticated(t *testing.T) {
var started *auth.State
state := &auth.State{Login: "viewer", UserID: "7"}
model := New(Options{
Streamers: twitch.LoadingStreamerEntries([]string{"alpha"}),
AuthState: state,
StartResolve: func(got *auth.State, ch chan<- StreamerUpdate) {
started = got
close(ch)
},
})
cmd := model.Init()
if cmd == nil {
t.Fatal("expected init command")
}
if _, ok := cmd().(streamerStartedMsg); !ok {
t.Fatalf("cmd() returned %T, want streamerStartedMsg", cmd())
}
if started != state {
t.Fatalf("started state = %#v, want %#v", started, state)
}
}
func TestStreamerUpdateAppliesEntry(t *testing.T) {
model := New(Options{
Streamers: twitch.LoadingStreamerEntries([]string{"alpha"}),
AuthState: &auth.State{Login: "viewer"},
})
model.mode = streamerView
updated, cmd := model.Update(StreamerUpdate{
Viewer: &twitch.Viewer{ID: "7", Login: "viewer"},
Index: 0,
Entry: &twitch.StreamerEntry{
ConfigLogin: "alpha",
Login: "alpha_live",
ChannelID: "1",
Live: true,
Status: twitch.StreamerReady,
},
})
if cmd != nil {
t.Fatal("expected nil cmd when no update channel is attached")
}
next := updated.(Model)
got := next.View()
want := "Logged in as viewer (7)\n\nStreamers\n1. alpha_live \x1b[32m●\x1b[0m (1)\n\n"
if got != want {
t.Fatalf("View() = %q, want %q", got, want)
}
}
func TestViewDisplaysOfflineReadyStreamerWithoutMarker(t *testing.T) {
model := New(Options{
Streamers: []twitch.StreamerEntry{
{ConfigLogin: "alpha", Login: "alpha_live", ChannelID: "1", Status: twitch.StreamerReady},
},
})
model.mode = streamerView
model.viewer = &twitch.Viewer{ID: "7", Login: "viewer"}
got := model.View()
want := "Logged in as viewer (7)\n\nStreamers\n1. alpha_live (1)\n\n"
if got != want {
t.Fatalf("View() = %q, want %q", got, want)
}
}