Task Issue 1041 TcView Executed Attribution - sebiboga/testlink-upgraded GitHub Wiki
Task — Issue #1041: has_been_executed attribution in the Test Case Viewer (EXECUTED badge)
What was missing
The Test Case Viewer shows an EXECUTED badge on a version card
(gui/templates/testcases/tcView.html:425-427, CSS .badge-executed at :38) and, when the
opened version is the executed one, a banner — "This version has been executed and can not be
edited." (tcview.executedNoEdit) or "…has been executed and can be edited."
(tcview.executedCanEdit), rendered by renderBanners() (tcView.html:368-373). The same
flag also hides the Edit button through canEditCurrent() (tcView.html:349), feeds
canAssignPlatforms() (api/testcases/index.php:1167), the relations canEdit
(api/testcases/index.php:1348) and the (✓ executed) marker of the version dropdown in
testSpec.html:955-960.
Legacy derives that flag from testcase::get_versions_status_quo()
(lib/functions/testcase.class.php:3057-3119), called with a single argument from
testcase.class.php:1091 — no tcversion_id, no testplan_id, so every version of the
test case and every test plan is considered. tcView.tpl:113-115 reads
$gui->status_quo[idx][$tcVersionID].executed into $hasBeenExecuted, which gates the marker
(:228), the downloadOnlyAfterExec attachment gate (:192-193, :314) and
tcViewViewer.inc.tpl:90-96.
The gap
The legacy loop does not flag the node an execution row points at:
// lib/functions/testcase.class.php:3102-3116
foreach($rs as $elem) {
$tcvid = null;
if ($elem['tcversion_number'] != $elem['version']) { // recorded number != node version
if (!is_null($elem['tcversion_number'])) {
$tcvid = $version_id[$elem['tcversion_number']]['id']; // -> node whose VERSION NUMBER matches
}
} else {
$tcvid = $elem['tcversion_id']; // -> the execution's own node
}
if (!is_null($tcvid)) { $recordset[$tcvid]['executed'] = $tcvid; }
}
$version_id (:3082) is a version-number → node-id map built over all versions of the
test case.
The modern BFF instead asked:
SELECT DISTINCT tcversion_id FROM executions WHERE tcversion_id IN (...)
which flags the execution's own node and never looks at executions.tcversion_number. On a
healthy install the two coincide, which is why this stayed invisible.
The issue as filed reported the sharper symptom — array_keys() on the numerically indexed
recordset returned by testcase::get_by_id(), producing WHERE tcversion_id IN (0,1) and a
permanently false flag. That part was already repaired by commit 4f549b24f; the
number-based remapping had not been ported.
Measured
Fixture tmp/fixtures_1041.php (project SM1041, suite, plan, three two-version cases). The
ground truth is produced by calling the legacy function live
(php tmp/verify_1041.php), the candidate by calling the BFF over HTTP
(bash tmp/verify_1041.sh).
| case | data | legacy | modern before | modern after |
|---|---|---|---|---|
SM1041EXEC |
execution on the v1 node, tcversion_number=1 |
{1:true, 2:false} |
{1:true, 2:false} |
{1:true, 2:false} |
SM1041NONE |
no execution | {1:false, 2:false} |
{1:false, 2:false} |
{1:false, 2:false} |
SM1041NUMBER |
execution on the v1 node, tcversion_number=2 |
{1:false, 2:true} |
{1:true, 2:false} ✗ |
{1:false, 2:true} |
| A second, smaller divergence fell out of the same read: because the modern flag was derived | ||||
from $versionsRaw, which ?tcversion_id= narrows to a single version, opening one version of |
||||
| a test case silently lost the execution context that legacy (which builds the status quo over | ||||
| all versions) still had. |
The fix
api/testcases/index.php gains one shared helper and both endpoints that expose the flag use
it:
tcVersionExecutedSet($dbHandler, $tcaseId)(api/testcases/index.php:1755-1818) — builds theversion number → node idmap over all versions of the test case, selectsDISTINCT E.tcversion_id, E.tcversion_number, TCV.versionfor every version node across all test plans, and applies the legacy branch verbatim (differing number → the node with that number, matching number → the execution's own node, NULL number → nothing flagged). Returns{tcversion_id: 1}.action=view(api/testcases/index.php:1093-1099) — the inline row-id collection and theIN (...)query are replaced by$executedSet = tcVersionExecutedSet($db, $tcaseId);.action=version_list(api/testcases/index.php:2330-2334) — same call, replacing its own inline query, so the viewer and the test-spec dropdown can no longer disagree. No screen and no i18n change was needed: the flag already drove the badge, the banners andcanEditCurrent()— only the attribution behind them was wrong.
Verification
- Suite 1041 in
tmp/TLU_Test_Cases.md— 14/14 PASS (python3 tmp/suite_1041.py), which diffs the live legacy answer against both endpoints for all three fixture cases plus the?tcversion_id=filter,is_latest, the 404/anonymous paths, theversion_listgrants block and all 10 i18n bundles. - Browser (admin):
SM1041NUMBERnow shows the EXECUTED badge on the "Version 2 LATEST" card with "This version has been executed and can not be edited." — before the fix the badge was on Version 1.SM1041EXECbadges Version 1 only,SM1041NONEbadges nothing, and opening the executed version directly hides the Edit button. - Regression:
bash tmp/verify_1038.sh21 PASS / 0 FAIL; Event Viewerlog_level=16(audit) only from this work; console clean. Commitd05417318(Refs #1041).
