Repository navigation
Test Plan Export Modernized
Modernization of the legacy Export Test Plan screen (lib/plan/planExport.php,
gui/templates/dashio/plan/planExport.tpl) — tracked in
#754.
The legacy Smarty screen is replaced by a standalone Dashio page
(gui/templates/plans/planExport.html) backed by a plain-PHP REST BFF API
(api/planexport/index.php). The Test Plan Management → Export Test Plan
Links toolbar button now opens the modern screen instead of the legacy
planExport.php redirect.
Path: Plans → Test Plan Management → row Export icon
URL: gui/templates/plans/planExport.html?tproject_id=..&tplan_id=..
BFF API: GET ?action=info + POST ?action=export on /api/planexport/
Rights: any authenticated session that can read the plan (parity with legacy).

The BFF reproduces lib/plan/planExport.php:
-
Export content modes (whitelisted, falls back to
linkedItems):-
linkedItems— linked test cases (minimal) and platforms -
tree— complete plan contents (suite tree, summaries, preconditions) -
4results— a format usable to import execution results
-
-
Default filename:
<mode>_<tplan>[+_<platform>][+_<build>].xml(spaces→_) - File type: always XML
-
File formats documentation link: below the File type select the form shows
a "(View file formats documentation)" link pointing to
/docs/tl-file-formats.pdf(opens in a new tab) — parity with the legacyplanExport.tpl:65link /PARTIAL_URL_TL_FILE_FORMATS_DOCUMENT(cfg/const.inc.php:917). Label keypex.viewFileFormatDoc(#1386).

-
GET ?action=inforesolves the plan, builds the default filename and the export-content dropdown (404 on unknown plan). - User picks a mode / file name and clicks Export.
-
POST ?action=exportstreams the XML asapplication/xml+Content-Disposition: attachment(filename CR/LF/quote-sanitized),Pragma: public,Cache-Control: must-revalidate. - Browser saves the XML via blob download; JSON errors surface as a toast.
Legacy parity with lib/plan/planExport.php:142-151 / the execution-window
launch (execNavigator.tpl → openExportTestPlan(...,'4results',form_token),
inc_filter_panel.tpl:204): when the popup is opened with
&form_token=<tree token>, the exported For results import XML is scoped
to the test cases currently shown in the execution window.
-
POST ?action=exportwithform_token>0reads$_SESSION['execution_mode'][token]['testcases_to_show']and passes it as thetcaseSetfilter toexportForResultsToXML()→getLinkedStaticView()restricts the XML viaNH_TCASE.id IN (...). Only the4resultsmode is scoped;linkedItems/treeare unaffected. -
GET ?action=inforeportsform_token+scopedCount; the page keeps a hidden<input name="form_token">(planExport.tpl:48parity) and shows a green hint "Export limited to the N test case(s) currently shown in the execution window" (keypex.scopedNote, 4results mode only). TheexportContentmode passed by the launch URL is also preserved. - Safety: token is
intval-cast before session-array indexing (no array injection); the scope set is read server-side from the session, never from the request. Without a token (Test Plan Management → Export) behaviour is unchanged: 4results exports every linked test case. - Tracked in #1385.

- Invalid
tplan_id→ 400 · Unknown plan → 404 · Unauthenticated → 401 - Empty file name → client-side toast "File name is required."
- JSON error payloads read from the blob and shown as toast (not downloaded)
-
Header injection:
Content-Dispositionfilename stripsCR/LF/" -
XSS: all DOM values escaped via
esc()/.text()/.val() -
SQL injection: ids
intval()-cast, mode whitelisted -
CSRF / same-origin:
bffSameOriginGuard()+X-Requested-With
-
exportAction→planExport.html✅ -
assignRolesAction→usersAssignPlan.html✅ -
gotoExecuteAction→execTest.html✅ -
importAction→ legacyplanImport.php(not yet modernized)
Each modernized base URL uses a clean tplan_id= so the front-end appends the
real plan id (avoids the duplicate-tplan_id bug feeding screen plan 0).
All strings use pex.* keys present in all ten locale bundles
(pex.viewFileFormatDoc added for the documentation link in #1386).
Suite 813 in tmp/TLU_Test_Cases.md — 14/14 PASS.
File-format-doc link (issue #1386) covered by Suite 1498 — 4/4 PASS.
form_token scoping of the 4results export (issue #1385) covered by Suite 1385
— PASS (see tmp/TLU_Test_Cases.md).