# Laporan Pengujian KabarNikah 1.0.0

Lingkungan: Linux, PHP 8.3.6, SQLite 3.45.1, Chromium (Playwright) untuk uji browser, Node.js 22 untuk worker. Tanggal: 13 November 2026.
Tidak ada pembayaran, email, atau pesan WhatsApp sungguhan yang dikirim selama pengujian. Data uji fiktif (domain `contoh.test`, nomor 62812000xxxxx).

## 1. Tes otomatis — `php kabarnikah/tests/run.php`

Runner menyalin aplikasi ke folder sementara, menjalankan installer, lalu mengirim permintaan HTTP in-process ke aplikasi (tanpa jaringan). Hasil lengkap: `docs/bukti/hasil-tes-otomatis.txt` dan `.json`.

**Hasil: 111 lulus, 0 gagal.**

| Kelompok | Jumlah | Contoh yang diperiksa |
|---|---|---|
| 1. Instalasi | 7 | redirect sebelum instal, kode bootstrap salah ditolak, installer terkunci (404), kode dihapus, tidak ada sandi bawaan |
| 2. Publik & header | 11 | CSP tanpa `unsafe-inline`/`unsafe-eval` + nonce, nosniff, frame-ancestors, 4 demo, traversal URL media, robots.txt, tidak ada testimoni karangan |
| 3. Akun & peran | 9 | `role=admin` saat daftar diabaikan, hash sandi, email ganda (beda huruf besar), CSRF 419, member ke /admin 403, pembatasan percobaan masuk |
| 4. Pembelian manual | 15 | produk terkunci sebelum lisensi & metode bayar, idempotensi checkout, snapshot harga, bukti tidak mengaktifkan hak, bukti privat (member lain/tamu 404), member tidak bisa menyetujui, persetujuan ganda tetap 1 hak, masa aktif 365 hari, audit |
| 5. Editor & undangan | 21 | akses silang draft (404), konflik revisi (409), template tidak bisa diganti lewat data, validasi terbit (422), XSS nama di-escape, URL `javascript:` tidak tersimpan, foto contoh tidak dimuat, draft tidak bocor ke tamu, RSVP/ucapan, honeypot, masa aktif habis (editor 403, publik nonaktif), perpanjangan undangan yang sama |
| 6. Midtrans | 6 | tanda tangan salah 403, tanda tangan benar tetapi status tidak terverifikasi API → tidak lunas, halaman kembali browser tidak melunasi, kunci terenkripsi & tidak tampil |
| 7. Kontak & pesan | 11 | impor CSV ke storage privat, validasi (valid/tidak valid/ganda), CSV baris ditolak, simpan idempoten, isolasi kontak antar-member, netralisasi formula saat ekspor, variabel pesan daftar-putih, normalisasi nomor |
| 8. WhatsApp | 25 | snapshot pesan per penerima, persetujuan wajib, HMAC worker (tanpa/salah/kedaluwarsa 401), nonce replay 409, lease tunggal 409, 1 pesan per nomor + jeda, lease token salah diabaikan, webhook tanda tangan salah 401, ack monoton (read tidak turun), webhook duplikat, kuota & pengembalian, kirim ulang, pengecualian nomor, API key tidak ke browser |
| 9. Admin | 6 | hak manual + audit, blokir mengeluarkan sesi, cadangan dibuat, arsip pemulihan berisi `../` ditolak, traversal unduh cadangan ditolak, pemeriksaan sistem |

Bug yang ditemukan oleh tes ini dan sudah diperbaiki: transaksi `BEGIN IMMEDIATE` tidak di-*rollback* saat terjadi galat (PDO `inTransaction()` bernilai salah setelah `BEGIN` manual) sehingga kunci tulis SQLite tertahan.

## 2. Uji alur di browser (Playwright, Chromium)

| Skrip | Alur | Hasil |
|---|---|---|
| `tools/qa_flow.js` | Admin isi rekening & konfirmasi lisensi → member daftar (390 px) → checkout → unggah bukti → admin setujui → editor: ubah nama (autosave), unggah & pasang foto, isi acara → terbit → halaman publik dengan nama tamu → RSVP & ucapan → RSVP tampil di dasbor → member lain ditolak (404) | Lulus |
| `tools/qa_admin.js` | 14 halaman admin | Semua 200 |
| `tools/qa_wa.js` + `tools/mock_openwa.js` | Admin isi & uji OpenWA → impor CSV (9 baris: 5 valid, 3 tidak valid, 1 ganda) → CSV ditolak → pesan Salam Islami & penolakan variabel asing → QR → tersambung → kampanye → kirim uji → konfirmasi | Lulus |
| Worker Node | 5 penerima + 1 uji: 3 dibaca, 1 gagal (nomor tidak terdaftar), 1 gagal setelah percobaan ulang (503), jeda ±5 dtk, kuota gagal dikembalikan, kampanye "selesai, ada yang gagal" | Sesuai harapan |
| `tools/qa_viewports.js` | 9 halaman publik, 9 member, 6 admin × 360/390/768/1366/1920 px | 8 overflow horizontal ditemukan → diperbaiki → 0 |
| `tools/color_check.js` | Token warna T02 & T03 sebelum/sesudah | Berubah nyata; T03 "Latar panel" diperbaiki |
| Pemantauan host luar | 4 demo, buka & gulir | Hanya embed Google Maps; 0 pelanggaran CSP |

