| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- using Admin.NET.Plugin.AiDOP.Entity.S8;
- using Admin.NET.Plugin.AiDOP.Service.S8;
- using Admin.NET.Plugin.AiDOP.Service.S8.Rules;
- using Admin.NET.Plugin.AiDOP.Service.S8.Rules.DataAccess;
- using Xunit;
- namespace Admin.NET.Test.S8;
- /// <summary>
- /// 规则取数配置校验(T1–T4)。
- ///
- /// 分两级:
- /// · ValidateForSave —— dataset_code 结构 + 目录归属,不要求 Provider 已上线(允许存草稿);
- /// · ValidateForEnable —— 完整运行条件(委托 Enable Gate)。
- ///
- /// S8-STANDARD-DATASET-HARD-CUTOVER-1:原有的 Legacy 分组用例
- /// (mode=NULL 可保存 / 缺 expression 被拒 / 不得混填 dataset_code /
- /// RequiresDataSource / UnknownDataAccessMode)已全部删除 ——
- /// 它们校验的是"两种取数模式之间的边界",而现在只剩一种模式。
- /// 那些字段(DataAccessMode / Expression / DataSourceId)连同校验分支一并物理消失,
- /// 用例既写不出来、也无对应风险可守。
- /// </summary>
- public class S8WatchRuleDataAccessValidatorTests
- {
- private const string ReadyDataset = "FAKE_VALIDATOR_DATASET";
- private const string DefinedNoProvider = "FAKE_VALIDATOR_DATASET_NO_PROVIDER";
- private static S8DatasetCapabilities TimeoutCapable() => new()
- {
- SupportsTimeout = true,
- HasSourceObjectId = true,
- HasRelatedObjectCode = true,
- HasDueAt = true,
- HasStatus = true
- };
- private sealed class FakeSource : IS8DatasetDefinitionSource
- {
- public IEnumerable<S8DatasetDefinition> GetDefinitions() => new[]
- {
- new S8DatasetDefinition
- {
- DatasetCode = ReadyDataset,
- DisplayName = "校验测试数据集",
- Kind = S8DatasetKind.Object,
- Capabilities = TimeoutCapable()
- },
- new S8DatasetDefinition
- {
- DatasetCode = DefinedNoProvider,
- DisplayName = "已定义未实现数据集",
- Kind = S8DatasetKind.Object,
- Capabilities = TimeoutCapable()
- }
- };
- }
- private sealed class TimeoutOnlyProvider : IS8MonitoringDataProvider
- {
- public string DatasetCode => ReadyDataset;
- public S8DatasetCapabilities Capabilities => TimeoutCapable();
- public Task<S8MonitoringRowSet> LoadAsync(S8MonitoringDataRequest request, CancellationToken cancellationToken = default)
- => Task.FromResult(S8MonitoringRowSet.Empty);
- }
- private static S8DatasetCatalog Catalog() => new(new[] { new FakeSource() });
- private static S8DatasetEnableGate Gate() =>
- new(Catalog(), new S8MonitoringDataProviderRegistry(new[] { new TimeoutOnlyProvider() }));
- private static AdoS8WatchRule Rule(string ruleType, string datasetCode = null) => new()
- {
- RuleCode = "UT_RULE",
- RuleType = ruleType,
- DatasetCode = datasetCode
- };
- // ---------- T1 / T2 / T3:保存级 ----------
- [Fact]
- public void DatasetRule_WithoutDatasetCode_IsRejectedOnSave()
- {
- var ex = Assert.Throws<S8BizException>(() =>
- S8WatchRuleDataAccessValidator.ValidateForSave(
- Rule("TIMEOUT"), Catalog()));
- Assert.Contains(S8DatasetReasonCode.CodeMissing, ex.Message);
- }
- [Fact]
- public void DatasetRule_WithUndefinedDataset_IsRejectedOnSave()
- {
- var ex = Assert.Throws<S8BizException>(() =>
- S8WatchRuleDataAccessValidator.ValidateForSave(
- Rule("TIMEOUT", "NO_SUCH_DATASET"), Catalog()));
- Assert.Contains(S8DatasetReasonCode.NotDefined, ex.Message);
- }
- [Fact]
- public void DatasetRule_DefinedButProviderMissing_CanBeSavedAsDraft()
- {
- // 关键行为:Provider 未上线时仍可保存配置。
- S8WatchRuleDataAccessValidator.ValidateForSave(
- Rule("TIMEOUT", DefinedNoProvider), Catalog());
- }
- // ---------- T3 / T4:启用级 ----------
- [Fact]
- public void DatasetRule_DefinedButProviderMissing_CannotBeEnabled()
- {
- var ex = Assert.Throws<S8BizException>(() =>
- S8WatchRuleDataAccessValidator.ValidateForEnable(
- Rule("TIMEOUT", DefinedNoProvider),
- Gate(), 1, 1));
- Assert.Contains(S8DatasetReasonCode.ProviderNotRegistered, ex.Message);
- }
- [Fact]
- public void DatasetRule_WithCapabilityMismatch_CannotBeEnabled()
- {
- // TIMEOUT-only 数据集挂 OUT_OF_RANGE 规则。
- var ex = Assert.Throws<S8BizException>(() =>
- S8WatchRuleDataAccessValidator.ValidateForEnable(
- Rule("OUT_OF_RANGE", ReadyDataset),
- Gate(), 1, 1));
- Assert.Contains(S8DatasetReasonCode.CapabilityMismatch, ex.Message);
- }
- [Fact]
- public void DatasetRule_Matching_IsEnabled_WithoutAnySql()
- {
- // 标准数据集规则不需要用户填写任何 SQL。
- var rule = Rule("TIMEOUT", ReadyDataset);
- S8WatchRuleDataAccessValidator.ValidateForSave(rule, Catalog());
- S8WatchRuleDataAccessValidator.ValidateForEnable(rule, Gate(), 1, 1);
- }
- }
|