Add browser and unit test suite with Pest + Playwright
Add comprehensive test coverage for core site features (content, navigation, language, FAQ, news, petition, newsletter) using Pest browser tests and unit tests for custom plugins. Includes test infrastructure (Containerfile.test, compose.test.yaml), test documentation, and test files covering petition form logic, CSV handling, translation, date formatting, rate limiting, and map data building.
This commit is contained in:
parent
0b61643ec5
commit
b8e6d2537d
20 changed files with 1331 additions and 33 deletions
58
AGENT.md
58
AGENT.md
|
|
@ -1,6 +1,6 @@
|
|||
# Stopp lidelsen - Site built on FolderWeb
|
||||
|
||||
Advocacy site for medical cannabis patients in Norway. Built on FolderWeb (minimal file-based CMS).
|
||||
Advocacy site for medical cannabis patients in Norway. Built on FolderWeb (minimal file-based CMS). Decade-scale maintainability, no volatile dependencies, only essential code.
|
||||
|
||||
## Edit instructions
|
||||
All edits to this AGENT.md file should be done in a compressed shortform for LLM consumption.
|
||||
|
|
@ -9,24 +9,21 @@ All edits to this AGENT.md file should be done in a compressed shortform for LLM
|
|||
|
||||
- `app/` is a **symlink** to the FolderWeb framework (`folderweb/app`). **NEVER modify files in `app/`.**
|
||||
- Only modify files in `custom/`, `content/`, and project root.
|
||||
- Framework docs: read `app/docs/` when needed for understanding routing, hooks, templates, etc.
|
||||
- Site-specific docs: read `docs/` in this repo for guidance on this site's features and customizations.
|
||||
- Framework docs: `../folderweb/docs/04-development/` (architecture, context API, hooks/plugins, rendering, templates, etc.)
|
||||
- Site-specific docs: `docs/` in this repo.
|
||||
|
||||
## Philosophy
|
||||
Minimal PHP for modern conveniences. Decade-scale maintainability. No volatile dependencies. Only essential code.
|
||||
## Standards
|
||||
|
||||
## Core Constraints
|
||||
**Stack:** HTML5, PHP 8.4+, CSS. no frameworks, no build tools, no package managers.
|
||||
**Stack:** HTML5, PHP 8.4+, CSS. No frameworks, no build tools, no package managers.
|
||||
|
||||
**Frontend:** Classless semantic HTML5. Modern CSS (nesting, `oklch()`, grid, `clamp()`, logical props). Responsive via fluid typography + flexible layouts. Comments only for major sections.
|
||||
**PHP:** Arrow functions, null coalescing, match. Type hints where practical. Single-purpose functions, avoid side effects.
|
||||
|
||||
**CSS:** Variables, native nesting, grid. `clamp()` over `@media`. Relative units. `oklch()`, `light-dark()`, logical props. Margin-top only (reset: `* { margin-bottom: 0 }`).
|
||||
|
||||
**HTML/Templates:** Classless semantic HTML5. `<?= htmlspecialchars($var) ?>` for UGC. `<?= $content ?>` for pre-rendered HTML.
|
||||
|
||||
**Security:** Path traversal protection, document root restriction, strict MIME types, escape all UGC, CSV injection prevention.
|
||||
|
||||
## Code Style
|
||||
**PHP:** Arrow functions, null coalescing, match. Type hints where practical. Single-purpose functions.
|
||||
**CSS:** Variables, native nesting, grid. `clamp()` over `@media`. Relative units. Margin-top only (reset: `* { margin-bottom: 0 }`).
|
||||
**Templates:** `<?= htmlspecialchars($var) ?>` for UGC. `<?= $content ?>` for pre-rendered HTML.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
|
|
@ -43,35 +40,30 @@ app/ -> symlink # FolderWeb framework (DO NOT EDIT)
|
|||
docs/ # Site-specific LLM documentation
|
||||
```
|
||||
|
||||
## Key Features
|
||||
|
||||
**Content:** Folders = URLs. `metadata.ini` controls titles, slugs, menu order, templates, feeds.
|
||||
**Languages:** Norwegian (default), English available. Language plugin via `[en]` sections in metadata.
|
||||
**Templates:** base.php wraps all pages. List templates: list.php, list-card-grid.php, list-faq.php, list-grid.php. Selected via `page_template` in metadata.
|
||||
**Atom feeds:** Enabled per-section via `feed = true` in metadata. URL: `/{section}/feed.xml`. Feed link auto-added to `<head>` when `$feedUrl` is set.
|
||||
**Petition system:** GDPR-compliant, CSV-based, double opt-in email confirmation, file locking, rate limiting. See `docs/petition-system.md`.
|
||||
**Newsletter:** Listmonk integration via public API. Hero and small themes. See `docs/newsletter-plugin.md`.
|
||||
Content: folders = URLs, numbered file prefixes control order, `cover.jpg` for list item images, `metadata.ini` controls titles/slugs/menu order/templates/feeds.
|
||||
|
||||
## Knowledge Base
|
||||
|
||||
Read these docs on-demand when working on related areas:
|
||||
Read on-demand:
|
||||
|
||||
| Topic | File | Read When |
|
||||
|---|---|---|
|
||||
| Templates & variables | `docs/templates.md` | Modifying templates, understanding available variables |
|
||||
| Content & metadata | `docs/content-system.md` | Adding/modifying content, metadata fields, feeds |
|
||||
| Petition system | `docs/petition-system.md` | Modifying petition form, CSV format, email flow |
|
||||
| Newsletter plugin | `docs/newsletter-plugin.md` | Modifying newsletter signup, Listmonk integration |
|
||||
| Framework internals | `app/docs/` | Understanding routing, hooks, plugins, rendering pipeline |
|
||||
| Topic | File |
|
||||
|---|---|
|
||||
| Templates & variables | `docs/templates.md` |
|
||||
| Content & metadata | `docs/content-system.md` |
|
||||
| Petition system | `docs/petition-system.md` |
|
||||
| Newsletter plugin | `docs/newsletter-plugin.md` |
|
||||
| Framework internals | `../folderweb/docs/04-development/` |
|
||||
| Test suite | `tests/README.md` | **Required before modifying `custom/` or `content/`** — workflow, how to run, how to write tests |
|
||||
|
||||
Site features: Norwegian (default) + English via `[en]` metadata sections. Atom feeds via `feed = true` in metadata. Petition: GDPR, CSV, double opt-in, rate limiting. Newsletter: Listmonk API, hero/small themes.
|
||||
|
||||
## Development Environment
|
||||
|
||||
Host has no PHP. Always use `podman compose` with `compose.yaml`.
|
||||
|
||||
**Dev server:** `localhost:4040`
|
||||
**Testing:** `curl localhost:4040/path` to fetch pages; `curl -X POST -d "field=value" localhost:4040/path` for forms
|
||||
**Container isolation:** ALL test data (CSV, temp files) MUST stay inside container filesystem, never in mounted volumes
|
||||
**Test data paths:** Use `/tmp/` or `/var/test/` inside container
|
||||
**Running tests:** `podman exec stopplidelsen.no php /path/to/test.php` or `podman-compose run --rm custom php /tmp/test-script.php`
|
||||
**Verification:** `curl localhost:4040/path`; `curl -X POST -d "field=value" localhost:4040/path` for forms
|
||||
**Container isolation:** ALL test data MUST stay inside container filesystem, never in mounted volumes. Use `/tmp/` or `/var/test/`.
|
||||
**Running scripts:** `podman exec stopplidelsen.no php /path/to/test.php`
|
||||
**Syntax checks:** `podman exec stopplidelsen.no php -l /var/www/custom/file.php`
|
||||
**Cleanup:** `podman-compose down && podman-compose up -d` between test runs
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue