S6ProcessInspectionReviewContractTests.cs 3.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. using Xunit;
  2. namespace Admin.NET.Plugin.AiDOP.Tests.S6.Manufacturing;
  3. /// <summary>
  4. /// S6 Phase 1D 桥接契约测试:Phase 1C bill 接入 ApprovalFlow(BizType=S6_PROCESS_INSPECTION)。
  5. /// 覆盖:独立 BizType 绑 bill.id、提交门槛 COMPLETED、FAIL→disposition_required、质量结果不改写、tenant/幂等/N1=Initiator。
  6. /// </summary>
  7. public class S6ProcessInspectionReviewContractTests
  8. {
  9. private static string Svc() => File.ReadAllText(FindFile("server", "Plugins", "Admin.NET.Plugin.AiDOP", "Manufacturing", "S6ProcessInspectionReviewService.cs"));
  10. private static string Handler() => File.ReadAllText(FindFile("server", "Plugins", "Admin.NET.Plugin.AiDOP", "Manufacturing", "S6ProcessInspectionFlowBizHandler.cs"));
  11. private static string Const() => File.ReadAllText(FindFile("server", "Plugins", "Admin.NET.Plugin.AiDOP", "Manufacturing", "S6ProcessInspectionFlowConst.cs"));
  12. private static string Seed() => File.ReadAllText(FindFile("server", "Plugins", "Admin.NET.Plugin.AiDOP", "Infrastructure", "S6ProcessInspectionFlowSeed.cs"));
  13. [Fact]
  14. public void BizType_IsIndependent_BoundToProcessInspectionBill()
  15. {
  16. Assert.Contains("\"S6_PROCESS_INSPECTION\"", Const());
  17. var s = Svc();
  18. // business_id = process_inspection_bill.id(StartFlow BizId=input.BillId),不绑 qms_gcjyd
  19. Assert.Contains("BizId = input.BillId", s);
  20. Assert.Contains("FROM ado_s6_process_inspection_bill", s);
  21. Assert.DoesNotContain("qms_gcjyd", s);
  22. }
  23. [Fact]
  24. public void Submit_Gate_RequiresCompleted()
  25. {
  26. var s = Svc();
  27. Assert.Contains("INSPECTION_NOT_COMPLETED", s);
  28. Assert.Contains("StatusCompleted", s);
  29. }
  30. [Fact]
  31. public void Gateway_FailDrivesDisposition_FromOverallResult()
  32. {
  33. // 网关判据 disposition_required 由 overall_result=FAIL 决定,只读、不改写质量结果
  34. var h = Handler();
  35. Assert.Contains("overall_result", h);
  36. Assert.Contains("ResultFail", h);
  37. Assert.Contains("[\"disposition_required\"]", h);
  38. // Handler 不 UPDATE 质量结果
  39. Assert.DoesNotContain("UPDATE ado_s6_process_inspection_result", h);
  40. }
  41. [Fact]
  42. public void Disposition_DoesNotOverwrite_QualityResult()
  43. {
  44. var s = Svc();
  45. // 处置落 ado_s6_ipqc_quality_disposition,绝不 UPDATE overall_result(§20 硬门)
  46. Assert.Contains("AdoS6IpqcQualityDisposition", s);
  47. Assert.DoesNotContain("UPDATE ado_s6_process_inspection_result SET overall_result", s);
  48. Assert.DoesNotContain("SET overall_result", s);
  49. }
  50. [Fact]
  51. public void Idempotent_And_TenantSafe_And_Transactional()
  52. {
  53. var s = Svc();
  54. Assert.Contains("已在审核中,请勿重复提交", s); // 一单一 active flow
  55. Assert.Contains("ResolveTenantOrThrow", s);
  56. Assert.Contains("UseTranAsync", s);
  57. Assert.DoesNotContain("tenant_id IS NULL", s);
  58. }
  59. [Fact]
  60. public void N1_IsInitiator_ReuseSupervisorAndQeRoles()
  61. {
  62. var seed = Seed();
  63. Assert.Contains("nameof(ApproverTypeEnum.Initiator)", seed); // N1=发起人
  64. Assert.Contains("RoleSupervisorId", seed); // N2 复用 IPQC 主管角色
  65. Assert.Contains("RoleQualityEngineerId", seed); // N3 复用 IPQC QE 角色
  66. // 复用 IPQC 角色 Id(不新造角色)
  67. Assert.Contains("IpqcInspectionFlowConst.RoleSupervisorId", Const());
  68. }
  69. private static string FindFile(params string[] parts)
  70. {
  71. var dir = new DirectoryInfo(AppContext.BaseDirectory);
  72. while (dir != null)
  73. {
  74. var candidate = Path.Combine(new[] { dir.FullName }.Concat(parts).ToArray());
  75. if (File.Exists(candidate)) return candidate;
  76. dir = dir.Parent;
  77. }
  78. throw new FileNotFoundException(string.Join("/", parts));
  79. }
  80. }