Bukti gambar: `docs/bukti/qa/` (ringkasan admin, editor, undangan publik, impor, QR, kampanye, warna, ponsel 360 px, halaman produk, tangkapan 4 template).

## 3. Instalasi bersih dari paket ZIP

`KabarNikah_Siap_Upload.zip` diekstrak ke folder kosong (682 entri, tanpa jalur berbahaya), `public_html` dilayani server PHP bawaan, lalu:

| Langkah | Hasil |
|---|---|
| Buka `/` sebelum instal | Dialihkan ke `/install` |
| Installer: kode dari baris ke-2 `kabarnikah/storage/install-code.txt`, alamat situs, admin pemilik | Berhasil → halaman masuk |
| Masuk admin → Ringkasan & Pemeriksaan Sistem | Tampil; uji akses folder privat: di luar document root |
| `/install` setelah selesai | 404 (terkunci) |
| `/`, `/desain`, detail produk, demo Istana Kertas, harga, FAQ (390 px) | 200, 0 sumber gagal dimuat |
| `kabarnikah/config/config.php` | Dibuat dengan izin 640 |
| `php kabarnikah/tests/run.php` dari paket hasil ekstrak | 111 lulus, 0 gagal |

Bukti: `docs/bukti/qa/16-instal-bersih-installer.jpg`, `17-instal-bersih-admin.jpg`, `18-instal-bersih-pemeriksaan-sistem.jpg`. Uji ini memakai server bawaan PHP; `.htaccess` (Apache) dan konfigurasi Nginx belum diuji pada server sungguhan.

## 4. Kompatibilitas OpenWA asli (v0.30.0, commit 6bb8b57)

Build dari sumber yang diberikan dijalankan lokal (engine Baileys, tanpa akun WhatsApp tertaut):

| Langkah | Hasil |
|---|---|
| `GET /api/health` + baca sesi dengan API key | OK ("OpenWA terhubung (versi 0.30.0)") |
| Buat sesi; buat ulang nama sama (409) → sesi yang sama ditemukan | OK |
| Daftar webhook dengan 5 event | OK (diterima validator OpenWA) |
| Start sesi → `initializing` → `qr_ready`; QR data URL | OK |
| Kirim teks saat sesi belum tertaut | HTTP 409 → diklasifikasikan "coba lagi" |
| Webhook `session.status` dari OpenWA ke KabarNikah | Tanda tangan HMAC valid, diterapkan |
| Hapus webhook & sesi | OK |

## 5. Aset nyata yang dihasilkan dari aplikasi

- Tangkapan layar 3 posisi + cover per template, video hero ±16 detik per template, video demo landing 31 detik (layar pembuka → katalog → demo → editor nama & warna), gambar fitur editor dan kampanye. Semua direkam dari aplikasi ini dengan data contoh.

## 6. Yang BELUM diuji (jujur)

| Area | Alasan | Saran sebelum produksi |
|---|---|---|
| Pembayaran Midtrans sungguhan (Snap, notifikasi lunas) | Tidak ada kunci sandbox/produksi | Isi kunci Sandbox, lakukan 1 transaksi uji, cek notifikasi & rekonsiliasi |
| Pengiriman email SMTP nyata | Tidak ada kredensial SMTP | Tekan "Kirim email uji" di Pengaturan |
| Pesan WhatsApp ke nomor nyata | Tidak menautkan akun WhatsApp | Uji dengan nomor sendiri memakai "Kirim uji" |
| Shared hosting nyata (Apache/LiteSpeed, cPanel) & Nginx | Diuji dengan server bawaan PHP | Jalankan installer & Pemeriksaan Sistem di server tujuan |
| Safari iOS, Firefox, perangkat fisik | Hanya Chromium (emulasi) | Coba demo & editor di ponsel nyata |
| Beban tinggi/serentak | Tidak ada uji beban | SQLite cocok untuk skala kecil–menengah; pantau bila ramai |
| Pemulihan cadangan penuh di server lain | Validasi & penjadwalan diuji, penukaran berkas belum dicoba lintas server | Uji pulihkan di server staging |
| Kinerja T03/T04 di ponsel kelas bawah | Tidak ada perangkat | Uji di ponsel target |
