Test Plan Import Modernized - sebiboga/testlink-upgraded GitHub Wiki
Modernization of the legacy Import Test Plan Links screen
(lib/plan/planImport.php, gui/templates/dashio/plan/planImport.tpl) —
tracked in #815.
The legacy Smarty screen is replaced by a standalone Dashio page
(gui/templates/plans/planImport.html) backed by a plain-PHP REST BFF API
(api/planimport/index.php). The Test Plan Management → Import Test Plan
Links toolbar button now opens the modern screen instead of the legacy
planImport.php redirect (the last remaining HIGH-priority redirect from
#754).
Path: Plans → Test Plan Management → row Import icon
URL: gui/templates/plans/planImport.html?tproject_id=..&tplan_id=..
BFF API: GET ?action=info + POST ?action=import on /api/planimport/
Rights: mgt_testplan_create at test project level (legacy parity); 403
without it and the upload button is disabled.


The BFF reproduces lib/plan/planImport.php:
-
Import type: always XML — imports test plan links to test cases and
platforms; items must already exist on the target test project. Next to the
fixed XML badge the File type row shows the "view file format
documentation" link (
/docs/tl-file-formats.pdf, opened in a new tab) — the import XML schema reference ported from legacyplanImport.tpl:37(PARTIAL_URL_TL_FILE_FORMATS_DOCUMENT,cfg/const.inc.php:917); i18n keypli.fileFormatsDoc, same pattern as the requirements importer. -
Upload: multipart field
uploadedFile, size limitimport_file_max_size_bytes(800000), same legacy error strings. -
Platforms: each
<platform>is linked to the plan if it exists on the project and is not already linked; unknown names abort (platform_not_on_tproject). -
Test case links: resolved by
<externalid>within the project; version must exist. If the target plan has platforms, every link must declare a valid platform, otherwiselink_without_platform_element/link_without_required_platform/platform_not_linked. If the plan has no platforms, links must come without a platform element (link_with_platform_not_needed). Hidden-status versions are refused (tcversion_status_forbidden); existing links are updated (execution order). -
Result report:
[message, status]pairs with legacy statusesOK/Not imported.
-
GET ?action=inforesolves the plan (400 missing id, 404 unknown plan), enforcesmgt_testplan_create, returns project/plan names, size limit and a zero-testcase warning when relevant. - User picks an
.xmlfile and clicks Upload file. -
POST ?action=import(multipart,X-Requested-With) saves the file to the session temp path, runs the legacy import pipeline, deletes the temp file and returnsresult_map. - The report card renders each Message/Status row (teal OK vs red Not imported).

- Missing/invalid
tplan_id→ 400 "Error Test Plan ID" - Unknown plan → 404 "Test plan not found"
- Unauthenticated → 401 "Not authenticated"
- No
mgt_testplan_createright → 403 "No permission" + upload disabled - No file → client-side toast "Please choose a file to import."
- File too large → 413 + legacy size message
- Malformed XML → single
simplexml_load_file_wrapper_errorrow, "Not imported"
- Permission (
mgt_testplan_create) enforced on both routes (legacy parity). - XSS: all DOM-bound values escaped; SQL: ids intval'd.
- CSRF / same-origin:
bffSameOriginGuard()+X-Requested-With. - Upload:
move_uploaded_file()into session temp path; temp file removed.
viewActions() in api/plans/index.php now maps importAction →
/gui/templates/plans/planImport.html ✅. Every HIGH-priority #754 redirect
with a modernized target now points at a .html screen; only plan
create/edit (planEdit.php, covered by #750 in-list modal) remain legacy.
All user-facing strings use pli.* keys in all ten locale bundles
(de, en, es, fr, it, ja, pt, ro, ru, zh). Result messages come from the legacy
lang_get() strings, identical to 1.9.20.
Suite 815 in tmp/TLU_Test_Cases.md — 12/12 PASS.