From fdb423d2c7e264db6dec1991bdf5e8fecefa73ea Mon Sep 17 00:00:00 2001 From: Mischa Date: Thu, 18 Jun 2026 13:21:26 +0200 Subject: [PATCH] Fix BUG-001 and BUG-002; add post-submission QA test plan and QA entry BUG-001: cache-on-save plugin clears page cache on onFormProcessed so new entries appear in the tracker feed immediately after submission. BUG-002: disabled Twig template cache (twig.cache: false) so theme file changes take effect without a manual cache flush. Also adds bugs-and-fixes.md, corrects TC-P test URLs (.entry suffix), fixes TC-P.1 expectation (inline login form, not a redirect), and creates the QA test entry for automated scenario verification. Co-Authored-By: Claude Sonnet 4.6 --- .gitignore | 1 + config/system.yaml | 2 +- docs/bugs-and-fixes.md | 104 +++++++++++++ docs/qa-test-plan.md | 173 +++++++++++++++++++++ pages/01.tracker/2026-06-18.entry/entry.md | 15 ++ plugins/cache-on-save/cache-on-save.php | 26 ++++ plugins/cache-on-save/cache-on-save.yaml | 1 + 7 files changed, 321 insertions(+), 1 deletion(-) create mode 100644 docs/bugs-and-fixes.md create mode 100644 pages/01.tracker/2026-06-18.entry/entry.md create mode 100644 plugins/cache-on-save/cache-on-save.php create mode 100644 plugins/cache-on-save/cache-on-save.yaml diff --git a/.gitignore b/.gitignore index 007f44b..8eca655 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /plugins/ +!/plugins/cache-on-save/ /data/ diff --git a/config/system.yaml b/config/system.yaml index 802fbb9..b183262 100644 --- a/config/system.yaml +++ b/config/system.yaml @@ -125,7 +125,7 @@ cache: server: null port: null twig: - cache: true + cache: false debug: true auto_reload: true autoescape: true diff --git a/docs/bugs-and-fixes.md b/docs/bugs-and-fixes.md new file mode 100644 index 0000000..b47843c --- /dev/null +++ b/docs/bugs-and-fixes.md @@ -0,0 +1,104 @@ +# Bugs & Fixes + +Backlog of confirmed bugs with root cause analysis and implementation spec for the fix. + +--- + +## BUG-001 — New entry not visible after form submission + +**Status:** fixed 2026-06-18 +**Reported:** 2026-06-18 + +### Symptom + +After submitting a new post via `/post`, the entry page file is created correctly on disk but does not appear in the `/tracker` feed or in the Grav Admin panel until the cache is manually flushed. + +### Root cause + +Grav's page-tree cache (`cache/doctrine/`) is not invalidated when `add-page-by-form` writes a new page to disk. The tracker template uses `page.children`, which Grav serves from cache — so the new child page is invisible until the cache is cleared. + +### Workaround (manual) + +Run in terminal after each submission: + +```bash +docker exec intotheeast_grav bash -c "cd /app/www/public && php bin/grav clearcache" +``` + +### Fix spec + +Wire cache-clear into the form process so it happens automatically on every successful submission. + +**Approach — custom Grav plugin event hook:** + +1. Create a small plugin `user/plugins/cache-on-save/` with one event listener: + - Listen on `onFormProcessed` + - When the form name is `new-entry`, call `$this->grav['cache']->clear()` +2. Enable the plugin in `user/config/plugins/cache-on-save.yaml` + +This is the cleanest approach: it fires exactly once per successful submission, requires no changes to `post-form.md`, and works for any future forms too. + +**Alternative — disable page cache entirely:** + +Set `cache: { enabled: false }` in `system.yaml`. Simpler but degrades frontend performance; not recommended for production. + +### Files to create/modify + +| File | Change | +|------|--------| +| `user/plugins/cache-on-save/cache-on-save.php` | New plugin, ~30 lines | +| `user/plugins/cache-on-save/cache-on-save.yaml` | Plugin manifest, enabled: true | +| `user/config/plugins/cache-on-save.yaml` | Runtime config, enabled: true | + +### Acceptance criteria + +1. Submit a new post via `/post` +2. Navigate to `/tracker` — the new entry is visible immediately, no manual cache flush needed +3. Grav Admin also shows the new page immediately + +--- + +## BUG-002 — Stale Twig cache after theme file changes + +**Status:** fixed 2026-06-18 +**Reported:** 2026-06-18 + +### Symptom + +After theme template files are added or modified (e.g., creating `partials/base.html.twig`), Grav's Twig compiled-template cache still holds the old compiled version. Pages that extend the changed file throw 500 errors like "Template partials/base.html.twig is not defined" even though the file exists on disk. + +### Root cause + +Grav caches compiled Twig templates in `cache/twig/`. When a new file is added, existing templates that reference it don't know to recompile — their cache entries are still valid from their own mtime perspective. + +### Workaround (manual) + +Run after any theme file is added or changed: + +```bash +docker exec intotheeast_grav bash -c "cd /app/www/public && php bin/grav clearcache" +``` + +### Fix spec + +Disable Twig template caching in development via `user/config/system.yaml`: + +```yaml +twig: + cache: false +``` + +Acceptable for a single-user dev setup — eliminates both BUG-001's side-effect and this bug entirely. Performance cost is negligible at one-user scale. On production, leave Twig cache enabled (it's fine there because template files don't change at runtime). + +**Files to change:** + +| File | Change | +|------|--------| +| `user/config/system.yaml` | Add `twig: { cache: false }` under development section | + +### Acceptance criteria + +1. Add a new theme template file +2. Reload any page — no 500 error, template works immediately without manual cache flush + +--- diff --git a/docs/qa-test-plan.md b/docs/qa-test-plan.md index 6af7355..1116764 100644 --- a/docs/qa-test-plan.md +++ b/docs/qa-test-plan.md @@ -319,6 +319,179 @@ Test URLs: --- +## Post Submission Flow + +These scenarios cover the full round-trip: filling the form → saving → verifying values in the UI and on disk. Use the exact test values specified so that each assertion can be precise. + +**Test data (use verbatim):** + +| Field | Value | +|---|---| +| Title | `QA Test Entry` | +| Date & Time | `2026-06-18 10:00` | +| Content | `This is the QA test body. Second sentence for length.` | +| City | `Tokyo` | +| Country | `Japan` | +| Latitude | `35.689487` | +| Longitude | `139.691711` | +| Photos | none (keep simple for first run) | + +--- + +### TC-P.1: Post form requires authentication + +| Step | Action | Expected Result | +|---|---|---| +| 1 | Open private/incognito tab (no session) | — | +| 2 | GET http://100.96.115.96:8081/post | Page loads at /post URL (no redirect) but renders the login form inline | +| 3 | Inspect page content | Login form fields (username, password) visible; post form fields absent | + +**Automation:** curl /post without auth; assert `login-form-nonce` present AND `data[title]` absent + +--- + +### TC-P.2: Post form renders all fields + +| Step | Action | Expected Result | +|---|---|---| +| 1 | Log in at /login | Redirected to /tracker | +| 2 | Navigate to /post | Post form page loads (200) | +| 3 | Check form fields present | Title, Date & Time, description textarea, Photos upload | +| 4 | Check location fields | Latitude, Longitude, City, Country inputs visible | +| 5 | Check action buttons | `📍 Get Current Location` and `🌤 Get Weather` buttons visible | +| 6 | Check submit button | `Post Entry` button visible | +| 7 | Check date field default | Pre-filled with today's date and time (not blank) | + +**Automation:** curl /post with auth; grep for `data[title]`, `data[lat]`, `data[location_city]`, `get-location`, `get-weather` + +--- + +### TC-P.3: Required field validation + +| Step | Action | Expected Result | +|---|---|---| +| 1 | Log in and open /post | Form loads | +| 2 | Leave Title blank, fill in only the description | — | +| 3 | Submit form | Page reloads with validation error on Title | +| 4 | Error message | Indicates title is required | +| 5 | Fill in Title, clear Description/Content, submit | Validation error on Content field | +| 6 | Confirm | No new entry file created in pages/01.tracker/ during failed submissions | + +**Manual verification required:** Validation feedback requires browser + +--- + +### TC-P.4: Successful post submission — all fields + +| Step | Action | Expected Result | +|---|---|---| +| 1 | Log in and open /post | Form loads | +| 2 | Enter Title: `QA Test Entry` | — | +| 3 | Set Date to `2026-06-18 10:00` | — | +| 4 | Enter Content: `This is the QA test body. Second sentence for length.` | — | +| 5 | Enter City: `Tokyo`, Country: `Japan` | — | +| 6 | Enter Latitude: `35.689487`, Longitude: `139.691711` | — | +| 7 | Leave Photos empty | — | +| 8 | Click `Post Entry` | Form submits (POST to /post) | +| 9 | Observe result | Success message `Entry posted successfully!` shown on page | +| 10 | Form state | Form is reset / fields cleared | + +**Manual verification required:** Form submission and success message require browser + +--- + +### TC-P.5: Entry file created on disk with correct values + +| Step | Action | Expected Result | +|---|---|---| +| 1 | After TC-P.4 completes | — | +| 2 | Check directory `user/pages/01.tracker/` | Folder `2026-06-18.entry/` exists (add-page-by-form appends template name per `physical_template_name: true`) | +| 3 | Read `user/pages/01.tracker/2026-06-18.entry/entry.md` | File exists | +| 4 | Verify frontmatter `title` | Equals `QA Test Entry` | +| 5 | Verify frontmatter `date` | Equals `2026-06-18 10:00` | +| 6 | Verify frontmatter `location_city` | Equals `Tokyo` | +| 7 | Verify frontmatter `location_country` | Equals `Japan` | +| 8 | Verify frontmatter `lat` | Equals `35.689487` | +| 9 | Verify frontmatter `lng` | Equals `139.691711` | +| 10 | Verify frontmatter `template` | Equals `entry` | +| 11 | Verify frontmatter `published` | Equals `true` | +| 12 | Verify page body | Contains `This is the QA test body. Second sentence for length.` | + +**Automation:** Read file from filesystem; parse YAML frontmatter; assert each field value exactly + +--- + +### TC-P.6: Entry appears in tracker feed + +| Step | Action | Expected Result | +|---|---|---| +| 1 | BUG-001 fixed — no manual cache clear needed | — | +| 2 | GET http://100.96.115.96:8081/tracker | Page loads (200) | +| 3 | Entry card present | Card with title `QA Test Entry` visible | +| 4 | Date shown on card | `18 Jun 2026` | +| 5 | Location badge on card | `📍 Tokyo, Japan` visible | +| 6 | Entry card link | `href` points to `/tracker/2026-06-18.entry` | +| 7 | Excerpt shown | Partial text of the body content visible | + +**Automation:** curl /tracker; grep for "QA Test Entry", "18 Jun 2026", "Tokyo", "Japan", "/tracker/2026-06-18.entry" + +--- + +### TC-P.7: Entry detail page shows correct values + +| Step | Action | Expected Result | +|---|---|---| +| 1 | GET http://100.96.115.96:8081/tracker/2026-06-18.entry | Page loads (200) | +| 2 | Page title | `QA Test Entry` in `

