124 lines
5.0 KiB
Go
124 lines
5.0 KiB
Go
// Copyright (c) 2026 Storm Dragon
|
|
// Authors: Storm Dragon, Angus Kola
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
package webscripts
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestSteamNotificationMatchingAndRoot(t *testing.T) {
|
|
message := &Notification{BusName: ":1.42", RootPath: "/toast", Text: "Username is now online"}
|
|
for _, process := range []string{"Chromium", "chromium", "brave", "", "steamwebhelper.exe"} {
|
|
if HandlesNotification(process, "object:text-changed:insert", 0, message) {
|
|
t.Fatalf("enabled Steam for %q", process)
|
|
}
|
|
}
|
|
for _, event := range []struct {
|
|
typeName string
|
|
detail int
|
|
want bool
|
|
}{
|
|
{"object:text-changed:insert", 0, true},
|
|
{"object:children-changed:add", 0, true},
|
|
{"object:state-changed:showing", 1, true},
|
|
{"object:state-changed:showing", 0, false},
|
|
{"object:state-changed:focused", 1, false},
|
|
} {
|
|
if got := HandlesNotification("steamwebhelper", event.typeName, event.detail, message); got != event.want {
|
|
t.Fatalf("%s/%d: %t", event.typeName, event.detail, got)
|
|
}
|
|
}
|
|
candidates := []NotificationCandidate{{ContainerLive: "assertive"}, {Role: "alert"}}
|
|
if index := NotificationRoot(candidates); index != 1 {
|
|
t.Fatalf("selected live leaf instead of alert ancestor: %d", index)
|
|
}
|
|
if index := NotificationRoot([]NotificationCandidate{{Live: "off"}, {Live: "polite"}}); index != 1 {
|
|
t.Fatalf("live root = %d", index)
|
|
}
|
|
if index := NotificationRoot([]NotificationCandidate{{Live: "off"}}); index != -1 {
|
|
t.Fatalf("non-live root = %d", index)
|
|
}
|
|
}
|
|
|
|
func TestSteamNotificationCoalescing(t *testing.T) {
|
|
for _, test := range []struct {
|
|
name string
|
|
fragments []string
|
|
want []string
|
|
}{
|
|
{"fragments", []string{" Username ", "Playing: Example Game"}, []string{"Steam: Username Playing: Example Game"}},
|
|
{"timestamp after", []string{"Username is now online", "2 minutes ago"}, []string{"Steam: Username is now online. 2 minutes ago"}},
|
|
{"timestamp before", []string{"2 minutes ago", "Username is now online"}, []string{"Steam: Username is now online. 2 minutes ago"}},
|
|
{"complete replaces fragment", []string{"Username", "Username is now online", "Username"}, []string{"Steam: Username is now online"}},
|
|
{"repeated complete", []string{"Username is now online", "Username is now online"}, []string{"Steam: Username is now online"}},
|
|
{"timestamp only", []string{"just now"}, nil},
|
|
{"empty", []string{"", " \ufffc "}, nil},
|
|
} {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
var registry Registry
|
|
now := time.Unix(100, 0)
|
|
for _, text := range test.fragments {
|
|
messages, handled := registry.Receive("steamwebhelper", "object:text-changed:insert", 0,
|
|
&Notification{BusName: ":1.42", RootPath: "/toast", Text: text}, now)
|
|
if !handled || len(messages) != 0 {
|
|
t.Fatalf("fragment presented early: %q, handled %t", messages, handled)
|
|
}
|
|
}
|
|
if got := registry.Flush(now.Add(499 * time.Millisecond)); len(got) != 0 {
|
|
t.Fatalf("presented before deadline: %q", got)
|
|
}
|
|
if got := registry.Flush(now.Add(500 * time.Millisecond)); !reflect.DeepEqual(got, test.want) {
|
|
t.Fatalf("messages = %q, want %q", got, test.want)
|
|
}
|
|
if !registry.Deadline().IsZero() {
|
|
t.Fatal("completed timer still armed")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSteamNotificationDeduplicationAndOwnership(t *testing.T) {
|
|
var registry Registry
|
|
now := time.Unix(100, 0)
|
|
queue := func(bus, root, text string, at time.Time) {
|
|
registry.Receive("steamwebhelper", "object:text-changed:insert", 0,
|
|
&Notification{BusName: bus, RootPath: root, Text: text, WindowPath: "/window"}, at)
|
|
}
|
|
queue(":1.42", "/first", "Username is now online", now)
|
|
if got := registry.Flush(now.Add(500 * time.Millisecond)); len(got) != 1 {
|
|
t.Fatalf("initial message: %q", got)
|
|
}
|
|
queue(":1.42", "/first", "Username is now online", now.Add(600*time.Millisecond))
|
|
if got := registry.Flush(now.Add(1100 * time.Millisecond)); len(got) != 0 {
|
|
t.Fatalf("duplicate within one second: %q", got)
|
|
}
|
|
queue(":1.42", "/first", "Username is now online", now.Add(time.Second))
|
|
if got := registry.Flush(now.Add(1500 * time.Millisecond)); len(got) != 1 {
|
|
t.Fatalf("new message after one second: %q", got)
|
|
}
|
|
queue(":1.42", "/first", "Username", now.Add(2*time.Second))
|
|
queue(":1.42", "/second", "Playing: Example Game", now.Add(2*time.Second))
|
|
queue(":1.43", "/first", "2 minutes ago", now.Add(2*time.Second))
|
|
if got := registry.Flush(now.Add(2500 * time.Millisecond)); !reflect.DeepEqual(got, []string{"Steam: Username", "Steam: Playing: Example Game"}) {
|
|
t.Fatalf("independent roots combined: %q", got)
|
|
}
|
|
queue(":1.42", "/first", "retired message", now.Add(3*time.Second))
|
|
registry.Retire(":1.43", "/window")
|
|
if registry.Deadline().IsZero() {
|
|
t.Fatal("other bus retired pending toast")
|
|
}
|
|
registry.Retire(":1.42", "/window")
|
|
if got := registry.Flush(now.Add(4 * time.Second)); len(got) != 0 {
|
|
t.Fatalf("destroyed window presented: %q", got)
|
|
}
|
|
queue(":1.42", "/first", "locked message", now)
|
|
registry.Reset()
|
|
if got := registry.Flush(now.Add(time.Second)); len(got) != 0 {
|
|
t.Fatalf("reset presented pending content: %q", got)
|
|
}
|
|
}
|