aboutsummaryrefslogtreecommitdiffstats
path: root/internal/notify/image_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/notify/image_test.go')
-rw-r--r--internal/notify/image_test.go101
1 files changed, 101 insertions, 0 deletions
diff --git a/internal/notify/image_test.go b/internal/notify/image_test.go
new file mode 100644
index 0000000..2db4c75
--- /dev/null
+++ b/internal/notify/image_test.go
@@ -0,0 +1,101 @@
+// 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 (
+ "bytes"
+ "image/png"
+ "testing"
+
+ "github.com/godbus/dbus/v5"
+)
+
+// rawVariant builds the (iiibiiay) struct the bus delivers for image-data.
+func rawVariant(w, h, stride int, alpha bool, ch int, data []byte) dbus.Variant {
+ return dbus.MakeVariant([]interface{}{
+ int32(w), int32(h), int32(stride), alpha, int32(8), int32(ch), data,
+ })
+}
+
+func TestImageDataFromHints(t *testing.T) {
+ // 2x1 RGBA: red, green.
+ rgba := []byte{255, 0, 0, 255, 0, 255, 0, 255}
+ cases := []struct {
+ name string
+ hints map[string]dbus.Variant
+ wantW int
+ want bool
+ }{
+ {"image-data wins", map[string]dbus.Variant{
+ "image-data": rawVariant(2, 1, 8, true, 4, rgba),
+ "image-path": dbus.MakeVariant("/tmp/x.png"),
+ }, 2, true},
+ {"icon_data fallback", map[string]dbus.Variant{
+ "icon_data": rawVariant(2, 1, 8, true, 4, rgba),
+ }, 2, true},
+ {"image_data alias", map[string]dbus.Variant{
+ "image_data": rawVariant(2, 1, 8, true, 4, rgba),
+ }, 2, true},
+ {"absent", map[string]dbus.Variant{}, 0, false},
+ }
+ for _, c := range cases {
+ t.Run(c.name, func(t *testing.T) {
+ got, ok := ImageDataFromHints(c.hints)
+ if ok != c.want {
+ t.Fatalf("ok = %v, want %v", ok, c.want)
+ }
+ if ok && got.Width != c.wantW {
+ t.Fatalf("width = %d, want %d", got.Width, c.wantW)
+ }
+ })
+ }
+}
+
+func TestImagePathFromHints(t *testing.T) {
+ got, ok := ImagePathFromHints(map[string]dbus.Variant{"image-path": dbus.MakeVariant("/tmp/shot.png")})
+ if !ok || got != "/tmp/shot.png" {
+ t.Fatalf("got %q ok=%v", got, ok)
+ }
+ if _, ok := ImagePathFromHints(map[string]dbus.Variant{}); ok {
+ t.Fatal("empty hints must not report a path")
+ }
+}
+
+func TestRawImagePNG(t *testing.T) {
+ // 2x1 RGBA on a rowstride wider than the data, to prove stride is honoured.
+ r := &RawImage{Width: 2, Height: 1, RowStride: 12, HasAlpha: true, BitsPerSample: 8, Channels: 4,
+ Data: []byte{255, 0, 0, 255, 0, 255, 0, 255, 9, 9, 9, 9}}
+ data, err := r.PNG()
+ if err != nil {
+ t.Fatalf("PNG: %v", err)
+ }
+ img, err := png.Decode(bytes.NewReader(data))
+ if err != nil {
+ t.Fatalf("decode: %v", err)
+ }
+ if img.Bounds().Dx() != 2 || img.Bounds().Dy() != 1 {
+ t.Fatalf("bounds = %v", img.Bounds())
+ }
+ r0, g0, b0, a0 := img.At(0, 0).RGBA()
+ if r0>>8 != 255 || g0>>8 != 0 || b0>>8 != 0 || a0>>8 != 255 {
+ t.Fatalf("pixel 0 = %d %d %d %d", r0>>8, g0>>8, b0>>8, a0>>8)
+ }
+}
+
+func TestRawImagePNGRejectsBadData(t *testing.T) {
+ if _, err := (&RawImage{Width: 0, Height: 1, Channels: 4, BitsPerSample: 8}).PNG(); err == nil {
+ t.Fatal("zero width must error")
+ }
+ if _, err := (&RawImage{Width: 1, Height: 1, Channels: 2, BitsPerSample: 8}).PNG(); err == nil {
+ t.Fatal("channels 2 must error")
+ }
+}