# Test Suite — Bank Sampah Faperta

## Test Stack

| Layer | Framework | Location |
|-------|-----------|----------|
| Unit/Component (React) | Vitest + @testing-library/react | `resources/js/**/*.test.jsx` |
| E2E (Full Stack) | Playwright | `tests/e2e/*.spec.js` |
| Feature/Integration (Laravel) | PHPUnit | `tests/Feature/**/*.php` |

---

## Running Tests

```bash
# Unit tests (React components)
npm run test          # single run
npm run test:watch    # watch mode

# E2E tests
npm run test:e2e
npx playwright test --ui    # UI mode

# PHPUnit (Laravel)
./vendor/bin/phpunit

# Run all JS tests
npm run test:all
```

---

## Test Files

### Vitest (React Component Tests)

| File | Feature(s) Tested |
|------|------------------|
| [Welcome.test.jsx](resources/js/Pages/Welcome.test.jsx) | Hero, workflow, schedule, price catalog, articles, contact section, impact counters, partners, conditional rendering (guest/auth) |
| [PriceCatalog.test.jsx](resources/js/Pages/Public/PriceCatalog.test.jsx) | Price listing, search filter, category filter, empty state, Rupiah formatting |
| [ArticleDirectory.test.jsx](resources/js/Pages/Public/ArticleDirectory.test.jsx) | Article grid, card content, empty state, slug links |
| [ArticleView.test.jsx](resources/js/Pages/Public/ArticleView.test.jsx) | Article detail content, sidebar recent articles, CTA, back link, category badge |
| [Contact.test.jsx](resources/js/Pages/Public/Contact.test.jsx) | Hero, address, WhatsApp, Instagram, Email sections, partner visibility, FAQ CTA, map iframe |
| [Dashboard.test.jsx](resources/js/Pages/Nasabah/Dashboard.test.jsx) | Welcome banner, saldo, level/gamification, badges, targets, transactions, pending alert, quick action cards |
| [Withdraw.test.jsx](resources/js/Pages/Nasabah/Withdraw.test.jsx) | Withdrawal methods (cash/transfer), admin fee info, saldo display, rules, form inputs |
| [PickupRequest.test.jsx](resources/js/Pages/Nasabah/PickupRequest.test.jsx) | Form elements, time slots, map section, pickup history, empty state, how-it-works |
| [History.test.jsx](resources/js/Pages/Nasabah/History.test.jsx) | Transaction list, filter tabs (all/deposit/withdrawal), status badges, +/- amounts, empty state |
| [PublicLayout.test.jsx](resources/js/Layouts/PublicLayout.test.jsx) | Nav items, brand, auth buttons, footer, mobile menu toggle, social links |
| [NasabahLayout.test.jsx](resources/js/Layouts/NasabahLayout.test.jsx) | Nav links, user avatar, role label, logout, brand, children rendering |
| [LoginModal.test.jsx](resources/js/Components/Auth/LoginModal.test.jsx) | Modal rendering, email/password inputs, submit button, remember me, switch to register, close button |
| [RegisterModal.test.jsx](resources/js/Components/Auth/RegisterModal.test.jsx) | All form fields, conditional rendering (employment type), email suffix, switch to login |

### Playwright E2E Tests

| File | Feature(s) Tested |
|------|------------------|
| [auth.spec.js](tests/e2e/auth.spec.js) | Login succeed/fail, register, logout, unauthorized redirect, login modal from homepage, modal close/switch, rate limiter |
| [public.spec.js](tests/e2e/public.spec.js) | Beranda, harga (search + filter), artikel, kontak, nav layout, footer, mobile hamburger menu, nav links |
| [nasabah.spec.js](tests/e2e/nasabah.spec.js) | Dashboard (saldo, gamification, activities), jemput (form, history), tarik (methods, rules), riwayat (filters), mobile bottom nav, logout |
| [admin.spec.js](tests/e2e/admin.spec.js) | Dashboard stats, users, trash-prices, deposits, withdrawals, pickup-requests, articles, badges, all site-settings pages, activity-logs, profile, logout |
| [security.spec.js](tests/e2e/security.spec.js) | Unauthorized access (all protected routes), security headers, CSRF, register rate limiting |

### PHPUnit Feature Tests

| File | Feature(s) Tested |
|------|------------------|
| [CmsAccessTest.php](tests/Feature/Admin/CmsAccessTest.php) | Role-based access: guest redirect, super_admin/petugas can access all CMS pages, nasabah blocked |
| [NasabahAccessTest.php](tests/Feature/Admin/NasabahAccessTest.php) | Nasabah portal access control, guest redirect, nasabah pages accessibility |
| [WelcomePublicTest.php](tests/Feature/Admin/WelcomePublicTest.php) | Public page HTTP status codes, site settings rendering |
| [SiteSettingsUpdateTest.php](tests/Feature/Admin/SiteSettingsUpdateTest.php) | Hero, workflow, schedule, contact settings CRUD |
| *(existing)* | Deposit approval/rejection, withdrawal approval/rejection, gamification service, auth, etc. |

---

## data-testid Additions Needed

The codebase currently lacks data-testid attributes. Add these for more resilient E2E tests:

