Files
cthulhu/internal/app/internal_ui_secret_test.go
ak47 573d15d7b4 Add Remote session foundations and feasibility checks
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.
2026-11-03 22:33:26 -05:00

94 lines
3.3 KiB
Go

// Copyright (c) 2026 Storm Dragon
// Authors: Storm Dragon, Angus Kola
// SPDX-License-Identifier: GPL-3.0-or-later
package app
import (
"context"
"errors"
"testing"
"time"
"git.stormux.org/storm/cthulhu/internal/braille"
"git.stormux.org/storm/cthulhu/internal/input"
"git.stormux.org/storm/cthulhu/internal/interaction"
)
type secretTestKeys struct {
uiTestKeys
failClose bool
}
func (keys *secretTestKeys) EndInternalUI(ctx context.Context, id uint64) error {
keys.uiTestKeys.EndInternalUI(ctx, id)
if keys.failClose {
return errors.New("fixture capture close failed")
}
return nil
}
func TestInternalUISecretOutputAndLifetime(t *testing.T) {
for _, ending := range []string{"submit", "escape", "revoke", "cancel", "close-error"} {
t.Run(ending, func(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
keys := &secretTestKeys{failClose: ending == "close-error"}
output := &ocrTestOutput{speech: make(chan speechRequest, 16)}
display := &brailleWorker{wake: make(chan struct{}, 1), cancel: func() {}, connected: true}
display.EnqueueFrame(braille.Frame{Text: "Application"})
ui := &internalUI{keys: keys, speech: output, braille: display, gate: &focusGate{}, events: make(chan input.CommandEvent, 16), requests: make(chan internalUIRequest, 1), done: make(chan struct{})}
go ui.run(ctx)
defer func() { cancel(); <-ui.done }()
formCtx, closeForm := context.WithCancel(ctx)
defer closeForm()
result, err := ui.Open(formCtx, interaction.Form{Title: "Connection", Elements: []interaction.Element{
{ID: "key", Label: "Channel key", Kind: interaction.Entry, Secret: true},
}})
if err != nil {
t.Fatal(err)
}
waitSpeech := func(want string) {
t.Helper()
select {
case got := <-output.speech:
if got.Text != want || got.Cause != "internal-ui" {
t.Fatal("unexpected secret field output")
}
case <-ctx.Done():
t.Fatal("secret field output timed out")
}
}
waitSpeech("Connection. Channel key, password edit, 0 characters")
ui.Handle(input.CommandEvent{Command: input.InternalUIKey, UISession: 1, Text: "fixture猫"})
waitSpeech("Inserted 8 characters")
waitTentacle(t, func() bool { return display.current().Text == "Channel key, password edit: ********" })
switch ending {
case "submit", "close-error":
ui.Handle(input.CommandEvent{Command: input.InternalUIKey, UISession: 1, Chord: input.CommandChord{Symbol: 0xff0d}})
case "escape":
ui.Handle(input.CommandEvent{Command: input.InternalUIKey, UISession: 1, Chord: input.CommandChord{Symbol: 0xff1b}})
case "revoke":
keys.session.Store(0)
case "cancel":
closeForm()
}
select {
case got := <-result:
if ending == "submit" {
if got.Err != nil || got.Cancelled || got.Activated != "key" || got.Values["key"].Text != "fixture猫" {
t.Fatal("secret not delivered on successful submission")
}
} else if got.Values != nil || got.Activated != "" || !got.Cancelled && got.Err == nil {
t.Fatal("failed or cancelled form delivered secret values")
}
case <-ctx.Done():
t.Fatal("secret form did not close")
}
if keys.InternalUISession() != 0 || display.current().Text != "Application" {
t.Fatal("secret form did not restore local input and Braille")
}
})
}
}