From da30e270c8c89e95421a80bc4ad6dd9e31b8b1e9 Mon Sep 17 00:00:00 2001 From: pqhuy1987 Date: Fri, 15 May 2026 01:47:17 +0700 Subject: [PATCH] =?UTF-8?q?[CLAUDE]=20Tests:=20Chunk=20L4=20=E2=80=94=20Up?= =?UTF-8?q?date=20K7=20Approver=20F2=20tests=20cho=20L1=20semantic=20refac?= =?UTF-8?q?tor=20(advance=20pointer=20NOT=20terminate)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Run #196 CI FAIL: K7 tests assume Phase=DaDuyet (Plan K K2 original semantic). L1 (`f3db9e6`) refactor Service ApproveV2Async F2 branch sang advance pointer tới NV cuối (Phase giữ ChoDuyet) — bro UAT correction. Em main quên update K7 tests cùng L1 commit → test_infra FAIL → CI block deploy. L2 (`10ddc87`) + L3 (`f212f04`) inherit failure → bundle hash unchanged prod (admin/user vẫn CRsX6cFo/X7qb4Zl4 K11 baseline) → L1+L2+L3 KHÔNG deploy. Fix 2 test assertions match new L1 semantic: 1. ApproveV2_SkipToFinal_AdminTickFlag_AdvancesToLastSlot (rename từ _SetsPhaseDaDuyet): - Phase.Should().Be(ChoDuyet) — giữ ChoDuyet KHÔNG terminal - CurrentWorkflowStepIndex.Should().Be(1) — lastStepIdx (Bước cuối) - CurrentApprovalLevelOrder.Should().Be(2) — lastLevelMaxOrder (Cấp cuối) - SlaDeadline.Should().NotBeNull — SLA reset 7d cho NV cuối - Changelog assertion: "Approver skip thẳng" (text mới) 2. ApproveV2_SkipToFinal_FlagOff_Admin_BypassesFlagCheck: - Phase.Should().Be(ChoDuyet) - Pointer advance tới (1, 2) - Changelog "Approver skip thẳng" 3. ApproveV2_SkipToFinal_FlagOff_NonAdmin_ThrowsConflictException — UNCHANGED (ConflictException semantic giống L1 — flag check trước advance). Verify: - dotnet test SolutionErp.slnx 104/104 PASS (58 Domain + 46 Infra) - 3 Approver F2 tests all green Pattern lesson saved: Service refactor → update test cùng commit (test-before §7 rule). Em main vi phạm UAT mode skip dotnet test mỗi chunk → CI catch retroactive. Co-Authored-By: Claude Opus 4.7 (1M context) --- ...valuationWorkflowServiceReturnModeTests.cs | 43 +++++++++++-------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/tests/SolutionErp.Infrastructure.Tests/Services/PurchaseEvaluationWorkflowServiceReturnModeTests.cs b/tests/SolutionErp.Infrastructure.Tests/Services/PurchaseEvaluationWorkflowServiceReturnModeTests.cs index 33a9f92..f684e2c 100644 --- a/tests/SolutionErp.Infrastructure.Tests/Services/PurchaseEvaluationWorkflowServiceReturnModeTests.cs +++ b/tests/SolutionErp.Infrastructure.Tests/Services/PurchaseEvaluationWorkflowServiceReturnModeTests.cs @@ -325,12 +325,15 @@ public class PurchaseEvaluationWorkflowServiceReturnModeTests } [Fact] - public async Task ApproveV2_SkipToFinal_AdminTickFlag_SetsPhaseDaDuyet() + public async Task ApproveV2_SkipToFinal_AdminTickFlag_AdvancesToLastSlot() { - // Happy path: workflow 2 Step × 2 Level. Slot Cấp 1 Bước 1 admin tick - // AllowApproverSkipToFinal=true. Actor = userA (Cấp 1 Bước 1 approver, - // non-admin role). PE pin workflow + Phase=ChoDuyet + pointer init Step 0 Cấp 1. - // → Phase=DaDuyet, pointer cleared, opinion + PEA + Changelog logged. + // Happy path (L1 S23 t2 semantic refactor): workflow 2 Step × 2 Level. + // Slot Cấp 1 Bước 1 admin tick AllowApproverSkipToFinal=true. Actor = userA + // (Cấp 1 Bước 1 approver, non-admin role). PE pin workflow + Phase=ChoDuyet + // + pointer init Step 0 Cấp 1. + // → Phase GIỮ ChoDuyet, pointer advance tới last Step (idx=1) + last Level + // (Order=2), opinion + PEA + Changelog logged. NV cuối vẫn cần ký thật để + // tiến DaDuyet (KHÔNG auto-approve terminal — S23 t2 fix bro UAT). var (svc, fix, db, _) = CreateService(); using (fix) { @@ -372,10 +375,10 @@ public class PurchaseEvaluationWorkflowServiceReturnModeTests skipToFinal: true, ct: CancellationToken.None); - pe.Phase.Should().Be(PurchaseEvaluationPhase.DaDuyet, "Skip → terminal trực tiếp"); - pe.CurrentWorkflowStepIndex.Should().BeNull("Pointer cleared khi terminal"); - pe.CurrentApprovalLevelOrder.Should().BeNull("Pointer cleared khi terminal"); - pe.SlaDeadline.Should().BeNull("SLA cleared khi terminal"); + pe.Phase.Should().Be(PurchaseEvaluationPhase.ChoDuyet, "L1 S23 t2: skip advance pointer, NV cuối duyệt thật để DaDuyet"); + pe.CurrentWorkflowStepIndex.Should().Be(1, "Pointer advance tới lastStepIdx (Bước cuối)"); + pe.CurrentApprovalLevelOrder.Should().Be(2, "Pointer advance tới lastLevelMaxOrder (Cấp cuối Bước cuối)"); + pe.SlaDeadline.Should().NotBeNull("SLA reset 7d cho NV cuối nhận lại"); // 1 PEL opinion UPSERT cho slot Cấp 1 Bước 1 trước skip var opinions = await db.PurchaseEvaluationLevelOpinions @@ -391,11 +394,11 @@ public class PurchaseEvaluationWorkflowServiceReturnModeTests approvals[0].ApproverUserId.Should().Be(userA.Id); approvals[0].Decision.Should().Be(ApprovalDecision.Approve); - // Changelog entry với context note chứa "Approver duyệt thẳng Cấp cuối" + // Changelog entry với context note chứa "Approver skip thẳng" + "Bước/Cấp" var changelogs = await db.PurchaseEvaluationChangelogs .Where(c => c.PurchaseEvaluationId == pe.Id).ToListAsync(); changelogs.Should().Contain(c => c.ContextNote != null - && c.ContextNote.Contains("Approver duyệt thẳng Cấp cuối")); + && c.ContextNote.Contains("Approver skip thẳng")); } } @@ -463,9 +466,11 @@ public class PurchaseEvaluationWorkflowServiceReturnModeTests [Fact] public async Task ApproveV2_SkipToFinal_FlagOff_Admin_BypassesFlagCheck() { - // Admin bypass: workflow same nhưng AllowApproverSkipToFinal=false cho slot Cấp 1 Bước 1. - // Actor = adminUser (actorRoles contains "Admin"), trong slot Cấp 1 Bước 1. - // → DaDuyet (admin bypass flag), pointer cleared, opinion logged, Changelog "Approver duyệt thẳng Cấp cuối". + // Admin bypass (L1 S23 t2 semantic): workflow same nhưng AllowApproverSkipToFinal=false + // cho slot Cấp 1 Bước 1. Actor = adminUser (actorRoles contains "Admin"), trong slot. + // → Phase GIỮ ChoDuyet, pointer advance tới last slot (idx=1, Order=2), + // opinion logged, Changelog "Approver skip thẳng". Admin bypass flag check + // — NV cuối vẫn cần ký thật để DaDuyet. var (svc, fix, db, _) = CreateService(); using (fix) { @@ -507,20 +512,20 @@ public class PurchaseEvaluationWorkflowServiceReturnModeTests skipToFinal: true, ct: CancellationToken.None); - pe.Phase.Should().Be(PurchaseEvaluationPhase.DaDuyet, "Admin bypass flag → terminal"); - pe.CurrentWorkflowStepIndex.Should().BeNull("Pointer cleared"); - pe.CurrentApprovalLevelOrder.Should().BeNull("Pointer cleared"); + pe.Phase.Should().Be(PurchaseEvaluationPhase.ChoDuyet, "L1 S23 t2: skip advance pointer, NV cuối duyệt thật"); + pe.CurrentWorkflowStepIndex.Should().Be(1, "Pointer advance tới lastStepIdx"); + pe.CurrentApprovalLevelOrder.Should().Be(2, "Pointer advance tới lastLevelMaxOrder"); // Opinion logged (UPSERT trước skip) var opinions = await db.PurchaseEvaluationLevelOpinions .Where(o => o.PurchaseEvaluationId == pe.Id).ToListAsync(); opinions.Should().HaveCount(1); - // Changelog entry với "Approver duyệt thẳng Cấp cuối" + // Changelog entry với "Approver skip thẳng" var changelogs = await db.PurchaseEvaluationChangelogs .Where(c => c.PurchaseEvaluationId == pe.Id).ToListAsync(); changelogs.Should().Contain(c => c.ContextNote != null - && c.ContextNote.Contains("Approver duyệt thẳng Cấp cuối")); + && c.ContextNote.Contains("Approver skip thẳng")); } }