### 1. [PublicLayout.jsx](resources/js/Layouts/PublicLayout.jsx)
| Line | Add |
|------|-----|
| 168 | `data-testid="brand-logo"` |
| 193 | `data-testid="mobile-menu-button"` |
| 196 | `data-testid="mobile-menu-icon"` |
| 225 | `data-testid="btn-login"` |
| 232 | `data-testid="btn-register"` |
| 243 | `data-testid="mobile-menu"` |
| 301 | `data-testid="footer"` |

### 2. [Welcome.jsx](resources/js/Pages/Welcome.jsx)
| Line | Add |
|------|-----|
| 60 | `data-testid="hero-image"` |
| 67 | `data-testid="hero-content"` |
| 97 | `data-testid="cta-daftar"` |
| 133 | `data-testid="impact-waste"` |
| 144 | `data-testid="impact-carbon"` |
| 155 | `data-testid="impact-trees"` |
| 171 | `data-testid="section-workflow"` |
| 247 | `data-testid="section-schedule"` |
| 307 | `data-testid="section-prices"` |
| 370 | `data-testid="section-articles"` |
| 467 | `data-testid="section-contact"` |
| 577 | `data-testid="section-partners"` |

### 3. [Contact.jsx](resources/js/Pages/Public/Contact.jsx)
| Line | Add |
|------|-----|
| 22 | `data-testid="contact-hero"` |
| 59 | `data-testid="contact-map"` |
| 75 | `data-testid="contact-address"` |
| 101 | `data-testid="contact-whatsapp"` |
| 129 | `data-testid="contact-instagram"` |
| 157 | `data-testid="contact-email"` |
| 185 | `data-testid="contact-partners"` |

### 4. [Nasabah/Dashboard.jsx](resources/js/Pages/Nasabah/Dashboard.jsx)
| Line | Add |
|------|-----|
| 44 | `data-testid="welcome-banner"` |
| 83 | `data-testid="saldo-card"` |
| 102 | `data-testid="quick-actions"` |
| 127 | `data-testid="green-impact"` |
| 214 | `data-testid="badge-collection"` |
| 264 | `data-testid="activity-history"` |
| 309 | `data-testid="target-tabungan"` |

### 5. [Nasabah/PickupRequest.jsx](resources/js/Pages/Nasabah/PickupRequest.jsx)
| Line | Add |
|------|-----|
| 210 | `data-testid="page-title"` |
| 220 | `data-testid="pickup-form"` |
| 250 | `data-testid="pickup-map"` |
| 314 | `data-testid="time-slots"` |
| 357 | `data-testid="btn-submit-pickup"` |
| 374 | `data-testid="pickup-history"` |

### 6. [Nasabah/Withdraw.jsx](resources/js/Pages/Nasabah/Withdraw.jsx)
| Line | Add |
|------|-----|
| 46 | `data-testid="page-title"` |
| 54 | `data-testid="method-tunai"` |
| 86 | `data-testid="method-transfer"` |
| 259 | `data-testid="saldo-card"` |
| 339 | `data-testid="withdraw-rules"` |

### 7. [Nasabah/History.jsx](resources/js/Pages/Nasabah/History.jsx)
| Line | Add |
|------|-----|
| 25 | `data-testid="page-title"` |
| 32 | `data-testid="filter-tabs"` |
| 66 | `data-testid="desktop-table"` |
| 135 | `data-testid="mobile-cards"` |

### 8. [Components/Auth/LoginModal.jsx](resources/js/Components/Auth/LoginModal.jsx)
| Line | Add |
|------|-----|
| 43 | `data-testid="btn-close-modal"` |
| 68 | `data-testid="input-email"` |
| 87 | `data-testid="input-password"` |
| 114 | `data-testid="checkbox-remember"` |
| 137 | `data-testid="btn-submit-login"` |

### 9. [Components/Auth/RegisterModal.jsx](resources/js/Components/Auth/RegisterModal.jsx)
| Line | Add |
|------|-----|
| 67 | `data-testid="btn-close-modal"` |
| 96 | `data-testid="input-name"` |
| 119 | `data-testid="input-email"` |
| 137 | `data-testid="input-phone"` |
| 155 | `data-testid="input-age"` |
| 174 | `data-testid="select-gender"` |
| 378 | `data-testid="btn-submit-register"` |

---

## Test Dependencies

```bash
# Already installed via npm:
# vitest, @testing-library/react, @testing-library/jest-dom, jsdom

# For Playwright (already present):
npx playwright install chromium

# For PHPUnit (already present via composer):
./vendor/bin/phpunit
```

---

## data-testid Naming Convention

Use kebab-case prefixed by context:
- `btn-*` — buttons
- `input-*` — form inputs
- `select-*` — select dropdowns
- `section-*` — page sections
- `card-*` — card components
- `modal-*` — modal elements
- `nav-*` — navigation elements

---

## Pre-commit Checklist

Before committing test changes:

- [ ] `npm run test` — all Vitest unit tests pass
- [ ] `./vendor/bin/phpunit` — all PHPUnit tests pass
- [ ] `npx playwright test` — all E2E tests pass (requires running app)
- [ ] No `.only` or `.skip` on tests (unless intentional)
