84 lines
7.7 KiB
Markdown
84 lines
7.7 KiB
Markdown
TEST-K4A: DONE — 6/6 PASS · Infra 569→575 · Domain 45 · tổng 620 · 0 hồi quy · 0 prod-code touched
|
||
|
||
# Lane test K4a — test-after 49 row menu KHKK 8-nhóm (S166, 2026-08-01)
|
||
|
||
Agent: test-specialist. Ghi-từng-mục TRONG LÚC LÀM (luật sống-còn bài K3 engine-exit).
|
||
Mục nào chưa chạy = ghi tiêu-đề + "CHƯA ĐO", KHÔNG điền số dự-đoán.
|
||
|
||
## §0 — Trạng thái khởi động
|
||
|
||
- [x] §0.1 ĐÃ đọc khuôn. Chốt harness: seeder là `private static` → REFLECTION.
|
||
- `SeedMenuTreeAsync(ApplicationDbContext, ILogger)` — 2 tham số.
|
||
- `SeedAllRolesReviewReadPermissionsAsync(ApplicationDbContext, RoleManager<Role>, ILogger)` — 3 tham số (site-2).
|
||
- Khuôn invoke đã có sẵn ở `ContractCatalogTests.cs:459` (`InvokePrivateSeedAsync`, rm nullable) →
|
||
dùng lại HÌNH, không chế fixture mới. Fixture = `IdentityFixture` (cần RoleManager cho site-2).
|
||
- [x] §0.2 ĐÃ đọc BE đã land (git diff, chưa commit):
|
||
- `MenuKeys.cs:72-84` — `KhkkGroupNumbers=[2..8]` · `KhkkLeafActions=[WfView,List,Create,Pending,Approved,Deleted]`
|
||
· `KhkkGroupMenuKeys` = SelectMany(group → 6 leaf) · spread `.. KhkkGroupMenuKeys` vào `All:244`.
|
||
- `DbInitializer.cs:2115-2157` — vòng seed 49 row menu (parent `KeHoachKyKet`, Order nhóm = n,
|
||
leaf Order 1..6) + `:2235` labelBackfill `Khkk_G1` + `:2442-2446` site-2 `KhkkKeys().Concat(KhkkGroupMenuKeys)`.
|
||
- Đếm BY-SOURCE `All` = 113 (tự cộng tay từng dòng initializer). **Chưa phải số ĐO** — sẽ đo runtime ở T1.
|
||
- [x] §0.3 CHỒNG LẤN ĐÃ CÓ (không viết lại): `ContractCatalogTests.cs:445` T6 K1 assert
|
||
`MenuKeys.All.Except(menuKeysInDb).Should().BeEmpty()` sau `SeedMenuTreeAsync` ⇒ invariant
|
||
"49 key mới ĐỀU có menu-row" ĐÃ được test cũ phủ tự động (nó là phép thử của claim by-construction).
|
||
Lane K4a KHÔNG nhân bản; thay vào đó đo cái test cũ KHÔNG đo: hình bộ sinh · đếm 56 row họ Khkk ·
|
||
idempotent ×2 · labelBackfill · grant site-2.
|
||
- [x] §0.4 **Baseline Infra ĐO TƯƠI 2026-08-01 (trước khi thêm file): 569 PASS / 0 FAIL** (42 s).
|
||
Đo trên cây có BE K4a đã land ⇒ test T6-K1 cũ (`All.Except(menuKeysInDb)`) XANH với 49 key mới
|
||
= bằng chứng độc lập rằng vòng seed 49 row khớp đúng bộ key trong `All`.
|
||
|
||
## §1..§4 — File test đã LAND: `tests/SolutionErp.Infrastructure.Tests/Application/KhkkGroupMenuSeedTests.cs` (6 test)
|
||
|
||
Harness: reflection `private static` + `IdentityFixture` (không fixture mới). Không đụng prod code.
|
||
|
||
| # | Test | Đo cái gì | Chống vacuous bằng |
|
||
|---|---|---|---|
|
||
| T1 | `KhkkGroupMenuKeys_Is49Keys_GroupImmediatelyFollowedBySixLeaves` | 49 key · `Equal` với **mảng 49 chuỗi VIẾT TAY** (không gọi lại factory ⇒ không tautology) · liền-kề `Khkk_G{n}` ngay trước `Khkk_G{n}_WfView` · pin 6 action | kỳ vọng là literal, sai 1 ký tự là đỏ |
|
||
| T2 | `MenuKeys_All_ContainsThe49_NoDuplicate_AndKeepsGroup1Outside` | All ⊇ 49 · `OnlyHaveUniqueItems` · **`HaveCount(113)` = số ĐO runtime** · `KhkkGroupNumbers == [2..8]` · 7 key nhóm 1 KHÔNG nằm trong All | vế cuối = guard thật: thêm số 1 vào bộ sinh ⇒ `tree.Add("Khkk_G1")` lần 2 ⇒ trùng PK lúc boot |
|
||
| T3 | `SeedMenuTree_RunTwice_Has56KhkkRows_NoDuplication_AndCorrectTreeShape` | seed ×2: **56 row họ Khkk** (7 nhóm-1 + 49) · lần 2 danh sách key Y NGUYÊN · **tổng bảng MenuItems bất động** · 8 group parent=`KeHoachKyKet` Order=n · mỗi group đúng 6 con · 8 nhãn nhóm phân biệt | đếm bằng Ordinal in-memory (không phụ thuộc collation LIKE); đã kiểm KHÔNG có `HasData` cho MenuItems ⇒ 56 row đến TỪ seeder, không phải EF seed |
|
||
| T4 | `SeedMenuTree_NewGroupLeaves_MirrorGroup1_LabelIconOrder` | 42 leaf mới khớp **nhãn + icon + Order** của leaf nhóm 1 tương ứng (đo DB↔DB, không bảng hardcode) | chốt trước "6 nhãn nhóm 1 PHÂN BIỆT" — nếu chúng trùng nhau, phép so mirror đúng ở mọi thế giới |
|
||
| T5 | `SeedMenuTree_LabelBackfill_HealsGroup1Label_WithoutAddingRows_ControlKeyStaysDirty` | **MA TRẬN cùng-ruột-khác-1-biến**: bôi hỏng nhãn CẢ `Khkk_G1` (ca thật: về chuỗi skeleton S159) LẪN `Khkk_G2` trong cùng 1 lần → seed lại → G1 **tự lành**, G2 **giữ chữ hỏng**; tổng row bất động | 2 kết quả TRÁI NGƯỢC trong 1 lần chạy; khác biệt duy nhất = có/không entry `labelBackfill` ⇒ chứng đúng cơ chế backfill, không phải upsert "tiện tay" ghi Label (gotcha #11) |
|
||
| T6 | `SeedAllRolesReviewRead_GrantsReadOnNew49KhkkKeys_ReadOnly_WithPeContrast` | site-2 phát CanRead cho cả 49 key (nêu tên `Khkk_G2_List`) · C/U/D=false · 7 key nhóm 1 GIỮ quyền (`.Concat` mở rộng chứ không thay thế) | **ĐỐI CHỨNG CÙNG LƯỢT**: cùng role đó `Pe_DuyetNcc_List` có CanCreate=true ⇒ chuỗi "false" trên Khkk không phải vì seeder no-op. Chạy `SeedMenuTreeAsync` trước = smoke FK cho TOÀN grant-set |
|
||
|
||
Đường vào duy nhất của 49 key ở site-2 = `KhkkKeys().Concat(MenuKeys.KhkkGroupMenuKeys)` (K4a) —
|
||
`All.Where(StartsWith "Pe_")` không bắt `Khkk_*` ⇒ gỡ `.Concat` là T6 ĐỎ.
|
||
|
||
## §5 — Chạy filtered — ĐÃ ĐO
|
||
|
||
`dotnet test tests/SolutionErp.Infrastructure.Tests --filter "FullyQualifiedName~KhkkGroupMenuSeed" --nologo`
|
||
→ **Failed: 0, Passed: 6, Total: 6** (3 s).
|
||
Ghi chú số: `MenuKeys.All` runtime = **113** ĐÚNG như đếm by-source của lane BE (assert xanh) ⇒
|
||
`Policies` DERIVED = 113 × 4 = **452**.
|
||
|
||
## §6 — Full suite — ĐÃ ĐO
|
||
|
||
- **Infra: Failed 0, Passed 575, Total 575** (30 s) — baseline 569 + 6 = 575 ⇒ **0 hồi quy**.
|
||
- **Domain: Failed 0, Passed 45** (311 ms) — đo tươi, không lấy từ trí nhớ.
|
||
- **Tổng suite = 45 + 575 = 620.**
|
||
|
||
Caveat trung thực: giữa lượt làm có commit `7a903cf` (lane F-1, FE + `ContractSigningPlanFeatures.cs`)
|
||
land vào repo. Đã kiểm: `git diff --stat -- src/` vẫn đúng 42/79 dòng của riêng K4a như lúc mở lượt
|
||
⇒ byte nguồn K4a KHÔNG đổi trong lúc đo; file lane F-1 đã nằm sẵn trên đĩa TRƯỚC lần chạy full
|
||
(nó là ` M` từ đầu, commit chỉ chuyển trạng thái index) ⇒ con số 575 đo đúng trạng thái đĩa hiện tại.
|
||
|
||
## §7 — Rào đã giữ
|
||
|
||
- KHÔNG chạm production code: `git status` cho thấy dưới `tests/` chỉ có **1 file MỚI**
|
||
`KhkkGroupMenuSeedTests.cs`; 2 file `src/` đang ` M` là diff của lane BE K4a (có từ trước lượt này).
|
||
- KHÔNG đụng `ContractSigningPlan*` / `KhkkWorkflowPanel` / `khkk.ts`.
|
||
- KHÔNG commit, KHÔNG push.
|
||
- KHÔNG sửa `SolutionErp.slnx` (project SDK-style tự glob `.cs`; test đã build + chạy).
|
||
|
||
## §8 — Quan sát gửi lead (KHÔNG phải bug, không tự sửa)
|
||
|
||
1. **Chồng lấn có lợi:** test T6 lane K1 (`ContractCatalogTests.cs:445`) nay là phép thử tự động cho
|
||
claim "49 key ∈ All đều có menu-row" — nó XANH ở baseline 569 ⇒ claim by-construction của K4a đã
|
||
có chứng nhân độc lập, lane K4a không cần lặp lại.
|
||
2. **Nhãn G2..G8 KHÔNG tự lành** (đo ở T5, đối chứng): nếu owner đổi chữ 7 nhãn nhóm sau khi prod đã
|
||
seed thì sửa trong `khkkGroupLabels` là VÔ TÁC DỤNG — phải thêm entry `labelBackfill`. Comment
|
||
BE `:2233-2234` đã khai đúng điều này; T5 nay khoá nó thành bất-biến có răng.
|
||
3. **Số canonical cần đổi kèm K4a:** `MenuKeys.All` ĐO runtime = 113 ⇒ `docs/STATUS.md` row
|
||
`Menu keys` = 113 · `Policies` = 452. (T2 sẽ ĐỎ nếu 2 số này drift khỏi mã.)
|
||
|
||
END sub-test-k4a — VERDICT=6/6 PASS (+6 test, suite 620 = 45 Domain + 575 Infra, 0 hồi quy)
|