UNPKG

24.6 kBJavaScriptView Raw
1process.env.NODE_TLS_REJECT_UNAUTHORIZED=0
2const axios = require('axios');
3const pretty = require('prettyjson');
4const Promise = require('bluebird');
5const oada = require('../build/index')
6const _ = require('lodash');
7var chai = require('chai');
8var chaiAsPromised = require("chai-as-promised");
9chai.use(chaiAsPromised);
10var expect = chai.expect;
11const {token, domain} = require('./config.js');
12const {tree, getConnections} = require('./utils.js');
13
14var resources = [];
15var connections;
16
17describe(`------------PUT-----------------`, async function() {
18 before(`Create connection types`, async function() {
19 connections = await getConnections({
20 domain,
21 token: 'def',
22 })
23 connections = Object.values(connections)
24// connections = connections.filter(co => co.cache ? true: false)
25 })
26
27 for (let i = 0; i < 4; i++) {
28 describe(`Testing connection ${i+1}`, async function() {
29
30 it(`1. Should error when neither 'url' nor 'path' are supplied`, async function() {
31 console.log(`Cache: ${connections[i].cache ? true : false}; Websocket: ${connections[i].websocket ? true : false}`)
32 return expect(connections[i].put({
33 data: `"abc123"`,
34 tree,
35 type: 'application/json'
36 })).to.be.rejectedWith(Error, 'Either path or url must be specified.')
37 })
38
39 it(`2. Shouldn't error when the 'Content-Type' header can be derived from the '_type' key in the PUT body`, async function() {
40 var response = await connections[i].put({
41 path: '/bookmarks/test/sometest',
42 data: { _type: 'application/json'},
43 })
44 expect(response.status).to.equal(204)
45 })
46
47 it(`3. Shouldn't error when the 'Content-Type' header can be derived from the 'type' key`, async function() {
48 var response = await connections[i].put({
49 path: '/bookmarks/test/somethingnew',
50 data: `"abc123"`,
51 type: 'application/json'
52 })
53 expect(response.status).to.equal(204)
54 })
55
56 it(`4. Shouldn't error when 'Content-Type' header is specified.`, async function() {
57 var response = await connections[i].put({
58 path: '/bookmarks/test/somethingnew',
59 data: `"abc123"`,
60 headers: {'Content-Type': 'application/json'}
61 })
62 expect(response.status).to.equal(204)
63 })
64
65 it(`5. Shouldn't error when 'Content-Type' header (_type) can be derived from the 'tree'`, async function() {
66 await connections[i].delete({path:'/bookmarks/test', tree})
67 await connections[i].resetCache();
68 var response = await connections[i].put({
69 path: '/bookmarks/test/aaa/bbb/index-one/sometest',
70 tree,
71 data: `"abc123"`,
72 })
73 expect(response.status).to.equal(204)
74 })
75
76 it(`6. Should error when _type cannot be derived from the above tested sources`, async function() {
77 return expect(connections[i].put({
78 path: '/bookmarks/test/sometest',
79 data: `"abc123"`,
80 })).to.be.rejectedWith(Error, `content-type header must be specified.`)
81 })
82
83 it(`7. Should produce a 403 error when using a content-type header for which your token does not have access to read/write`, async function() {
84 await connections[i].resetCache()
85 await connections[i].delete({path:'/bookmarks/test', tree})
86 return expect(connections[i].put({
87 path: '/bookmarks/test/aaa/bbb/index-one/ccc',
88 headers: {'Content-Type': 'application/vnd.oada.foobar.1+json'},
89 tree: tree,
90 data: {anothertest: 123},
91 })).to.be.rejectedWith(Error, 'Request failed with status code 403')
92 })
93
94 it(`8. Should produce a 403 error when using a content-type specified in the middle of the 'tree' for which your token does not have access to read/write`, async function() {
95 await connections[i].delete({path:'/bookmarks/test', tree})
96 await connections[i].resetCache()
97 var newTree = _.cloneDeep(tree)
98 newTree.bookmarks.test.aaa.bbb._type = 'application/vnd.oada.foobar.1+json';
99 return expect(connections[i].put({
100 path: '/bookmarks/test/aaa/bbb/index-one/ccc/',
101 tree: newTree,
102 data: {anothertest: 123},
103 })).to.be.rejectedWith(Error, 'Request failed with status code 403')
104 })
105
106 it(`9. Should properly create a single new resource. The link _rev should not remain as "0-0"`, async function() {
107 await connections[i].resetCache();
108 await connections[i].delete({path:'/bookmarks/test', tree})
109 var response = await connections[i].put({
110 path: '/bookmarks/test/aaa',
111 data: {'sometest': 123},
112 tree,
113 })
114 expect(response.status).to.equal(204)
115 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev', 'location'])
116
117 response = await connections[i].get({
118 path: '/bookmarks',
119 tree
120 })
121 expect(response.status).to.equal(200)
122 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev'])
123 expect(response.data).to.include.keys(['_id', '_rev', 'test'])
124 expect(response.data.test._rev).not.to.equal('0-0')
125 })
126
127 it(`10. Should create the proper resource breaks on the server when a 'tree' parameter is supplied to a deep endpoint`, async function() {
128 this.timeout(4000)
129 await connections[i].delete({path:'/bookmarks/test', tree})
130 await connections[i].resetCache();
131 var response = await connections[i].put({
132 path: '/bookmarks/test/aaa/bbb/index-one/ccc/index-two/ddd/index-three/eee',
133 data: {"test": "some test"},
134 tree,
135 })
136 expect(response.status).to.equal(204)
137 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev', 'location'])
138 response = await connections[i].get({
139 path: '/bookmarks/test/aaa',
140 })
141 response = await connections[i].get({
142 path: '/bookmarks/test/aaa',
143 })
144 if (connections[i].cache) {
145 expect(response.cached).to.equal(true)
146 }
147 expect(response.status).to.equal(200)
148 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev'])
149 expect(response.data).to.include.keys(['_id', '_rev', 'bbb'])
150 expect(response.data.bbb).to.have.keys(['_id', '_rev'])
151 expect(response.data.bbb).to.not.include.keys(['index-one'])
152
153 await connections[i].get({
154 path: '/bookmarks/test/aaa/bbb',
155 })
156 response = await connections[i].get({
157 path: '/bookmarks/test/aaa/bbb',
158 })
159 expect(response.status).to.equal(200)
160 if (connections[i].cache) {
161 expect(response.cached).to.equal(true)
162 }
163 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev'])
164 expect(response.data).to.include.keys(['_id', '_rev', 'index-one'])
165 expect(response.data['index-one']).to.not.include.keys(['_id', '_rev'])
166 expect(response.data['index-one']).to.include.keys(['ccc'])
167
168 await connections[i].get({
169 path: '/bookmarks/test/aaa/bbb/index-one',
170 })
171 response = await connections[i].get({
172 path: '/bookmarks/test/aaa/bbb/index-one',
173 })
174 expect(response.status).to.equal(200)
175 if (connections[i].cache) {
176 expect(response.cached).to.equal(true)
177 }
178 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev'])
179 expect(response.data).to.not.include.keys(['_id', '_rev'])
180 expect(response.data).to.include.keys(['ccc'])
181 expect(response.data.ccc).to.have.keys(['_id', '_rev'])
182
183 await connections[i].get({
184 path: '/bookmarks/test/aaa/bbb/index-one/ccc',
185 })
186 response = await connections[i].get({
187 path: '/bookmarks/test/aaa/bbb/index-one/ccc',
188 })
189 expect(response.status).to.equal(200)
190 if (connections[i].cache) {
191 expect(response.cached).to.equal(true)
192 }
193 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev'])
194 expect(response.data).to.include.keys(['_id', '_type', '_rev', 'index-two'])
195 expect(response.data['index-two']).to.not.include.keys(['_id', '_rev'])
196
197 await connections[i].get({
198 path: '/bookmarks/test/aaa/bbb/index-one/ccc/index-two',
199 })
200 response = await connections[i].get({
201 path: '/bookmarks/test/aaa/bbb/index-one/ccc/index-two',
202 })
203 expect(response.status).to.equal(200)
204 if (connections[i].cache) {
205 expect(response.cached).to.equal(true)
206 }
207 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev'])
208 expect(response.data).to.not.include.keys(['_id', '_rev'])
209 expect(response.data).to.include.keys(['ddd'])
210 expect(response.data['ddd']).to.have.keys(['_id', '_rev'])
211
212 await connections[i].get({
213 path: '/bookmarks/test/aaa/bbb/index-one/ccc/index-two/ddd',
214 })
215 response = await connections[i].get({
216 path: '/bookmarks/test/aaa/bbb/index-one/ccc/index-two/ddd',
217 })
218 expect(response.status).to.equal(200)
219 if (connections[i].cache) {
220 expect(response.cached).to.equal(true)
221 }
222 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev'])
223 expect(response.data).to.include.keys(['_id', '_type', '_rev', 'index-three'])
224 expect(response.data['index-three']).to.not.include.keys(['_id', '_rev'])
225 expect(response.data['index-three']).to.include.keys(['eee'])
226
227 await connections[i].get({
228 path: '/bookmarks/test/aaa/bbb/index-one/ccc/index-two/ddd/index-three',
229 })
230 response = await connections[i].get({
231 path: '/bookmarks/test/aaa/bbb/index-one/ccc/index-two/ddd/index-three',
232 })
233 expect(response.status).to.equal(200)
234 if (connections[i].cache) {
235 expect(response.cached).to.equal(true)
236 }
237 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev'])
238 expect(response.data).to.not.include.keys(['_id', '_rev'])
239 expect(response.data).to.include.keys(['eee'])
240 expect(response.data['eee']).to.have.keys(['_id'])
241 expect(response.data['eee']).to.not.have.keys(['_rev'])
242
243 await connections[i].get({
244 path: '/bookmarks/test/aaa/bbb/index-one/ccc/index-two/ddd/index-three/eee',
245 })
246 response = await connections[i].get({
247 path: '/bookmarks/test/aaa/bbb/index-one/ccc/index-two/ddd/index-three/eee',
248 })
249 expect(response.status).to.equal(200)
250 if (connections[i].cache) {
251 expect(response.cached).to.equal(true)
252 }
253 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev'])
254 expect(response.data).to.include.keys(['_id', '_rev', 'test'])
255 expect(response.data['test']).to.not.include.keys(['_id', '_rev'])
256 })
257
258 it(`11. Should allow for a PUT request without a 'tree' parameter`, async function() {
259 var response = await connections[i].put({
260 path: '/bookmarks/test/aaa/bbb/index-one/ccc/index-two/ddd/index-three/eee/test/123',
261 type: 'application/vnd.oada.as-harvested.yield-moisture-dataset.1+json',
262 data: `"some test"`,
263 })
264 expect(response.status).to.equal(204)
265 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev', 'location'])
266
267 response = await connections[i].get({
268 path: '/bookmarks/test',
269 })
270 expect(response.status).to.equal(200)
271 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev'])
272 expect(response.data).to.include.keys(['_id', '_rev', 'aaa'])
273 expect(response.data.aaa).to.have.keys(['_id', '_rev'])
274 expect(response.data.aaa).to.not.include.keys(['bbb'])
275 })
276
277
278 it('12. Should create the proper resource if we PUT to a different path on an existing subtree', async function() {
279 var response = await connections[i].put({
280 path: '/bookmarks/test/aaa/bbb/index-one/ccc/index-two/ggg/index-three/hhh/test/123',
281 type: 'application/vnd.oada.as-harvested.yield-moisture-dataset.1+json',
282 data: `"some test"`,
283 tree,
284 })
285 expect(response.status).to.equal(204)
286 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev', 'location'])
287
288 response = await connections[i].get({
289 path: '/bookmarks/test',
290 })
291 expect(response.status).to.equal(200)
292 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev'])
293 expect(response.data).to.include.keys(['_id', '_rev', 'aaa'])
294 expect(response.data.aaa).to.have.keys(['_id', '_rev'])
295 expect(response.data.aaa).to.not.include.keys(['bbb'])
296
297 response = await connections[i].get({
298 path: '/bookmarks/test/aaa',
299 })
300 expect(response.status).to.equal(200)
301 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev'])
302 expect(response.data).to.include.keys(['_id', '_rev', 'bbb'])
303 expect(response.data.bbb).to.have.keys(['_id', '_rev'])
304 expect(response.data.bbb).to.not.include.keys(['index-one'])
305
306 response = await connections[i].get({
307 path: '/bookmarks/test/aaa/bbb',
308 })
309 expect(response.status).to.equal(200)
310 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev'])
311 expect(response.data).to.include.keys(['_id', '_rev', 'index-one'])
312 expect(response.data['index-one']).to.not.include.keys(['_id', '_rev'])
313 expect(response.data['index-one']).to.include.keys(['ccc'])
314
315 response = await connections[i].get({
316 path: '/bookmarks/test/aaa/bbb/index-one',
317 })
318 expect(response.status).to.equal(200)
319 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev'])
320 expect(response.data).to.not.include.keys(['_id', '_rev'])
321 expect(response.data).to.include.keys(['ccc'])
322 expect(response.data.ccc).to.have.keys(['_id', '_rev'])
323
324 response = await connections[i].get({
325 path: '/bookmarks/test/aaa/bbb/index-one/ccc',
326 })
327 expect(response.status).to.equal(200)
328 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev'])
329 expect(response.data).to.include.keys(['_id', '_rev', 'index-two'])
330 expect(response.data['index-two']).to.not.include.keys(['_id', '_rev'])
331
332 response = await connections[i].get({
333 path: '/bookmarks/test/aaa/bbb/index-one/ccc/index-two',
334 })
335 expect(response.status).to.equal(200)
336 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev'])
337 expect(response.data).to.not.include.keys(['_id', '_rev'])
338 expect(response.data).to.include.keys(['ggg'])
339 expect(response.data['ggg']).to.have.keys(['_id', '_rev'])
340
341 response = await connections[i].get({
342 path: '/bookmarks/test/aaa/bbb/index-one/ccc/index-two/ggg',
343 })
344 expect(response.status).to.equal(200)
345 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev'])
346 expect(response.data).to.include.keys(['_id', '_rev', 'index-three'])
347 expect(response.data['index-three']).to.not.include.keys(['_id', '_rev'])
348 expect(response.data['index-three']).to.include.keys(['hhh'])
349
350 response = await connections[i].get({
351 path: '/bookmarks/test/aaa/bbb/index-one/ccc/index-two/ggg/index-three',
352 })
353 expect(response.status).to.equal(200)
354 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev'])
355 expect(response.data).to.not.include.keys(['_id', '_rev'])
356 expect(response.data).to.include.keys(['hhh'])
357 expect(response.data['hhh']).to.have.keys(['_id'])
358 expect(response.data['hhh']).to.not.have.keys(['_rev'])
359
360 response = await connections[i].get({
361 path: '/bookmarks/test/aaa/bbb/index-one/ccc/index-two/ggg/index-three/hhh',
362 })
363 expect(response.status).to.equal(200)
364 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev'])
365 expect(response.data).to.include.keys(['_id', '_rev', 'test'])
366 expect(response.data['test']).to.not.include.keys(['_id', '_rev'])
367 })
368
369 it(`13. Should use an _id specified via the 'tree'`, async function() {
370 this.timeout(4000)
371 await connections[i].resetCache();
372 await connections[i].delete({path:'/bookmarks/test', tree})
373 var newTree = _.cloneDeep(tree)
374 newTree.bookmarks.test.aaa.sss = {
375 _id: 'resources/sssssssss',
376 _type: 'application/vnd.oada.yield.1+json',
377 _rev: '0-0'
378 }
379 var putResponse = await connections[i].put({
380 path: '/bookmarks/test/aaa/sss',
381 tree: newTree,
382 data: {anothertest: 123},
383 })
384 var response = await connections[i].get({
385 path: '/bookmarks/test/aaa/sss',
386 })
387 expect(response.status).to.equal(200)
388 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev'])
389 expect(response.data).to.include.keys(['_id', '_rev', 'anothertest'])
390 expect(response.data._id).to.equal('resources/sssssssss')
391 })
392
393 it(`14. Should use an _id specified via the 'data'`, async function() {
394 this.timeout(4000)
395 var putResponse = await connections[i].put({
396 path: '/bookmarks/test/aaa/bbb',
397 tree: tree,
398 data: {_id: 'resources/foobar_foobar', sometest: 123},
399 })
400 var response = await connections[i].get({
401 path: '/bookmarks/test/aaa/bbb',
402 })
403 expect(response.status).to.equal(200)
404 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev'])
405 expect(response.data).to.include.keys(['_id', '_rev', 'sometest'])
406 expect(response.data._id).to.equal('resources/foobar_foobar')
407 expect(response.data.sometest).to.equal(123)
408 })
409
410 it('15. Should make unversioned links where _rev is not specified on resources', async function() {
411 this.timeout(4000)
412 await connections[i].resetCache();
413 await connections[i].delete({path:'/bookmarks/test', tree})
414
415 var newTree = _.cloneDeep(tree)
416 delete newTree.bookmarks.test.aaa.bbb._rev
417
418 var putResponse = await connections[i].put({
419 path: '/bookmarks/test/aaa/bbb/index-one/ccc/',
420 tree: newTree,
421 data: {anothertest: 123},
422 })
423 var response = await connections[i].get({
424 path: '/bookmarks/test/aaa',
425 })
426 expect(response.status).to.equal(200)
427 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev'])
428 expect(response.data.bbb).to.include.keys(['_id'])
429 expect(response.data.bbb).to.not.include.keys(['_rev'])
430 })
431
432 it(`16. Should produce a 412 if the 'If-Match' header doesn't match the existing _rev`, async function() {
433 await connections[i].resetCache();
434 await connections[i].delete({path:'/bookmarks/test', tree})
435 return expect(connections[i].put({
436 path: '/bookmarks/test',
437 data: {'sometest': 'foobar'},
438 headers: {
439 'If-Match': '2-foobar',
440 'Content-Type': 'application/json'
441 }
442 })).to.be.rejectedWith(Error, 'Request failed with status code 412');
443 })
444
445 it(`17. Should produce a 412 if two PUTs are executed in series with the same 'If-Match' header`, async function() {
446 await connections[i].resetCache();
447 await connections[i].delete({path:'/bookmarks/test', tree})
448 var response = await connections[i].get({path: '/bookmarks'})
449 expect(response.status).to.equal(200)
450 var putOne = await connections[i].put({
451 path: '/bookmarks/test',
452 data: {'testOne': 'putOne'},
453 headers: {
454 'If-Match': response.headers['x-oada-rev'],
455 'Content-Type': 'application/json'
456 }
457 })
458 expect(putOne.status).to.equal(204)
459 return expect(connections[i].put({
460 path: '/bookmarks/test',
461 data: {'testTwo': 'putTwo'},
462 headers: {
463 'If-Match': response.headers['x-oada-rev'],
464 'Content-Type': 'application/json'
465 }
466 })).to.be.rejectedWith(Error, 'Request failed with status code 412');
467 })
468
469 it(`18. Should produce a 412 if two PUTs are executed in parallel with the same 'If-Match' header`, async function() {
470 await connections[i].resetCache();
471 await connections[i].delete({path:'/bookmarks/test', tree})
472 var response = await connections[i].get({path: '/bookmarks'})
473 expect(response.status).to.equal(200)
474 var putOne = connections[i].put({
475 path: '/bookmarks/test',
476 data: {'testOne': 'putOne'},
477 headers: {
478 'If-Match': response.headers['x-oada-rev'],
479 'Content-Type': 'application/json'
480 }
481 })
482 var putTwo = connections[i].put({
483 path: '/bookmarks/test',
484 data: {'testTwo': 'putTwo'},
485 headers: {
486 'If-Match': response.headers['x-oada-rev'],
487 'Content-Type': 'application/json'
488 }
489 })
490 return expect(
491 Promise.join(putOne,putTwo, async function(putOne,putTwo) {console.log(putOne,putTwo)})
492 ).to.be.rejectedWith(Error, 'Request failed with status code 412')
493 })
494
495 it(`19. Should work under a sequence of PUT, DELETE, PUT`, async function() {
496 this.timeout(3000);
497 await connections[i].resetCache();
498 await connections[i].delete({path:'/bookmarks/test', tree})
499 var putOne = await connections[i].put({
500 path: '/bookmarks/test/aaa/bbb/index-one/ccc',
501 tree,
502 data: {sometest: 123},
503 })
504 var deleteOne = await connections[i].delete({
505 path: '/bookmarks/test/aaa/bbb/index-one/ccc',
506 tree,
507 })
508 var putTwo = await connections[i].put({
509 path: '/bookmarks/test/aaa/bbb/index-one/ccc',
510 tree,
511 data: {anothertest: 123},
512 })
513 var response = await connections[i].get({
514 path: '/bookmarks/test',
515 tree
516 })
517 expect(response.status).to.equal(200)
518 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev'])
519 expect(response.data).to.include.keys(['_id', '_rev', '_type', 'aaa'])
520 expect(response.data.aaa).to.include.keys(['_id', '_rev', 'bbb', '_type'])
521 expect(response.data.aaa.bbb).to.include.keys(['_id', '_rev', 'index-one', '_type'])
522 expect(response.data.aaa.bbb['index-one']).to.include.keys(['ccc'])
523 expect(response.data.aaa.bbb['index-one'].ccc).to.include.keys(['_id', '_rev', '_type', 'anothertest'])
524 expect(response.data.aaa.bbb['index-one'].ccc).to.not.include.keys(['sometest'])
525 })
526
527 it(`20. Should work under a sequence of PUTs to similar (same parent tree) endpoints`, async function() {
528 this.timeout(15000);
529 await connections[i].resetCache();
530 await connections[i].delete({path:'/bookmarks/test', tree})
531 var putOne = connections[i].put({
532 path: '/bookmarks/test/aaa/bbb/index-one/ccc/index-two/ddd/index-three/eee',
533 tree: tree,
534 data: {testOne: 123},
535 })
536 var putTwo = connections[i].put({
537 path: '/bookmarks/test/aaa/bbb/index-one/ccc/index-two/fff/index-three/eee',
538 tree: tree,
539 data: {testTwo: 123},
540 })
541 var putThree = connections[i].put({
542 path: '/bookmarks/test/aaa/bbb/index-one/ggg/index-two/ddd/index-three/eee',
543 tree: tree,
544 data: {testThree: 123},
545 })
546 var putFour = connections[i].put({
547 path: '/bookmarks/test/aaa/bbb/index-one/ccc/index-two/ddd/index-three/eee',
548 tree: tree,
549 data: {testFour: 123},
550 })
551 var result = await Promise.join(putOne,putTwo,putThree, putFour, async function(putOne,putTwo,putThree,putFour) {
552 var response = await connections[i].get({
553 path: '/bookmarks/test',
554 tree
555 })
556 expect(putOne.status).to.equal(204)
557 expect(putTwo.status).to.equal(204)
558 expect(putThree.status).to.equal(204)
559 expect(response.status).to.equal(200)
560 expect(response.status).to.equal(200)
561 expect(response.headers).to.include.keys(['content-location', 'x-oada-rev'])
562 expect(response.data).to.include.keys(['_id', '_rev', '_type', 'aaa'])
563 expect(response.data.aaa).to.include.keys(['_id', '_rev', 'bbb', '_type'])
564 expect(response.data.aaa.bbb).to.include.keys(['_id', '_rev', 'index-one', '_type'])
565 expect(response.data.aaa.bbb['index-one']).to.include.keys(['ccc', 'ggg'])
566 expect(response.data.aaa.bbb['index-one'].ccc).to.include.keys(['_id', '_rev', '_type', 'index-two'])
567 expect(response.data.aaa.bbb['index-one'].ggg).to.include.keys(['_id', '_rev', '_type', 'index-two'])
568 expect(response.data.aaa.bbb['index-one'].ccc['index-two']).to.include.keys(['ddd', 'fff'])
569 expect(response.data.aaa.bbb['index-one'].ccc['index-two'].ddd).to.include.keys(['_id', '_rev', '_type', 'index-three'])
570 expect(response.data.aaa.bbb['index-one'].ccc['index-two'].fff).to.include.keys(['_id', '_rev', '_type', 'index-three'])
571 expect(response.data.aaa.bbb['index-one'].ccc['index-two'].ddd['index-three'].eee).to.include.keys(['_id', '_rev', '_type', 'testOne', 'testFour'])
572 expect(response.data.aaa.bbb['index-one'].ccc['index-two'].fff['index-three'].eee).to.include.keys(['_id', '_rev', '_type', 'testTwo'])
573 expect(response.data.aaa.bbb['index-one'].ggg['index-two']).to.include.keys(['ddd'])
574 expect(response.data.aaa.bbb['index-one'].ggg['index-two'].ddd).to.include.keys(['_id', '_rev', '_type', 'index-three'])
575 expect(response.data.aaa.bbb['index-one'].ggg['index-two'].ddd['index-three'].eee).to.include.keys(['_id', '_rev', '_type', 'testThree'])
576 })
577 })
578
579 it('21. Now clean up', async function() {
580 this.timeout(3000);
581 await connections[i].resetCache();
582 await connections[i].delete({path:'/bookmarks/test', tree})
583 })
584 })
585 }
586})