Skip to content

Three admin grids never drew a row — and the first bug was hiding two more (TIGER-390) - #371

Merged
WebTigers merged 1 commit into
mainfrom
fix/tiger-390-usedatatables-gate
Oct 25, 2026
Merged

WebTigers merged 1 commit into
mainfrom
fix/tiger-390-usedatatables-gate

Conversation

@WebTigers

Copy link
Copy Markdown
Owner

Found during a UI functional-testing pass. Nothing in the suite renders a page, so none of these four showed up as a failing test.

The chain

# Defect Where
1 Missing useDataTables → layout emits no jQuery/DataTables/tiger.datatable.js Comment_AdminController, Newsletter_AdminController, System_SitesController
2 Wrong service key — method: where the helper reads action: → the /api message names no action comment.admin.js, newsletter.admin.js
3 _dtParams() called with no arguments against array $params → TypeError on every request Comment_Service_Comment::datatable()
4 DataTables' default errMode is alert() → a blocking native dialog, and the failure never reaches the console tiger.datatable.js

Each fix exposed the next. Loading the library revealed the wrong key; fixing the key revealed the TypeError; seeing the TypeError at all required replacing the alert with a console error first.

#1 is the nastiest shape we ship: 200, empty table, zero console errors — because the screen's own guard (if (!window.tigerDataTable) { return; }) is doing exactly what it was written to do. Our cheapest browser detector is "no console errors," and it is blind to this.

Counts for scale: 12 controllers set the flag correctly, 13 grids pass action, 15 services pass $params. These three screens were the gap in each.

Fixes

  • One line in each of the three controller actions.
  • method: → action: in the two grid scripts.
  • _dtParams($params) in the comment service.
  • tiger.datatable.js: errMode = 'throw' (never a dialog), plus an explicit guard that refuses a grid missing {module, service, action} and logs the cause at the call site — so the next occurrence of Add Module: tab the UI (Browse / URL / Upload) + zip upload install #2 is caught by a developer and by the browser probe, with no modal.

Verified in a real browser on dev

All three screens: headers, search, sort and pagination render, the /api call succeeds, the empty state is the grid's own (No data available), console clean.

The errMode + guard change was mutation-checked in-page — re-passing the old shape returns null and logs use `action`, not `method` with no dialog:

{ errMode: "throw",
  returned: null,
  consoleError: "tigerDataTable(#tiger-guard-probe): service needs { module, service, action } — got {\"module\":\"newsletter\",\"service\":\"subscribe\",\"method\":\"datatable\"} (use `action`, not `method`)" }

Comments were switched on for the check and switched back off — off by default is deliberate.

Suites: 1200 unit / 18318 assertions and 1554 integration / 5217 assertions, both green.

Also

tests/ui/README.md now states the harness's scope as decided: scenarios run on demand — no CI job, no promoted-spec directory, no Playwright suite to maintain. A finding becomes a Jira ticket; a statically detectable class of finding belongs in paradigm-scan.php. The empty regression/ directory is gone.

🤖 Generated with Claude Code

https://claude.ai/code/session_013vdyTeoDrGE4hKxt53TsE8

… more (TIGER-390)

Found during a UI functional-testing pass, not by a failing test: nothing in the suite renders a
page, so all four defects below were invisible.

1. MISSING GATE. Comment_AdminController, Newsletter_AdminController and System_SitesController
   draw a DataTables grid but never set `$this->view->useDataTables = true`, so the admin layout
   emitted no jQuery, no DataTables and no tiger.datatable.js. Each screen's JS guards on the
   missing global and returns, so the page served 200 with an empty table and NOT ONE console
   error — the guard doing its job is what hid it. Twelve other controllers set the flag; these
   three were the gap.

2. WRONG SERVICE KEY. tiger.datatable.js reads `service.action`; comment.admin.js and
   newsletter.admin.js passed `method`. So the /api message named no action and the gateway could
   only refuse it. Thirteen other grids pass `action`. This was masked by (1): the code never ran.

3. SERVER-SIDE ARGUMENT. Comment_Service_Comment::datatable() called `$this->_dtParams()` with no
   arguments against a signature that requires `array $params` — a hard TypeError on every
   request, so the moderation queue could never have loaded. Fifteen other call sites pass
   `$params`. Masked by (1) and (2) in turn.

4. A BROWSER DIALOG, against the house rule. DataTables' default errMode is `alert()`, so (3)
   surfaced as a blocking native dialog — which also kept the failure OUT of the console, where
   our cheapest detector looks. tiger.datatable.js now sets errMode to 'throw' and refuses a
   misconfigured grid at the call site with a console error naming the cause, so the next
   occurrence of (2) is caught by a developer, by the browser probe, and without a modal.

Why this chain is the interesting part: each fix exposed the next. Loading the library revealed the
wrong key; fixing the key revealed the TypeError; seeing the TypeError at all required replacing the
alert with a console error first.

Verified in a real browser on dev, all three screens: headers, search, sort and pagination render,
the /api call succeeds, the empty state is the grid's own ("No data available"), and the console is
clean. The errMode + guard change was mutation-checked in-page — re-passing the old `method:` shape
returns null and logs "use `action`, not `method`" with no dialog. Comments were switched on for
the check and switched back off, since off by default is deliberate.

tests/ui/README.md: the harness is scenarios run on demand, by decision — no CI job, no
promoted-spec directory, no Playwright suite. A finding becomes a Jira ticket; a statically
detectable CLASS of finding belongs in paradigm-scan.php.

Suites: 1200 unit / 18318 assertions and 1554 integration / 5217 assertions, both green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013vdyTeoDrGE4hKxt53TsE8
@WebTigers
WebTigers merged commit 07febd9 into main Oct 25, 2026
14 checks passed
@WebTigers
WebTigers deleted the fix/tiger-390-usedatatables-gate branch October 25, 2026 12:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant