7.7 KiB
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
- §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).
- §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.. KhkkGroupMenuKeysvàoAll:244.DbInitializer.cs:2115-2157— vòng seed 49 row menu (parentKeHoachKyKet, Order nhóm = n, leaf Order 1..6) +:2235labelBackfillKhkk_G1+:2442-2446site-2KhkkKeys().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.
- §0.3 CHỒNG LẤN ĐÃ CÓ (không viết lại):
ContractCatalogTests.cs:445T6 K1 assertMenuKeys.All.Except(menuKeysInDb).Should().BeEmpty()sauSeedMenuTreeAsync⇒ 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. - §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 trongAll.
§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 statuscho thấy dướitests/chỉ có 1 file MỚIKhkkGroupMenuSeedTests.cs; 2 filesrc/đangMlà 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)
- 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. - 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
khkkGroupLabelslà VÔ TÁC DỤNG — phải thêm entrylabelBackfill. Comment BE:2233-2234đã khai đúng điều này; T5 nay khoá nó thành bất-biến có răng. - Số canonical cần đổi kèm K4a:
MenuKeys.AllĐO runtime = 113 ⇒docs/STATUS.mdrowMenu 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)