-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathpod.test.js
More file actions
163 lines (134 loc) · 5.12 KB
/
pod.test.js
File metadata and controls
163 lines (134 loc) · 5.12 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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/**
* Pod lifecycle tests
*/
import { describe, it, before, after } from 'node:test';
import assert from 'node:assert';
import {
startTestServer,
stopTestServer,
request,
createTestPod,
assertStatus,
assertHeader,
assertHeaderContains
} from './helpers.js';
describe('Pod Lifecycle', () => {
before(async () => {
await startTestServer();
});
after(async () => {
await stopTestServer();
});
describe('POST /.pods', () => {
it('should create a new pod', async () => {
const res = await request('/.pods', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'alice' })
});
assertStatus(res, 201);
assertHeader(res, 'Location');
const data = await res.json();
assert.strictEqual(data.name, 'alice');
assert.ok(data.webId.endsWith('/alice/profile/card.jsonld#me'));
assert.ok(data.podUri.endsWith('/alice/'));
});
it('should reject duplicate pod names', async () => {
// First create
await request('/.pods', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'bob' })
});
// Duplicate attempt
const res = await request('/.pods', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'bob' })
});
assertStatus(res, 409);
});
it('should reject invalid pod names', async () => {
const res = await request('/.pods', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: '../evil' })
});
assertStatus(res, 400);
});
it('should reject empty pod name', async () => {
const res = await request('/.pods', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({})
});
assertStatus(res, 400);
});
});
describe('Pod Structure', () => {
it('should create standard folders', async () => {
await createTestPod('carol');
// Check inbox exists (needs auth - inbox only allows public append, not read)
const inbox = await request('/carol/inbox/', { auth: 'carol' });
assertStatus(inbox, 200);
// Check public exists (public read via root ACL default)
const pub = await request('/carol/public/');
assertStatus(pub, 200);
// Check private exists (needs auth)
const priv = await request('/carol/private/', { auth: 'carol' });
assertStatus(priv, 200);
// Check Settings exists (needs auth)
const settings = await request('/carol/settings/', { auth: 'carol' });
assertStatus(settings, 200);
});
it('should create settings files', async () => {
await createTestPod('dan');
// Check prefs.jsonld (needs auth - settings is private)
const prefs = await request('/dan/settings/prefs.jsonld', { auth: 'dan' });
assertStatus(prefs, 200);
// Check public type index (needs auth)
const pubIndex = await request('/dan/settings/publicTypeIndex.jsonld', { auth: 'dan' });
assertStatus(pubIndex, 200);
// Check private type index (needs auth)
const privIndex = await request('/dan/settings/privateTypeIndex.jsonld', { auth: 'dan' });
assertStatus(privIndex, 200);
});
it('should make publicTypeIndex publicly readable but keep privateTypeIndex private', async () => {
await createTestPod('elsa');
// publicTypeIndex: no auth required (per Solid Type Indexes spec)
const pubIndex = await request('/elsa/settings/publicTypeIndex.jsonld');
assertStatus(pubIndex, 200);
// privateTypeIndex: auth required
const privIndex = await request('/elsa/settings/privateTypeIndex.jsonld');
assertStatus(privIndex, 401);
// prefs: auth required (private by inheritance from /settings/)
const prefs = await request('/elsa/settings/prefs.jsonld');
assertStatus(prefs, 401);
});
it('should mark type indexes as ListedDocument / UnlistedDocument', async () => {
await createTestPod('frida');
const pub = await request('/frida/settings/publicTypeIndex.jsonld');
assertStatus(pub, 200);
const pubBody = await pub.json();
assert.ok(
Array.isArray(pubBody['@type']) && pubBody['@type'].includes('solid:ListedDocument'),
'publicTypeIndex should be solid:ListedDocument'
);
assert.ok(
Array.isArray(pubBody['@type']) && pubBody['@type'].includes('solid:TypeIndex'),
'publicTypeIndex should be solid:TypeIndex'
);
const priv = await request('/frida/settings/privateTypeIndex.jsonld', { auth: 'frida' });
assertStatus(priv, 200);
const privBody = await priv.json();
assert.ok(
Array.isArray(privBody['@type']) && privBody['@type'].includes('solid:UnlistedDocument'),
'privateTypeIndex should be solid:UnlistedDocument'
);
assert.ok(
Array.isArray(privBody['@type']) && privBody['@type'].includes('solid:TypeIndex'),
'privateTypeIndex should be solid:TypeIndex'
);
});
});
});