# Testing Guide

## Already checked during generation

- `npm run check` (Node.js syntax parsing across sources, scripts and tests).
- Source/API contract review against the supplied MySQL schema.

## Not executed here

Dependency installation timed out; MySQL server was unavailable. Consequently `npm test`, live database transactions, PDF rendering and SMTP were **not** tested end-to-end in this environment. Perform these checks before relying on the API.

## Minimum local checks

1. `npm install` then `npm run check && npm test`.
2. Initialize MySQL 8.0.16+ empty database, then `npm run db:init` and `npm run admin:create ...`.
3. Start API and verify `/health` and Admin login.
4. Create employee + login; verify employee cannot access `/employees`, `/finance/income`, `/payroll/runs` or other employees' payslips (403).
5. Suspend account and confirm login/previous JWT is rejected.
6. Create a financial month; create LKR account; add pending income (balance stays same), received income (credit), paid expense (debit), transfer to another LKR account (aggregate does not change).
7. Close period and assert new income/expense/payroll is rejected.
8. Create payroll run with salary 50,000 + skilled pay 40,000 and EPF base 50,000; verify net 86,000, employer total 97,500; approve and issue payslip; download A4 PDF as employee.
9. Submit leave → email notification pending → approve/reject with reason → decision retained in history; run email worker against a local SMTP testing server.
10. Upload image and PDF; confirm content signature checks and ownership checks on download.
11. Check bank snapshot vs actual ledger balance; snapshots must **not** change current ledger balances.
12. Verify financial report monthly totals and no double counted payroll operating expense.
13. Test interrupted transactions, duplicate unique keys, invalid amounts/dates, and simultaneous requests.

## Browser frontend migration

The last HTML V14 prototype writes to localStorage; it does **not** consume this backend. Replace localStorage reads/writes with authenticated API calls and preserve the role-specific UX. Store JWTs in a carefully designed session mechanism; consider secure HttpOnly cookies with CSRF mitigations for a real deployment.