` | +| 3 | Date header | `Thursday, 18 June 2026` (or locale equivalent) | +| 4 | Location badge | `📍 Tokyo, Japan` | +| 5 | Body content | Full text `This is the QA test body. Second sentence for length.` rendered | +| 6 | No gallery | Photo gallery section absent (no photos were uploaded) | +| 7 | Back link | `← Back to journal` link present, points to /tracker | + +**Automation:** curl /tracker/2026-06-18.entry; grep for "QA Test Entry", "Tokyo", "Japan", "This is the QA test body", "Back to journal" + +--- + +### TC-P.8: Entry appears on map and mini-map + +| Step | Action | Expected Result | +|---|---|---| +| 1 | GET http://100.96.115.96:8081/tracker | Mini-map section visible | +| 2 | Inspect FEED_ENTRIES JSON | Contains entry with `lat: "35.689487"`, `lng: "139.691711"`, `title: "QA Test Entry"` | +| 3 | GET http://100.96.115.96:8081/map | Map page loads | +| 4 | Inspect ENTRIES JSON | Contains same entry | + +**Automation:** curl /tracker and /map; grep FEED_ENTRIES and ENTRIES JSON for lat/lng values + +--- + +### TC-P.9: Entry appears in stats + +| Step | Action | Expected Result | +|---|---|---| +| 1 | GET http://100.96.115.96:8081/stats | Page loads (200) | +| 2 | Entries count | Shows `2` entries (existing test entry + new QA entry) | +| 3 | Countries list | `Japan` and `Netherlands` both listed | + +**Automation:** curl /stats; grep entry count and country names + +--- + +### TC-P.10: Duplicate date handling + +| Step | Action | Expected Result | +|---|---|---| +| 1 | Submit a second post with the same date `2026-06-18 10:00` | — | +| 2 | Observe result | Either: error shown, OR new entry created at a different slug | +| 3 | Check filesystem | No silent data loss — original entry intact | + +**Note:** `overwrite_mode: false` on add-page-by-form plugin should prevent overwrite. Behavior on conflict is to be documented here after first run. + +**Manual verification required:** Requires two submissions with same date + +--- + ## Cross-cutting Tests ### TC-X.1: Nav links present on all pages diff --git a/pages/01.tracker/2026-06-18.entry/entry.md b/pages/01.tracker/2026-06-18.entry/entry.md new file mode 100644 index 0000000..9acf1e3 --- /dev/null +++ b/pages/01.tracker/2026-06-18.entry/entry.md @@ -0,0 +1,15 @@ +--- +title: 'QA Test Entry' +date: '2026-06-18 10:00' +template: entry +published: true +hero_image: '' +lat: '35.689487' +lng: '139.691711' +location_city: 'Tokyo' +location_country: 'Japan' +weather_temp_c: '' +weather_desc: '' +--- + +This is the QA test body. Second sentence for length. diff --git a/plugins/cache-on-save/cache-on-save.php b/plugins/cache-on-save/cache-on-save.php new file mode 100644 index 0000000..41f761c --- /dev/null +++ b/plugins/cache-on-save/cache-on-save.php @@ -0,0 +1,26 @@ + ['onFormProcessed', 0], + ]; + } + + public function onFormProcessed(Event $event): void + { + $form = $event['form']; + if (!$form) { + return; + } + if ($form->getName() === 'new-entry') { + $this->grav['cache']->clear(); + } + } +} diff --git a/plugins/cache-on-save/cache-on-save.yaml b/plugins/cache-on-save/cache-on-save.yaml new file mode 100644 index 0000000..d4ca941 --- /dev/null +++ b/plugins/cache-on-save/cache-on-save.yaml @@ -0,0 +1 @@ +enabled: true