← Quay lại mục lục

Bài 9 — Xác thực OTP có timer

Form OTP 6 chữ số với expire timer + max 3 attempts + Resend cooldown. Tổng hợp State Transition + Time-based + Cooldown. Demo: timer 30s, cooldown 15s.

Trung bình #state-transition #otp #timer #cooldown #counter-reset #resend

📱 Bài 9: Xác thực mã OTP có timer

Sau khi đăng ký hoặc đăng nhập, hệ thống gửi mã OTP 6 chữ số qua SMS/Email. Người dùng cần nhập mã trong thời gian quy định để xác thực. Bài này tổng hợp State Transition + Time-based + Cooldown.

⏱️ Để tiện demo: OTP hết hạn sau 30 giây (spec gốc 60s), Resend cooldown 15 giây (spec gốc 30s). Mọi logic khác giữ nguyên.

📌 Test data

  • OTP ban đầu: 123456
  • Sau khi click Resend: sinh OTP mới ngẫu nhiên (hiển thị trong "Demo Info" panel để học viên test).
  • Phone đã nhận OTP: ***-***-7890
  • Max attempts: 3
  • OTP timer: 30 giây
  • Resend cooldown: 15 giây

🔄 State Transition Diagram

Trạng thái hiện tại Sự kiện Trạng thái kế tiếp Output mong đợi
S0 — OTP active, timer chạy Nhập OTP đúng SUCCESS Verification successful + timer DỪNG + form lock
S0 Nhập OTP sai (lần 1) S1 Invalid OTP. 2 attempts remaining
S1 Nhập OTP sai (lần 2) S2 Invalid OTP. 1 attempt remaining
S2 Nhập OTP sai (lần 3) BLOCKED Too many failed attempts. Account temporarily blocked.
S0/S1/S2 Hết 30s timer EXPIRED OTP expired. Please click Resend to receive a new code.
EXPIRED Nhập OTP cũ (kể cả đúng) EXPIRED Vẫn báo expired — không chấp nhận
S1/S2/EXPIRED Click Resend (sau cooldown 15s) S0 OTP mới sinh, timer reset 30s, attempt counter reset 0
Bất kỳ state nào Click Resend khi đang cooldown Giữ nguyên Button bị disable / message Please wait N seconds
BLOCKED Submit / Resend Giữ nguyên Tất cả thao tác bị từ chối

📝 Message expected

Trường hợpMessage
Chưa nhập đủ 6 sốPlease input full 6-digit OTP
OTP sai (còn N attempts)Invalid OTP. N attempts remaining (số ít: 1 attempt remaining)
OTP hết hạnOTP expired. Please click Resend to receive a new code.
Quá 3 lần saiToo many failed attempts. Account temporarily blocked.
Click Resend khi đang cooldownPlease wait N seconds before requesting a new OTP
OTP đúngVerification successful

🎯 Yêu cầu công việc

  1. Vẽ State Transition Diagram đầy đủ (S0 → S1 → S2 → BLOCKED, S0/S1/S2 → EXPIRED → S0 sau Resend, SUCCESS).
  2. Thiết kế test case cover các transition + edge cases:
    • Happy path: Nhập OTP đúng ngay lần đầu.
    • Sai 1/2 lần rồi đúng: counter có reset không sau success?
    • Sai 3 lần liên tiếp: block đúng cách?
    • Expired: đợi 30s, thử OTP cũ → phải bị từ chối.
    • Resend khi đang cooldown: button bị disable hay vẫn click được?
    • Resend sau cooldown: OTP mới có thay thế OTP cũ? Counter có reset?
    • Resend khi đã sai 2 lần: sau Resend, counter có về 0 hay vẫn là 2?
    • SUCCESS: timer còn chạy không? Form có lock không? Click verify lần nữa được không?
    • OTP rỗng / chưa đủ 6 số: có tính như 1 attempt không?
    • OTP có ký tự không phải số: hệ thống xử lý ra sao?
  3. Sang tab "🧪 Form thực hành" để thực hiện test.
  4. Ghi nhận các bug phát hiện được.
💡 Gợi ý kỹ thuật test:
  • State Transition Testing với 5 states + multiple transitions, đặc biệt time-based (EXPIRED).
  • 1-switch coverage: cover các cặp transition liên tiếp như "S1 → Resend → S0 → đúng" để test counter reset.
  • Time-based testing: kiên nhẫn đợi timer hết để test EXPIRED state.
  • Concurrent click: thử click Resend nhanh nhiều lần để test cooldown enforcement.
  • Pluralization: chú ý 1 attempt (số ít) vs 2 attempts (số nhiều); 1 second vs 2 seconds.
  • Form behavior khi BLOCKED/SUCCESS: input và button có thực sự disable không?
  • Refresh trang sẽ reset state — đây là demo client-side, "intended" trong scope demo.
⚠️ Lưu ý: Form có cài cắm bug ở các vùng: timer behavior, OTP expiry logic, attempt counter reset, resend cooldown enforcement, message text. Bài này có nhiều logic time-based đan xen — hãy test kiên nhẫn.
🔐

Vui lòng đăng nhập để nộp bài.

Đăng nhập
🔐

Tab dành cho giảng viên

Tab này chứa danh sách các lỗi đã cài cắm trong form. Vui lòng nhập mã giảng viên để mở khóa. Mã sẽ ghi nhớ trong phiên làm việc — chỉ cần nhập 1 lần cho cả 3 bài.