Add opt-in Tentacle protocol 1.1, explicit remote grants, lifecycle IPC and expiring core leases in both SDKs. Revoke access before update preparation, including failed updates. Add transient secret entries, shared Braille cell export and isolated Xorg recovery experiments with focused tests and documented limitations. Production consent, desktop services and live interoperability remain pending.
79 lines
3.6 KiB
Go
79 lines
3.6 KiB
Go
package tentaclewire
|
|
|
|
import (
|
|
"encoding/json"
|
|
"git.stormux.org/storm/cthulhu/internal/interaction"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestInteractionContract(t *testing.T) {
|
|
form := &interaction.Form{Title: "Wormhole menu", Elements: []interaction.Element{{ID: "choices", Label: "Options", Kind: interaction.List, Items: []interaction.Item{{ID: "send", Label: "Send focused item"}}}}}
|
|
for _, value := range []Interaction{
|
|
{Form: form, Next: "choice"}, {Form: form, Next: "choice", Poll: "status"}, {Source: "focus", Next: "send"}, {Source: "clipboard", Next: "send"},
|
|
{Presentation: Presentation{Speech: "Ready"}, Done: true}, {Done: true}, {},
|
|
} {
|
|
data, _ := json.Marshal(value)
|
|
if _, err := DecodeInteraction(data); err != nil {
|
|
t.Fatalf("%s: %v", data, err)
|
|
}
|
|
}
|
|
for _, raw := range []string{`null`, ` null `, `{"form":null}`, `{"clipboard":null}`, `{"unknown":true}`, `{"source":"desktop","next":"send"}`, `{"source":"focus"}`, `{"next":"send"}`, `{"poll":"status"}`, `{"speech":"bad\u0000"}`, `{"uninterruptible":true}`} {
|
|
if _, err := DecodeInteraction([]byte(raw)); err == nil {
|
|
t.Fatal("accepted", raw)
|
|
}
|
|
}
|
|
for _, value := range []Interaction{{Form: form}, {Form: form, Next: "choice", Done: true}, {Form: form, Next: "choice", Source: "focus"}} {
|
|
data, _ := json.Marshal(value)
|
|
if _, err := DecodeInteraction(data); err == nil {
|
|
t.Fatal("accepted", string(data))
|
|
}
|
|
}
|
|
copy := strings.Repeat("x", MaxPresentationBytes+1)
|
|
data, _ := json.Marshal(Interaction{Clipboard: ©})
|
|
if _, err := DecodeInteraction(data); err == nil {
|
|
t.Fatal("accepted oversized clipboard write")
|
|
}
|
|
form.Title = "Bad\x1btitle"
|
|
data, _ = json.Marshal(Interaction{Form: form, Next: "choice"})
|
|
if _, err := DecodeInteraction(data); err == nil {
|
|
t.Fatal("accepted control in title")
|
|
}
|
|
}
|
|
func TestInteractionGrantsRemainExplicit(t *testing.T) {
|
|
for _, apis := range [][]string{{"commands"}, {"commands", "presentation"}, {"commands", "presentation", "interaction"}} {
|
|
if !ValidAPIs(apis, apis) {
|
|
t.Fatal("rejected", apis)
|
|
}
|
|
}
|
|
for _, apis := range [][]string{{"commands", "interaction"}, {"commands", "presentation", "unknown"}, {"commands", "interaction", "presentation"}} {
|
|
if ValidAPIs(apis, apis) {
|
|
t.Fatal("accepted", apis)
|
|
}
|
|
}
|
|
if ValidAPIs([]string{"commands", "presentation", "interaction"}, []string{"commands", "presentation"}) {
|
|
t.Fatal("missing grant accepted")
|
|
}
|
|
}
|
|
|
|
func TestSecretInteractionContract(t *testing.T) {
|
|
base := `{"form":{"title":"Connection","elements":[{"id":"key","label":"Channel key","kind":2,%s}]},"next":"connect"}`
|
|
for _, flag := range []string{`"secret":true`, `"secret":false`} {
|
|
value, err := DecodeInteraction([]byte(strings.Replace(base, "%s", flag, 1)))
|
|
if err != nil || value.Form.Elements[0].Secret != (flag == `"secret":true`) {
|
|
t.Fatal("valid secret flag rejected or changed")
|
|
}
|
|
}
|
|
for _, flag := range []string{`"secret":null`, `"secret":1`, `"secret":"true"`, `"Secret":true`, `"secret":true,"secret":false`, `"secret":true,"Secret":false`, `"secret":true,"unknown":true`} {
|
|
if _, err := DecodeInteraction([]byte(strings.Replace(base, "%s", flag, 1))); err == nil {
|
|
t.Fatal("malformed secret flag accepted", flag)
|
|
}
|
|
}
|
|
page := PreferencePage{ID: "connection", Title: "Connection", Command: "connect",
|
|
Elements: []interaction.Element{{ID: "key", Label: "Channel key", Kind: interaction.Entry, Secret: true}},
|
|
Values: map[string]interaction.Value{"key": {Text: "fixture"}}}
|
|
if ValidateExtensions(Extensions{Pages: []PreferencePage{page}}) == nil || ValidatePageValues(page, page.Values) == nil {
|
|
t.Fatal("secret permitted in persistent page values")
|
|
}
|
|
}
|