forked from JavaScriptSolidServer/JavaScriptSolidServer
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathurl.test.js
More file actions
120 lines (102 loc) · 4.68 KB
/
url.test.js
File metadata and controls
120 lines (102 loc) · 4.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/**
* Unit tests for src/utils/url.js
*
* Focus: getPodName() resolution across the four supported deployment modes.
* Regression guard for #278 (single-user root-pod PUT → ENOTDIR).
*/
import { describe, it } from 'node:test';
import assert from 'node:assert';
import { getPodName, getContentType } from '../src/utils/url.js';
describe('getPodName', () => {
describe('subdomain mode', () => {
it('returns request.podName when the subdomain is recognized', () => {
const req = { subdomainsEnabled: true, podName: 'alice', url: '/profile/card' };
assert.strictEqual(getPodName(req), 'alice');
});
it('returns null on base-domain access (no recognized subdomain)', () => {
const req = { subdomainsEnabled: true, podName: null, url: '/anything' };
assert.strictEqual(getPodName(req), null);
});
});
describe('single-user mode', () => {
it("returns '.' for a root pod (singleUserName empty)", () => {
const req = { singleUser: true, singleUserName: '', url: '/index.html' };
assert.strictEqual(getPodName(req), '.');
});
it("returns '.' for a root pod (singleUserName '/')", () => {
const req = { singleUser: true, singleUserName: '/', url: '/index.html' };
assert.strictEqual(getPodName(req), '.');
});
it('returns singleUserName for a named pod, regardless of URL', () => {
const req = { singleUser: true, singleUserName: 'me', url: '/index.html' };
assert.strictEqual(getPodName(req), 'me');
});
it('does not mistake a URL segment for a pod in single-user mode', () => {
// Regression for #278: PUT /index.html previously produced pod
// "index.html", making the quota sidecar path <dataRoot>/index.html/.quota.json.
const req = { singleUser: true, singleUserName: '', url: '/index.html' };
assert.notStrictEqual(getPodName(req), 'index.html');
});
});
describe('path-based multi-pod (default)', () => {
it('returns the first URL segment as the pod name', () => {
const req = { url: '/alice/profile/card' };
assert.strictEqual(getPodName(req), 'alice');
});
it('returns null for requests at /', () => {
const req = { url: '/' };
assert.strictEqual(getPodName(req), null);
});
it('skips system paths beginning with a dot', () => {
const req = { url: '/.well-known/openid-configuration' };
assert.strictEqual(getPodName(req), null);
});
});
describe('string-form input', () => {
it('extracts pod name from a URL path string', () => {
assert.strictEqual(getPodName('/alice/foo'), 'alice');
});
it('returns null for the root path', () => {
assert.strictEqual(getPodName('/'), null);
});
});
});
// Regression coverage for #294 — .acl and .meta must be recognised as RDF
// resources so content negotiation kicks in for Turtle-native clients.
describe('getContentType', () => {
describe('extension-based mapping (existing)', () => {
it('maps .jsonld → application/ld+json', () => {
assert.strictEqual(getContentType('/x/card.jsonld'), 'application/ld+json');
});
it('maps .ttl → text/turtle', () => {
assert.strictEqual(getContentType('/x/card.ttl'), 'text/turtle');
});
it('falls back to application/octet-stream for unknown extensions', () => {
assert.strictEqual(getContentType('/x/file.xyz'), 'application/octet-stream');
});
});
describe('Solid convention dotfiles (#294)', () => {
it('treats .acl as application/ld+json (the format JSS writes it in)', () => {
assert.strictEqual(getContentType('/alice/public/.acl'), 'application/ld+json');
assert.strictEqual(getContentType('.acl'), 'application/ld+json');
});
it('treats .meta as application/ld+json', () => {
assert.strictEqual(getContentType('/alice/public/.meta'), 'application/ld+json');
assert.strictEqual(getContentType('.meta'), 'application/ld+json');
});
it('does not mistake non-dotfile paths containing .acl for ACL files', () => {
// A regular file that happens to have "acl" in its name/path stays
// classified by extension, not by coincidence.
assert.strictEqual(getContentType('/alice/notes/my-acl-plan.md'), 'text/markdown');
});
});
describe('.acl / .meta as extensions (#297)', () => {
it('treats *.acl (extension) as application/ld+json', () => {
assert.strictEqual(getContentType('/settings/publicTypeIndex.jsonld.acl'), 'application/ld+json');
assert.strictEqual(getContentType('/alice/private/secret.json.acl'), 'application/ld+json');
});
it('treats *.meta (extension) as application/ld+json', () => {
assert.strictEqual(getContentType('/alice/resource.meta'), 'application/ld+json');
});
});
});