aboutsummaryrefslogtreecommitdiff
path: root/modules/test
diff options
context:
space:
mode:
Diffstat (limited to 'modules/test')
-rw-r--r--modules/test/test-download-url.js55
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);