127 lines
4.8 KiB
Go
127 lines
4.8 KiB
Go
package api
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/ponzischeme89/memby/server/internal/appupdate"
|
|
"github.com/ponzischeme89/memby/server/internal/sonarr"
|
|
"github.com/ponzischeme89/memby/server/internal/store"
|
|
)
|
|
|
|
func TestFilterClientAlertsByCategory(t *testing.T) {
|
|
prefs := store.DefaultNotificationPreferences()
|
|
prefs.SonarrAlerts = false
|
|
prefs.LibraryAlerts = false
|
|
alerts := []clientAlert{
|
|
{ID: "sonarr", Kind: alertKindSonarrAired},
|
|
{ID: "radarr", Kind: alertKindRadarrImport},
|
|
{ID: "library", Kind: alertKindLibrarySync},
|
|
{ID: "system", Kind: alertKindServerDown},
|
|
}
|
|
|
|
filtered := filterClientAlerts(alerts, prefs)
|
|
if len(filtered) != 2 || filtered[0].ID != "radarr" || filtered[1].ID != "system" {
|
|
t.Fatalf("filtered alerts = %#v", filtered)
|
|
}
|
|
}
|
|
|
|
func TestFilterClientAlertsMasterSwitch(t *testing.T) {
|
|
prefs := store.DefaultNotificationPreferences()
|
|
prefs.Enabled = false
|
|
if got := filterClientAlerts([]clientAlert{{ID: "one", Kind: alertKindRadarrImport}}, prefs); len(got) != 0 {
|
|
t.Fatalf("master switch returned %#v", got)
|
|
}
|
|
}
|
|
|
|
func TestFilterStoredSonarrNotifications(t *testing.T) {
|
|
prefs := store.DefaultNotificationPreferences()
|
|
prefs.SonarrAlerts = false
|
|
notifications := []store.UserNotification{
|
|
{ID: 1, Kind: "show-return"},
|
|
{ID: 2, Kind: "future-category"},
|
|
}
|
|
filtered := filterStoredNotifications(notifications, prefs)
|
|
if len(filtered) != 1 || filtered[0].ID != 2 {
|
|
t.Fatalf("filtered notifications = %#v", filtered)
|
|
}
|
|
}
|
|
|
|
func TestUpdatePreferenceNeverSuppressesMandatoryUpdate(t *testing.T) {
|
|
mandatory := appupdate.Decision{Status: appupdate.StatusMandatory, Version: "2.0.0"}
|
|
if got := updateDecisionForPreferences(mandatory, false); got.Status != appupdate.StatusMandatory {
|
|
t.Fatalf("mandatory update was suppressed: %#v", got)
|
|
}
|
|
optional := appupdate.Decision{Status: appupdate.StatusOptional, Version: "2.0.0"}
|
|
if got := updateDecisionForPreferences(optional, false); got.Status != appupdate.StatusNone {
|
|
t.Fatalf("optional update was not suppressed: %#v", got)
|
|
}
|
|
}
|
|
|
|
// A clear-all press aimed at the alerts on screen must never reach past them. The one case
|
|
// that can differ is a kind the viewer's own preferences have withdrawn: it is still a row
|
|
// in the table, it is not in their list, and clearing it would be this shortcut deciding
|
|
// something the viewer never saw.
|
|
func TestClearableNotificationIDsHonourPreferences(t *testing.T) {
|
|
notifications := []store.UserNotification{
|
|
{ID: 1, Kind: "show-return"},
|
|
{ID: 2, Kind: watchTimeWeeklyKind},
|
|
{ID: 3, Kind: "library-added"},
|
|
}
|
|
prefs := store.DefaultNotificationPreferences()
|
|
prefs.WatchTimeDigest = false
|
|
ids := clearableNotificationIDs(notifications, prefs)
|
|
if len(ids) != 2 || ids[0] != 1 || ids[1] != 3 {
|
|
t.Fatalf("expected the two visible rows, got %v", ids)
|
|
}
|
|
|
|
prefs.Enabled = false
|
|
if ids := clearableNotificationIDs(notifications, prefs); len(ids) != 0 {
|
|
t.Fatalf("notifications switched off should clear nothing, got %v", ids)
|
|
}
|
|
if ids := clearableNotificationIDs(nil, store.DefaultNotificationPreferences()); len(ids) != 0 {
|
|
t.Fatalf("an empty list should clear nothing, got %v", ids)
|
|
}
|
|
}
|
|
|
|
func TestNotificationResponsesShowRemoveMyShowsActionOnlyForCurrentFollow(t *testing.T) {
|
|
shows := []store.UserShow{
|
|
{ItemID: "emby-1", Title: "The Peripheral", Year: intPtr(2022)},
|
|
{ItemID: "emby-2", Title: "Shogun", Year: intPtr(2024)},
|
|
}
|
|
series := []sonarr.Series{
|
|
{ID: 10, TVDBID: 123, Title: "The Peripheral", Year: 2022},
|
|
{ID: 11, TVDBID: 456, Title: "Shogun", Year: 2024},
|
|
}
|
|
notifications := []store.UserNotification{
|
|
{ID: 1, Kind: "show-cancelled", SourceKey: "show-cancelled:tvdb:123:9", Title: "The Peripheral - Cancelled"},
|
|
{ID: 2, Kind: "show-cancelled", SourceKey: "show-cancelled:tvdb:999:8", Title: "Unknown Show - Cancelled"},
|
|
{ID: 3, Kind: "show-return", SourceKey: "show-return:emby-2:2026-08-27", Title: "Shogun returns"},
|
|
}
|
|
|
|
got := notificationResponses(notifications, shows, series)
|
|
if got[0].Action == nil {
|
|
t.Fatalf("cancelled followed show should offer an action: %#v", got[0])
|
|
}
|
|
if got[0].Action.Kind != "remove-my-show" || got[0].Action.Label != "Remove from My Shows" {
|
|
t.Fatalf("unexpected action = %#v", got[0].Action)
|
|
}
|
|
if got[0].ItemID != "emby-1" {
|
|
t.Fatalf("cancelled followed show item = %q, want emby-1", got[0].ItemID)
|
|
}
|
|
if got[1].Action != nil {
|
|
t.Fatalf("unfollowed cancelled show should not offer an action: %#v", got[1])
|
|
}
|
|
if got[2].Action != nil {
|
|
t.Fatalf("non-cancelled notification should not offer an action: %#v", got[2])
|
|
}
|
|
}
|
|
|
|
func TestCancelledNotificationCopy(t *testing.T) {
|
|
if got := cancelledNotificationTitle("The Peripheral"); got != "The Peripheral - Cancelled" {
|
|
t.Fatalf("title = %q", got)
|
|
}
|
|
if got := cancelledNotificationBody("The Peripheral"); got != "The Peripheral has been cancelled by the network." {
|
|
t.Fatalf("body = %q", got)
|
|
}
|
|
}
|