using Admin.NET.Plugin.AiDOP.ChatBI; using Xunit; namespace Admin.NET.Plugin.AiDOP.Tests.ChatBI; public class ChatBIQuestionMatchTests { [Theory] [InlineData("物料交货满足率(%)", "物料交货满足率")] [InlineData("订单评审周期(天)", "订单评审周期")] [InlineData("主计划人数(行/人)", "主计划人数")] public void NormalizeMetricLabel_StripsUnitSuffix(string raw, string expected) { Assert.Equal(expected, ChatBIService.NormalizeMetricLabel(raw)); } [Fact] public void NamedQuestion_MatchesDeliveryRate_NotOrderReview() { const string question = "物料交货满足率什么情况"; Assert.Contains(ChatBIService.NormalizeMetricLabel("物料交货满足率(%)"), question); Assert.DoesNotContain(ChatBIService.NormalizeMetricLabel("订单评审周期(天)"), question); Assert.DoesNotContain(ChatBIService.NormalizeMetricLabel("订单评审满足率(%)"), question); } [Theory] [InlineData("整体做的最好的是哪个", null, "best_metric")] [InlineData("谁做得最好", "S4", "best_metric")] [InlineData("物料交货满足率什么情况", "S4", "unrecognized")] [InlineData("今天天气怎么样", null, "unrecognized")] [InlineData("老板是谁", "S1", "unrecognized")] [InlineData("当前最严重的问题是什么", null, "global_bottleneck")] [InlineData("哪些模块出现红灯指标?", null, "global_bottleneck")] [InlineData("订单评审周期为什么红了", "S1", "root_cause")] [InlineData("当前九宫格看板显示的物料计划满足率是来自哪些订单的数据计算出来的?", null, "data_query")] [InlineData("物料计划满足率怎么算的", "S3", "data_query")] [InlineData("下一步应该创建什么改善计划?", null, "improvement_plan")] public void ClassifyIntent_FollowsQuestion(string question, string? module, string expected) { Assert.Equal(expected, ChatBIService.ClassifyIntent(question, module)); } [Theory] [InlineData("data_query", "物料计划满足率是来自哪些订单的数据计算出来的?", "data_query")] [InlineData("data_query", "物料交货满足率什么情况", "data_query")] [InlineData("compare", "整体做的最好的是哪个", "best_metric")] [InlineData("compare", "当前最差的是哪个", "global_bottleneck")] [InlineData("locate", "当前最严重的问题是什么", "global_bottleneck")] [InlineData("diagnose", "订单评审周期为什么红了", "root_cause")] [InlineData("diagnose", "下一步应该创建什么改善计划?", "improvement_plan")] [InlineData("unrecognized", "今天天气怎么样", "unrecognized")] public void MapLlmTypeToIntent_MapsFourQuestionTypes(string type, string question, string expected) { Assert.Equal(expected, ChatBIService.MapLlmTypeToIntent(type, question)); } [Fact] public void ParseLlmClassification_ReadsJsonAndIgnoresFence() { var parsed = ChatBIService.ParseLlmClassification(""" ```json {"type":"data_query","metricHint":"物料计划满足率"} ``` """); Assert.NotNull(parsed); Assert.Equal("data_query", parsed!.Type); Assert.Equal("物料计划满足率", parsed.MetricHint); } [Fact] public void ParseLlmClassification_RejectsUnknownType() { Assert.Null(ChatBIService.ParseLlmClassification("""{"type":"sql","metricHint":""}""")); } [Fact] public void SelectBestMetrics_PrefersGreenOverRed() { var cards = new List { new() { MetricCode = "RED", MetricName = "订单评审周期", StatusColor = "red", CurrentValue = 69, TargetValue = 3, Direction = "lower_is_better", MetricLevel = 1 }, new() { MetricCode = "GREEN", MetricName = "库存周转", StatusColor = "green", CurrentValue = 98, TargetValue = 90, Direction = "higher_is_better", MetricLevel = 1 }, }; var best = ChatBIService.SelectBestMetrics(cards); Assert.Equal("GREEN", best[0].MetricCode); } }