using Admin.NET.Plugin.AiDOP.Service.S8; using Xunit; namespace Admin.NET.Plugin.AiDOP.Tests.S8; /// /// S8NotificationLayerResolver 静态契约单元测试。 /// 实例方法 DispatchByLayerAsync 依赖 SqlSugarRepository + S8RoleResolver + S8NotificationPushAdapter, /// 在带 DB 的集成环境(dev DB seed: scene_code=S8_DEMO_DEFAULT/severity=HIGH/target=sys_admin/channel=SignalR)验证。 /// 本文件覆盖渠道解析契约 + 静态防御。 /// public class S8NotificationLayerResolverTests { [Fact] public void ParseChannels_NullOrEmpty_ReturnsEmpty() { Assert.Empty(S8NotificationLayerResolver.ParseChannels(null)); Assert.Empty(S8NotificationLayerResolver.ParseChannels("")); Assert.Empty(S8NotificationLayerResolver.ParseChannels(" ")); } [Fact] public void ParseChannels_Comma_TrimsAndSplits() { var r = S8NotificationLayerResolver.ParseChannels(" SignalR , Email , DingTalk "); Assert.Equal(new[] { "SignalR", "Email", "DingTalk" }, r); } [Fact] public void ParseChannels_Semicolon_AlsoSupported() { var r = S8NotificationLayerResolver.ParseChannels("Email;Sms;WorkWeixin"); Assert.Equal(new[] { "Email", "Sms", "WorkWeixin" }, r); } [Fact] public void ParseChannels_Mixed_DropsEmpty() { var r = S8NotificationLayerResolver.ParseChannels("SignalR,;Email,,Sms"); Assert.Equal(new[] { "SignalR", "Email", "Sms" }, r); } [Fact] public void DispatchByLayerInput_DefaultsAreSafe() { var x = new S8NotificationLayerResolver.DispatchByLayerInput(); Assert.Equal(string.Empty, x.SceneCode); Assert.Equal(string.Empty, x.Severity); Assert.Equal(string.Empty, x.Title); Assert.Equal(string.Empty, x.Content); Assert.Null(x.ExceptionId); Assert.Null(x.ExceptionNo); Assert.Null(x.JumpUrl); Assert.False(x.Recovered); } [Fact] public void DispatchByLayerInput_RecoveredFlag_Settable() { var x = new S8NotificationLayerResolver.DispatchByLayerInput { Recovered = true }; Assert.True(x.Recovered); } /// /// 验证 recovered 字段在 payload summary 中的布尔解析契约: /// Context["recovered"]="true"(大小写不敏感)→ true;其余 → false。 /// [Theory] [InlineData("true", true)] [InlineData("True", true)] [InlineData("TRUE", true)] [InlineData("false", false)] [InlineData("", false)] [InlineData(null, false)] public void RecoveredContextValue_ParsesCorrectly(string? raw, bool expected) { var result = "true".Equals(raw, StringComparison.OrdinalIgnoreCase); Assert.Equal(expected, result); } }