Results by Keyword Bar Chart Modernized - sebiboga/testlink-upgraded GitHub Wiki
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).
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.
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:
- resolves the plan and derives the owning project server-side;
- checks
testplan_metricson that owning project and plan withgetAccess = true(a right held only globally no longer reaches a private project; an unknown plan is a plain404, as in the sibling BFFs); - treats
tproject_idas a client-side assertion (project_mismatchβ 404); - 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, withnosniff+no-store.
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).
A plan without keyword-linked test cases shows the localized Nothing to chart state with the context strip still rendered:

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

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).