// Copyright (c) 2026 Storm Dragon // Authors: Storm Dragon, Angus Kola // SPDX-License-Identifier: GPL-3.0-or-later package app import ( "sync/atomic" "testing" "git.stormux.org/storm/cthulhu/internal/input" ) type uiOutputRecorder struct { messages []speechRequest interrupts atomic.Int32 } func (output *uiOutputRecorder) Enqueue(request speechRequest) { output.messages = append(output.messages, request) } func (output *uiOutputRecorder) Interrupt() { output.interrupts.Add(1) } func TestInternalUISuppressesApplicationOutputAndInputInterruption(t *testing.T) { keys := &uiTestKeys{} keys.session.Store(1) output := &uiOutputRecorder{} speaker := gatedSpeech{speech: output, gate: &focusGate{internalUI: keys}} speaker.Enqueue(speechRequest{Text: "Application event", Cause: "focus"}) speaker.Interrupt() if speaker.InterruptForInput(input.Event{}) || len(output.messages) != 0 || output.interrupts.Load() != 0 { t.Fatal("application output interrupted internal UI") } speaker.InterruptInternalUI() speaker.Enqueue(speechRequest{Text: "Choice", Cause: "internal-ui"}) if len(output.messages) != 1 || output.interrupts.Load() != 1 { t.Fatal("internal UI output was suppressed") } keys.session.Store(0) speaker.Enqueue(speechRequest{Text: "Application event", Cause: "focus"}) if len(output.messages) != 2 { t.Fatal("normal presentation did not resume") } }