Results by Keyword Bar Chart Modernized - sebiboga/testlink-upgraded GitHub Wiki

Results by Keyword Bar Chart β€” Modernized Screen

Modernization of the Results by Keyword Bar Chart report (lib/results/keywordBarChart.php) β€” GitHub issue #1906.

With every ASIDE entry already pointing at a modern screen (docs/MODERNIZATION-STATUS.md: TODO = 0), an exhaustive sweep of the remaining legacy controllers found one last family of live legacy renderers: the four pChart PNG chart endpoints. Three of them β€” plus the Priority Bar Chart (#1845) and the Top Level Suites Bar Chart (#1905) β€” already had modern twins; keywordBarChart.php was the sibling left behind. The modern Graphical Charts screen renders the same pixels (charts_data β†’ by_keyword), but it has no per-keyword DataTable, no progress column, no totals row, no CSV export and no ownership-checked BFF. This screen is now a standalone Dashio page (gui/templates/results/keywordBarChart.html) backed by a plain-PHP REST BFF (api/keywordbarchart/index.php), reachable from the Results by Keyword section of the modern Graphical Charts report.

Path: Results β†’ Graphical Charts β†’ Results by Keyword β†’ Open Results by Keyword Bar Chart URL: gui/templates/results/keywordBarChart.html?tplan_id=N&tproject_id=P BFF API: api/keywordbarchart/index.php (GET|HEAD ?action=init&tplan_id=N[&tproject_id=P]) Legacy URL: lib/results/keywordBarChart.php β€” now a launcher shim (302 / 405 / 400) Auth: session (401 anonymous) + same-origin CSRF guard + the testplan_metrics right on the owning test project (403 otherwise).

1. What the legacy file did

lib/results/keywordBarChart.php never rendered a Smarty template. It required charts.inc.php and answered a PNG of a stacked bar chart: one bar per keyword actually linked to a plan test case, series pass / fail / blocked / not run, over all builds + all platforms. Data came from tlTestPlanMetrics::getStatusTotalsByKeywordForRender() (status totals keyed by keyword id, latest recorded result per test case wins). The chart drew $item_descr = array_flip($dataSet) + ksort(), so keywords appear alphabetically by name β€” the BFF reproduces that map and order exactly. A plan with zero keyword-linked test cases answered nothing (issue #634): the screen shows a localized empty state.

By 2.0.1 the endpoint was a dead end β€” it required two files that no longer exist (third_party/charts/charts.php, lib/functions/results.class.php), so every request was an uncaught fatal (HTTP 500) and no caller reached it.

2. Security gap closed

The legacy gate was a global hasRight('testplan_metrics', ...) that never proved the plan the numbers belonged to; tproject_id came raw from $_REQUEST. The new BFF:

  1. resolves the plan and derives the owning project server-side;
  2. checks testplan_metrics on that owning project and plan with getAccess = true (a right held only globally no longer reaches a private project; an unknown plan is a plain 404, as in the sibling BFFs);
  3. treats tproject_id as a client-side assertion (project_mismatch β†’ 404);
  4. answers the full JSON contract: 400 invalid_request, 401 not_authenticated / session_expired, 403 no_right, 404 tplan_not_found / project_mismatch, 405 method_not_allowed, with nosniff + no-store.

3. The screen

gui/templates/results/keywordBarChart.html follows the #1845/#1905 pattern: Dashio shell, context strip (project, plan, keyword count, version count), a back-to-Charts link, stacked horizontal bars in plain CSS, and a DataTable with the exact numbers, a Totals row and a Progress (executed / total) column. Refresh, Export CSV (RFC 4180 + UTF-8 BOM), Close, and a footer locale switcher. Every label is a bundle key (kwbc.*, footers.keywordBarChart, charts.openKeywordBarChart) in all ten locales — the RomÒnă locale was translated.

Entry points: the charts.html Open Results by Keyword Bar Chart link, the $actions->keywordBarChart registration in lib/functions/common.php (inside the tplan_id guard), and the legacy endpoint now being a session-guarded 302 shim (document β†’ redirect; XHR/<img> β†’ 405 modern_endpoint_only; missing tplan_id β†’ 400; anonymous β†’ login redirect preserving the destination).

4. Empty state

A plan without keyword-linked test cases shows the localized Nothing to chart state with the context strip still rendered:

5. Charts hub entry

The Results by Keyword section of the Graphical Charts report gained the Open Results by Keyword Bar Chart link, beside the #1845/#1905 links:

6. Testing

One fresh-DB end-to-end suite was appended to tmp/TLU_Test_Cases.md (## Task — Issue #1906); 17 steps, all PASS (chart render with a real 2-keyword dataset incl. the latest-wins rule, empty state, CSV export, RomÒnă locale, no_right denial as a restricted role-3 user, the full BFF contract matrix, the shim matrix and the charts.html entry link). events shows no unexpected Error/Warning rows (the single ERROR is the BFF's own intended no_right audit denial exercised by the suite).

⚠️ **GitHub.com Fallback** ⚠️