Skip to content

Test Plan Export Modernized

github-actions[bot] edited this page Sep 14, 2026 · 3 revisions

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

Test Plan Export normal state

Behavior

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 legacy planExport.tpl:65 link / PARTIAL_URL_TL_FILE_FORMATS_DOCUMENT (cfg/const.inc.php:917). Label key pex.viewFileFormatDoc (#1386).

File formats documentation link on the Export form

Flow

  1. GET ?action=info resolves the plan, builds the default filename and the export-content dropdown (404 on unknown plan).
  2. User picks a mode / file name and clicks Export.
  3. POST ?action=export streams the XML as application/xml + Content-Disposition: attachment (filename CR/LF/quote-sanitized), Pragma: public, Cache-Control: must-revalidate.
  4. Browser saves the XML via blob download; JSON errors surface as a toast.

Execution-window scoping of the 4results export (form_token)

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=export with form_token>0 reads $_SESSION['execution_mode'][token]['testcases_to_show'] and passes it as the tcaseSet filter to exportForResultsToXML() → getLinkedStaticView() restricts the XML via NH_TCASE.id IN (...). Only the 4results mode is scoped; linkedItems/tree are unaffected.
  • GET ?action=info reports form_token + scopedCount; the page keeps a hidden <input name="form_token"> (planExport.tpl:48 parity) and shows a green hint "Export limited to the N test case(s) currently shown in the execution window" (key pex.scopedNote, 4results mode only). The exportContent mode 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.

4results export scoped to the 1 execution-window test case

Error handling

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

Security

  • Header injection: Content-Disposition filename strips CR/LF/"
  • XSS: all DOM values escaped via esc()/.text()/.val()
  • SQL injection: ids intval()-cast, mode whitelisted
  • CSRF / same-origin: bffSameOriginGuard() + X-Requested-With

Related redirect fixes (#754)

  • exportAction → planExport.html ✅
  • assignRolesAction → usersAssignPlan.html ✅
  • gotoExecuteAction → execTest.html ✅
  • importAction → legacy planImport.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).

i18n

All strings use pex.* keys present in all ten locale bundles (pex.viewFileFormatDoc added for the documentation link in #1386).

Test coverage

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

Clone this wiki locally