140 lines
3.9 KiB
Go
140 lines
3.9 KiB
Go
package tui
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"path/filepath"
|
||
|
|
"strings"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
tea "charm.land/bubbletea/v2"
|
||
|
|
|
||
|
|
"lazyntfy/internal/config"
|
||
|
|
"lazyntfy/internal/history"
|
||
|
|
"lazyntfy/internal/ntfy"
|
||
|
|
"lazyntfy/internal/store"
|
||
|
|
)
|
||
|
|
|
||
|
|
func sample() Model {
|
||
|
|
m := New(config.App{
|
||
|
|
DefaultHost: "https://ntfy.example",
|
||
|
|
Auth: config.Auth{Token: "tk_test"},
|
||
|
|
Subs: []config.Sub{{Origin: "https://ntfy.example", Name: "alerts", Auth: config.Auth{Token: "tk_test"}}},
|
||
|
|
}, nil, ntfy.NewClient(), nil, nil)
|
||
|
|
m.width = 120
|
||
|
|
m.height = 30
|
||
|
|
m.store.Put(store.Message{ID: "new", Time: 200, Topic: "alerts", Title: "DiskFull", Body: `{"status":"firing","commonLabels":{"alertname":"DiskFull","severity":"critical"}}`})
|
||
|
|
m.store.Put(store.Message{ID: "old", Time: 100, Topic: "alerts", Body: "backup finished"})
|
||
|
|
m = m.ensureSelection()
|
||
|
|
return m
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestViewShowsNewestAlert(t *testing.T) {
|
||
|
|
view := sample().render()
|
||
|
|
if !strings.Contains(view, "lazyntfy") || !strings.Contains(view, "DiskFull") || !strings.Contains(view, "firing") {
|
||
|
|
t.Fatalf("%s", view)
|
||
|
|
}
|
||
|
|
lines := strings.Split(view, "\n")
|
||
|
|
if len(lines) != 30 {
|
||
|
|
t.Fatalf("height %d", len(lines))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestMoveKeepsSelectionByID(t *testing.T) {
|
||
|
|
m := sample()
|
||
|
|
if m.selected["alerts"] != "new" {
|
||
|
|
t.Fatalf("selected %s", m.selected["alerts"])
|
||
|
|
}
|
||
|
|
m = m.move(1)
|
||
|
|
if m.selected["alerts"] != "old" {
|
||
|
|
t.Fatalf("after down %s", m.selected["alerts"])
|
||
|
|
}
|
||
|
|
next, cmd := m.Update(tea.KeyPressMsg{Text: "q", Code: 'q'})
|
||
|
|
if cmd == nil {
|
||
|
|
t.Fatal("expected quit")
|
||
|
|
}
|
||
|
|
if next.(Model).selected["alerts"] != "old" {
|
||
|
|
t.Fatal("quit changed selection")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestFilterAndDelete(t *testing.T) {
|
||
|
|
m := sample()
|
||
|
|
m.filter = "backup"
|
||
|
|
m = m.ensureSelection()
|
||
|
|
if m.selected["alerts"] != "old" {
|
||
|
|
t.Fatalf("filter selected %s", m.selected["alerts"])
|
||
|
|
}
|
||
|
|
if !strings.Contains(m.render(), "backup finished") {
|
||
|
|
t.Fatal(m.render())
|
||
|
|
}
|
||
|
|
m = m.apply(ntfy.Notice{Event: &ntfy.Event{ID: "old", Event: "message_delete", Topic: "alerts"}})
|
||
|
|
if len(m.store.List("alerts")) != 1 {
|
||
|
|
t.Fatal("delete")
|
||
|
|
}
|
||
|
|
m = m.apply(ntfy.Notice{Event: &ntfy.Event{Event: "message_clear", Topic: "alerts"}})
|
||
|
|
if len(m.store.List("alerts")) != 0 {
|
||
|
|
t.Fatal("clear")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestPublishRequiresMessage(t *testing.T) {
|
||
|
|
m := sample()
|
||
|
|
m.mode = modePublish
|
||
|
|
m.formIdx = 3
|
||
|
|
got, _ := m.updatePublish(tea.KeyPressMsg{Text: "enter", Code: tea.KeyEnter})
|
||
|
|
if got.(Model).status != "message is empty" {
|
||
|
|
t.Fatalf("status %q", got.(Model).status)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestAddTopicUsesDefaultHost(t *testing.T) {
|
||
|
|
m := sample()
|
||
|
|
m.addInput.SetValue("backups")
|
||
|
|
m = m.submitAdd()
|
||
|
|
if len(m.subs) != 2 || m.subs[1].Name != "backups" || m.subs[1].Origin != "https://ntfy.example" {
|
||
|
|
t.Fatalf("%+v", m.subs)
|
||
|
|
}
|
||
|
|
if m.subs[1].Auth.Token != "tk_test" {
|
||
|
|
t.Fatal("auth not copied")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestRejectsNonHTTPClick(t *testing.T) {
|
||
|
|
if err := validateURL("file:///etc/passwd"); err == nil {
|
||
|
|
t.Fatal("expected reject")
|
||
|
|
}
|
||
|
|
if err := validateURL("https://example.com/a"); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestRestoresMessagesAndTopicFromHistory(t *testing.T) {
|
||
|
|
db, err := history.Open(filepath.Join(t.TempDir(), "history.db"))
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
defer db.Close()
|
||
|
|
if err := db.SaveMessage("https://ntfy.example", store.Message{
|
||
|
|
ID: "h1", Topic: "alerts", Time: 50, Title: "from disk",
|
||
|
|
}); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
if err := db.SetState("topic", "alerts"); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
|
||
|
|
m := New(config.App{
|
||
|
|
DefaultHost: "https://ntfy.example",
|
||
|
|
Subs: []config.Sub{{Origin: "https://ntfy.example", Name: "alerts"}},
|
||
|
|
}, nil, ntfy.NewClient(), nil, db)
|
||
|
|
if m.restored != 1 || len(m.store.List("alerts")) != 1 {
|
||
|
|
t.Fatalf("restored %d messages %d", m.restored, len(m.store.List("alerts")))
|
||
|
|
}
|
||
|
|
if m.savedTopic != "alerts" || m.currentName() != "alerts" {
|
||
|
|
t.Fatalf("saved %q current %q", m.savedTopic, m.currentName())
|
||
|
|
}
|
||
|
|
m.width, m.height = 120, 30
|
||
|
|
if !strings.Contains(m.render(), "from disk") {
|
||
|
|
t.Fatalf("restored message missing from view:\n%s", m.render())
|
||
|
|
}
|
||
|
|
}
|