Files

124 lines
4.0 KiB
Go

// Copyright (c) 2026 Storm Dragon
// Authors: Storm Dragon, Angus Kola
// SPDX-License-Identifier: GPL-3.0-or-later
package notification
import (
"testing"
"time"
)
func TestPresenterSavesHistoryAndEnforcesMaximumSize(t *testing.T) {
now := time.Unix(1_800_000_000, 0)
presenter := NewPresenterAt(func() time.Time { return now })
for number := 0; number < historySize+2; number++ {
presenter.Save(time.Unix(int64(number), 0).Format("2006"))
now = now.Add(time.Second)
}
entries := presenter.Entries()
if len(entries) != historySize {
t.Fatalf("history length = %d, want %d", len(entries), historySize)
}
if entries[0].Source != SourceGeneric {
t.Fatalf("first source = %q, want %q", entries[0].Source, SourceGeneric)
}
}
func TestPresenterNavigationMatchesReferenceBoundaries(t *testing.T) {
now := time.Unix(1_800_000_000, 0)
presenter := NewPresenterAt(func() time.Time { return now })
presenter.Save("first")
presenter.Save("second")
assertMessages := func(t *testing.T, got []string, want ...string) {
t.Helper()
if len(got) != len(want) {
t.Fatalf("message count = %d, want %d: %q", len(got), len(want), got)
}
for index := range want {
if got[index] != want[index] {
t.Fatalf("message %d = %q, want %q", index, got[index], want[index])
}
}
}
t.Run("last", func(t *testing.T) {
assertMessages(t, presenter.PresentLast(), "second 0 seconds ago")
})
t.Run("previous then top", func(t *testing.T) {
assertMessages(t, presenter.PresentPrevious(), "first 0 seconds ago")
assertMessages(t, presenter.PresentPrevious(), MessageListTop, "first 0 seconds ago")
})
t.Run("next then bottom", func(t *testing.T) {
assertMessages(t, presenter.PresentNext(), "second 0 seconds ago")
assertMessages(t, presenter.PresentNext(), MessageListBottom, "second 0 seconds ago")
assertMessages(t, presenter.PresentNext(), MessageListBottom, "second 0 seconds ago")
})
t.Run("empty", func(t *testing.T) {
empty := NewPresenterAt(func() time.Time { return now })
assertMessages(t, empty.PresentLast(), MessageNoMessages)
assertMessages(t, empty.PresentPrevious(), MessageNoMessages)
assertMessages(t, empty.PresentNext(), MessageNoMessages)
})
}
func TestPresenterStartsAtLatestNotification(t *testing.T) {
now := time.Unix(1_800_000_000, 0)
presenter := NewPresenterAt(func() time.Time { return now })
presenter.Save("first")
presenter.Save("second")
assertMessages(t, presenter.PresentPrevious(), "first 0 seconds ago")
}
func TestPresenterRemovalKeepsHistoryNavigationValid(t *testing.T) {
for _, removeAt := range []int{0, 1, 2} {
t.Run(time.Duration(removeAt).String(), func(t *testing.T) {
now := time.Unix(1_800_000_000, 0)
presenter := NewPresenterAt(func() time.Time { return now })
entries := []Entry{presenter.Save("first"), presenter.Save("second"), presenter.Save("third")}
presenter.PresentPrevious()
presenter.PresentPrevious()
if !presenter.Remove(entries[removeAt]) {
t.Fatal("notification was not removed")
}
want := "first 0 seconds ago"
if removeAt == 0 {
want = "second 0 seconds ago"
}
assertMessages(t, presenter.PresentPrevious(), MessageListTop, want)
presenter.PresentNext()
})
}
}
func assertMessages(t *testing.T, got []string, want ...string) {
t.Helper()
if len(got) != len(want) {
t.Fatalf("message count = %d, want %d: %q", len(got), len(want), got)
}
for index := range want {
if got[index] != want[index] {
t.Fatalf("message %d = %q, want %q", index, got[index], want[index])
}
}
}
func TestRelativeTimeUsesReferenceRounding(t *testing.T) {
now := time.Unix(1_800_000_000, 0)
for _, test := range []struct {
elapsed time.Duration
want string
}{
{90 * time.Second, "2 minutes ago"},
{150 * time.Second, "2 minutes ago"},
{89 * time.Second, "1 minute ago"},
{90 * time.Minute, "2 hours ago"},
{90 * time.Hour, "4 days ago"},
} {
if got := relativeTime(now.Add(-test.elapsed), now); got != test.want {
t.Fatalf("relativeTime(%s) = %q, want %q", test.elapsed, got, test.want)
}
}
}