discordo/internal/ui/chat/model_test.go

99 lines
2.8 KiB
Go

package chat
import (
"path/filepath"
"testing"
"time"
"github.com/ayn2op/arikawa/v3/discord"
"github.com/ayn2op/arikawa/v3/gateway"
"github.com/ayn2op/discordo/internal/config"
"github.com/ayn2op/tview"
"github.com/gdamore/tcell/v3"
)
func newTestModel(t *testing.T) *Model {
t.Helper()
cfg, err := config.Load(filepath.Join(t.TempDir(), "config.toml"))
if err != nil {
t.Fatal(err)
}
m := NewModel(cfg, "")
return &m
}
func TestModelHandle(t *testing.T) {
t.Run("typing in the channels picker", func(t *testing.T) {
m := newTestModel(t)
m.openPicker()
area := tview.Rectangle{Width: 120, Height: 40}
// The picker's action passes through the panes below it, which must leave it alone.
msg := m.View().Handle(tcell.NewEventKey(tcell.KeyRune, "a", tcell.ModNone), area)
if msg == nil {
t.Fatal("typing produced no message")
}
if _, ok := msg.(paneMsg); ok {
t.Fatalf("the picker's action was marked for a pane: %v", msg)
}
*m, _ = m.Update(msg)
})
}
func TestModelUpdate(t *testing.T) {
t.Run("typing expires unless extended", func(t *testing.T) {
m := newTestModel(t)
m.addTyper(1)
m.addTyper(1)
*m, _ = m.Update(typingExpiredMsg{userID: 1})
if _, ok := m.typers[1]; !ok {
t.Fatal("an extended typing indicator expired early")
}
m.typers[1] = time.Now().Add(-time.Second)
*m, _ = m.Update(typingExpiredMsg{userID: 1})
if _, ok := m.typers[1]; ok {
t.Fatal("the typing indicator did not expire")
}
})
}
func TestModelAddMessageOrNotify(t *testing.T) {
for _, tt := range []struct {
name string
focused bool
whenUnfocused bool
want bool
}{
{"focused", true, true, false},
{"unfocused", false, true, true},
{"unfocused but disabled", false, false, false},
} {
t.Run(tt.name, func(t *testing.T) {
m := newTestModel(t)
m.cfg.Notifications.WhenUnfocused = tt.whenUnfocused
m.setSelectedChannel(&discord.Channel{ID: 1})
*m, _ = m.Update(tcell.NewEventFocus(tt.focused))
cmd := m.addMessageOrNotify(&gateway.MessageCreateEvent{Message: discord.Message{ID: 1, ChannelID: 1}})
if got := cmd != nil; got != tt.want {
t.Fatalf("notified = %v, want %v", got, tt.want)
}
})
}
}
func TestModelCycleFocus(t *testing.T) {
m := newTestModel(t)
m.setSelectedChannel(&discord.Channel{ID: 1, GuildID: 2, Type: discord.GuildText})
m.focused = paneGuildsTree
// The composer is disabled without permission to send messages, so it is skipped.
for _, want := range []pane{paneMessagesList, paneMembersTree, paneGuildsTree} {
if m.cycleFocus(1); m.focused != want {
t.Fatalf("focused = %v, want %v", m.focused, want)
}
}
for _, want := range []pane{paneMembersTree, paneMessagesList, paneGuildsTree} {
if m.cycleFocus(-1); m.focused != want {
t.Fatalf("focused = %v, want %v", m.focused, want)
}
}
}