package catalogue import ( "encoding/json" "reflect" "testing" ) // Defends novox/hq ADR 0208: the graphical session is one module per piece, on the mesh's seats. // ยง2: the eleven roles are the mesh's own node seats, each with the verbs it starts with. func TestTheGraphicalSessionsSeatsAreTheMeshsOwnWithTheirVerbs(t *testing.T) { want := map[string][]string{ LoginManagerSeat: {"sessions"}, DisplayServerSeat: {"displays", "layout"}, DisplaySessionSeat: {"reload", "workspaces", "windows"}, TerminalEmulatorSeat: {"open"}, LauncherSeat: {"menu", "secret"}, NotifierSeat: {"send", "history"}, LockScreenSeat: {"lock"}, ClipboardSeat: {"history", "copy"}, BarSeat: nil, CompositorSeat: nil, SecretServiceSeat: nil, } for name, verbs := range want { s, ok := SeatNamed(name) if !ok { t.Errorf("%s is not in the mesh's set", name) continue } if s.Scope != ScopeNode || s.Decision != "novox/hq ADR 0208" { t.Errorf("%s is %s-scoped under %q", name, s.Scope, s.Decision) } var got []string for _, v := range s.Serves { got = append(got, v.Name) if v.Description == "" || v.Input["type"] != "object" { t.Errorf("%s.%s has no description or no object schema", name, v.Name) } } if !reflect.DeepEqual(got, verbs) { t.Errorf("%s serves %v, want %v", name, got, verbs) } } // The launcher's menu takes a list, and the layout verb says its actions. menu, _ := SeatNamed(LauncherSeat) choices := menu.Serves[0].Input["properties"].(map[string]any)["choices"].(map[string]any) if choices["type"] != "array" { t.Errorf("menu's choices are %v, not a list", choices["type"]) } display, _ := SeatNamed(DisplayServerSeat) action := display.Serves[1].Input["properties"].(map[string]any)["action"].(map[string]any) if !reflect.DeepEqual(action["enum"], []string{"list", "save", "apply"}) { t.Errorf("layout's actions are %v", action["enum"]) } // And they survive the store's JSON, which is where the live set comes from. if _, err := json.Marshal(graphicalSessionSeats()); err != nil { t.Fatal(err) } }