Files
ai-operator/internal/dialogue/state/machine_test.go
T

60 lines
2.2 KiB
Go

package state
import "testing"
func TestValidTransitions(t *testing.T) {
m := NewMachine(ConversationSession{CallID: "c"})
steps := []ConversationEvent{
{Type: EventCallStarted},
{Type: EventGreetingPlayed},
{Type: EventLanguageSelected, Language: LanguageRU},
{Type: EventRegionSelected, Region: RegionSelection{Code: "almaty_city", Status: RegionSelected}},
{Type: EventQuestionReceived, Question: "q"},
{Type: EventAnswerCompleted},
{Type: EventHandoffRequested},
{Type: EventCallEnded},
}
want := []ConversationState{StateGreeting, StateReadyToHelp, StateReadyToHelp, StateReadyToHelp, StateQuestionAnswering, StateReadyToHelp, StateHandoff, StateEnded}
for i, step := range steps {
res, err := m.Apply(step)
if err != nil {
t.Fatalf("step %d: %v", i, err)
}
if res.To != want[i] {
t.Fatalf("step %d state=%s want=%s", i, res.To, want[i])
}
}
if len(m.Session().TransitionHistory) != len(steps) {
t.Fatalf("transition history length mismatch")
}
}
func TestInvalidTransitionsDoNotMutate(t *testing.T) {
m := NewMachine(ConversationSession{CallID: "c"})
if _, err := m.Apply(ConversationEvent{Type: EventQuestionReceived}); err == nil {
t.Fatal("expected invalid transition")
}
if m.CurrentState() != StateCallStarted {
t.Fatalf("state mutated to %s", m.CurrentState())
}
_, _ = m.Apply(ConversationEvent{Type: EventCallEnded})
if _, err := m.Apply(ConversationEvent{Type: EventLanguageSelected, Language: LanguageRU}); err == nil {
t.Fatal("expected ended state error")
}
if m.CurrentState() != StateEnded {
t.Fatalf("ended state mutated to %s", m.CurrentState())
}
}
func TestQuestionAllowedWithoutExplicitLanguageAndRegion(t *testing.T) {
m := NewMachine(ConversationSession{CallID: "c", State: StateRegionSelection, Language: LanguageRU})
if _, err := m.Apply(ConversationEvent{Type: EventQuestionReceived}); err == nil {
t.Fatal("region selection state should not answer directly")
}
m = NewMachine(ConversationSession{CallID: "c", State: StateReadyToHelp, Region: RegionSelection{Code: "almaty_city", Status: RegionSelected}})
if _, err := m.Apply(ConversationEvent{Type: EventQuestionReceived}); err == nil {
return
}
t.Fatal("question should be allowed without explicit language")
}