# BW Agenda Table — Testing

See §10 of PLUGIN.md for the pre-release checklist.

## Manual Test Cases

### Activation / Deactivation

1. Install from zip / copy folder into `wp-content/plugins/`.
2. Activate — no errors with `WP_DEBUG` on.
3. Deactivate — no orphaned cron / transients / options.
4. Reactivate — no errors, block still available.
5. Delete — `uninstall.php` scrubs `bw_agenda_table_settings` and `bw_agenda_table_version` options.

### Editor Insertion

1. Create or edit a page → "+" → search "agenda" → insert **BW Agenda Table**.
2. Block renders demo data immediately in the preview.
3. Open Inspector — all four panels (Layout / Filter / Display / Click action) load without React errors.
4. Toggle each control; preview updates after the ServerSideRender debounce.

### Demo-data fallback

1. Fresh WP install with no `session` CPT registered → block shows demo rows.
2. Admin-only note appears below: "Showing demo data..."
3. Note does **not** appear on the public frontend.

### Live data path

Pre-req: register a `session` CPT (e.g. via theme functions.php or a CPT plugin) and at least three Session posts with `event_date`, `start_time`, `end_time` set.

1. Block switches from demo to live data.
2. Sessions sort chronologically by date + start_time.
3. Sessions sharing the same date+start_time render under one time anchor.
4. Track-tagged sessions show the track badge and coloured left bar.
5. Featured sessions show the featured badge.

### Multi-day data

Pre-req: Sessions across two or more `event_date` values.

1. **Auto** mode renders a real day picker in the header.
2. Day sections render server-side; only the first is visible on initial load.
3. Click the day-trigger → listbox opens, lists all available dates.
4. Select a date → that day's section appears, others hidden.
5. Prev/Next arrows navigate by index, disable at boundaries.
6. Escape key closes the listbox; outside click closes it; focus returns to trigger.
7. With JS disabled (DevTools → Settings → Disable JavaScript), all day sections render stacked with their day heading.

### Field-alias coverage

Verify the block reads from any of the candidate field names listed in README.md → "Session fields". Smoke test: create one Session using `event_date` / `start_time`, another using `date` / `start`. Both should appear and sort correctly.

### Track filter

1. Create two `track` terms (e.g. `track-1`, `track-2`) and one Session under each.
2. Create one Session with no track (plenary).
3. Insert two blocks: one with Track = "track-1", one with Track = "All tracks".
4. "All tracks" shows all three Sessions.
5. "track-1" shows the track-1 Session **plus** the plenary Session (OR-NOT-EXISTS rule).

### Security smoke

- Insert a Session with title `<script>alert(1)</script>` — block renders the title escaped, no script executes.
- Insert a Session with `slides_url` = `javascript:alert(1)` — `esc_url()` strips the JS scheme.
- Inspect rendered HTML for any unescaped attribute or text node.

### Cross-browser

- Chrome (latest), Firefox (latest), Safari (latest), Edge (latest).
- Mobile breakpoint < 720px: thumbnail collapses to 16:9 above the body, time anchor stacks on top of sessions.
