Test Plan Export Modernized - sebiboga/testlink-upgraded GitHub Wiki

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

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