@interop/was-conformance-suite 0.14.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +1 -0
  2. package/dist/helpers.d.ts.map +1 -1
  3. package/dist/helpers.js +3 -6
  4. package/dist/helpers.js.map +1 -1
  5. package/dist/suites/authz-ordering-api.d.ts.map +1 -1
  6. package/dist/suites/authz-ordering-api.js +1 -26
  7. package/dist/suites/authz-ordering-api.js.map +1 -1
  8. package/dist/suites/blinded-index-api.d.ts.map +1 -1
  9. package/dist/suites/blinded-index-api.js +2 -4
  10. package/dist/suites/blinded-index-api.js.map +1 -1
  11. package/dist/suites/changes-query-api.js +1 -1
  12. package/dist/suites/changes-query-api.js.map +1 -1
  13. package/dist/suites/chunks-api.js +1 -1
  14. package/dist/suites/chunks-api.js.map +1 -1
  15. package/dist/suites/client-spaces.d.ts.map +1 -1
  16. package/dist/suites/client-spaces.js +19 -6
  17. package/dist/suites/client-spaces.js.map +1 -1
  18. package/dist/suites/collection-api.d.ts.map +1 -1
  19. package/dist/suites/collection-api.js +317 -126
  20. package/dist/suites/collection-api.js.map +1 -1
  21. package/dist/suites/conditional-requests-api.d.ts.map +1 -1
  22. package/dist/suites/conditional-requests-api.js +122 -30
  23. package/dist/suites/conditional-requests-api.js.map +1 -1
  24. package/dist/suites/delegation-cryptosuites-api.js +1 -1
  25. package/dist/suites/delegation-cryptosuites-api.js.map +1 -1
  26. package/dist/suites/denial-reasons-api.d.ts.map +1 -1
  27. package/dist/suites/denial-reasons-api.js +5 -2
  28. package/dist/suites/denial-reasons-api.js.map +1 -1
  29. package/dist/suites/digest-api.js +1 -1
  30. package/dist/suites/digest-api.js.map +1 -1
  31. package/dist/suites/encryption-descriptor-api.d.ts.map +1 -1
  32. package/dist/suites/encryption-descriptor-api.js +48 -51
  33. package/dist/suites/encryption-descriptor-api.js.map +1 -1
  34. package/dist/suites/governed-log-api.d.ts.map +1 -1
  35. package/dist/suites/governed-log-api.js +18 -17
  36. package/dist/suites/governed-log-api.js.map +1 -1
  37. package/dist/suites/index.d.ts +2 -1
  38. package/dist/suites/index.d.ts.map +1 -1
  39. package/dist/suites/index.js +3 -1
  40. package/dist/suites/index.js.map +1 -1
  41. package/dist/suites/invocation-target-api.js +1 -1
  42. package/dist/suites/invocation-target-api.js.map +1 -1
  43. package/dist/suites/plaintext-declaration-api.d.ts.map +1 -1
  44. package/dist/suites/plaintext-declaration-api.js +24 -15
  45. package/dist/suites/plaintext-declaration-api.js.map +1 -1
  46. package/dist/suites/policy-api.js +1 -1
  47. package/dist/suites/policy-api.js.map +1 -1
  48. package/dist/suites/reserved-methods-api.d.ts +9 -0
  49. package/dist/suites/reserved-methods-api.d.ts.map +1 -0
  50. package/dist/suites/reserved-methods-api.js +549 -0
  51. package/dist/suites/reserved-methods-api.js.map +1 -0
  52. package/dist/suites/resource-api.js +1 -1
  53. package/dist/suites/resource-api.js.map +1 -1
  54. package/dist/suites/spaces-api.d.ts.map +1 -1
  55. package/dist/suites/spaces-api.js +193 -63
  56. package/dist/suites/spaces-api.js.map +1 -1
  57. package/dist/suites/write-validation-api.d.ts.map +1 -1
  58. package/dist/suites/write-validation-api.js +16 -36
  59. package/dist/suites/write-validation-api.js.map +1 -1
  60. package/package.json +6 -6
