Add unit tests for autoSaveService to handle document dirty states and periodic saves

- Implement tests for various scenarios including user edits, initial dirty state, and document changes.
- Ensure proper flagging of uncommitted changes and silent saves for documents opened in a dirty state.
- Test debounce behavior for document change notifications and version clearing functionality.
- Validate suspension and resumption of auto-saving during versioning processes.
This commit is contained in:
Suphonchai Phoonsawat 2026-11-03 13:34:21 +07:00
parent 0b6ee8cc84
commit 454c90d17e
17 changed files with 1167 additions and 33 deletions

View file

@ -203,7 +203,7 @@ dialog ยืนยัน → progress ทั้ง 7 ขั้นลำดั
### Auto-save (FR-17)
- เริ่มตั้งแต่ mount **ไม่ผูกกับ phase** (detect ยังไม่จบก็รันได้)
- periodic ทุก 30 วิ: ไฟล์ dirty → save + ตั้ง flag `hasUncommitted`; สะอาด → ข้าม
- periodic ทุก 30 วิ: ไฟล์ dirty → save; สะอาด → ข้าม · ตั้ง flag `hasUncommitted` **เฉพาะ clean→dirty** (เคยเห็น document สะอาดอย่างน้อยหนึ่งจุดก่อน) หรือเมื่อ service ที่แก้เอกสารจริงเรียก `notifyDocumentChanged()` — ไฟล์ที่เปิดมา dirty ตั้งแต่แรก (quirk ของ Word ที่รายงาน saved=false ค้างหลัง stamp properties/custom XML part หรือแก้ค้างจาก session ก่อน) ถูก save เงียบ ๆ **ไม่นับเป็น "ผู้ใช้แก้"** กัน banner FR-3 เด้งทั้งที่ผู้ใช้ไม่ได้ทำอะไร (2026-11-03)
- save ล้ม → `autoSaveError` (warning bar); สำเร็จครั้งถัดไป → เคลียร์ bar
- ทุก flow versioning ต้อง **suspend** auto-save ตอนเริ่มและ **resume** ตอนจบ (กัน save แทรกกลาง stamp/capture)
- สร้าง version สำเร็จ → เคลียร์ `hasUncommitted`
@ -297,7 +297,7 @@ response: `{ url: string, expiresAt: string }` — UI เปิด `url` ใน
- แสดงเฉพาะมีช่องที่ตั้ง tag ≥1 ช่อง (จากผลสแกน): ฟอร์ม label+input ต่อ tag (id `wordaddin-template-value-<index>`) ค่าเริ่ม = ค่าปัจจุบันของช่องแรกของ tag นั้น + ปุ่ม primary `เขียนค่าลงเอกสาร` (icon PenLine → "กำลังเขียนค่า…" ตอนรัน)
- **ช่องที่เว้นว่าง = ไม่ถูกแตะ** (กันเผลอล้างค่าจริง) · เขียนทุก CC ที่ tag ตรง (tag ซ้ำหลายช่อง = เขียนทุกช่องแบบ mail merge) · อ่าน id+tag สดรอบเดียวแล้วเขียน**แยก Word.run ราย tag** — tag ที่ Word ปฏิเสธ fail เฉพาะตัว เหลืออื่นยังเขียนได้ (ผลลัพธ์: `appliedCount` = จำนวนช่องที่เขียนจริง + `missingTags` ไม่พบช่อง + `failures` พร้อม code/errorLocation จาก OfficeExtension.Error) · UI รวมเป็น warning พร้อมชี้นำ "ถ้าเอกสารถูกล็อค (Review → Restrict Editing) ให้ปลดก่อน" — เคสจริงที่เจอ: error `0x800A16C6` บนเอกสารที่ `make-protected.mjs` ล็อคไว้ (readOnly + enforcement)
- ผลลัพธ์: success "เขียนค่าทดสอบลงแล้ว N ช่อง" (N = จำนวนช่องที่เขียนจริง — tag ซ้ำหลายช่องนับทุกช่อง) + warning missingTags ถ้ามี → **สแกนใหม่โดยคงค่าฟอร์ม** (เฉพาะ tag ที่ยังอยู่ในเอกสาร — tag ที่ถูกลบไปตัดทิ้ง) ให้แก้ต่อ · ปุ่ม disabled เมื่อยังไม่มีช่องที่กรอกค่าเลย · หลังเขียนสำเร็จ `notifyDocumentChanged()` ตั้ง debounce auto-save 3 วิ ส่วน banner FR-3 ตั้งเมื่อ periodic tick ถัดไปของ autoSaveService เห็น document dirty (พฤติกรรมเดิมของ service — ไม่ใช่ทันที)
- ผลลัพธ์: success "เขียนค่าทดสอบลงแล้ว N ช่อง" (N = จำนวนช่องที่เขียนจริง — tag ซ้ำหลายช่องนับทุกช่อง) + warning missingTags ถ้ามี → **สแกนใหม่โดยคงค่าฟอร์ม** (เฉพาะ tag ที่ยังอยู่ในเอกสาร — tag ที่ถูกลบไปตัดทิ้ง) ให้แก้ต่อ · ปุ่ม disabled เมื่อยังไม่มีช่องที่กรอกค่าเลย · หลังเขียนสำเร็จ `notifyDocumentChanged()` ตั้ง debounce auto-save 3 วิ + ตั้ง flag FR-3 ทันที (2026-11-03 — เดิมรอ periodic tick เห็น dirty ก่อน)
### §3 แทรกย่อหน้า / ตัวแบ่ง (2026-10-19)