4.9 KiB
sub-test-specialist-2 — S161 W3 ĐỢT-2 TEST-BEFORE (6 test sàn, kỳ vọng ĐỎ)
Ghi TỪNG MỤC trong lúc làm (bài #53: chỉ thứ trên đĩa mới sống). Scope MINE:
tests/SolutionErp.Infrastructure.Tests/Application/ContractSigningPlanApprovalTests.cs(file MỚI). KHÔNG chạm:src/Backend/**·fe-*/**· slnx · commit/push · MEMORY.md.
⚠️ Tên file sub-md: lệnh lead (khối LUẬT) ghi sub-test-specialist-2.md; khối RUN-TRACE
boilerplate ghi sub-test-specialist-0.md. Chọn -2 vì khớp đánh số của chính run-folder này
(implementer-backend-0, implementer-frontend-1) và tránh đè file (bài S133: 2 invocation
cùng role + cùng index ghi đè nhau, mất trọn nội dung). Khai ở đây để lead không phải đoán.
§0 — ĐO TRƯỚC KHI GÕ (baseline TƯƠI, không tin số đề bài)
| Mục đo | Lệnh | Kết quả |
|---|---|---|
| Baseline | dotnet test SolutionErp.slnx --nologo -v minimal -p:BuildInParallel=false -maxcpucount:1 |
Domain 45/45 · Infra 529/529 · Failed 0 ⇒ 574 — KHỚP số bàn giao |
| Chữ ký service | IContractSigningPlanWorkflowService.cs:25-29 + ContractSigningPlanWorkflowService.cs:78-82 |
new ContractSigningPlanWorkflowService(db, currentUser, dateTime, notifications) · TransitionAsync(planId, action, comment, ct) |
| Record trả về | IContractSigningPlanWorkflowService.cs:38-41 |
ContractSigningPlanTransitionResult(int Phase, int? CurrentWorkflowStepIndex, int? CurrentApprovalLevelOrder) — Phase là int (QUYẾT-1 lane BE) |
| Skeleton ném gì | ContractSigningPlanWorkflowService.cs:108/113/117/121 |
NotImplementedException("W3 đợt-3: " + action) cho cả 4 nhánh ⇒ ĐỎ THẬT |
| Inbox W2 (không chạm service) | ContractSigningPlanFeatures.cs:725-752 + :229-264 |
GetMyContractSigningPlanInboxQueryHandler(db, currentUser); non-admin qua ResolveV2InboxIdsAsync ⇒ CHẠY ĐƯỢC HÔM NAY |
| Con-trỏ là INDEX hay Order? | ContractSigningPlanFeatures.cs:256-260 |
steps[idx] sau OrderBy(s => s.Order) ⇒ CurrentWorkflowStepIndex = INDEX 0-based, KHÔNG phải Step.Order. Mã W2 đã chốt ⇒ test được phép ép Step.Order ≠ index (xem §2 T2) |
| FK bắt buộc row thật | ApprovalWorkflowConfiguration.cs:72-75 (Level.ApproverUserId → Users Restrict) · ContractSigningPlanConfiguration.cs:36-39 (Plan.ApprovalWorkflowId → ApprovalWorkflows Restrict) |
⇒ seed PHẢI có User thật + ApprovalWorkflow thật |
| loose-Guid (khỏi seed) | ContractSigningPlanConfiguration.cs:10-12 + ContractSigningPlan.cs:24-29 |
PurchaseEvaluationId / ProjectId / DepartmentId / DrafterUserId KHÔNG FK ⇒ không cần seed PE/Project/Department (khác hẳn W2) |
MaKeHoach UNIQUE |
ContractSigningPlanConfiguration.cs:28 |
filtered unique ⇒ mỗi phiếu trong 1 fixture phải mã KHÁC nhau |
| Nguồn copy đợt-3 (để biết đo cái gì) | ContractWorkflowService.cs:246 GroupBy · :255-266 OR-of-N + admin bypass · :289-316 UPSERT · :355-393 advance/terminal |
terminal set CẢ HAI con-trỏ = null (:380-381) ⇒ test pin null tại terminal |
| Stub notify có sẵn | CreateContractCommandApplicableTypeTests.cs:95 NoOpNotificationServiceApp — cùng namespace ...Tests.Application |
dùng thẳng, KHÔNG đẻ stub thứ 2 |
Kết luận §0: seed W3 NHẸ hơn W2 nhiều (không PE, không Supplier, không quote) — chỉ
Users + ApprovalWorkflow(+Steps+Levels) + ContractSigningPlan(+Lines).
§1 — 2 quyết định hạ tầng của file test
(1) Fixture RIÊNG KhkkWorkflowFixture có AuditingInterceptor (mirror ContractSigningPlanCrudTests.cs:49-82 W2).
Lý do KHÔNG dùng IdentityFixture: guard trình đợt-3 = CreatedBy == actor ∨ DeptManager ∨ Admin
⇒ CreatedBy của phiếu phải là NGƯỜI THẬT. TestApplicationDbContext trần KHÔNG wire interceptor
⇒ CreatedBy sẽ là null cho mọi phiếu ⇒ nhánh CreatedBy == actor KHÔNG BAO GIỜ đúng, test
submit sẽ đỏ vì lý do sai. Seed phiếu bằng context của chính người soạn ⇒ CreatedBy khớp
DrafterUserId (2 đường đọc, cùng 1 giá trị — đợt-3 chọn đường nào cũng đúng).
(2) User seed THẲNG db.Users.Add(...), KHÔNG qua UserManager.
Service đợt-3 lấy role từ ICurrentUser.Roles (lane BE khai QUYẾT-2: cố ý KHÔNG inject
UserManager) ⇒ kéo cả Identity stack vào chỉ để có row FK là phí. Repo chưa có tiền lệ
db.Users.Add trong tests (grep 0 hit) ⇒ mục này là cái mới, và nó chỉ hợp lệ vì
Level.ApproverUserId cần row tồn tại, không cần đăng nhập được.
§2 — 6 test: đo gì, bẫy cài ở đâu
(điền tiếp bên dưới trong lúc viết)