feat: show no-WFB kiosk fallback only while video absent (#2)
Build Ground Station / build (push) Successful in 44s
Build Ground Station / build (push) Successful in 44s
This commit was merged in pull request #9.
This commit is contained in:
@@ -18,10 +18,15 @@ import (
|
||||
|
||||
// buildTarget selects the target-specific opener and template. Each target
|
||||
// owns its own backend and layouts; there is no shared global template.
|
||||
// buildTarget wires one shared video presence signal into both the opener
|
||||
// (which observes the video output lifecycle) and the fallback template
|
||||
// (which shows or hides itself from it).
|
||||
func buildTarget(name string) (display.Opener, display.Template, error) {
|
||||
switch name {
|
||||
case "x11":
|
||||
return display.X11Opener{}, display.NewStatusTemplate("Brak polaczenia WFB"), nil
|
||||
video := display.NewVideoPresence()
|
||||
return display.X11Opener{Video: video},
|
||||
display.NewFallbackTemplate(video, "Brak połączenia WFB"), nil
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("unknown display target %q (supported: x11)", name)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.piksar.eu/piotr/groundstation/internal/display"
|
||||
)
|
||||
|
||||
type recordingCanvas struct {
|
||||
width, height int
|
||||
lines []string
|
||||
clears, flushes int
|
||||
}
|
||||
|
||||
func (c *recordingCanvas) Size() (int, int) { return c.width, c.height }
|
||||
func (c *recordingCanvas) Clear() { c.clears++ }
|
||||
func (c *recordingCanvas) Text(_, _ int, message string) {
|
||||
c.lines = append(c.lines, message)
|
||||
}
|
||||
func (c *recordingCanvas) Flush() { c.flushes++ }
|
||||
|
||||
func TestBuildTargetWiresSharedVideoPresenceToFallback(t *testing.T) {
|
||||
opener, template, err := buildTarget("x11")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
x11, ok := opener.(display.X11Opener)
|
||||
if !ok {
|
||||
t.Fatalf("opener %T must be the X11 target", opener)
|
||||
}
|
||||
if x11.Video == nil {
|
||||
t.Fatal("x11 opener must observe the video presence signal")
|
||||
}
|
||||
|
||||
canvas := &recordingCanvas{width: 800, height: 600}
|
||||
template.Draw(canvas)
|
||||
if len(canvas.lines) != 1 || canvas.lines[0] != "Brak połączenia WFB" {
|
||||
t.Fatalf("lines=%q want the exact fallback text", canvas.lines)
|
||||
}
|
||||
|
||||
// The opener and the template must share one presence signal so the
|
||||
// video lifecycle observed by the session drives the fallback.
|
||||
x11.Video.SetActive(true)
|
||||
canvas.lines = nil
|
||||
template.Draw(canvas)
|
||||
if len(canvas.lines) != 0 {
|
||||
t.Fatalf("lines=%q must disappear while video is present", canvas.lines)
|
||||
}
|
||||
|
||||
x11.Video.SetActive(false)
|
||||
canvas.lines = nil
|
||||
template.Draw(canvas)
|
||||
if len(canvas.lines) != 1 || canvas.lines[0] != "Brak połączenia WFB" {
|
||||
t.Fatalf("lines=%q want the fallback back after video end", canvas.lines)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildTargetRejectsUnknownTarget(t *testing.T) {
|
||||
if _, _, err := buildTarget("hdmi-mirror"); err == nil {
|
||||
t.Fatal("unknown target must fail")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user