package policy import ( "testing" "ai-operator/internal/dialogue/state" "ai-operator/internal/tools" ) func TestToolPolicyAndGuardrail(t *testing.T) { cases := []struct { name string session state.ConversationSession tool string allowed bool reason string }{ {"search call started", state.ConversationSession{State: state.StateCallStarted}, tools.SearchKnowledgeBase, true, "ok"}, {"search language selection", state.ConversationSession{State: state.StateLanguageSelection}, tools.SearchKnowledgeBase, true, "ok"}, {"set language allowed", state.ConversationSession{State: state.StateLanguageSelection}, tools.SetLanguage, true, "ok"}, {"search region selection", state.ConversationSession{State: state.StateRegionSelection, Language: state.LanguageRU}, tools.SearchKnowledgeBase, true, "ok"}, {"set region allowed", state.ConversationSession{State: state.StateRegionSelection, Language: state.LanguageRU}, tools.SetRegion, true, "ok"}, {"search ready", state.ConversationSession{State: state.StateReadyToHelp, Language: state.LanguageRU, Region: state.RegionSelection{Code: "global", Status: state.RegionSelected}}, tools.SearchKnowledgeBase, true, "ok"}, {"search ended", state.ConversationSession{State: state.StateEnded, Language: state.LanguageRU, Region: state.RegionSelection{Code: "global", Status: state.RegionSelected}}, tools.SearchKnowledgeBase, false, "call_ended"}, {"unknown", state.ConversationSession{State: state.StateReadyToHelp}, "bad_tool", false, "unknown_tool"}, {"handoff non-ended", state.ConversationSession{State: state.StateRegionSelection}, tools.RequestHumanHandoff, true, "ok"}, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { got := AuthorizeTool(tc.session, tc.tool) if got.Allowed != tc.allowed || got.ReasonCode != tc.reason { t.Fatalf("decision=%+v", got) } }) } } func TestHardGuardrail(t *testing.T) { base := state.ConversationSession{State: state.StateReadyToHelp} if !AuthorizeTool(base, tools.SearchKnowledgeBase).Allowed { t.Fatal("search denied without explicit language") } base.Language = state.LanguageRU if !AuthorizeTool(base, tools.SearchKnowledgeBase).Allowed { t.Fatal("search denied without region") } base.Region = state.RegionSelection{Code: "almaty_city", Status: state.RegionSelected} if !AuthorizeTool(base, tools.SearchKnowledgeBase).Allowed { t.Fatal("search denied after language and region") } base.State = state.StateQuestionAnswering if !AuthorizeTool(base, tools.SearchKnowledgeBase).Allowed { t.Fatal("search denied in question answering") } }