[CLAUDE] PurchaseEvaluation: require quy trinh duyet V2 o create+submit (dong lo hong quy-trinh-cu)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m58s
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m58s
Validator NotEmpty(ApprovalWorkflowId) + submit guard (sau Section-3, truoc mutate phase). Dong lo hong validate FE-only -> phieu null-workflow ket nhanh V1-legacy "quy trinh cu" (khong Buoc/Cap, khong route duyet). Test-before (RED confirmed): +2 validator test (PeWorkItemGuardTests) + rewrite test 7/13 PeSubmitGuardAndBypass (V1-submit deprecated, data V1 wipe S59). 356 pass (45D+311I). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -74,7 +74,7 @@ public class PeWorkItemGuardTests
|
||||
}
|
||||
|
||||
private static CreatePurchaseEvaluationCommand BuildCreateCommand(
|
||||
Guid projectId, Guid? workItemId)
|
||||
Guid projectId, Guid? workItemId, Guid? approvalWorkflowId = null)
|
||||
=> new(
|
||||
Type: PurchaseEvaluationType.DuyetNcc,
|
||||
TenGoiThau: "Gói thầu test",
|
||||
@ -84,7 +84,7 @@ public class PeWorkItemGuardTests
|
||||
MoTa: null,
|
||||
PaymentTerms: null,
|
||||
BudgetPeriodAmount: null,
|
||||
ApprovalWorkflowId: null,
|
||||
ApprovalWorkflowId: approvalWorkflowId,
|
||||
WorkItemId: workItemId);
|
||||
|
||||
// ============================================================
|
||||
@ -127,10 +127,10 @@ public class PeWorkItemGuardTests
|
||||
[Fact]
|
||||
public void Validator_WorkItemIdPresent_NoErrorOnWorkItemId()
|
||||
{
|
||||
// Chỉ assert rule WorkItemId pass — command còn lại đã hợp lệ ở BuildCreateCommand
|
||||
// nên result.IsValid=true; nhưng narrow assert vào property để test đúng rule này.
|
||||
// Chỉ assert rule WorkItemId pass — command còn lại đã hợp lệ ở BuildCreateCommand.
|
||||
// [S83] +ApprovalWorkflowId (cũng NotEmpty từ S83) để command FULL-valid → IsValid=true.
|
||||
var validator = new CreatePurchaseEvaluationCommandValidator();
|
||||
var cmd = BuildCreateCommand(Guid.NewGuid(), workItemId: Guid.NewGuid());
|
||||
var cmd = BuildCreateCommand(Guid.NewGuid(), workItemId: Guid.NewGuid(), approvalWorkflowId: Guid.NewGuid());
|
||||
|
||||
var result = validator.Validate(cmd);
|
||||
|
||||
@ -138,6 +138,38 @@ public class PeWorkItemGuardTests
|
||||
result.IsValid.Should().BeTrue();
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 1b. VALIDATOR — RuleFor(ApprovalWorkflowId).NotEmpty() [S83 bug fix]
|
||||
// ============================================================
|
||||
// Đóng lỗ hổng validate FE-only: phiếu null-workflow lọt vào ChoDuyet = kẹt nhánh
|
||||
// V1-legacy ("quy trình cũ", không Bước/Cấp, không route duyệt). FE canSubmit bắt
|
||||
// buộc chọn quy trình lúc create → BE validator phải mirror (defense-in-depth).
|
||||
|
||||
[Fact]
|
||||
public void Validator_ApprovalWorkflowIdNull_IsInvalid_WithErrorOnWorkflow()
|
||||
{
|
||||
var validator = new CreatePurchaseEvaluationCommandValidator();
|
||||
var cmd = BuildCreateCommand(Guid.NewGuid(), workItemId: Guid.NewGuid(), approvalWorkflowId: null);
|
||||
|
||||
var result = validator.Validate(cmd);
|
||||
|
||||
result.IsValid.Should().BeFalse();
|
||||
result.Errors.Should().Contain(
|
||||
e => e.PropertyName == nameof(CreatePurchaseEvaluationCommand.ApprovalWorkflowId));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validator_ApprovalWorkflowIdPresent_NoErrorOnWorkflow()
|
||||
{
|
||||
var validator = new CreatePurchaseEvaluationCommandValidator();
|
||||
var cmd = BuildCreateCommand(Guid.NewGuid(), workItemId: Guid.NewGuid(), approvalWorkflowId: Guid.NewGuid());
|
||||
|
||||
var result = validator.Validate(cmd);
|
||||
|
||||
result.Errors.Should().NotContain(
|
||||
e => e.PropertyName == nameof(CreatePurchaseEvaluationCommand.ApprovalWorkflowId));
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 2. CREATE HANDLER — FK-invariant guard
|
||||
// ============================================================
|
||||
|
||||
Reference in New Issue
Block a user