| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- using System.Reflection;
- using Microsoft.AspNetCore.Mvc;
- using Admin.NET.Plugin.AiDOP.Controllers.S8;
- using Admin.NET.Plugin.AiDOP.Entity.S8;
- using Admin.NET.Plugin.AiDOP.Service.S8;
- using Admin.NET.Plugin.AiDOP.Service.S8.Rules.DataAccess;
- using Xunit;
- namespace Admin.NET.Plugin.AiDOP.Tests.S8;
- /// <summary>
- /// S8-STANDARD-DATASET-HARD-CUTOVER-1:规则创建只认治理数据集。
- ///
- /// 本文件锁的是「创建链路上再也没有 SQL / 物理数据源的位置」,
- /// 与 <see cref="S8LegacySymbolsRemovedTests"/> 互补:那边证明类型不存在,
- /// 这边证明**残存的类型也不再提供入口**。
- /// </summary>
- public class S8DatasetOnlyRuleCreationTests
- {
- private static readonly Assembly PluginAssembly = typeof(AdoS8WatchRule).Assembly;
- // ============================================================
- // T7 / T8:向导与数据源入口
- // ============================================================
- /// <summary>
- /// T7:向导后端不得再持有任何生成 SQL 的能力。
- ///
- /// 这几个方法曾按 monitor_object.source_table + monitor_metric 字段映射拼 SELECT,
- /// 是 S8 最后一处「自己造 SQL 去读别人的业务表」。逐名断言而非只看行为,
- /// 是因为它们是 private —— 行为测试删掉一个分支就能变绿,名字还在就说明能力还在。
- /// </summary>
- [Theory]
- [InlineData("BuildExpression")]
- [InlineData("ValidateSqlIdentifier")]
- [InlineData("BuildSoftDeletePredicate")]
- public void ConfigDraftService_HasNoSqlGenerationCapability(string methodName)
- {
- Assert.Null(typeof(S8ConfigDraftService).GetMethod(
- methodName, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public));
- }
- /// <summary>向导服务不得再注入任何能提供物理数据源的依赖。</summary>
- [Fact]
- public void ConfigDraftService_HoldsNoDataSourceDependency()
- {
- var fieldTypes = typeof(S8ConfigDraftService)
- .GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
- .Select(f => f.FieldType.FullName ?? f.FieldType.Name)
- .ToArray();
- Assert.DoesNotContain(fieldTypes, t => t.Contains("AdoS8DataSource", StringComparison.Ordinal));
- Assert.DoesNotContain(fieldTypes, t => t.Contains("S8SqlSugarScopeFactory", StringComparison.Ordinal));
- // 正向:必须持有数据集目录,否则无从校验用户选的 dataset_code。
- Assert.Contains(fieldTypes, t => t.Contains("IS8DatasetCatalog", StringComparison.Ordinal));
- }
- /// <summary>T8:数据源 Controller / Service / Entity 三者都不存在。</summary>
- [Theory]
- [InlineData("Admin.NET.Plugin.AiDOP.Entity.S8.AdoS8DataSource")]
- [InlineData("Admin.NET.Plugin.AiDOP.Service.S8.S8DataSourceService")]
- [InlineData("Admin.NET.Plugin.AiDOP.Controllers.S8.AdoS8ConfigDataSourcesController")]
- [InlineData("Admin.NET.Plugin.AiDOP.Service.S8.Rules.S8DataSourceRowLoader")]
- [InlineData("Admin.NET.Plugin.AiDOP.Service.S8.Rules.S8SqlSugarScopeFactory")]
- [InlineData("Admin.NET.Plugin.AiDOP.Service.S8.Rules.DataAccess.S8LegacySqlDataProvider")]
- [InlineData("Admin.NET.Plugin.AiDOP.Service.S8.Rules.DataAccess.IS8LegacySqlDataProvider")]
- [InlineData("Admin.NET.Plugin.AiDOP.Service.S8.Rules.DataAccess.S8DataAccessMode")]
- [InlineData("Admin.NET.Plugin.AiDOP.Service.S8.Rules.DataAccess.S8RuleCreationPolicy")]
- [InlineData("Admin.NET.Plugin.AiDOP.Service.S8.Rules.DataAccess.S8RuleCreationOrigin")]
- public void LegacyDataAccessType_NoLongerExists(string fullName)
- {
- Assert.Null(PluginAssembly.GetType(fullName, throwOnError: false));
- }
- // ============================================================
- // 数据集目录端点
- // ============================================================
- /// <summary>
- /// 取代数据源端点的是一个**只读**目录。二者性质不同,不是改名:
- /// 旧的是租户可写的物理连接配置,新的是平台级只读目录。
- /// 因此本用例断言它一个写动作都没有。
- /// </summary>
- [Fact]
- public void DatasetsController_IsReadOnly()
- {
- var actions = typeof(AdoS8ConfigDatasetsController)
- .GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
- .ToArray();
- Assert.NotEmpty(actions);
- foreach (var m in actions)
- {
- Assert.Empty(m.GetCustomAttributes<HttpPostAttribute>());
- Assert.Empty(m.GetCustomAttributes<HttpPutAttribute>());
- Assert.Empty(m.GetCustomAttributes<HttpDeleteAttribute>());
- Assert.Empty(m.GetCustomAttributes<HttpPatchAttribute>());
- }
- }
- // ============================================================
- // T11:Rule 01 仍然合法
- // ============================================================
- /// <summary>
- /// T11:Rule 01 的配置形态在删掉三个 Legacy 列之后仍然完整可表达 ——
- /// 它本来就只依赖 dataset_code,这也是当初把它建成 STANDARD_DATASET 的意义。
- /// </summary>
- [Fact]
- public void Rule01Shape_RemainsExpressible_AfterLegacyColumnsRemoved()
- {
- var rule01 = new AdoS8WatchRule
- {
- Id = 1329909460023L,
- RuleCode = "RULE_S4_PURCHASE_DELIVERY_DATE_DELAY",
- TenantId = 838257186181189L,
- FactoryId = 838257186320453L,
- RuleType = "TIMEOUT",
- DatasetCode = "PURCHASE_DELIVERY",
- Enabled = false
- };
- Assert.Equal("PURCHASE_DELIVERY", rule01.DatasetCode);
- Assert.False(rule01.Enabled);
- // 保存级校验只看 dataset_code 是否在目录内 —— Rule 01 用的正是真实业务数据集定义。
- var catalog = new S8DatasetCatalog(new IS8DatasetDefinitionSource[]
- {
- new Admin.NET.Plugin.AiDOP.Service.S8.Rules.DataAccess.Providers.S8BusinessDatasetDefinitions()
- });
- S8WatchRuleDataAccessValidator.ValidateForSave(rule01, catalog);
- }
- }
|