using Xunit; namespace Admin.NET.Plugin.AiDOP.Tests.S6.Manufacturing; /// /// S6 Phase 1E 展示收口契约:displayStatus/质量文案/history/disposition 展示、列表状态列、Approval Center deep-link。 /// 纯展示层,不改业务真源;后端拥有业务中文语义,前端不猜。 /// public class S6ProcessInspectionPresentationTests { private static string Svc() => File.ReadAllText(FindFile("server", "Plugins", "Admin.NET.Plugin.AiDOP", "Manufacturing", "S6ProcessInspectionReviewService.cs")); private static string Dto() => File.ReadAllText(FindFile("server", "Plugins", "Admin.NET.Plugin.AiDOP", "Manufacturing", "Dto", "S6ProcessInspectionReviewDto.cs")); private static string ListSvc() => File.ReadAllText(FindFile("server", "Plugins", "Admin.NET.Plugin.AiDOP", "Manufacturing", "S6ProductionInstructionService.cs")); private static string PendingList() => File.ReadAllText(FindFile("Web", "src", "views", "approvalFlow", "center", "components", "PendingList.vue")); [Fact] public void ReviewState_Has_DisplayFields() { var d = Dto(); Assert.Contains("DisplayStatus", d); Assert.Contains("QualityText", d); Assert.Contains("S6DispositionView", d); Assert.Contains("List History", d); } [Fact] public void Service_Maps_BusinessChinese_NotRawCodes() { var s = Svc(); // 节点/动作/质量/处置 → 业务中文映射 Assert.Contains("\"提交审核\"", s); Assert.Contains("\"检验主管审核\"", s); Assert.Contains("\"质量处置\"", s); Assert.Contains("\"合格\"", s); Assert.Contains("\"不合格\"", s); Assert.Contains("\"已关闭\"", s); } [Fact] public void History_ReusesApprovalFlowLog_NoSecondHistory() { var s = Svc(); Assert.Contains("FROM ApprovalFlowLog", s); Assert.Contains("LoadHistoryAsync", s); } [Fact] public void Disposition_DisplayOnly_DoesNotOverwriteQuality() { var s = Svc(); Assert.Contains("LoadDispositionAsync", s); Assert.DoesNotContain("SET overall_result", s); } [Fact] public void List_Has_StatusColumns_NoRowMultiplication() { var l = ListSvc(); Assert.Contains("BillId", l); Assert.Contains("OverallResult", l); Assert.Contains("FlowStatusRaw", l); // 去重子查询避免一工单多单据造成行膨胀 Assert.Contains("MAX(id) AS bill_id", l); Assert.Contains("GROUP BY work_order_no", l); // 租户约束 Assert.Contains("WHERE tenant_id=@TenantId GROUP BY work_order_no", l); } [Fact] public void ApprovalCenter_DeepLink_S6_ByBillId_NotWorkOrder() { var p = PendingList(); Assert.Contains("S6_PROCESS_INSPECTION", p); Assert.Contains("goToS6", p); // S6 deep-link 用 billId=bizId(=bill.id),不按 WorkOrder 猜单据 Assert.Contains("order-list?billId=", p); // goToS6 内不引 qms_gcjyd(限定在 S6 函数体内检查,不误伤其它 bizType 的历史 case) var s6fn = p.Substring(p.IndexOf("function goToS6")); s6fn = s6fn.Substring(0, s6fn.IndexOf('}') + 1); Assert.DoesNotContain("qms_gcjyd", s6fn); } 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)); } }