[CLAUDE] Tests: Chunk L4 — Update K7 Approver F2 tests cho L1 semantic refactor (advance pointer NOT terminate)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m7s
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m7s
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) <noreply@anthropic.com>
This commit is contained in:
@ -325,12 +325,15 @@ public class PurchaseEvaluationWorkflowServiceReturnModeTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[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
|
// Happy path (L1 S23 t2 semantic refactor): workflow 2 Step × 2 Level.
|
||||||
// AllowApproverSkipToFinal=true. Actor = userA (Cấp 1 Bước 1 approver,
|
// Slot Cấp 1 Bước 1 admin tick AllowApproverSkipToFinal=true. Actor = userA
|
||||||
// non-admin role). PE pin workflow + Phase=ChoDuyet + pointer init Step 0 Cấp 1.
|
// (Cấp 1 Bước 1 approver, non-admin role). PE pin workflow + Phase=ChoDuyet
|
||||||
// → Phase=DaDuyet, pointer cleared, opinion + PEA + Changelog logged.
|
// + 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();
|
var (svc, fix, db, _) = CreateService();
|
||||||
using (fix)
|
using (fix)
|
||||||
{
|
{
|
||||||
@ -372,10 +375,10 @@ public class PurchaseEvaluationWorkflowServiceReturnModeTests
|
|||||||
skipToFinal: true,
|
skipToFinal: true,
|
||||||
ct: CancellationToken.None);
|
ct: CancellationToken.None);
|
||||||
|
|
||||||
pe.Phase.Should().Be(PurchaseEvaluationPhase.DaDuyet, "Skip → terminal trực tiếp");
|
pe.Phase.Should().Be(PurchaseEvaluationPhase.ChoDuyet, "L1 S23 t2: skip advance pointer, NV cuối duyệt thật để DaDuyet");
|
||||||
pe.CurrentWorkflowStepIndex.Should().BeNull("Pointer cleared khi terminal");
|
pe.CurrentWorkflowStepIndex.Should().Be(1, "Pointer advance tới lastStepIdx (Bước cuối)");
|
||||||
pe.CurrentApprovalLevelOrder.Should().BeNull("Pointer cleared khi terminal");
|
pe.CurrentApprovalLevelOrder.Should().Be(2, "Pointer advance tới lastLevelMaxOrder (Cấp cuối Bước cuối)");
|
||||||
pe.SlaDeadline.Should().BeNull("SLA cleared khi terminal");
|
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
|
// 1 PEL opinion UPSERT cho slot Cấp 1 Bước 1 trước skip
|
||||||
var opinions = await db.PurchaseEvaluationLevelOpinions
|
var opinions = await db.PurchaseEvaluationLevelOpinions
|
||||||
@ -391,11 +394,11 @@ public class PurchaseEvaluationWorkflowServiceReturnModeTests
|
|||||||
approvals[0].ApproverUserId.Should().Be(userA.Id);
|
approvals[0].ApproverUserId.Should().Be(userA.Id);
|
||||||
approvals[0].Decision.Should().Be(ApprovalDecision.Approve);
|
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
|
var changelogs = await db.PurchaseEvaluationChangelogs
|
||||||
.Where(c => c.PurchaseEvaluationId == pe.Id).ToListAsync();
|
.Where(c => c.PurchaseEvaluationId == pe.Id).ToListAsync();
|
||||||
changelogs.Should().Contain(c => c.ContextNote != null
|
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]
|
[Fact]
|
||||||
public async Task ApproveV2_SkipToFinal_FlagOff_Admin_BypassesFlagCheck()
|
public async Task ApproveV2_SkipToFinal_FlagOff_Admin_BypassesFlagCheck()
|
||||||
{
|
{
|
||||||
// Admin bypass: workflow same nhưng AllowApproverSkipToFinal=false cho slot Cấp 1 Bước 1.
|
// Admin bypass (L1 S23 t2 semantic): workflow same nhưng AllowApproverSkipToFinal=false
|
||||||
// Actor = adminUser (actorRoles contains "Admin"), trong slot Cấp 1 Bước 1.
|
// cho slot Cấp 1 Bước 1. Actor = adminUser (actorRoles contains "Admin"), trong slot.
|
||||||
// → DaDuyet (admin bypass flag), pointer cleared, opinion logged, Changelog "Approver duyệt thẳng Cấp cuối".
|
// → 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();
|
var (svc, fix, db, _) = CreateService();
|
||||||
using (fix)
|
using (fix)
|
||||||
{
|
{
|
||||||
@ -507,20 +512,20 @@ public class PurchaseEvaluationWorkflowServiceReturnModeTests
|
|||||||
skipToFinal: true,
|
skipToFinal: true,
|
||||||
ct: CancellationToken.None);
|
ct: CancellationToken.None);
|
||||||
|
|
||||||
pe.Phase.Should().Be(PurchaseEvaluationPhase.DaDuyet, "Admin bypass flag → terminal");
|
pe.Phase.Should().Be(PurchaseEvaluationPhase.ChoDuyet, "L1 S23 t2: skip advance pointer, NV cuối duyệt thật");
|
||||||
pe.CurrentWorkflowStepIndex.Should().BeNull("Pointer cleared");
|
pe.CurrentWorkflowStepIndex.Should().Be(1, "Pointer advance tới lastStepIdx");
|
||||||
pe.CurrentApprovalLevelOrder.Should().BeNull("Pointer cleared");
|
pe.CurrentApprovalLevelOrder.Should().Be(2, "Pointer advance tới lastLevelMaxOrder");
|
||||||
|
|
||||||
// Opinion logged (UPSERT trước skip)
|
// Opinion logged (UPSERT trước skip)
|
||||||
var opinions = await db.PurchaseEvaluationLevelOpinions
|
var opinions = await db.PurchaseEvaluationLevelOpinions
|
||||||
.Where(o => o.PurchaseEvaluationId == pe.Id).ToListAsync();
|
.Where(o => o.PurchaseEvaluationId == pe.Id).ToListAsync();
|
||||||
opinions.Should().HaveCount(1);
|
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
|
var changelogs = await db.PurchaseEvaluationChangelogs
|
||||||
.Where(c => c.PurchaseEvaluationId == pe.Id).ToListAsync();
|
.Where(c => c.PurchaseEvaluationId == pe.Id).ToListAsync();
|
||||||
changelogs.Should().Contain(c => c.ContextNote != null
|
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"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user