@bedrock/vc-verifier 9.0.0 → 12.0.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.
@@ -1,868 +0,0 @@
1
- /*!
2
- * Copyright (c) 2019-2022 Digital Bazaar, Inc. All rights reserved.
3
- */
4
- import * as bedrock from '@bedrock/core';
5
- import * as helpers from './helpers.js';
6
- import {agent} from '@bedrock/https-agent';
7
- import {createContextDocumentLoader} from '@bedrock/service-context-store';
8
- import {createRequire} from 'node:module';
9
- import {documentStores} from '@bedrock/service-agent';
10
- import {httpClient} from '@digitalbazaar/http-client';
11
- import {mockData} from './mock.data.js';
12
- const require = createRequire(import.meta.url);
13
- const {CapabilityAgent} = require('@digitalbazaar/webkms-client');
14
-
15
- const {baseUrl} = mockData;
16
- const serviceType = 'vc-verifier';
17
-
18
- describe('provision API', () => {
19
- let capabilityAgent;
20
- const zcaps = {};
21
- beforeEach(async () => {
22
- const secret = '53ad64ce-8e1d-11ec-bb12-10bf48838a41';
23
- const handle = 'test';
24
- capabilityAgent = await CapabilityAgent.fromSecret({secret, handle});
25
-
26
- // create keystore for capability agent
27
- const keystoreAgent = await helpers.createKeystoreAgent(
28
- {capabilityAgent});
29
-
30
- // create EDV for storage (creating hmac and kak in the process)
31
- const {
32
- edvConfig,
33
- hmac,
34
- keyAgreementKey
35
- } = await helpers.createEdv({capabilityAgent, keystoreAgent});
36
-
37
- // get service agent to delegate to
38
- const serviceAgentUrl =
39
- `${baseUrl}/service-agents/${encodeURIComponent(serviceType)}`;
40
- const {data: serviceAgent} = await httpClient.get(serviceAgentUrl, {
41
- agent
42
- });
43
-
44
- // delegate edv, hmac, and key agreement key zcaps to service agent
45
- const {id: edvId} = edvConfig;
46
- zcaps.edv = await helpers.delegate({
47
- controller: serviceAgent.id,
48
- delegator: capabilityAgent,
49
- invocationTarget: edvId
50
- });
51
- const {keystoreId} = keystoreAgent;
52
- zcaps.hmac = await helpers.delegate({
53
- capability: `urn:zcap:root:${encodeURIComponent(keystoreId)}`,
54
- controller: serviceAgent.id,
55
- invocationTarget: hmac.id,
56
- delegator: capabilityAgent
57
- });
58
- zcaps.keyAgreementKey = await helpers.delegate({
59
- capability: `urn:zcap:root:${encodeURIComponent(keystoreId)}`,
60
- controller: serviceAgent.id,
61
- invocationTarget: keyAgreementKey.kmsId,
62
- delegator: capabilityAgent
63
- });
64
- });
65
- describe('create config', () => {
66
- it('throws error on missing zcaps', async () => {
67
- let err;
68
- let result;
69
- try {
70
- result = await helpers.createConfig({capabilityAgent});
71
- } catch(e) {
72
- err = e;
73
- }
74
- should.exist(err);
75
- should.not.exist(result);
76
- err.data.details.errors.should.have.length(1);
77
- const [error] = err.data.details.errors;
78
- error.name.should.equal('ValidationError');
79
- error.message.should.contain(`should have required property 'zcaps'`);
80
- });
81
- it('creates a config', async () => {
82
- let err;
83
- let result;
84
- try {
85
- result = await helpers.createConfig({capabilityAgent, zcaps});
86
- } catch(e) {
87
- err = e;
88
- }
89
- assertNoError(err);
90
- should.exist(result);
91
- result.should.have.keys([
92
- 'controller', 'id', 'sequence', 'meterId', 'zcaps'
93
- ]);
94
- result.sequence.should.equal(0);
95
- const {id: capabilityAgentId} = capabilityAgent;
96
- result.controller.should.equal(capabilityAgentId);
97
- });
98
- it('creates a config including proper ipAllowList', async () => {
99
- const ipAllowList = ['127.0.0.1/32'];
100
-
101
- let err;
102
- let result;
103
- try {
104
- result = await helpers.createConfig(
105
- {capabilityAgent, ipAllowList, zcaps});
106
- } catch(e) {
107
- err = e;
108
- }
109
- assertNoError(err);
110
- should.exist(result);
111
- result.should.have.keys([
112
- 'controller', 'id', 'ipAllowList', 'sequence', 'meterId', 'zcaps'
113
- ]);
114
- result.sequence.should.equal(0);
115
- const {id: capabilityAgentId} = capabilityAgent;
116
- result.controller.should.equal(capabilityAgentId);
117
- result.ipAllowList.should.eql(ipAllowList);
118
- });
119
- it('throws error on invalid ipAllowList', async () => {
120
- // this is not a valid CIDR
121
- const ipAllowList = ['127.0.0.1/33'];
122
-
123
- let err;
124
- let result;
125
- try {
126
- result = await helpers.createConfig(
127
- {capabilityAgent, ipAllowList, zcaps});
128
- } catch(e) {
129
- err = e;
130
- }
131
- should.exist(err);
132
- should.not.exist(result);
133
- err.data.details.errors.should.have.length(1);
134
- const [error] = err.data.details.errors;
135
- error.name.should.equal('ValidationError');
136
- error.message.should.contain('should match pattern');
137
- error.details.path.should.equal('.ipAllowList[0]');
138
- });
139
- it('throws error on invalid ipAllowList', async () => {
140
- // an empty allow list is invalid
141
- const ipAllowList = [];
142
-
143
- let err;
144
- let result;
145
- try {
146
- result = await helpers.createConfig(
147
- {capabilityAgent, ipAllowList, zcaps});
148
- } catch(e) {
149
- err = e;
150
- }
151
- should.exist(err);
152
- should.not.exist(result);
153
- err.data.details.errors.should.have.length(1);
154
- const [error] = err.data.details.errors;
155
- error.name.should.equal('ValidationError');
156
- error.message.should.contain('should NOT have fewer than 1 items');
157
- error.details.path.should.equal('.ipAllowList');
158
- });
159
- it('throws error on no "sequence"', async () => {
160
- const url = `${bedrock.config.server.baseUri}/verifiers`;
161
- const config = {
162
- controller: capabilityAgent.id
163
- };
164
-
165
- let err;
166
- let result;
167
- try {
168
- result = await httpClient.post(url, {agent, json: config});
169
- } catch(e) {
170
- err = e;
171
- }
172
- should.exist(err);
173
- should.not.exist(result);
174
- err.data.type.should.equal('ValidationError');
175
- err.data.message.should.equal(
176
- 'A validation error occured in the \'createConfigBody\' validator.');
177
- });
178
- });
179
-
180
- describe('get config', () => {
181
- it('gets a config', async () => {
182
- const config = await helpers.createConfig(
183
- {capabilityAgent, zcaps});
184
- let err;
185
- let result;
186
- try {
187
- result = await helpers.getConfig({id: config.id, capabilityAgent});
188
- } catch(e) {
189
- err = e;
190
- }
191
- assertNoError(err);
192
- should.exist(result);
193
- result.should.have.keys([
194
- 'controller', 'id', 'sequence', 'meterId', 'zcaps'
195
- ]);
196
- result.id.should.equal(config.id);
197
- });
198
- it('gets a config with ipAllowList', async () => {
199
- const ipAllowList = ['127.0.0.1/32'];
200
-
201
- const config = await helpers.createConfig(
202
- {capabilityAgent, ipAllowList, zcaps});
203
- let err;
204
- let result;
205
- try {
206
- result = await helpers.getConfig({id: config.id, capabilityAgent});
207
- } catch(e) {
208
- err = e;
209
- }
210
- assertNoError(err);
211
- should.exist(result);
212
- result.should.have.keys([
213
- 'controller', 'id', 'ipAllowList', 'sequence', 'meterId', 'zcaps'
214
- ]);
215
- result.should.have.property('id');
216
- result.id.should.equal(config.id);
217
- result.ipAllowList.should.eql(ipAllowList);
218
- });
219
- it('returns NotAllowedError for invalid source IP', async () => {
220
- const ipAllowList = ['8.8.8.8/32'];
221
-
222
- const config = await helpers.createConfig(
223
- {capabilityAgent, ipAllowList, zcaps});
224
- let err;
225
- let result;
226
- try {
227
- result = await helpers.getConfig({id: config.id, capabilityAgent});
228
- } catch(e) {
229
- err = e;
230
- }
231
- should.not.exist(result);
232
- should.exist(err);
233
- err.status.should.equal(403);
234
- err.data.type.should.equal('NotAllowedError');
235
- });
236
- }); // get config
237
-
238
- describe('update config', () => {
239
- it('updates a config', async () => {
240
- // create new capability agent to change config `controller` to
241
- const capabilityAgent2 = await CapabilityAgent.fromSecret(
242
- {secret: 's2', handle: 'h2'});
243
-
244
- let err;
245
- let result;
246
- let existingConfig;
247
- try {
248
- existingConfig = result = await helpers.createConfig(
249
- {capabilityAgent, zcaps});
250
- } catch(e) {
251
- err = e;
252
- }
253
- assertNoError(err);
254
- should.exist(result);
255
- result.should.have.property('id');
256
- result.should.have.property('sequence');
257
- result.sequence.should.equal(0);
258
- const {id: capabilityAgentId} = capabilityAgent;
259
- result.should.have.property('controller');
260
- result.controller.should.equal(capabilityAgentId);
261
-
262
- // this update does not change the `meterId`
263
- const {id: url} = result;
264
- const newConfig = {
265
- controller: capabilityAgent2.id,
266
- id: url,
267
- meterId: existingConfig.meterId,
268
- sequence: 1,
269
- zcaps
270
- };
271
-
272
- err = null;
273
- result = null;
274
- try {
275
- const zcapClient = helpers.createZcapClient({capabilityAgent});
276
- result = await zcapClient.write({url, json: newConfig});
277
- } catch(e) {
278
- err = e;
279
- }
280
- assertNoError(err);
281
- should.exist(result.data);
282
- result.status.should.equal(200);
283
- result.data.should.have.keys([
284
- 'id', 'controller', 'sequence', 'meterId', 'zcaps'
285
- ]);
286
- const expectedConfig = {
287
- ...existingConfig,
288
- ...newConfig
289
- };
290
- result.data.should.eql(expectedConfig);
291
-
292
- // should fail to retrieve the config now that controller
293
- // has changed
294
- err = null;
295
- result = null;
296
- try {
297
- result = await helpers.getConfig(
298
- {id: newConfig.id, capabilityAgent});
299
- } catch(e) {
300
- err = e;
301
- }
302
- should.exist(err);
303
- should.not.exist(result);
304
- err.status.should.equal(403);
305
- err.data.type.should.equal('NotAllowedError');
306
-
307
- // retrieve the config to confirm update was effective
308
- err = null;
309
- result = null;
310
- try {
311
- result = await helpers.getConfig(
312
- {id: newConfig.id, capabilityAgent: capabilityAgent2});
313
- } catch(e) {
314
- err = e;
315
- }
316
- assertNoError(err);
317
- should.exist(result);
318
- result.should.eql(expectedConfig);
319
- });
320
- it('rejects config update for an invalid zcap', async () => {
321
- const capabilityAgent2 = await CapabilityAgent.fromSecret(
322
- {secret: 's2', handle: 'h2'});
323
-
324
- let err;
325
- let result;
326
- try {
327
- result = await helpers.createConfig(
328
- {capabilityAgent, zcaps});
329
- } catch(e) {
330
- err = e;
331
- }
332
- assertNoError(err);
333
- should.exist(result);
334
- result.should.have.property('id');
335
- result.should.have.property('sequence');
336
- result.sequence.should.equal(0);
337
- const {id: capabilityAgentId} = capabilityAgent;
338
- result.should.have.property('controller');
339
- result.controller.should.equal(capabilityAgentId);
340
-
341
- const {id: url} = result;
342
- const newConfig = {
343
- controller: capabilityAgent2.id,
344
- id: url,
345
- meterId: result.meterId,
346
- sequence: 1,
347
- zcaps
348
- };
349
-
350
- err = null;
351
- result = null;
352
- try {
353
- // the capability invocation here is signed by `capabilityAgent2`
354
- // which is not the `controller` of the config
355
- const zcapClient = helpers.createZcapClient({
356
- capabilityAgent: capabilityAgent2
357
- });
358
- result = await zcapClient.write({url, json: newConfig});
359
- } catch(e) {
360
- err = e;
361
- }
362
- should.exist(err);
363
- should.not.exist(result);
364
- err.status.should.equal(403);
365
- err.data.type.should.equal('NotAllowedError');
366
- err.data.cause.message.should.contain(
367
- 'The capability controller does not match the verification method ' +
368
- '(or its controller) used to invoke.');
369
- });
370
- it('rejects config update with an invalid sequence', async () => {
371
- const capabilityAgent2 = await CapabilityAgent.fromSecret(
372
- {secret: 's2', handle: 'h2'});
373
-
374
- let err;
375
- let result;
376
- try {
377
- result = await helpers.createConfig(
378
- {capabilityAgent, zcaps});
379
- } catch(e) {
380
- err = e;
381
- }
382
- assertNoError(err);
383
- should.exist(result);
384
- result.should.have.property('id');
385
- result.should.have.property('sequence');
386
- result.sequence.should.equal(0);
387
- const {id: capabilityAgentId} = capabilityAgent;
388
- result.should.have.property('controller');
389
- result.controller.should.equal(capabilityAgentId);
390
-
391
- const {id: url} = result;
392
- const newConfig = {
393
- controller: capabilityAgent2.id,
394
- id: url,
395
- meterId: result.meterId,
396
- // the proper sequence would be 1
397
- sequence: 10,
398
- zcaps
399
- };
400
-
401
- err = null;
402
- result = null;
403
- try {
404
- const zcapClient = helpers.createZcapClient({capabilityAgent});
405
- result = await zcapClient.write({url, json: newConfig});
406
- } catch(e) {
407
- err = e;
408
- }
409
- should.exist(err);
410
- should.not.exist(result);
411
- err.status.should.equal(409);
412
- err.data.type.should.equal('InvalidStateError');
413
- });
414
- describe('updates with ipAllowList', () => {
415
- it('updates a config with ipAllowList', async () => {
416
- const capabilityAgent2 = await CapabilityAgent.fromSecret(
417
- {secret: 's2', handle: 'h2'});
418
-
419
- const ipAllowList = ['127.0.0.1/32'];
420
-
421
- let err;
422
- let result;
423
- let existingConfig;
424
- try {
425
- existingConfig = result = await helpers.createConfig(
426
- {capabilityAgent, ipAllowList, zcaps});
427
- } catch(e) {
428
- err = e;
429
- }
430
- assertNoError(err);
431
- should.exist(result);
432
- result.should.have.property('id');
433
- result.should.have.property('sequence');
434
- result.sequence.should.equal(0);
435
- const {id: capabilityAgentId} = capabilityAgent;
436
- result.should.have.property('controller');
437
- result.controller.should.equal(capabilityAgentId);
438
-
439
- const {id: url} = result;
440
- const newConfig = {
441
- controller: capabilityAgent2.id,
442
- id: url,
443
- ipAllowList,
444
- meterId: existingConfig.meterId,
445
- sequence: 1,
446
- zcaps
447
- };
448
-
449
- err = null;
450
- result = null;
451
- try {
452
- const zcapClient = helpers.createZcapClient({capabilityAgent});
453
- result = await zcapClient.write({url, json: newConfig});
454
- } catch(e) {
455
- err = e;
456
- }
457
- assertNoError(err);
458
- should.exist(result.data);
459
- result.status.should.equal(200);
460
- result.data.should.have.keys([
461
- 'id', 'controller', 'sequence', 'meterId', 'ipAllowList', 'zcaps'
462
- ]);
463
- const expectedConfig = {
464
- ...existingConfig,
465
- ...newConfig
466
- };
467
- result.data.should.eql(expectedConfig);
468
-
469
- // should fail to retrieve the config now that controller
470
- // has changed
471
- err = null;
472
- result = null;
473
- try {
474
- result = await helpers.getConfig(
475
- {id: newConfig.id, capabilityAgent});
476
- } catch(e) {
477
- err = e;
478
- }
479
- should.exist(err);
480
- should.not.exist(result);
481
- err.status.should.equal(403);
482
- err.data.type.should.equal('NotAllowedError');
483
-
484
- // retrieve the config to confirm update was effective
485
- err = null;
486
- result = null;
487
- try {
488
- result = await helpers.getConfig(
489
- {id: newConfig.id, capabilityAgent: capabilityAgent2});
490
- } catch(e) {
491
- err = e;
492
- }
493
- assertNoError(err);
494
- should.exist(result);
495
- result.should.eql(expectedConfig);
496
- });
497
- it('returns NotAllowedError for invalid source IP', async () => {
498
- const capabilityAgent2 = await CapabilityAgent.fromSecret(
499
- {secret: 's2', handle: 'h2'});
500
-
501
- const ipAllowList = ['8.8.8.8/32'];
502
-
503
- let err;
504
- let result;
505
- try {
506
- result = await helpers.createConfig(
507
- {capabilityAgent, ipAllowList, zcaps});
508
- } catch(e) {
509
- err = e;
510
- }
511
- assertNoError(err);
512
- should.exist(result);
513
- result.should.have.property('id');
514
- result.should.have.property('sequence');
515
- result.sequence.should.equal(0);
516
- const {id: capabilityAgentId} = capabilityAgent;
517
- result.should.have.property('controller');
518
- result.controller.should.equal(capabilityAgentId);
519
-
520
- const {id: url} = result;
521
- const newConfig = {
522
- controller: capabilityAgent2.id,
523
- id: url,
524
- ipAllowList,
525
- meterId: result.meterId,
526
- sequence: 1,
527
- zcaps
528
- };
529
-
530
- err = null;
531
- result = null;
532
- try {
533
- const zcapClient = helpers.createZcapClient({capabilityAgent});
534
- result = await zcapClient.write({url, json: newConfig});
535
- } catch(e) {
536
- err = e;
537
- }
538
- should.not.exist(result);
539
- should.exist(err);
540
- err.status.should.equal(403);
541
- err.data.type.should.equal('NotAllowedError');
542
- });
543
- }); // updates with ipAllowList
544
- }); // end update config
545
-
546
- describe('revocations', () => {
547
- it('throws error with invalid zcap when revoking', async () => {
548
- const config = await helpers.createConfig({capabilityAgent, zcaps});
549
- const zcap = {
550
- '@context': ['https://w3id.org/zcap/v1'],
551
- id: 'urn:uuid:895d985c-8e20-11ec-b82f-10bf48838a41',
552
- proof: {}
553
- };
554
-
555
- const url =
556
- `${config.id}/zcaps/revocations/${encodeURIComponent(zcap.id)}`;
557
-
558
- let err;
559
- let result;
560
- try {
561
- result = await httpClient.post(url, {agent, json: zcap});
562
- } catch(e) {
563
- err = e;
564
- }
565
- should.exist(err);
566
- should.not.exist(result);
567
- err.data.type.should.equal('ValidationError');
568
- err.data.message.should.equal(
569
- 'A validation error occured in the \'Delegated ZCAP\' validator.');
570
- });
571
- it('revokes a zcap', async () => {
572
- const config = await helpers.createConfig({capabilityAgent, zcaps});
573
-
574
- const capabilityAgent2 = await CapabilityAgent.fromSecret(
575
- {secret: 's2', handle: 'h2'});
576
-
577
- const zcap = await helpers.delegate({
578
- controller: capabilityAgent2.id,
579
- invocationTarget: config.id,
580
- delegator: capabilityAgent
581
- });
582
-
583
- // zcap should work to get config
584
- const zcapClient = helpers.createZcapClient(
585
- {capabilityAgent: capabilityAgent2});
586
- const {data} = await zcapClient.read({capability: zcap});
587
- data.should.have.keys([
588
- 'controller', 'id', 'sequence', 'meterId', 'zcaps'
589
- ]);
590
- data.id.should.equal(config.id);
591
-
592
- // revoke zcap
593
- await helpers.revokeDelegatedCapability({
594
- serviceObjectId: config.id,
595
- capabilityToRevoke: zcap,
596
- invocationSigner: capabilityAgent.getSigner()
597
- });
598
-
599
- // now getting config should fail
600
- let err;
601
- try {
602
- await zcapClient.read({capability: zcap});
603
- } catch(e) {
604
- err = e;
605
- }
606
- should.exist(err);
607
- err.data.type.should.equal('NotAllowedError');
608
- });
609
- }); // end revocations
610
-
611
- describe('contexts', () => {
612
- it('fails to inserts a context due to bad zcap', async () => {
613
- const config = await helpers.createConfig({capabilityAgent, zcaps});
614
-
615
- // insert `context`
616
- const contextId = 'https://test.example/v1';
617
- const context = {'@context': {term: 'https://test.example#term'}};
618
- const client = helpers.createZcapClient({capabilityAgent});
619
- const url = `${config.id}/contexts`;
620
-
621
- // intentionally bad root zcap here; the root zcap must be for the
622
- // service object config, not `/contexts` URL as it is set here
623
- const rootZcap = `urn:zcap:root:${encodeURIComponent(url)}`;
624
-
625
- let err;
626
- try {
627
- await client.write({
628
- url, json: {id: contextId, context},
629
- capability: rootZcap
630
- });
631
- } catch(e) {
632
- err = e;
633
- }
634
- should.exist(err);
635
- err.data.type.should.equal('NotAllowedError');
636
- });
637
- it('inserts a context', async () => {
638
- const config = await helpers.createConfig({capabilityAgent, zcaps});
639
- const rootZcap = `urn:zcap:root:${encodeURIComponent(config.id)}`;
640
-
641
- // insert `context`
642
- const contextId = 'https://test.example/v1';
643
- const context = {'@context': {term: 'https://test.example#term'}};
644
- const client = helpers.createZcapClient({capabilityAgent});
645
- const url = `${config.id}/contexts`;
646
-
647
- let err;
648
- let response;
649
- try {
650
- response = await client.write({
651
- url, json: {id: contextId, context},
652
- capability: rootZcap
653
- });
654
- } catch(e) {
655
- err = e;
656
- }
657
- assertNoError(err);
658
- should.exist(response);
659
- should.exist(response.data);
660
- response.data.should.deep.equal({
661
- id: 'https://test.example/v1',
662
- context,
663
- sequence: 0
664
- });
665
- });
666
- it('throws error on no "context"', async () => {
667
- const config = await helpers.createConfig({capabilityAgent, zcaps});
668
- const rootZcap = `urn:zcap:root:${encodeURIComponent(config.id)}`;
669
-
670
- const contextId = 'https://test.example/v1';
671
- const client = helpers.createZcapClient({capabilityAgent});
672
- const url = `${config.id}/contexts`;
673
-
674
- let err;
675
- let result;
676
- try {
677
- await client.write({url, json: {id: contextId}, capability: rootZcap});
678
- } catch(e) {
679
- err = e;
680
- }
681
- should.exist(err);
682
- should.not.exist(result);
683
- err.data.type.should.equal('ValidationError');
684
- err.data.message.should.equal(
685
- 'A validation error occured in the \'createContextBody\' validator.');
686
- });
687
- it('updates a context', async () => {
688
- const config = await helpers.createConfig({capabilityAgent, zcaps});
689
- const rootZcap = `urn:zcap:root:${encodeURIComponent(config.id)}`;
690
-
691
- // insert `context`
692
- const contextId = 'https://test.example/v1';
693
- const context = {'@context': {term: 'https://test.example#term'}};
694
- const client = helpers.createZcapClient({capabilityAgent});
695
- let url = `${config.id}/contexts`;
696
- await client.write({
697
- url, json: {id: contextId, context},
698
- capability: rootZcap
699
- });
700
-
701
- // update `context`
702
- context['@context'].term2 = 'https://test.example#term2';
703
- url = `${url}/${encodeURIComponent(contextId)}`;
704
- let err;
705
- let response;
706
- try {
707
- response = await client.write({
708
- url, json: {id: contextId, context, sequence: 1},
709
- capability: rootZcap
710
- });
711
- } catch(e) {
712
- err = e;
713
- }
714
- assertNoError(err);
715
- should.exist(response);
716
- should.exist(response.data);
717
- response.data.should.deep.equal({
718
- id: 'https://test.example/v1',
719
- context,
720
- sequence: 1
721
- });
722
- });
723
- it('fails to update a context with wrong sequence', async () => {
724
- const config = await helpers.createConfig({capabilityAgent, zcaps});
725
- const rootZcap = `urn:zcap:root:${encodeURIComponent(config.id)}`;
726
-
727
- // insert `context`
728
- const contextId = 'https://test.example/v1';
729
- const context = {'@context': {term: 'https://test.example#term'}};
730
- const client = helpers.createZcapClient({capabilityAgent});
731
- let url = `${config.id}/contexts`;
732
- await client.write({
733
- url, json: {id: contextId, context},
734
- capability: rootZcap
735
- });
736
-
737
- // update `context`
738
- context['@context'].term2 = 'https://test.example#term2';
739
- url = `${url}/${encodeURIComponent(contextId)}`;
740
- let err;
741
- let response;
742
- try {
743
- response = await client.write({
744
- url, json: {id: contextId, context, sequence: 10},
745
- capability: rootZcap
746
- });
747
- } catch(e) {
748
- err = e;
749
- }
750
- should.exist(err);
751
- should.not.exist(response);
752
- err.data.type.should.equal('InvalidStateError');
753
- });
754
- it('gets a context', async () => {
755
- const config = await helpers.createConfig({capabilityAgent, zcaps});
756
- const rootZcap = `urn:zcap:root:${encodeURIComponent(config.id)}`;
757
-
758
- // insert `context`
759
- const contextId = 'https://test.example/v1';
760
- const context = {'@context': {term: 'https://test.example#term'}};
761
- const client = helpers.createZcapClient({capabilityAgent});
762
- let url = `${config.id}/contexts`;
763
- await client.write({
764
- url, json: {id: contextId, context},
765
- capability: rootZcap
766
- });
767
-
768
- url = `${url}/${encodeURIComponent(contextId)}`;
769
- let err;
770
- let response;
771
- try {
772
- response = await client.read({
773
- url, capability: rootZcap
774
- });
775
- } catch(e) {
776
- err = e;
777
- }
778
- assertNoError(err);
779
- should.exist(response);
780
- should.exist(response.data);
781
- response.data.should.deep.equal({
782
- id: 'https://test.example/v1',
783
- context,
784
- sequence: 0
785
- });
786
- });
787
- it('gets a context with a context document loader', async () => {
788
- const config = await helpers.createConfig({capabilityAgent, zcaps});
789
- const rootZcap = `urn:zcap:root:${encodeURIComponent(config.id)}`;
790
-
791
- // insert `context`
792
- const contextId = 'https://test.example/v1';
793
- const context = {'@context': {term: 'https://test.example#term'}};
794
- const client = helpers.createZcapClient({capabilityAgent});
795
- const url = `${config.id}/contexts`;
796
- await client.write({
797
- url, json: {id: contextId, context},
798
- capability: rootZcap
799
- });
800
-
801
- const documentLoader = await createContextDocumentLoader({
802
- config, serviceType
803
- });
804
-
805
- let err;
806
- let result;
807
- try {
808
- result = await documentLoader(contextId);
809
- } catch(e) {
810
- err = e;
811
- }
812
- assertNoError(err);
813
- should.exist(result);
814
- should.exist(result.documentUrl);
815
- should.exist(result.document);
816
- result.documentUrl.should.equal(contextId);
817
- result.document.should.deep.equal(context);
818
- });
819
- it('fails to get a context with wrong meta type', async () => {
820
- const config = await helpers.createConfig({capabilityAgent, zcaps});
821
- const rootZcap = `urn:zcap:root:${encodeURIComponent(config.id)}`;
822
-
823
- // insert `context`
824
- const contextId = 'https://test.example/v1';
825
- const context = {'@context': {term: 'https://test.example#term'}};
826
- const client = helpers.createZcapClient({capabilityAgent});
827
- const url = `${config.id}/contexts`;
828
- await client.write({
829
- url, json: {id: contextId, context},
830
- capability: rootZcap
831
- });
832
-
833
- // get context successfully
834
- const documentLoader = await createContextDocumentLoader({
835
- config, serviceType
836
- });
837
-
838
- let err;
839
- let result;
840
- try {
841
- result = await documentLoader(contextId);
842
- } catch(e) {
843
- err = e;
844
- }
845
- assertNoError(err);
846
- should.exist(result);
847
- should.exist(result.documentUrl);
848
- should.exist(result.document);
849
- result.documentUrl.should.equal(contextId);
850
- result.document.should.deep.equal(context);
851
-
852
- // now erroneously update context to new meta type
853
- const docStore = await documentStores.get({config, serviceType});
854
- await docStore.upsert({
855
- content: {id: contextId, context},
856
- meta: {type: 'different'}
857
- });
858
-
859
- try {
860
- await documentLoader(contextId);
861
- } catch(e) {
862
- err = e;
863
- }
864
- should.exist(err);
865
- err.name.should.equal('NotFoundError');
866
- });
867
- }); // end contexts
868
- });