diff options
Diffstat (limited to 'modules/test')
| -rw-r--r-- | modules/test/test-download-url.js | 55 |
1 files changed, 38 insertions, 17 deletions
diff --git a/modules/test/test-download-url.js b/modules/test/test-download-url.js index 63cabde..7815aae 100644 --- a/modules/test/test-download-url.js +++ b/modules/test/test-download-url.js @@ -1,7 +1,13 @@ // node modules/test/test-download-url.js -// Regression guard for the download/share URL space (2026-10-21). -// The URL must follow the WebDAV config (the logged-in user's space), NOT the -// page path — /spaces/newos4/ is the app, not the user. +// Regression guard for the download/share URL space (2026-10-21, tightened 2026-10-24). +// The URL must follow the WebDAV config (the logged-in user's space), NOT the page path — +// /spaces/newos4/ is the app, not the user. +// +// 2026-10-24 (T6): this test used to re-implement both helpers locally, so it passed 4/4 +// whatever filemgr.js did. It now requires the shipped functions. +const { fmDetectSpaceName, fmExtractSpaceNameFromUrl, fmBuildShareUrl } = + require('../ext/filemgr.js'); + const cases = [ { page: '/spaces/newos4/', cfg: 'https://webx11.duckdns.org/spaces/agando/', want: 'agando' }, { page: '/spaces/newos4/', cfg: 'https://webx11.duckdns.org/spaces/mindtech/', want: 'mindtech' }, @@ -9,24 +15,39 @@ const cases = [ { page: '/spaces/newos4/', cfg: '', want: 'newos4' }, // no config → fall back to the page space ]; -function detectSpaceName(path) { - const parts = path.split('/').filter(Boolean); - const i = parts.indexOf('spaces'); - return (i >= 0 && i + 1 < parts.length) ? parts[i + 1] : ''; -} -function extractSpaceNameFromUrl(url) { - if (!url) return ''; - const parts = new URL(url).pathname.split('/').filter(Boolean); - const i = parts.indexOf('spaces'); - return (i >= 0 && i + 1 < parts.length) ? parts[i + 1] : ''; -} - let bad = 0; for (const c of cases) { - const got = extractSpaceNameFromUrl(c.cfg) || detectSpaceName(c.page); + const got = fmExtractSpaceNameFromUrl(c.cfg) || fmDetectSpaceName(c.page); const ok = got === c.want; if (!ok) bad++; console.log((ok ? 'PASS' : 'FAIL'), c.page, 'cfg=' + (c.cfg || '(none)'), '→', got, '(want', c.want + ')'); } -console.log(bad ? `\n${bad} FAILED` : `\n${cases.length} PASS`); + +// T5: an unresolved space must produce null — never a "spaces//" URL. +{ + const got = fmBuildShareUrl('', 'docs/x.md'); + const ok = got === null; + if (!ok) bad++; + console.log((ok ? 'PASS' : 'FAIL'), 'empty space →', got, '(want null)'); +} + +// Paths with spaces must be percent-encoded per segment. +{ + const got = fmBuildShareUrl('newos4', 'docs/a file/b&c.md'); + const want = 'https://webx11.duckdns.org/spaces/newos4/docs/a%20file/b%26c.md'; + const ok = got === want; + if (!ok) bad++; + console.log((ok ? 'PASS' : 'FAIL'), 'encoded path →', got); +} + +// Belt and braces: no case may ever produce a double slash after /spaces/. +for (const c of cases) { + const url = fmBuildShareUrl(fmExtractSpaceNameFromUrl(c.cfg) || fmDetectSpaceName(c.page), 'docs/x.md'); + if (url && url.indexOf('/spaces//') !== -1) { + bad++; + console.log('FAIL double space slash →', url); + } +} + +console.log(bad ? `\n${bad} FAILED` : `\n${cases.length + 2} PASS`); process.exit(bad ? 1 : 0); |