@@ -0,0 +1,549 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * WAS conformance tests -- Methods at Reserved Endpoints (spec "Methods at
6
+ * Reserved Endpoints").
7
+ *
8
+ * A request to a reserved endpoint (see the spec's three Reserved Path
9
+ * Segment Registry tables) with a method the server does not implement there
10
+ * MUST be answered `405 Method Not Allowed`, with an `Allow` header naming
11
+ * the methods it does implement, an `about:blank` problem type, and the
12
+ * title "Method Not Allowed". An endpoint whose whole feature group is an
13
+ * OPTIONAL extension the server does not implement at all is instead
14
+ * governed by that group's own rule -- typically `unsupported-operation`
15
+ * (501) -- so most cases here accept a 501 in place of the 405. Every case
16
+ * is still required, since either answer is spec-conformant and any other
17
+ * answer is not. A method this specification never assigns an operation to
18
+ * anywhere (`PATCH`), and the container-URL `PUT` refusal, carry no 501
19
+ * escape.
20
+ *
21
+ * Every request is a signed root invocation by Alice: several reserved
22
+ * endpoints require authorization for unsafe methods before the refusal is
23
+ * ever reached (`requireAuthHeadersOrPublicRead` lets only safe methods
24
+ * through unauthenticated), so signing throughout keeps every case on the
25
+ * same footing. Raw `signCapabilityInvocation` + `fetch` is used instead of
26
+ * the high-level `ZcapClient.request()` so arbitrary methods (`PATCH`,
27
+ * `HEAD`) and bodyless success responses can be inspected directly, without
28
+ * the high-level client's success-body JSON parsing or its throw-on-4xx/5xx
29
+ * behavior getting in the way.
30
+ */
31
+ import { signCapabilityInvocation } from '@interop/http-signature-zcap-invoke';
32
+ import assert from '../harness/assert.js';
33
+ /**
34
+ * Signs a raw capability invocation for an arbitrary method and sends it via
35
+ * `fetch`, returning the response untouched.
36
+ *
37
+ * @param options {object}
38
+ * @param options.url {string} the target URL
39
+ * @param options.method {string} the HTTP method to send
40
+ * @param options.invocationSigner {ISigner} the caller's signer
41
+ * @param [options.json] {object} an optional JSON body
42
+ * @returns {Promise<Response>}
43
+ */
44
+ async function signedRequest({ url, method, invocationSigner, json }) {
45
+ const body = json === undefined
46
+ ? undefined
47
+ : new TextEncoder().encode(JSON.stringify(json));
48
+ const signatureHeaders = await signCapabilityInvocation({
49
+ url,
50
+ method,
51
+ headers: {
52
+ date: new Date().toUTCString(),
53
+ ...(body !== undefined && { 'content-type': 'application/json' })
54
+ },
55
+ ...(body !== undefined && { body }),
56
+ invocationSigner,
57
+ capabilityAction: method
58
+ });
59
+ return fetch(url, {
60
+ method,
61
+ headers: signatureHeaders,
62
+ ...(body !== undefined && { body: new Blob([body]) })
63
+ });
64
+ }
65
+ /**
66
+ * Reads a `application/problem+json` body, or `undefined` for a bodyless
67
+ * response.
68
+ *
69
+ * @param response {Response}
70
+ * @returns {Promise<any>}
71
+ */
72
+ async function readProblem(response) {
73
+ const text = await response.text();
74
+ return text ? JSON.parse(text) : undefined;
75
+ }
76
+ /**
77
+ * Splits an `Allow` header into its method tokens.
78
+ *
79
+ * @param allow {string | null}
80
+ * @returns {string[]}
81
+ */
82
+ function allowedMethods(allow) {
83
+ return (allow ?? '')
84
+ .split(',')
85
+ .map(entry => entry.trim())
86
+ .filter(Boolean);
87
+ }
88
+ /**
89
+ * Sends a signed request for a method this specification does not define at
90
+ * `url`, and asserts the spec "Methods at Reserved Endpoints" refusal: `405`,
91
+ * an `Allow` header that does not name the refused method, and an
92
+ * `about:blank` problem body titled "Method Not Allowed". When `tolerate501`
93
+ * is set, a `501 unsupported-operation` is also accepted -- the endpoint's
94
+ * whole feature group may be unimplemented, in which case the group's own
95
+ * rule governs instead of this subsection.
96
+ *
97
+ * @param options {object}
98
+ * @param options.invocationSigner {ISigner}
99
+ * @param options.url {string}
100
+ * @param options.method {string}
101
+ * @param [options.tolerate501] {boolean}
102
+ * @returns {Promise<{ status: number; allow: string }>}
103
+ */
104
+ async function assertMethodRefused({ invocationSigner, url, method, tolerate501 }) {
105
+ const needsBody = method === 'POST' || method === 'PUT' || method === 'PATCH';
106
+ const response = await signedRequest({
107
+ url,
108
+ method,
109
+ invocationSigner,
110
+ ...(needsBody && { json: {} })
111
+ });
112
+ if (tolerate501 && response.status === 501) {
113
+ return { status: 501, allow: '' };
114
+ }
115
+ assert.equal(response.status, 405, `expected 405 for ${method} ${url}, got ${response.status}`);
116
+ const allow = response.headers.get('allow') ?? '';
117
+ assert.ok(!allowedMethods(allow).includes(method), `Allow header should not list ${method} for ${url} (got "${allow}")`);
118
+ assert.match(response.headers.get('content-type') ?? '', /application\/problem\+json/, `expected a problem+json body refusing ${method} ${url}`);
119
+ const problem = await readProblem(response);
120
+ assert.equal(problem?.type, 'about:blank', `expected an about:blank problem type refusing ${method} ${url}`);
121
+ assert.equal(problem?.title, 'Method Not Allowed', `expected the title "Method Not Allowed" refusing ${method} ${url}`);
122
+ return { status: 405, allow };
123
+ }
124
+ /**
125
+ * Builds the URL for a reserved segment at the given container level.
126
+ *
127
+ * @param options {object}
128
+ * @param options.serverUrl {string}
129
+ * @param options.spaceId {string}
130
+ * @param options.collectionId {string}
131
+ * @param options.resourceId {string}
132
+ * @param options.level {'space' | 'collection' | 'resource'}
133
+ * @param options.segment {string} the reserved segment, e.g. `meta`
134
+ * @returns {string}
135
+ */
136
+ function reservedEndpointUrl({ serverUrl, spaceId, collectionId, resourceId, level, segment }) {
137
+ let relativePath;
138
+ if (level === 'space') {
139
+ relativePath = `/space/${spaceId}/${segment}`;
140
+ }
141
+ else if (level === 'collection') {
142
+ relativePath = `/space/${spaceId}/${collectionId}/${segment}`;
143
+ }
144
+ else {
145
+ relativePath = `/space/${spaceId}/${collectionId}/${resourceId}/${segment}`;
146
+ }
147
+ return new URL(relativePath, serverUrl).toString();
148
+ }
149
+ const RESERVED_ENDPOINT_CHECKS = [
150
+ // Space-level reserved endpoints (spec "Space-level reserved endpoints").
151
+ {
152
+ id: 'reserved-methods.space-meta-delete',
153
+ name: '[root] DELETE /space/:s/meta is refused (405)',
154
+ level: 'space',
155
+ segment: 'meta',
156
+ methods: ['DELETE'],
157
+ tolerate501: true,
158
+ specRefs: [
159
+ 'https://wallet.storage/spec#space-metadata-data-model',
160
+ 'https://wallet.storage/spec#methods-at-reserved-endpoints'
161
+ ]
162
+ },
163
+ {
164
+ id: 'reserved-methods.space-policy-patch',
165
+ name: '[root] PATCH /space/:s/policy is refused (405)',
166
+ level: 'space',
167
+ segment: 'policy',
168
+ methods: ['PATCH'],
169
+ tolerate501: true,
170
+ specRefs: [
171
+ 'https://wallet.storage/spec#space-level-reserved-endpoints',
172
+ 'https://wallet.storage/spec#methods-at-reserved-endpoints'
173
+ ]
174
+ },
175
+ {
176
+ id: 'reserved-methods.space-backends-patch',
177
+ name: '[root] PATCH /space/:s/backends is refused (405)',
178
+ level: 'space',
179
+ segment: 'backends',
180
+ methods: ['PATCH'],
181
+ tolerate501: true,
182
+ specRefs: [
183
+ 'https://wallet.storage/spec#space-backends-available',
184
+ 'https://wallet.storage/spec#methods-at-reserved-endpoints'
185
+ ]
186
+ },
187
+ {
188
+ id: 'reserved-methods.space-collections-retired',
189
+ name: '[root] DELETE/PATCH /space/:s/collections are refused (405) -- the ' +
190
+ 'retired segment defines no operation',
191
+ level: 'space',
192
+ segment: 'collections',
193
+ methods: ['DELETE', 'PATCH'],
194
+ tolerate501: false,
195
+ specRefs: [
196
+ 'https://wallet.storage/spec#space-level-reserved-endpoints',
197
+ 'https://wallet.storage/spec#methods-at-reserved-endpoints'
198
+ ]
199
+ },
200
+ {
201
+ id: 'reserved-methods.space-export-get',
202
+ name: '[root] GET /space/:s/export is refused (405)',
203
+ level: 'space',
204
+ segment: 'export',
205
+ methods: ['GET'],
206
+ tolerate501: true,
207
+ specRefs: [
208
+ 'https://wallet.storage/spec#space-level-reserved-endpoints',
209
+ 'https://wallet.storage/spec#methods-at-reserved-endpoints'
210
+ ]
211
+ },
212
+ {
213
+ id: 'reserved-methods.space-import-get',
214
+ name: '[root] GET /space/:s/import is refused (405)',
215
+ level: 'space',
216
+ segment: 'import',
217
+ methods: ['GET'],
218
+ tolerate501: true,
219
+ specRefs: [
220
+ 'https://wallet.storage/spec#space-level-reserved-endpoints',
221
+ 'https://wallet.storage/spec#methods-at-reserved-endpoints'
222
+ ]
223
+ },
224
+ {
225
+ id: 'reserved-methods.space-linkset-delete',
226
+ name: '[root] DELETE /space/:s/linkset is refused (405)',
227
+ level: 'space',
228
+ segment: 'linkset',
229
+ methods: ['DELETE'],
230
+ tolerate501: true,
231
+ specRefs: [
232
+ 'https://wallet.storage/spec#space-linkset',
233
+ 'https://wallet.storage/spec#methods-at-reserved-endpoints'
234
+ ]
235
+ },
236
+ {
237
+ id: 'reserved-methods.space-query-refused',
238
+ name: '[root] GET/PUT/DELETE/PATCH /space/:s/query are refused (405) -- no ' +
239
+ 'cross-collection query operation is defined for them',
240
+ level: 'space',
241
+ segment: 'query',
242
+ methods: ['GET', 'PUT', 'DELETE', 'PATCH'],
243
+ tolerate501: false,
244
+ specRefs: [
245
+ 'https://wallet.storage/spec#space-level-reserved-endpoints',
246
+ 'https://wallet.storage/spec#methods-at-reserved-endpoints'
247
+ ]
248
+ },
249
+ {
250
+ id: 'reserved-methods.space-quotas-put',
251
+ name: '[root] PUT /space/:s/quotas is refused (405)',
252
+ level: 'space',
253
+ segment: 'quotas',
254
+ methods: ['PUT'],
255
+ tolerate501: true,
256
+ specRefs: [
257
+ 'https://wallet.storage/spec#quotas',
258
+ 'https://wallet.storage/spec#methods-at-reserved-endpoints'
259
+ ]
260
+ },
261
+ // Collection-level reserved endpoints (spec "Collection-level reserved
262
+ // endpoints"). The Collection need not exist -- the refusal reads no ids.
263
+ {
264
+ id: 'reserved-methods.collection-policy-patch',
265
+ name: '[root] PATCH /space/:s/:c/policy is refused (405)',
266
+ level: 'collection',
267
+ segment: 'policy',
268
+ methods: ['PATCH'],
269
+ tolerate501: true,
270
+ specRefs: [
271
+ 'https://wallet.storage/spec#collection-level-reserved-endpoints',
272
+ 'https://wallet.storage/spec#methods-at-reserved-endpoints'
273
+ ]
274
+ },
275
+ {
276
+ id: 'reserved-methods.collection-backend-delete',
277
+ name: '[root] DELETE /space/:s/:c/backend is refused (405)',
278
+ level: 'collection',
279
+ segment: 'backend',
280
+ methods: ['DELETE'],
281
+ tolerate501: true,
282
+ specRefs: [
283
+ 'https://wallet.storage/spec#collection-backend-selected',
284
+ 'https://wallet.storage/spec#methods-at-reserved-endpoints'
285
+ ]
286
+ },
287
+ {
288
+ id: 'reserved-methods.collection-linkset-delete',
289
+ name: '[root] DELETE /space/:s/:c/linkset is refused (405)',
290
+ level: 'collection',
291
+ segment: 'linkset',
292
+ methods: ['DELETE'],
293
+ tolerate501: true,
294
+ specRefs: [
295
+ 'https://wallet.storage/spec#collection-linkset',
296
+ 'https://wallet.storage/spec#methods-at-reserved-endpoints'
297
+ ]
298
+ },
299
+ {
300
+ id: 'reserved-methods.collection-meta-delete',
301
+ name: '[root] DELETE /space/:s/:c/meta is refused (405)',
302
+ level: 'collection',
303
+ segment: 'meta',
304
+ methods: ['DELETE'],
305
+ tolerate501: true,
306
+ specRefs: [
307
+ 'https://wallet.storage/spec#collection-metadata-data-model',
308
+ 'https://wallet.storage/spec#collection-level-reserved-endpoints',
309
+ 'https://wallet.storage/spec#methods-at-reserved-endpoints'
310
+ ]
311
+ },
312
+ {
313
+ id: 'reserved-methods.collection-meta-log-delete',
314
+ name: '[root] DELETE /space/:s/:c/meta/log is refused (405)',
315
+ level: 'collection',
316
+ segment: 'meta/log',
317
+ methods: ['DELETE'],
318
+ tolerate501: true,
319
+ specRefs: [
320
+ 'https://wallet.storage/spec#collection-governing-history-log',
321
+ 'https://wallet.storage/spec#methods-at-reserved-endpoints'
322
+ ]
323
+ },
324
+ {
325
+ id: 'reserved-methods.collection-query-get',
326
+ name: '[root] GET /space/:s/:c/query is refused (405)',
327
+ level: 'collection',
328
+ segment: 'query',
329
+ methods: ['GET'],
330
+ tolerate501: true,
331
+ specRefs: [
332
+ 'https://wallet.storage/spec#query-profile-registry',
333
+ 'https://wallet.storage/spec#methods-at-reserved-endpoints'
334
+ ]
335
+ },
336
+ {
337
+ id: 'reserved-methods.collection-quota-put',
338
+ name: '[root] PUT /space/:s/:c/quota is refused (405)',
339
+ level: 'collection',
340
+ segment: 'quota',
341
+ methods: ['PUT'],
342
+ tolerate501: true,
343
+ specRefs: [
344
+ 'https://wallet.storage/spec#quotas',
345
+ 'https://wallet.storage/spec#methods-at-reserved-endpoints'
346
+ ]
347
+ },
348
+ // Resource-level reserved endpoints (spec "Resource-level reserved
349
+ // endpoints"). Neither the Collection nor the Resource need exist.
350
+ {
351
+ id: 'reserved-methods.resource-meta-post',
352
+ name: '[root] POST /space/:s/:c/:r/meta is refused (405)',
353
+ level: 'resource',
354
+ segment: 'meta',
355
+ methods: ['POST'],
356
+ tolerate501: true,
357
+ specRefs: [
358
+ 'https://wallet.storage/spec#resource-metadata-data-model',
359
+ 'https://wallet.storage/spec#resource-level-reserved-endpoints',
360
+ 'https://wallet.storage/spec#methods-at-reserved-endpoints'
361
+ ]
362
+ },
363
+ {
364
+ id: 'reserved-methods.resource-chunks-delete',
365
+ name: '[root] DELETE /space/:s/:c/:r/chunks/ is refused (405)',
366
+ level: 'resource',
367
+ segment: 'chunks/',
368
+ methods: ['DELETE'],
369
+ tolerate501: true,
370
+ specRefs: [
371
+ 'https://wallet.storage/spec#chunked-resources',
372
+ 'https://wallet.storage/spec#resource-level-reserved-endpoints',
373
+ 'https://wallet.storage/spec#methods-at-reserved-endpoints'
374
+ ]
375
+ }
376
+ ];
377
+ const reservedEndpointTests = RESERVED_ENDPOINT_CHECKS.map(check => ({
378
+ id: check.id,
379
+ name: check.name,
380
+ specRefs: check.specRefs,
381
+ run: async (ctx, state) => {
382
+ const { alice, collectionId, resourceId } = state;
383
+ const url = reservedEndpointUrl({
384
+ serverUrl: ctx.serverUrl,
385
+ spaceId: alice.space1.id,
386
+ collectionId,
387
+ resourceId,
388
+ level: check.level,
389
+ segment: check.segment
390
+ });
391
+ for (const method of check.methods) {
392
+ await assertMethodRefused({
393
+ invocationSigner: alice.rootClient.invocationSigner,
394
+ url,
395
+ method,
396
+ tolerate501: check.tolerate501
397
+ });
398
+ }
399
+ }
400
+ }));
401
+ export const reservedMethodsApi = {
402
+ id: 'reserved-methods-api',
403
+ name: 'Methods at reserved endpoints (405)',
404
+ specRefs: [
405
+ 'https://wallet.storage/spec#reserved-path-segment-registry',
406
+ 'https://wallet.storage/spec#methods-at-reserved-endpoints'
407
+ ],
408
+ setup: async (ctx) => {
409
+ const alice = { ...ctx.actors.alice };
410
+ alice.space1 = { id: ctx.generateId() };
411
+ await ctx.createSpace({
412
+ spaceDescription: {
413
+ id: alice.space1.id,
414
+ name: "Alice's Reserved-Methods Space",
415
+ controller: alice.did
416
+ },
417
+ rootClient: alice.rootClient
418
+ });
419
+ return {
420
+ alice,
421
+ // Neither Collection nor Resource need exist: the refusal reads no
422
+ // ids, so a plain literal id exercises the same code path as a real
423
+ // one without any provisioning cost.
424
+ collectionId: 'reserved-methods-collection',
425
+ resourceId: 'reserved-methods-resource'
426
+ };
427
+ },
428
+ teardown: async (ctx, state) => {
429
+ const { alice } = state;
430
+ try {
431
+ await alice.rootClient.request({
432
+ url: new URL(`/space/${alice.space1.id}/`, ctx.serverUrl).toString(),
433
+ method: 'DELETE'
434
+ });
435
+ }
436
+ catch {
437
+ /* best-effort cleanup */
438
+ }
439
+ },
440
+ tests: [
441
+ ...reservedEndpointTests,
442
+ {
443
+ id: 'reserved-methods.space-container-put',
444
+ name: '[root] PUT /space/:s/ is refused (405), Allow excludes PUT',
445
+ specRefs: [
446
+ 'https://wallet.storage/spec#space-metadata-data-model',
447
+ 'https://wallet.storage/spec#methods-at-reserved-endpoints'
448
+ ],
449
+ run: async (ctx, state) => {
450
+ const { alice } = state;
451
+ const url = new URL(`/space/${alice.space1.id}/`, ctx.serverUrl).toString();
452
+ await assertMethodRefused({
453
+ invocationSigner: alice.rootClient.invocationSigner,
454
+ url,
455
+ method: 'PUT'
456
+ });
457
+ }
458
+ },
459
+ {
460
+ id: 'reserved-methods.collection-container-put',
461
+ name: '[root] PUT /space/:s/:c/ is refused (405), Allow excludes PUT',
462
+ specRefs: [
463
+ 'https://wallet.storage/spec#collection-metadata-data-model',
464
+ 'https://wallet.storage/spec#methods-at-reserved-endpoints'
465
+ ],
466
+ run: async (ctx, state) => {
467
+ const { alice, collectionId } = state;
468
+ const url = new URL(`/space/${alice.space1.id}/${collectionId}/`, ctx.serverUrl).toString();
469
+ await assertMethodRefused({
470
+ invocationSigner: alice.rootClient.invocationSigner,
471
+ url,
472
+ method: 'PUT'
473
+ });
474
+ }
475
+ },
476
+ {
477
+ id: 'reserved-methods.identical-for-absent-space',
478
+ name: '[root] the 405 refusal is identical whether the Space exists',
479
+ specRefs: [
480
+ 'https://wallet.storage/spec#methods-at-reserved-endpoints',
481
+ 'https://wallet.storage/spec#error-handling'
482
+ ],
483
+ run: async (ctx, state) => {
484
+ const { alice } = state;
485
+ const answers = [];
486
+ for (const spaceId of [alice.space1.id, `absent-${ctx.generateId()}`]) {
487
+ const url = new URL(`/space/${spaceId}/`, ctx.serverUrl).toString();
488
+ answers.push(await assertMethodRefused({
489
+ invocationSigner: alice.rootClient.invocationSigner,
490
+ url,
491
+ method: 'PUT'
492
+ }));
493
+ }
494
+ assert.equal(answers[0].status, 405);
495
+ assert.deepStrictEqual(answers[1], answers[0], 'the refusal must read no ids: an absent Space gets the same answer');
496
+ }
497
+ },
498
+ {
499
+ id: 'reserved-methods.head-follows-get',
500
+ name: '[root] HEAD is not refused where GET is defined at a reserved ' +
501
+ 'endpoint',
502
+ optional: true,
503
+ specRefs: [
504
+ 'https://wallet.storage/spec#methods-at-reserved-endpoints',
505
+ 'https://wallet.storage/spec#space-linkset'
506
+ ],
507
+ run: async (ctx, state) => {
508
+ const { alice } = state;
509
+ const url = new URL(`/space/${alice.space1.id}/linkset`, ctx.serverUrl).toString();
510
+ const getResponse = await signedRequest({
511
+ url,
512
+ method: 'GET',
513
+ invocationSigner: alice.rootClient.invocationSigner
514
+ });
515
+ if (getResponse.status === 501) {
516
+ ctx.skip('Space Linkset (GET) not implemented (501)');
517
+ }
518
+ assert.notEqual(getResponse.status, 405, 'GET should not itself be refused');
519
+ const headResponse = await signedRequest({
520
+ url,
521
+ method: 'HEAD',
522
+ invocationSigner: alice.rootClient.invocationSigner
523
+ });
524
+ assert.notEqual(headResponse.status, 405, 'HEAD should follow GET rather than being refused');
525
+ }
526
+ },
527
+ {
528
+ id: 'reserved-methods.options-preflight-not-refused',
529
+ name: '[root] an OPTIONS CORS preflight at a reserved endpoint is not ' +
530
+ 'refused',
531
+ optional: true,
532
+ specRefs: ['https://wallet.storage/spec#methods-at-reserved-endpoints'],
533
+ run: async (ctx, state) => {
534
+ const { alice } = state;
535
+ const url = new URL(`/space/${alice.space1.id}/linkset`, ctx.serverUrl).toString();
536
+ const response = await fetch(url, {
537
+ method: 'OPTIONS',
538
+ headers: {
539
+ origin: 'https://app.example',
540
+ 'access-control-request-method': 'DELETE'
541
+ }
542
+ });
543
+ assert.notEqual(response.status, 405, 'an OPTIONS preflight must not be caught by the reserved-methods ' +
544
+ 'refusal');
545
+ }
546
+ }
547
+ ]
548
+ };
549
+ //# sourceMappingURL=reserved-methods-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reserved-methods-api.js","sourceRoot":"","sources":["../../src/suites/reserved-methods-api.ts"],"names":[],"mappings":"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"}
@@ -94,7 +94,7 @@ export const resourceApi = {
94
94
  const { alice } = state;
95
95
  try {
96
96
  await alice.rootClient.request({
97
- url: new URL(`/space/${alice.space1.id}`, ctx.serverUrl).toString(),
97
+ url: new URL(`/space/${alice.space1.id}/`, ctx.serverUrl).toString(),
98
98
  method: 'DELETE'
99
99
  });
100
100
  }