wal: flush 20260729T2205
This commit is contained in:
@ -0,0 +1,54 @@
|
||||
# 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)
|
||||
Reference in New Issue
Block a user