diff options
Diffstat (limited to 'internal/notify/store_test.go')
| -rw-r--r-- | internal/notify/store_test.go | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/internal/notify/store_test.go b/internal/notify/store_test.go new file mode 100644 index 0000000..4e4dd79 --- /dev/null +++ b/internal/notify/store_test.go @@ -0,0 +1,126 @@ +// Copyright (C) 2026 Danilo M. <danix@danix.xyz> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +package notify + +import "testing" + +type event struct { + id uint32 + reason uint32 +} + +func newTestStore() (*Store, *[]event) { + emitted := &[]event{} + s := NewStore( + func(id, reason uint32) { *emitted = append(*emitted, event{id, reason}) }, + func(live, history []Popup) {}, + ) + return s, emitted +} + +func popup(app string) *Popup { + return &Popup{App: app, Urgency: Normal, Created: 1} +} + +func TestAddAssignsIdsFromOne(t *testing.T) { + s, _ := newTestStore() + a, replaced := s.Add(popup("a"), "", 0) + b, _ := s.Add(popup("b"), "", 0) + if replaced { + t.Fatal("first add reported replaced") + } + if a != 1 || b != 2 { + t.Errorf("ids = %d, %d, want 1, 2", a, b) + } +} + +func TestReplaceByIDReusesTheIDAndEmitsNothing(t *testing.T) { + s, emitted := newTestStore() + id, _ := s.Add(popup("a"), "", 0) + *emitted = nil + again, replaced := s.Add(popup("a2"), "", id) + if !replaced { + t.Fatal("replace by id not reported") + } + if again != id { + t.Errorf("replace id = %d, want %d", again, id) + } + if len(*emitted) != 0 { + t.Errorf("replace emitted %v, want none", *emitted) + } +} + +func TestReplaceByStackTag(t *testing.T) { + s, _ := newTestStore() + first, _ := s.Add(popup("mail"), "mail-account", 0) + second, replaced := s.Add(popup("mail"), "mail-account", 0) + if !replaced || second != first { + t.Errorf("stack replace = id %d replaced %v, want id %d replaced true", second, replaced, first) + } +} + +func TestExpireClosesOnceAndKeepsTheEntry(t *testing.T) { + s, emitted := newTestStore() + id, _ := s.Add(popup("a"), "", 0) + s.Expire(id) + s.Expire(id) + if len(*emitted) != 1 || (*emitted)[0].reason != 1 { + t.Fatalf("emitted = %v, want one reason 1", *emitted) + } + if s.Actionable(id) { + t.Error("expired entry still actionable") + } +} + +func TestDismissFilesHistoryAndEmitsDismissed(t *testing.T) { + s, emitted := newTestStore() + id, _ := s.Add(popup("a"), "", 0) + s.Dismiss(id, 2) + if len(*emitted) != 1 || (*emitted)[0].reason != 2 { + t.Fatalf("emitted = %v, want one reason 2", *emitted) + } + if s.Actionable(id) { + t.Error("dismissed entry still live") + } +} + +func TestDismissAfterExpireEmitsNothingMore(t *testing.T) { + s, emitted := newTestStore() + id, _ := s.Add(popup("a"), "", 0) + s.Expire(id) + *emitted = nil + s.Dismiss(id, 2) + if len(*emitted) != 0 { + t.Errorf("dismiss after expire emitted %v, want none", *emitted) + } +} + +func TestQueueCapEvictsToHistory(t *testing.T) { + s, emitted := newTestStore() + for i := 0; i < 21; i++ { + s.Add(popup("a"), "", 0) + } + if len(*emitted) == 0 { + t.Fatal("eviction emitted nothing") + } +} + +func TestHistoryRingCapsAtTwenty(t *testing.T) { + s, _ := newTestStore() + for i := 0; i < 30; i++ { + id, _ := s.Add(popup("a"), "", 0) + s.Dismiss(id, 2) + } + if got := len(s.historySnapshot()); got != 20 { + t.Errorf("history length = %d, want 20", got) + } +} |
