| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- using Xunit;
- namespace Admin.NET.Plugin.AiDOP.Tests.S6.Manufacturing;
- /// <summary>
- /// S6 Phase 1B 源码契约测试:解析器 map-only + tenant-safe;生成服务 事务/幂等/快照/仅MATCHED写;前端无人工选择器。
- /// </summary>
- public class S6ProcessInspectionContractTests
- {
- private static string Resolver() => File.ReadAllText(FindFile("server", "Plugins", "Admin.NET.Plugin.AiDOP", "Manufacturing", "S6ProcessSpecResolver.cs"));
- private static string Service() => File.ReadAllText(FindFile("server", "Plugins", "Admin.NET.Plugin.AiDOP", "Manufacturing", "S6ProcessInspectionService.cs"));
- private static string Vue() => File.ReadAllText(FindFile("Web", "src", "views", "aidop", "s6", "production-record", "productionInstructionList.vue"));
- [Fact]
- public void Resolver_RuntimeReadsMapTable_TenantAndItemScoped()
- {
- var s = Resolver();
- Assert.Contains("FROM ado_s6_ipqc_spec_material_map", s);
- Assert.Contains("m.tenant_id=@TenantId AND m.item_code=@ItemCode AND m.match_status='EXACT'", s);
- Assert.Contains("g.tenant_id=@TenantId", s); // 检规同租户
- }
- [Fact]
- public void Resolver_NoIdDescFallback_NoManualPick()
- {
- var s = Resolver();
- Assert.DoesNotContain("ORDER BY g.id DESC", s);
- Assert.DoesNotContain("ORDER BY id DESC LIMIT 1", s);
- // 裁决按 wjbh 分组
- Assert.Contains("GroupBy(c => (c.Wjbh", s);
- }
- [Fact]
- public void Service_StrictTenantScope_EveryQuery()
- {
- var s = Service();
- Assert.Contains("AidopTenantScope.ResolveOrThrow", s);
- Assert.DoesNotContain("tenant_id IS NULL", s);
- Assert.DoesNotContain("tenant_id = 0", s);
- var n = s.Split("tenant_id=@TenantId").Length - 1;
- Assert.True(n >= 4, $"expected tenant predicate on load/idempotency/insert/snapshot/detail, found {n}");
- }
- [Fact]
- public void Service_OnlyMatchedWrites()
- {
- var s = Service();
- Assert.Contains("resolve.Status != S6SpecResolveStatus.Matched", s);
- Assert.Contains("return res; // 非唯一解析:不写库", s);
- Assert.Contains("resolve.CandidateCount != 1", s);
- }
- [Fact]
- public void Service_TransactionalGeneration()
- {
- var s = Service();
- Assert.Contains("BeginTran()", s);
- Assert.Contains("CommitTran()", s);
- Assert.Contains("RollbackTran()", s);
- }
- [Fact]
- public void Service_IdempotentReuseActiveBill()
- {
- var s = Service();
- Assert.Contains("inspection_status IN ('DRAFT','ACTIVE')", s);
- Assert.Contains("Reused = true", s);
- }
- [Fact]
- public void Service_SnapshotFreezesFromS0Detail_WithResultType()
- {
- var s = Service();
- Assert.Contains("INSERT INTO ado_s6_process_inspection_snapshot_head", s);
- Assert.Contains("INSERT INTO ado_s6_process_inspection_snapshot_line", s);
- Assert.Contains("FROM qms_gcjygfzb z", s); // 快照冻结自 S0 明细
- Assert.Contains("z.lrlx", s); // ResultType 进快照
- }
- [Fact]
- public void Frontend_NoManualSpecSelector_CallsPrepare()
- {
- var v = Vue();
- Assert.Contains("prepareProcessInspection", v);
- Assert.DoesNotContain(":disabled=\"true\"", v); // 按钮不再禁用
- // 无人工检规下拉/选择器
- Assert.DoesNotContain("specSelect", v);
- Assert.DoesNotContain("选择检规", v);
- }
- private static string FindFile(params string[] parts)
- {
- var dir = new DirectoryInfo(AppContext.BaseDirectory);
- while (dir != null)
- {
- var candidate = Path.Combine(new[] { dir.FullName }.Concat(parts).ToArray());
- if (File.Exists(candidate)) return candidate;
- dir = dir.Parent;
- }
- throw new FileNotFoundException(string.Join("/", parts));
- }
- }
|