beanbagdb 0.5.52 → 0.5.53

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,14 +1,24 @@
1
- // to test database operations. assuming the class is initialized successfully
2
- // to test initialization of the BeanBagDB class
3
- import { get_pdb_doc } from './pouchdb.js';
4
- import { throws, strictEqual,rejects } from "assert";
5
- import {BeanBagDB,ValidationError} from '../src/index.js';
1
+ // to test database operations. assuming the class is initialized successfully
2
+ // to test initialization of the BeanBagDB class
3
+ import { get_pdb_doc } from "./pouchdb.js";
4
+ import assert, { throws, strictEqual, rejects } from "assert";
5
+ import { BeanBagDB, DocCreationError, EncryptionError, ValidationError,DocNotFoundError, DocUpdateError } from "../src/index.js";
6
6
 
7
- let database // this is the global db object
7
+ import * as chai from 'chai';
8
+ import chaiAsPromised from 'chai-as-promised';
9
+
10
+ chai.use(chaiAsPromised);
11
+
12
+ // Then either:
13
+ const expect = chai.expect;
14
+
15
+ let database; // this is the global db object
16
+ let database1
17
+ let database2
8
18
 
9
19
  describe("Successful database class init (required for further testing) ", async () => {
10
20
  it("DB init successful", () => {
11
- let doc_obj = get_pdb_doc("test_database_25","qwertyuiopaqwsde1254")
21
+ let doc_obj = get_pdb_doc("test_database_25", "qwertyuiopaqwsde1254");
12
22
  database = new BeanBagDB(doc_obj);
13
23
  strictEqual(
14
24
  database instanceof BeanBagDB,
@@ -20,122 +30,148 @@ describe("Successful database class init (required for further testing) ", async
20
30
 
21
31
  describe("Schema doc insertion gives errors when", async () => {
22
32
  let schema_docs_invalid = [
23
- [ "name missing",
24
- {
25
- name: "",
26
- description: "",
27
- schema: {},
28
- settings: {},
29
- }],
30
- ["name is too short ",
31
- {
32
- name: "nos",
33
- description: "",
34
- schema: {},
35
- settings: {},
36
- }],
37
- ["schema is blank",
38
- {
39
- name: "contact",
40
- description: "",
41
- schema: {},
42
- settings: {},
43
- }],
44
- ["schema object missing",
45
- {
46
- name: "contact",
47
- description: "This can be left blank",
48
- settings: {},
49
- }],
50
- [
51
- "no schema.type",{
52
- name: "contact",
53
- description: "This can be left blank",
54
- schema: {
55
- "abc":"something"
56
- },
57
- settings: {},
58
- }],
59
- ["schema.type is invalid",
60
- {
61
- name: "contact",
62
- description: "This can be left blank",
63
- schema: {
64
- "type":"something",
65
- },
66
- settings: {},
67
- }],
68
- ["schema.properties is missing",
69
- {
70
- name: "contact",
71
- description: "This can be left blank",
72
- schema: {
73
- "type":"object",
74
- },
75
- settings: {},
76
- }],
77
- ["schema.properties is invalid",
78
- {
79
- name: "contact",
80
- description: "This can be left blank",
81
- schema: {
82
- "type":"object",
83
- "properties":"something"
84
- },
85
- settings: {},
86
- }],
87
- ["schema.properties are missing/blank object",
88
- {
89
- name: "contact",
90
- description: "This can be left blank",
91
- schema: {
92
- "type":"object",
93
- "properties":{}
94
- },
95
- settings: {},
96
- }],
97
- ["schema.additionalProperties is missing",
98
- {
99
- name: "contact",
100
- description: "This can be left blank",
101
- schema: {
102
- "type":"object",
103
- "properties":{"name":{"type":"string"}}
104
- },
105
- settings: {},
106
- }],
107
- ["schema.additionalProperties is invalid",
108
- {
109
- name: "contact",
110
- description: "This can be left blank",
111
- schema: {
112
- "type":"object",
113
- "properties":{"name":{"type":"string"}},
114
- "additionalProperties":"no"
115
- },
116
- settings: {},
117
- }],
118
- [
119
- "setting is missing",{
120
- name: "contact",
121
- description: "This can be left blank",
122
- schema: {
123
- "type":"object",
124
- "properties":{"name":{"type":"string"}},
125
- "additionalProperties":true
126
- }
127
- }],
128
- [
129
- "setting is invalid",{
130
- name: "contact",
131
- description: "This can be left blank",
132
- schema: {
133
- "type":"object",
134
- "properties":{"name":{"type":"string"}},
135
- "additionalProperties":true
136
- },
137
- settings:"none"
138
- }],
33
+ [
34
+ "name missing",
35
+ {
36
+ name: "",
37
+ description: "",
38
+ schema: {},
39
+ settings: {},
40
+ },
41
+ ],
42
+ [
43
+ "name is too short ",
44
+ {
45
+ name: "nos",
46
+ description: "",
47
+ schema: {},
48
+ settings: {},
49
+ },
50
+ ],
51
+ [
52
+ "schema is blank",
53
+ {
54
+ name: "contact",
55
+ description: "",
56
+ schema: {},
57
+ settings: {},
58
+ },
59
+ ],
60
+ [
61
+ "schema object missing",
62
+ {
63
+ name: "contact",
64
+ description: "This can be left blank",
65
+ settings: {},
66
+ },
67
+ ],
68
+ [
69
+ "no schema.type",
70
+ {
71
+ name: "contact",
72
+ description: "This can be left blank",
73
+ schema: {
74
+ abc: "something",
75
+ },
76
+ settings: {},
77
+ },
78
+ ],
79
+ [
80
+ "schema.type is invalid",
81
+ {
82
+ name: "contact",
83
+ description: "This can be left blank",
84
+ schema: {
85
+ type: "something",
86
+ },
87
+ settings: {},
88
+ },
89
+ ],
90
+ [
91
+ "schema.properties is missing",
92
+ {
93
+ name: "contact",
94
+ description: "This can be left blank",
95
+ schema: {
96
+ type: "object",
97
+ },
98
+ settings: {},
99
+ },
100
+ ],
101
+ [
102
+ "schema.properties is invalid",
103
+ {
104
+ name: "contact",
105
+ description: "This can be left blank",
106
+ schema: {
107
+ type: "object",
108
+ properties: "something",
109
+ },
110
+ settings: {},
111
+ },
112
+ ],
113
+ [
114
+ "schema.properties are missing/blank object",
115
+ {
116
+ name: "contact",
117
+ description: "This can be left blank",
118
+ schema: {
119
+ type: "object",
120
+ properties: {},
121
+ },
122
+ settings: {},
123
+ },
124
+ ],
125
+ [
126
+ "schema.additionalProperties is missing",
127
+ {
128
+ name: "contact",
129
+ description: "This can be left blank",
130
+ schema: {
131
+ type: "object",
132
+ properties: { name: { type: "string" } },
133
+ },
134
+ settings: {},
135
+ },
136
+ ],
137
+ [
138
+ "schema.additionalProperties is invalid",
139
+ {
140
+ name: "contact",
141
+ description: "This can be left blank",
142
+ schema: {
143
+ type: "object",
144
+ properties: { name: { type: "string" } },
145
+ additionalProperties: "no",
146
+ },
147
+ settings: {},
148
+ },
149
+ ],
150
+ [
151
+ "setting is missing",
152
+ {
153
+ name: "contact",
154
+ description: "This can be left blank",
155
+ schema: {
156
+ type: "object",
157
+ properties: { name: { type: "string" } },
158
+ additionalProperties: true,
159
+ },
160
+ },
161
+ ],
162
+ [
163
+ "setting is invalid",
164
+ {
165
+ name: "contact",
166
+ description: "This can be left blank",
167
+ schema: {
168
+ type: "object",
169
+ properties: { name: { type: "string" } },
170
+ additionalProperties: true,
171
+ },
172
+ settings: "none",
173
+ },
174
+ ],
139
175
  // ["settings.primary_keys is missing",
140
176
  // {
141
177
  // name: "contact",
@@ -148,163 +184,194 @@ describe("Schema doc insertion gives errors when", async () => {
148
184
  // settings: {
149
185
  // },
150
186
  // }],
151
- ["settings.primary_keys is invalid",
152
- {
153
- name: "contact",
154
- description: "This can be left blank",
155
- schema: {
156
- "type":"object",
157
- "properties":{"name":{"type":"string"}},
158
- "additionalProperties":true
159
- },
160
- settings: {
161
- primary_keys:"name"
162
- },
163
- }],
164
- ["settings.non_editable_fields is invalid",
165
- {
166
- name: "contact",
167
- description: "This can be left blank",
168
- schema: {
169
- "type":"object",
170
- "properties":{"name":{"type":"string"}},
171
- "additionalProperties":true
172
- },
173
- settings: {
174
- primary_keys:["name"],
175
- non_editable_fields:"all"
176
- },
177
- }],
178
- ["settings.single_record is invalid",
179
- {
180
- name: "contact",
181
- description: "This can be left blank",
182
- schema: {
183
- "type":"object",
184
- "properties":{"name":{"type":"string"}},
185
- "additionalProperties":true
186
- },
187
- settings: {
188
- primary_keys:["name"],
189
- non_editable_fields:[],
190
- single_record:"no"
191
- },
192
- }],
193
- ["settings.encrypted_fields is invalid",
194
- {
195
- name: "contact",
196
- description: "This can be left blank",
197
- schema: {
198
- "type":"object",
199
- "properties":{"name":{"type":"string"}},
200
- "additionalProperties":true
201
- },
202
- settings: {
203
- primary_keys:["name"],
204
- non_editable_fields:[],
205
- single_record:false,
206
- encrypted_fields:"none"
207
- },
208
- }],
209
- ["settings.primary_keys fields are not defined in schema",
210
- {
211
- name: "contact",
212
- description: "This can be left blank",
213
- schema: {
214
- "type":"object",
215
- "properties":{"name":{"type":"string"}},
216
- "additionalProperties":true
217
- },
218
- settings: {
219
- primary_keys:["name1"],
220
- non_editable_fields:[],
221
- single_record:false,
222
- encrypted_fields:"none"
223
- },
224
- }],
225
- ["settings.primary_keys field is an object",
226
- {
227
- name: "contact",
228
- description: "This can be left blank",
229
- schema: {
230
- "type":"object",
231
- "properties":{"name":{"type":"object"},"address":{type:"string"}},
232
- "additionalProperties":true
233
- },
234
- settings: {
235
- primary_keys:["name"],
236
- non_editable_fields:[],
237
- single_record:false,
238
- encrypted_fields:[]
239
- },
240
- }],
241
- ["settings.non_editable_fields not defined in the schema",
242
- {
243
- name: "contact",
244
- description: "This can be left blank",
245
- schema: {
246
- "type":"object",
247
- "properties":{"name":{"type":"string"},"address":{type:"string"}},
248
- "additionalProperties":true
249
- },
250
- settings: {
251
- primary_keys:["name"],
252
- non_editable_fields:["mobile"],
253
- single_record:false,
254
- encrypted_fields:[]
255
- },
256
- }],
257
- ["settings.encrypted_fields not defined in the schema",
258
- {
259
- name: "contact",
260
- description: "This can be left blank",
261
- schema: {
262
- "type":"object",
263
- "properties":{"name":{"type":"string"},"address":{type:"object"},"secret":{"type":"string"}},
264
- "additionalProperties":true
265
- },
266
- settings: {
267
- primary_keys:["name"],
268
- non_editable_fields:["mobile"],
269
- single_record:false,
270
- encrypted_fields:["password"]
271
- },
272
- }],
273
- ["settings.encrypted_fields is not a string",
274
- {
275
- name: "contact",
276
- description: "This can be left blank",
277
- schema: {
278
- "type":"object",
279
- "properties":{"name":{"type":"string"},"address":{type:"object"},"secret":{"type":"string"}},
280
- "additionalProperties":true
281
- },
282
- settings: {
283
- primary_keys:["name"],
284
- non_editable_fields:["mobile"],
285
- single_record:false,
286
- encrypted_fields:["address"]
287
- },
288
- }],
289
- ["settings.encrypted_fields is a primary key",
290
- {
291
- name: "contact",
292
- description: "This can be left blank",
293
- schema: {
294
- "type":"object",
295
- "properties":{"name":{"type":"string"},"address":{type:"object"},"secret":{"type":"string"}},
296
- "additionalProperties":true
297
- },
298
- settings: {
299
- primary_keys:["name"],
300
- non_editable_fields:["mobile"],
301
- single_record:false,
302
- encrypted_fields:["name"]
303
- },
304
- }]
187
+ [
188
+ "settings.primary_keys is invalid",
189
+ {
190
+ name: "contact",
191
+ description: "This can be left blank",
192
+ schema: {
193
+ type: "object",
194
+ properties: { name: { type: "string" } },
195
+ additionalProperties: true,
196
+ },
197
+ settings: {
198
+ primary_keys: "name",
199
+ },
200
+ },
201
+ ],
202
+ [
203
+ "settings.non_editable_fields is invalid",
204
+ {
205
+ name: "contact",
206
+ description: "This can be left blank",
207
+ schema: {
208
+ type: "object",
209
+ properties: { name: { type: "string" } },
210
+ additionalProperties: true,
211
+ },
212
+ settings: {
213
+ primary_keys: ["name"],
214
+ non_editable_fields: "all",
215
+ },
216
+ },
217
+ ],
218
+ [
219
+ "settings.single_record is invalid",
220
+ {
221
+ name: "contact",
222
+ description: "This can be left blank",
223
+ schema: {
224
+ type: "object",
225
+ properties: { name: { type: "string" } },
226
+ additionalProperties: true,
227
+ },
228
+ settings: {
229
+ primary_keys: ["name"],
230
+ non_editable_fields: [],
231
+ single_record: "no",
232
+ },
233
+ },
234
+ ],
235
+ [
236
+ "settings.encrypted_fields is invalid",
237
+ {
238
+ name: "contact",
239
+ description: "This can be left blank",
240
+ schema: {
241
+ type: "object",
242
+ properties: { name: { type: "string" } },
243
+ additionalProperties: true,
244
+ },
245
+ settings: {
246
+ primary_keys: ["name"],
247
+ non_editable_fields: [],
248
+ single_record: false,
249
+ encrypted_fields: "none",
250
+ },
251
+ },
252
+ ],
253
+ [
254
+ "settings.primary_keys fields are not defined in schema",
255
+ {
256
+ name: "contact",
257
+ description: "This can be left blank",
258
+ schema: {
259
+ type: "object",
260
+ properties: { name: { type: "string" } },
261
+ additionalProperties: true,
262
+ },
263
+ settings: {
264
+ primary_keys: ["name1"],
265
+ non_editable_fields: [],
266
+ single_record: false,
267
+ encrypted_fields: "none",
268
+ },
269
+ },
270
+ ],
271
+ [
272
+ "settings.primary_keys field is an object",
273
+ {
274
+ name: "contact",
275
+ description: "This can be left blank",
276
+ schema: {
277
+ type: "object",
278
+ properties: { name: { type: "object" }, address: { type: "string" } },
279
+ additionalProperties: true,
280
+ },
281
+ settings: {
282
+ primary_keys: ["name"],
283
+ non_editable_fields: [],
284
+ single_record: false,
285
+ encrypted_fields: [],
286
+ },
287
+ },
288
+ ],
289
+ [
290
+ "settings.non_editable_fields not defined in the schema",
291
+ {
292
+ name: "contact",
293
+ description: "This can be left blank",
294
+ schema: {
295
+ type: "object",
296
+ properties: { name: { type: "string" }, address: { type: "string" } },
297
+ additionalProperties: true,
298
+ },
299
+ settings: {
300
+ primary_keys: ["name"],
301
+ non_editable_fields: ["mobile"],
302
+ single_record: false,
303
+ encrypted_fields: [],
304
+ },
305
+ },
306
+ ],
307
+ [
308
+ "settings.encrypted_fields not defined in the schema",
309
+ {
310
+ name: "contact",
311
+ description: "This can be left blank",
312
+ schema: {
313
+ type: "object",
314
+ properties: {
315
+ name: { type: "string" },
316
+ address: { type: "object" },
317
+ secret: { type: "string" },
318
+ },
319
+ additionalProperties: true,
320
+ },
321
+ settings: {
322
+ primary_keys: ["name"],
323
+ non_editable_fields: ["mobile"],
324
+ single_record: false,
325
+ encrypted_fields: ["password"],
326
+ },
327
+ },
328
+ ],
329
+ [
330
+ "settings.encrypted_fields is not a string",
331
+ {
332
+ name: "contact",
333
+ description: "This can be left blank",
334
+ schema: {
335
+ type: "object",
336
+ properties: {
337
+ name: { type: "string" },
338
+ address: { type: "object" },
339
+ secret: { type: "string" },
340
+ },
341
+ additionalProperties: true,
342
+ },
343
+ settings: {
344
+ primary_keys: ["name"],
345
+ non_editable_fields: ["mobile"],
346
+ single_record: false,
347
+ encrypted_fields: ["address"],
348
+ },
349
+ },
350
+ ],
351
+ [
352
+ "settings.encrypted_fields is a primary key",
353
+ {
354
+ name: "contact",
355
+ description: "This can be left blank",
356
+ schema: {
357
+ type: "object",
358
+ properties: {
359
+ name: { type: "string" },
360
+ address: { type: "object" },
361
+ secret: { type: "string" },
362
+ },
363
+ additionalProperties: true,
364
+ },
365
+ settings: {
366
+ primary_keys: ["name"],
367
+ non_editable_fields: ["mobile"],
368
+ single_record: false,
369
+ encrypted_fields: ["name"],
370
+ },
371
+ },
372
+ ],
305
373
  ];
306
374
 
307
-
308
375
  before(async () => {
309
376
  let doc_obj = get_pdb_doc("test_database_25", "qwertyuiopaqwsde1254");
310
377
  database = new BeanBagDB(doc_obj);
@@ -314,14 +381,1348 @@ describe("Schema doc insertion gives errors when", async () => {
314
381
 
315
382
  schema_docs_invalid.forEach((element, index) => {
316
383
  it(`${element[0]}`, async () => {
317
- await rejects(
318
- async () => {
319
- await database.create("schema", element[1]);
320
- },
321
- ValidationError
322
- );
384
+ await rejects(async () => {
385
+ await database.create("schema", element[1]);
386
+ }, ValidationError);
323
387
  });
324
- });
325
-
388
+ });
326
389
  });
327
390
 
391
+ describe("Doc insertion tests", async () => {
392
+ let schema_docs_invalid = [
393
+ [
394
+ "error when title empty",
395
+ {
396
+ title: "",
397
+ author: "J.K. Rowling",
398
+ isbn: "9780439139601",
399
+ publicationYear: 1999,
400
+ genre: "Fantasy",
401
+ },
402
+ ],
403
+ [
404
+ "error , author empty ",
405
+ {
406
+ title: "Harry Potter",
407
+ author: "",
408
+ isbn: "9780439139601",
409
+ publicationYear: 1999,
410
+ genre: "Fantasy",
411
+ },
412
+ ],
413
+ [
414
+ "error incorrect isbn length",
415
+ {
416
+ title: "Harry Potter",
417
+ author: "J.K. Rowling",
418
+ isbn: "123456",
419
+ publicationYear: 1999,
420
+ genre: "Fantasy",
421
+ },
422
+ ],
423
+ [
424
+ "error when incorrect pub date incorrect",
425
+ {
426
+ title: "Harry Potter",
427
+ author: "J.K. Rowling",
428
+ isbn: "9780439139601",
429
+ publicationYear: 2050,
430
+ genre: "Fantasy",
431
+ },
432
+ ],
433
+ [
434
+ "no schema.type",
435
+ {
436
+ name: "contact",
437
+ description: "This can be left blank",
438
+ schema: {
439
+ abc: "something",
440
+ },
441
+ settings: {},
442
+ },
443
+ ],
444
+ [
445
+ "error with incorrect genre",
446
+ {
447
+ title: "Harry Potter",
448
+ author: "J.K. Rowling",
449
+ isbn: "9780439139601",
450
+ publicationYear: 1999,
451
+ genre: "Unknown Genre",
452
+ },
453
+ ],
454
+ [
455
+ "error empty publisher ",
456
+ {
457
+ title: "Harry Potter",
458
+ author: "J.K. Rowling",
459
+ isbn: "9780439139601",
460
+ publicationYear: 1999,
461
+ genre: "Fantasy",
462
+ publisher: "",
463
+ },
464
+ ],
465
+ [
466
+ "error incorrect page no",
467
+ {
468
+ title: "Harry Potter",
469
+ author: "J.K. Rowling",
470
+ isbn: "9780439139601",
471
+ publicationYear: 1999,
472
+ genre: "Fantasy",
473
+ pages: 0,
474
+ },
475
+ ],
476
+ [
477
+ "error when language incorrect",
478
+ {
479
+ title: "Harry Potter",
480
+ author: "J.K. Rowling",
481
+ isbn: "9780439139601",
482
+ publicationYear: 1999,
483
+ genre: "Fantasy",
484
+ language: 123,
485
+ },
486
+ ],
487
+ [
488
+ "error with additional data",
489
+ {
490
+ title: "Harry Potter",
491
+ author: "J.K. Rowling",
492
+ isbn: "9780439139601",
493
+ publicationYear: 1999,
494
+ genre: "Fantasy",
495
+ unknownField: "Some data",
496
+ },
497
+ ],
498
+ [
499
+ "error when pub_date in not year",
500
+ {
501
+ title: "Harry Potter",
502
+ author: "J.K. Rowling",
503
+ isbn: "9780439139601",
504
+ publicationYear: "1999",
505
+ genre: "Fantasy",
506
+ },
507
+ ],
508
+ [
509
+ "error when required author field is missing",
510
+ {
511
+ title: "Harry Potter",
512
+ author: "J.K. Rowling",
513
+ isbn: "9780439139601",
514
+ genre: "Fantasy",
515
+ },
516
+ ],
517
+ [
518
+ "error when required genre is missing",
519
+ {
520
+ title: "Harry Potter",
521
+ author: "J.K. Rowling",
522
+ isbn: "9780439139601",
523
+ publicationYear: 1999,
524
+ },
525
+ ],
526
+ [
527
+ "error when author name is not string",
528
+ {
529
+ title: "Harry Potter",
530
+ author: ["J.K. Rowling"],
531
+ isbn: "9780439139601",
532
+ publicationYear: 1999,
533
+ genre: "Fantasy",
534
+ },
535
+ ],
536
+ ];
537
+
538
+ const test_schema = {
539
+ name:"book",
540
+ description:"Test schema 1",
541
+ schema: {
542
+ $schema: "http://json-schema.org/draft-07/schema#",
543
+ type: "object",
544
+ properties: {
545
+ title: {
546
+ type: "string",
547
+ minLength: 1,
548
+ description: "The title of the book",
549
+ },
550
+ author: {
551
+ type: "string",
552
+ minLength: 1,
553
+ description: "The author of the book",
554
+ },
555
+ isbn: {
556
+ type: "string",
557
+ pattern: "^(97(8|9))?\\d{9}(\\d|X)$",
558
+ description: "The ISBN of the book, can be 10 or 13 digits",
559
+ },
560
+ publicationYear: {
561
+ type: "integer",
562
+ minimum: 1450,
563
+ maximum: 2024,
564
+ description:
565
+ "The year the book was published (between 1450 and 2024)",
566
+ },
567
+ genre: {
568
+ type: "string",
569
+ enum: [
570
+ "Fiction",
571
+ "Non-Fiction",
572
+ "Science",
573
+ "History",
574
+ "Fantasy",
575
+ "Biography",
576
+ "Children",
577
+ "Mystery",
578
+ "Horror",
579
+ ],
580
+ description: "The genre of the book",
581
+ },
582
+ language: {
583
+ type: "string",
584
+ description: "The language of the book",
585
+ default: "English",
586
+ },
587
+ publisher: {
588
+ type: "string",
589
+ description: "The publisher of the book",
590
+ minLength: 1,
591
+ },
592
+ pages: {
593
+ type: "integer",
594
+ minimum: 1,
595
+ description: "The number of pages in the book",
596
+ },
597
+ },
598
+ required: ["title", "author", "isbn", "publicationYear", "genre"],
599
+ additionalProperties: false,
600
+ },
601
+ settings : {
602
+ primary_keys:['title','author'],
603
+ encrypted_fields:[],
604
+ non_editable_fields:[],
605
+ single_record:false
606
+ }
607
+ }
608
+
609
+ before(async () => {
610
+ // adding a schema
611
+ let doc_obj = get_pdb_doc("test_database_26", "qwertyuiopaqwsde1254");
612
+ database = new BeanBagDB(doc_obj);
613
+ await database.ready(); // Ensure the database is ready before running tests
614
+ try {
615
+ //console.log(test_schema)
616
+ let a = await database.create("schema",test_schema)
617
+ console.log("Ready for more tests...");
618
+ } catch (error) {
619
+ console.log("error in before")
620
+ console.log(error)
621
+ }
622
+ })
623
+
624
+ const book1 = {
625
+ title: "Harry Potter",
626
+ author: "J.K. Rowling",
627
+ isbn: "9780439139601",
628
+ publicationYear: 1999,
629
+ genre: "Fantasy",
630
+ publisher: "ABC DEF"
631
+ }
632
+
633
+ it(`when inserting the book schema again, must throw error`, async () => {
634
+ await rejects(async () => {
635
+ try {
636
+ await database.create("schema", test_schema);
637
+ } catch (error) {
638
+ console.log(error)
639
+ throw error
640
+ }
641
+ }, DocCreationError);
642
+ })
643
+
644
+ schema_docs_invalid.forEach((element, index) => {
645
+ it(`${element[0]}`, async () => {
646
+ await rejects(async () => {
647
+ await database.create("schema", element[1]);
648
+ }, ValidationError);
649
+ })
650
+ })
651
+
652
+ it('successfully inserts a book doc', async () => {
653
+ await expect(database.create("book", book1)).to.eventually.have.property("_id");
654
+ });
655
+
656
+
657
+ let invalid_meta = [
658
+ ["invalid field",{tabs:[]}],
659
+ ["invalid tags",{tags:"a,b,c"}],
660
+ ["invalid link",{link:{'1':1}}],
661
+ ]
662
+
663
+ invalid_meta.forEach((element, index) => {
664
+ it(`${element[0]}`, async () => {
665
+ let bd = {...book1}
666
+ bd.title = bd.title+" "+index
667
+ await rejects(async () => {
668
+ await database.create("schema",bd,element[1]);
669
+ }, ValidationError);
670
+ })
671
+ })
672
+
673
+ it('successfully inserts a book doc with a link', async () => {
674
+ let bd = {...book1}
675
+ bd.title = bd.title+" test1"
676
+ let new_rec = await database.create("book", bd,{link:"sample1"})
677
+ assert(new_rec.meta.link=="sample1")
678
+ });
679
+
680
+ it(`throw error when inserting the book with same link again`, async () => {
681
+ await rejects(async () => {
682
+ try {
683
+ let bd = {...book1}
684
+ bd.title = bd.title+" test1234"
685
+ await database.create("book", bd,{link:"sample1"});
686
+ } catch (error) {
687
+ console.log(error)
688
+ console.log("22222")
689
+ throw error
690
+ }
691
+ }, DocCreationError);
692
+ })
693
+
694
+
695
+ it('successfully inserts a book doc with tags', async () => {
696
+ let bd = {...book1}
697
+ bd.title = bd.title+" test2"
698
+ let tags1 = ["tag1"]
699
+ let new_rec = await database.create("book", bd,{tags:tags1})
700
+ assert(new_rec.meta.tags===tags1)
701
+ });
702
+
703
+ it(`throw error when no schema provided`, async () => {
704
+ await rejects(async () => {
705
+ try {
706
+ let bd = {...book1}
707
+ bd.title = bd.title+" test1234"
708
+ await database.create("", bd,{link:"sample1"});
709
+ } catch (error) {
710
+ console.log(error)
711
+ console.log("22222")
712
+ throw error
713
+ }
714
+ }, DocCreationError);
715
+ })
716
+
717
+ it(`throw error when no data provided`, async () => {
718
+ await rejects(async () => {
719
+ try {
720
+ let bd = {...book1}
721
+ bd.title = bd.title+" test1234"
722
+ await database.create("book",{},{link:"sample1"});
723
+ } catch (error) {
724
+ console.log(error)
725
+ throw error
726
+ }
727
+ }, DocCreationError);
728
+ })
729
+
730
+
731
+ })
732
+
733
+ describe("Doc insertion tests with encryption", async () => {
734
+ const test_schema = {
735
+ name:"book",
736
+ description:"Test schema 1",
737
+ schema: {
738
+ $schema: "http://json-schema.org/draft-07/schema#",
739
+ type: "object",
740
+ properties: {
741
+ title: {
742
+ type: "string",
743
+ minLength: 1,
744
+ description: "The title of the book",
745
+ },
746
+ author: {
747
+ type: "string",
748
+ minLength: 1,
749
+ description: "The author of the book",
750
+ },
751
+ isbn: {
752
+ type: "string",
753
+ pattern: "^(97(8|9))?\\d{9}(\\d|X)$",
754
+ description: "The ISBN of the book, can be 10 or 13 digits",
755
+ },
756
+ publicationYear: {
757
+ type: "integer",
758
+ minimum: 1450,
759
+ maximum: 2024,
760
+ description:
761
+ "The year the book was published (between 1450 and 2024)",
762
+ },
763
+ genre: {
764
+ type: "string",
765
+ enum: [
766
+ "Fiction",
767
+ "Non-Fiction",
768
+ "Science",
769
+ "History",
770
+ "Fantasy",
771
+ "Biography",
772
+ "Children",
773
+ "Mystery",
774
+ "Horror",
775
+ ],
776
+ description: "The genre of the book",
777
+ },
778
+ language: {
779
+ type: "string",
780
+ description: "The language of the book",
781
+ default: "English",
782
+ },
783
+ publisher: {
784
+ type: "string",
785
+ description: "The publisher of the book",
786
+ minLength: 1,
787
+ },
788
+ pages: {
789
+ type: "integer",
790
+ minimum: 1,
791
+ description: "The number of pages in the book",
792
+ },
793
+ secret: {
794
+ type: "string",
795
+ description: "Super secret related to the book",
796
+ minLength: 1,
797
+ },
798
+ },
799
+ required: ["title", "author", "isbn", "publicationYear", "genre"],
800
+ additionalProperties: false,
801
+ },
802
+ settings : {
803
+ primary_keys:['title','author'],
804
+ encrypted_fields:['secret'],
805
+ non_editable_fields:[],
806
+ single_record:false
807
+ }
808
+ };
809
+
810
+ before(async () => {
811
+ // adding a schema
812
+ let doc_obj_orig = get_pdb_doc("test_database_27", "qwertyuiopaqwsde1254");
813
+ let doc_obj_dupl = get_pdb_doc("test_database_27", "qwertyuiopaqwsde12545");
814
+ database1 = new BeanBagDB(doc_obj_orig);
815
+ await database1.ready(); // Ensure the database is ready before running tests
816
+ console.log(database1.encryption_key)
817
+ database2 = new BeanBagDB(doc_obj_dupl);
818
+ await database2.ready(); // Ensure the database is ready before running tests
819
+ try {
820
+ //console.log(test_schema)
821
+ let a = await database1.create("schema",test_schema)
822
+ } catch (error) {
823
+ console.log("error in before")
824
+ console.log(error)
825
+ }
826
+ });
827
+
828
+ it(`when inserting the book schema again in db1, must throw error`, async () => {
829
+ await rejects(async () => {
830
+ try {
831
+ await database1.create("schema", test_schema);
832
+ } catch (error) {
833
+ //console.log(error)
834
+ throw error
835
+ }
836
+ }, DocCreationError);
837
+ });
838
+
839
+ it(`when inserting the book schema again in db2 , must throw error`, async () => {
840
+ await rejects(async () => {
841
+ try {
842
+ await database2.create("schema", test_schema);
843
+ } catch (error) {
844
+ //console.log(error)
845
+ throw error
846
+ }
847
+ }, DocCreationError);
848
+ });
849
+
850
+ it('successfully inserts a book doc with some secret', async () => {
851
+ const book1 = {
852
+ title: "Harry Potter",
853
+ author: "J.K. Rowling",
854
+ isbn: "9780439139601",
855
+ publicationYear: 1999,
856
+ genre: "Fantasy",
857
+ publisher: "ABC DEF",
858
+ secret: "Super secret 1"
859
+ }
860
+ await expect(database1.create("book", book1)).to.eventually.have.property("_id");
861
+ });
862
+
863
+ it('gives error when inserting the same doc again', async () => {
864
+ const book1 = {
865
+ title: "Harry Potter",
866
+ author: "J.K. Rowling",
867
+ isbn: "9780439139601",
868
+ publicationYear: 1999,
869
+ genre: "Fantasy",
870
+ publisher: "ABC DEF",
871
+ secret: "Super secret 1"
872
+ };
873
+ await rejects(async () => {
874
+ try {
875
+ await database1.create("book", book1);
876
+ } catch (error) {
877
+ //console.log(error)
878
+ throw error
879
+ }
880
+ }, DocCreationError);
881
+ })
882
+
883
+ it('fetches the doc and the encrypted field is returned successfully', async () => {
884
+ const book1 = {
885
+ title: "Harry Potter",
886
+ author: "J.K. Rowling",
887
+ isbn: "9780439139601",
888
+ publicationYear: 1999,
889
+ genre: "Fantasy",
890
+ publisher: "ABC DEF",
891
+ secret: "Super secret 1"
892
+ };
893
+ let data = await database1.read({schema:"book",data:{"title":book1.title,"author":book1.author}})
894
+ //console.log(data)
895
+ assert(data.doc.data.secret == book1.secret)
896
+ })
897
+
898
+ it('should throw encryption error when using the incorrect key', async () => {
899
+ const book1 = {
900
+ title: "Harry Potter",
901
+ author: "J.K. Rowling",
902
+ isbn: "9780439139601",
903
+ publicationYear: 1999,
904
+ genre: "Fantasy",
905
+ publisher: "ABC DEF",
906
+ secret: "Super secret 1"
907
+ }
908
+
909
+ await rejects(async () => {
910
+ try {
911
+ let d = await database2.read({schema:"book",data:{"title":book1.title,"author":book1.author}});
912
+ } catch (error) {
913
+ //console.log(error)
914
+ throw error
915
+ }
916
+ }, EncryptionError)
917
+ })
918
+
919
+ })
920
+
921
+
922
+ /**
923
+ * read
924
+ */
925
+
926
+ describe("Doc read tests", async () => {
927
+ let database3
928
+
929
+
930
+ const test_schema = {
931
+ name:"book",
932
+ description:"Test schema 1",
933
+ schema: {
934
+ $schema: "http://json-schema.org/draft-07/schema#",
935
+ type: "object",
936
+ properties: {
937
+ title: {
938
+ type: "string",
939
+ minLength: 1,
940
+ description: "The title of the book",
941
+ },
942
+ author: {
943
+ type: "string",
944
+ minLength: 1,
945
+ description: "The author of the book",
946
+ },
947
+ isbn: {
948
+ type: "string",
949
+ pattern: "^(97(8|9))?\\d{9}(\\d|X)$",
950
+ description: "The ISBN of the book, can be 10 or 13 digits",
951
+ },
952
+ publicationYear: {
953
+ type: "integer",
954
+ minimum: 1450,
955
+ maximum: 2024,
956
+ description:
957
+ "The year the book was published (between 1450 and 2024)",
958
+ },
959
+ genre: {
960
+ type: "string",
961
+ enum: [
962
+ "Fiction",
963
+ "Non-Fiction",
964
+ "Science",
965
+ "History",
966
+ "Fantasy",
967
+ "Biography",
968
+ "Children",
969
+ "Mystery",
970
+ "Horror",
971
+ ],
972
+ description: "The genre of the book",
973
+ },
974
+ language: {
975
+ type: "string",
976
+ description: "The language of the book",
977
+ default: "English",
978
+ },
979
+ publisher: {
980
+ type: "string",
981
+ description: "The publisher of the book",
982
+ minLength: 1,
983
+ },
984
+ pages: {
985
+ type: "integer",
986
+ minimum: 1,
987
+ description: "The number of pages in the book",
988
+ },
989
+ secret:{
990
+ type:"string"
991
+ }
992
+ },
993
+ required: ["title", "author"],
994
+ additionalProperties: false,
995
+ },
996
+ settings : {
997
+ primary_keys:['title','author'],
998
+ encrypted_fields:[],
999
+ non_editable_fields:["secret"],
1000
+ single_record:false
1001
+ }
1002
+ }
1003
+
1004
+ const book1 = {
1005
+ title: "Harry Potter",
1006
+ author: "J.K. Rowling",
1007
+ isbn: "9780439139601",
1008
+ publicationYear: 1999,
1009
+ genre: "Fantasy",
1010
+ publisher: "ABC DEF",
1011
+ secret:"Super secret1"
1012
+ }
1013
+ const meta = {
1014
+ link:"sample1"
1015
+ }
1016
+ let doc_inserted
1017
+
1018
+ before(async () => {
1019
+ // adding a schema
1020
+ let doc_obj = get_pdb_doc("test_database_28", "qwertyuiopaqwsde1254");
1021
+ database3 = new BeanBagDB(doc_obj);
1022
+ await database3.ready(); // Ensure the database is ready before running tests
1023
+ try {
1024
+ let a = await database3.create("schema",test_schema)
1025
+ doc_inserted = await database3.create("book",book1,meta)
1026
+ console.log("Ready for more tests...");
1027
+ } catch (error) {
1028
+ //console.log("error in before")
1029
+ console.log(error)
1030
+ }
1031
+ })
1032
+
1033
+ it('fetches the doc and the encrypted field is returned unencrypted successfully', async () => {
1034
+ let data = await database3.read({schema:"book",data:{"title":book1.title,"author":book1.author}})
1035
+ assert(data.doc.data.secret == book1.secret)
1036
+ })
1037
+
1038
+
1039
+ it('read doc using _id', async () => {
1040
+ let data = await database3.read({"_id":doc_inserted._id})
1041
+ assert(data.doc.data.secret == book1.secret)
1042
+ })
1043
+
1044
+ it('read doc using link', async () => {
1045
+ let data = await database3.read({"link":meta.link})
1046
+ assert(data.doc.data.secret == book1.secret)
1047
+ })
1048
+
1049
+ it('read doc using primary key', async () => {
1050
+ let data = await database3.read({schema:"book",data:{title:book1.title,author:book1.author}})
1051
+ assert(data.doc.data.secret == book1.secret)
1052
+ })
1053
+
1054
+ it('throws error when incomplete primary key given', async () => {
1055
+ await rejects(async () => {
1056
+ try {
1057
+ let a = await database3.read({"schema":"book","data":{title:book1.title}});
1058
+ } catch (error) {
1059
+ //console.log(error)
1060
+ throw error
1061
+ }
1062
+ }, ValidationError);
1063
+ })
1064
+
1065
+ it('error when doc does not exists by _id', async () => {
1066
+ await rejects(async () => {
1067
+ try {
1068
+ let a = await database3.read({"_id":"test"});
1069
+ } catch (error) {
1070
+ //console.log(error)
1071
+ throw error
1072
+ }
1073
+ }, DocNotFoundError);
1074
+ })
1075
+
1076
+ it('error when doc does not exists by link', async () => {
1077
+ await rejects(async () => {
1078
+ try {
1079
+ let a = await database3.read({"link":"test"});
1080
+ } catch (error) {
1081
+ //console.log(error)
1082
+ throw error
1083
+ }
1084
+ }, DocNotFoundError);
1085
+ })
1086
+
1087
+ it('error when doc does not exists by schema', async () => {
1088
+ await rejects(async () => {
1089
+ try {
1090
+ let a = await database3.read({"schema":"book","data":{"title":"sample","author":"sample"}});
1091
+ } catch (error) {
1092
+ //console.log(error)
1093
+ throw error
1094
+ }
1095
+ }, DocNotFoundError);
1096
+ })
1097
+
1098
+ it('check if schema included', async () => {
1099
+ let data = await database3.read({schema:"book",data:{"title":book1.title,"author":book1.author}},true)
1100
+ assert(Object.keys(data).length==2)
1101
+ })
1102
+
1103
+ it('check if schema not included', async () => {
1104
+ let data = await database3.read({schema:"book",data:{"title":book1.title,"author":book1.author}},false)
1105
+ assert(Object.keys(data).length==1)
1106
+ })
1107
+ })
1108
+
1109
+ /**
1110
+ * update
1111
+ * - update a system doc
1112
+
1113
+ */
1114
+
1115
+
1116
+ describe("Doc update tests", async () => {
1117
+ let database3
1118
+
1119
+ const test_schema = {
1120
+ name:"book",
1121
+ description:"Test schema 1",
1122
+ schema: {
1123
+ $schema: "http://json-schema.org/draft-07/schema#",
1124
+ type: "object",
1125
+ properties: {
1126
+ title: {
1127
+ type: "string",
1128
+ minLength: 1,
1129
+ description: "The title of the book",
1130
+ },
1131
+ author: {
1132
+ type: "string",
1133
+ minLength: 1,
1134
+ description: "The author of the book",
1135
+ },
1136
+ isbn: {
1137
+ type: "string",
1138
+ pattern: "^(97(8|9))?\\d{9}(\\d|X)$",
1139
+ description: "The ISBN of the book, can be 10 or 13 digits",
1140
+ },
1141
+ publicationYear: {
1142
+ type: "integer",
1143
+ minimum: 1450,
1144
+ maximum: 2024,
1145
+ description:
1146
+ "The year the book was published (between 1450 and 2024)",
1147
+ },
1148
+ genre: {
1149
+ type: "string",
1150
+ enum: [
1151
+ "Fiction",
1152
+ "Non-Fiction",
1153
+ "Science",
1154
+ "History",
1155
+ "Fantasy",
1156
+ "Biography",
1157
+ "Children",
1158
+ "Mystery",
1159
+ "Horror",
1160
+ ],
1161
+ description: "The genre of the book",
1162
+ },
1163
+ language: {
1164
+ type: "string",
1165
+ description: "The language of the book",
1166
+ default: "English",
1167
+ },
1168
+ publisher: {
1169
+ type: "string",
1170
+ description: "The publisher of the book",
1171
+ minLength: 1,
1172
+ },
1173
+ pages: {
1174
+ type: "integer",
1175
+ minimum: 1,
1176
+ description: "The number of pages in the book",
1177
+ },
1178
+ secret:{
1179
+ type:"string"
1180
+ }
1181
+ },
1182
+ required: ["title", "author"],
1183
+ additionalProperties: false,
1184
+ },
1185
+ settings : {
1186
+ primary_keys:['title','author'],
1187
+ non_editable_fields:['pages','genre'],
1188
+ encrypted_fields:["secret"]
1189
+ }
1190
+ }
1191
+
1192
+ const book1 = {
1193
+ title: "Harry Potter",
1194
+ author: "J.K. Rowling",
1195
+ isbn: "9780439139601",
1196
+ publicationYear: 1999,
1197
+ genre: "Fantasy",
1198
+ publisher: "ABC DEF",
1199
+ secret:"Super secret1"
1200
+ }
1201
+ const meta = {
1202
+ link:"sample1",
1203
+ tags:["tag1"]
1204
+ }
1205
+ let doc_inserted
1206
+
1207
+ before(async () => {
1208
+ // adding a schema
1209
+ let doc_obj = get_pdb_doc("test_database_29", "qwertyuiopaqwsde1254");
1210
+ database3 = new BeanBagDB(doc_obj);
1211
+ await database3.ready(); // Ensure the database is ready before running tests
1212
+ try {
1213
+ let a = await database3.create("schema",test_schema)
1214
+ doc_inserted = await database3.create("book",book1,meta)
1215
+ let b = await database3.create("book",{...book1,title:"HP2"},{...meta,link:"sample2"})
1216
+ //console.log(b)
1217
+ console.log("Ready for more tests...");
1218
+ } catch (error) {
1219
+ //console.log("error in before")
1220
+ console.log(error)
1221
+ }
1222
+ })
1223
+
1224
+ it('error when nothing to update ', async () => {
1225
+ await rejects(async () => {
1226
+ try {
1227
+ let udata = await database3.update({"_id":doc_inserted._id},{})
1228
+ } catch (error) {
1229
+ //console.log(error)
1230
+ throw error
1231
+ }
1232
+ }, DocUpdateError)
1233
+ })
1234
+
1235
+ it('update selected fields -1 ', async () => {
1236
+ let updates = {publisher:"Something else"}
1237
+ let udata = await database3.update({"_id":doc_inserted._id},{data:updates})
1238
+ let rdata= await database3.read({_id:doc_inserted._id})
1239
+ assert(rdata.doc.data.publisher === updates.publisher )
1240
+ })
1241
+
1242
+ it('update selected fields - primary key', async () => {
1243
+ let updates = {title:"Something else"}
1244
+ let udata = await database3.update({"_id":doc_inserted._id},{data:updates})
1245
+ let rdata= await database3.read({_id:doc_inserted._id})
1246
+ assert(rdata.doc.data.title === updates.title )
1247
+ })
1248
+
1249
+ it('error when updating primary keys that already exists', async () => {
1250
+ let updates = {title:"HP2"}
1251
+
1252
+ //assert(data.doc.data.secret == book1.secret)
1253
+ await rejects(async () => {
1254
+ try {
1255
+ let udata = await database3.update({"_id":doc_inserted._id},{data:updates})
1256
+ } catch (error) {
1257
+ //console.log(error)
1258
+ throw error
1259
+ }
1260
+ }, DocUpdateError)
1261
+ })
1262
+
1263
+ // it('updating full doc', async () => {
1264
+ // let updates = {title:""}
1265
+ // let udata = await database3.update({"_id":doc_inserted._id})
1266
+ // assert(data.doc.data.secret == book1.secret)
1267
+ // })
1268
+
1269
+ it('updating encrypted field', async () => {
1270
+ let updates = {secret:"Something else"}
1271
+ let udata = await database3.update({"_id":doc_inserted._id},{data:updates})
1272
+ let rdata= await database3.read({_id:doc_inserted._id})
1273
+ assert(rdata.doc.data.secret === updates.secret )
1274
+ })
1275
+
1276
+ it('updating meta.link', async () => {
1277
+ let updates = {title:"Something else"}
1278
+ let udata = await database3.update({"_id":doc_inserted._id},{meta:{link:"this-is-new"}})
1279
+ //console.log(udata)
1280
+ let rdata= await database3.read({_id:doc_inserted._id})
1281
+ //console.log(rdata)
1282
+ assert(rdata.doc.meta.link === "this-is-new" )
1283
+ })
1284
+
1285
+ it('error updating meta.link not valid ', async () => {
1286
+ await rejects(async () => {
1287
+ try {
1288
+ let udata = await database3.update({"_id":doc_inserted._id},{meta:{link:1234}})
1289
+ } catch (error) {
1290
+ //console.log(error)
1291
+ throw error
1292
+ }
1293
+ }, ValidationError)
1294
+ })
1295
+
1296
+ it('error updating meta.link already exists ', async () => {
1297
+ await rejects(async () => {
1298
+ try {
1299
+ let udata = await database3.update({"_id":doc_inserted._id},{meta:{link:"sample2"}})
1300
+ } catch (error) {
1301
+ //console.log(error)
1302
+ throw error
1303
+ }
1304
+ }, DocUpdateError)
1305
+ })
1306
+
1307
+
1308
+ it('updating meta.tags,link at the same time ', async () => {
1309
+ let updates = {tags:["something","in","the","way"],link:"something-in-the-way"}
1310
+ let udata = await database3.update({"_id":doc_inserted._id},{meta:updates})
1311
+ let rdata= await database3.read({_id:doc_inserted._id})
1312
+ assert(rdata.doc.meta.tags.join(",") == updates.tags.join(",") && rdata.doc.meta.link === updates.link )
1313
+ })
1314
+
1315
+ it('updating meta.tags ', async () => {
1316
+ let updates = {tags:["something","in","the","way","all","apologies"]}
1317
+ let udata = await database3.update({"_id":doc_inserted._id},{meta:updates})
1318
+ let rdata= await database3.read({_id:doc_inserted._id})
1319
+ assert(rdata.doc.meta.tags.join(",") == updates.tags.join(","))
1320
+ })
1321
+
1322
+
1323
+ it('error when updating fields that does not exists', async () => {
1324
+ await rejects(async () => {
1325
+ try {
1326
+ let updates = {text1:"sample text 1"}
1327
+ let udata = await database3.update({"_id":doc_inserted._id},{data:updates})
1328
+ } catch (error) {
1329
+ //console.log(error)
1330
+ throw error
1331
+ }
1332
+ }, DocUpdateError)
1333
+ })
1334
+
1335
+ it('updating only non editable fields generates error', async () => {
1336
+ await rejects(async () => {
1337
+ try {
1338
+ let updates = {page:1234,genre:"Horror"}
1339
+ let udata = await database3.update({"_id":doc_inserted._id},{data:updates})
1340
+ } catch (error) {
1341
+ //console.log(error)
1342
+ throw error
1343
+ }
1344
+ }, DocUpdateError)
1345
+ })
1346
+
1347
+ it('updating non editable fields not allowed', async () => {
1348
+ let updates = {title:"HP1234",genre:"Horror"}
1349
+ let udata = await database3.update({"_id":doc_inserted._id},{data:updates})
1350
+ let rdata= await database3.read({_id:doc_inserted._id})
1351
+ assert(rdata.doc.data.title == updates.title && rdata.doc.data.genre != updates.genre )
1352
+ })
1353
+ })
1354
+
1355
+ /**
1356
+ * Delete doc
1357
+ */
1358
+
1359
+ describe("Doc delete tests", async () => {
1360
+ let database3
1361
+
1362
+ const test_schema = {
1363
+ name:"book",
1364
+ description:"Test schema 1",
1365
+ schema: {
1366
+ $schema: "http://json-schema.org/draft-07/schema#",
1367
+ type: "object",
1368
+ properties: {
1369
+ title: {
1370
+ type: "string",
1371
+ minLength: 1,
1372
+ description: "The title of the book",
1373
+ },
1374
+ author: {
1375
+ type: "string",
1376
+ minLength: 1,
1377
+ description: "The author of the book",
1378
+ },
1379
+ isbn: {
1380
+ type: "string",
1381
+ pattern: "^(97(8|9))?\\d{9}(\\d|X)$",
1382
+ description: "The ISBN of the book, can be 10 or 13 digits",
1383
+ },
1384
+ publicationYear: {
1385
+ type: "integer",
1386
+ minimum: 1450,
1387
+ maximum: 2024,
1388
+ description:
1389
+ "The year the book was published (between 1450 and 2024)",
1390
+ },
1391
+ genre: {
1392
+ type: "string",
1393
+ enum: [
1394
+ "Fiction",
1395
+ "Non-Fiction",
1396
+ "Science",
1397
+ "History",
1398
+ "Fantasy",
1399
+ "Biography",
1400
+ "Children",
1401
+ "Mystery",
1402
+ "Horror",
1403
+ ],
1404
+ description: "The genre of the book",
1405
+ },
1406
+ language: {
1407
+ type: "string",
1408
+ description: "The language of the book",
1409
+ default: "English",
1410
+ },
1411
+ publisher: {
1412
+ type: "string",
1413
+ description: "The publisher of the book",
1414
+ minLength: 1,
1415
+ },
1416
+ pages: {
1417
+ type: "integer",
1418
+ minimum: 1,
1419
+ description: "The number of pages in the book",
1420
+ },
1421
+ secret:{
1422
+ type:"string"
1423
+ }
1424
+ },
1425
+ required: ["title", "author"],
1426
+ additionalProperties: false,
1427
+ },
1428
+ settings : {
1429
+ primary_keys:['title','author'],
1430
+ non_editable_fields:['pages','genre'],
1431
+ encrypted_fields:["secret"]
1432
+ }
1433
+ }
1434
+
1435
+ const book1 = {
1436
+ title: "Harry Potter",
1437
+ author: "J.K. Rowling",
1438
+ isbn: "9780439139601",
1439
+ publicationYear: 1999,
1440
+ genre: "Fantasy",
1441
+ publisher: "ABC DEF",
1442
+ secret:"Super secret1"
1443
+ }
1444
+ const meta = {
1445
+ link:"sample1",
1446
+ tags:["tag1"]
1447
+ }
1448
+ let doc_inserted
1449
+
1450
+ before(async () => {
1451
+ // adding a schema
1452
+ let doc_obj = get_pdb_doc("test_database_30", "qwertyuiopaqwsde1254");
1453
+ database3 = new BeanBagDB(doc_obj);
1454
+ await database3.ready(); // Ensure the database is ready before running tests
1455
+ try {
1456
+ let a = await database3.create("schema",test_schema)
1457
+ doc_inserted = await database3.create("book",book1,meta)
1458
+ let b = await database3.create("book",{...book1,title:"HP2"},{...meta,link:"sample2"})
1459
+ //console.log(b)
1460
+ console.log("Ready for more tests...");
1461
+ } catch (error) {
1462
+ //console.log("error in before")
1463
+ console.log(error)
1464
+ }
1465
+ })
1466
+
1467
+ it('error when doc not found ', async () => {
1468
+ await rejects(async () => {
1469
+ try {
1470
+ let udata = await database3.delete({})
1471
+ } catch (error) {
1472
+ //console.log(error)
1473
+ throw error
1474
+ }
1475
+ }, ValidationError)
1476
+ })
1477
+
1478
+ it('error when doc not found ', async () => {
1479
+ await rejects(async () => {
1480
+ try {
1481
+ let udata = await database3.delete({_id:"1234"})
1482
+ } catch (error) {
1483
+ //console.log(error)
1484
+ throw error
1485
+ }
1486
+ }, DocNotFoundError)
1487
+ })
1488
+
1489
+
1490
+
1491
+ it('error when deleting system schema', async () => {
1492
+ await rejects(async () => {
1493
+ try {
1494
+ let udata = await database3.delete({"schema":"schema","criteria":{"name":"schema"}})
1495
+ } catch (error) {
1496
+ //console.log(error)
1497
+ throw error
1498
+ }
1499
+ }, Error)
1500
+ })
1501
+
1502
+ it('error when deleting custom schema', async () => {
1503
+ await rejects(async () => {
1504
+ try {
1505
+ let udata = await database3.delete({"schema":"schema","criteria":{"name":"book"}})
1506
+ } catch (error) {
1507
+ //console.log(error)
1508
+ throw error
1509
+ }
1510
+ }, Error)
1511
+ })
1512
+
1513
+ it('doc deleted successfully', async () => {
1514
+ await rejects(async () => {
1515
+ try {
1516
+ let udata = await database3.delete({"_id":doc_inserted._id})
1517
+ let del_doc = await database3.read({"_id":doc_inserted._id})
1518
+ } catch (error) {
1519
+ throw error
1520
+ }
1521
+ }, DocNotFoundError)
1522
+ })
1523
+ })
1524
+
1525
+ // search
1526
+ describe("Doc search tests", async () => {
1527
+ let database3
1528
+
1529
+ const test_schema = {
1530
+ name:"book",
1531
+ description:"Test schema 1",
1532
+ schema: {
1533
+ $schema: "http://json-schema.org/draft-07/schema#",
1534
+ type: "object",
1535
+ properties: {
1536
+ title: {
1537
+ type: "string",
1538
+ minLength: 1,
1539
+ description: "The title of the book",
1540
+ },
1541
+ author: {
1542
+ type: "string",
1543
+ minLength: 1,
1544
+ description: "The author of the book",
1545
+ },
1546
+ isbn: {
1547
+ type: "string",
1548
+ pattern: "^(97(8|9))?\\d{9}(\\d|X)$",
1549
+ description: "The ISBN of the book, can be 10 or 13 digits",
1550
+ },
1551
+ publicationYear: {
1552
+ type: "integer",
1553
+ minimum: 1450,
1554
+ maximum: 2024,
1555
+ description:
1556
+ "The year the book was published (between 1450 and 2024)",
1557
+ },
1558
+ genre: {
1559
+ type: "string",
1560
+ enum: [
1561
+ "Fiction",
1562
+ "Non-Fiction",
1563
+ "Science",
1564
+ "History",
1565
+ "Fantasy",
1566
+ "Biography",
1567
+ "Children",
1568
+ "Mystery",
1569
+ "Horror",
1570
+ ],
1571
+ description: "The genre of the book",
1572
+ },
1573
+ language: {
1574
+ type: "string",
1575
+ description: "The language of the book",
1576
+ default: "English",
1577
+ },
1578
+ publisher: {
1579
+ type: "string",
1580
+ description: "The publisher of the book",
1581
+ minLength: 1,
1582
+ },
1583
+ pages: {
1584
+ type: "integer",
1585
+ minimum: 1,
1586
+ description: "The number of pages in the book",
1587
+ },
1588
+ secret:{
1589
+ type:"string"
1590
+ }
1591
+ },
1592
+ required: ["title", "author"],
1593
+ additionalProperties: false,
1594
+ },
1595
+ settings : {
1596
+ primary_keys:['title','author'],
1597
+ non_editable_fields:['pages','genre'],
1598
+ encrypted_fields:["secret"]
1599
+ }
1600
+ }
1601
+
1602
+ const book1 = {
1603
+ title: "Harry Potter",
1604
+ author: "J.K. Rowling",
1605
+ isbn: "9780439139601",
1606
+ publicationYear: 1999,
1607
+ genre: "Fantasy",
1608
+ publisher: "ABC DEF",
1609
+ secret:"Super secret1"
1610
+ }
1611
+
1612
+ const book2 = {
1613
+ title: "Harry Potter 2",
1614
+ author: "J.K. Rowling",
1615
+ isbn: "9780439139601",
1616
+ publicationYear: 1999,
1617
+ genre: "Fantasy",
1618
+ publisher: "ABC DEF",
1619
+ secret:"Super secret1"
1620
+ }
1621
+
1622
+ const meta = {
1623
+ link:"sample1",
1624
+ tags:["tag1"]
1625
+ }
1626
+ let doc_inserted
1627
+ before(async () => {
1628
+ // adding a schema
1629
+ let doc_obj = get_pdb_doc("test_database_31", "qwertyuiopaqwsde1254");
1630
+ database3 = new BeanBagDB(doc_obj);
1631
+ await database3.ready(); // Ensure the database is ready before running tests
1632
+ try {
1633
+ let a = await database3.create("schema",test_schema)
1634
+ doc_inserted = await database3.create("book",book1,meta)
1635
+ let b = await database3.create("book",book2,{...meta,link:"sample2"})
1636
+ //console.log(b)
1637
+ console.log("Ready for more tests...");
1638
+ } catch (error) {
1639
+ //console.log("error in before")
1640
+ console.log(error)
1641
+ }
1642
+ })
1643
+
1644
+
1645
+ it('error error with invalid query', async () => {
1646
+ await rejects(async () => {
1647
+ try {
1648
+ let udata = await database3.search({})
1649
+ } catch (error) {
1650
+ //console.log(error)
1651
+ throw error
1652
+ }
1653
+ }, ValidationError)
1654
+ })
1655
+
1656
+ it('all docs', async () => {
1657
+ try {
1658
+ let udata = await database3.search({selector:{}})
1659
+ assert(udata.docs.length==8)
1660
+ } catch (error) {
1661
+ //console.log(error)
1662
+ throw error
1663
+ }
1664
+ })
1665
+
1666
+ it('read docs', async () => {
1667
+ try {
1668
+ let udata = await database3.search({selector:{"schema":"book"}})
1669
+ assert(udata.docs.length==2)
1670
+ } catch (error) {
1671
+ //console.log(error)
1672
+ throw error
1673
+ }
1674
+ })
1675
+
1676
+ it('read docs 2', async () => {
1677
+ try {
1678
+ let udata = await database3.search({selector:{"schema":"schema"}})
1679
+ assert(udata.docs.length==4) // schema,book,setting,key
1680
+ } catch (error) {
1681
+ //console.log(error)
1682
+ throw error
1683
+ }
1684
+ })
1685
+
1686
+ it('read docs 3', async () => {
1687
+ try {
1688
+ let udata = await database3.search({selector:{"meta.link":"sample1"}})
1689
+ assert(udata.docs.length==1) // schema,book,setting,key
1690
+ } catch (error) {
1691
+ //console.log(error)
1692
+ throw error
1693
+ }
1694
+ })
1695
+
1696
+ it('read docs 4', async () => {
1697
+ try {
1698
+ let udata = await database3.search({selector:{"schema":"book","data":{"title":"Book"}}})
1699
+ assert(udata.docs.length==0) // schema,book,setting,key
1700
+ } catch (error) {
1701
+ //console.log(error)
1702
+ throw error
1703
+ }
1704
+ })
1705
+
1706
+ // it('error when deleting system schema', async () => {
1707
+ // await rejects(async () => {
1708
+ // try {
1709
+ // let udata = await database3.delete({"schema":"schema","criteria":{"name":"schema"}})
1710
+ // } catch (error) {
1711
+ // //console.log(error)
1712
+ // throw error
1713
+ // }
1714
+ // }, Error)
1715
+ // })
1716
+
1717
+ // it('error when deleting custom schema', async () => {
1718
+ // await rejects(async () => {
1719
+ // try {
1720
+ // let udata = await database3.delete({"schema":"schema","criteria":{"name":"book"}})
1721
+ // } catch (error) {
1722
+ // //console.log(error)
1723
+ // throw error
1724
+ // }
1725
+ // }, Error)
1726
+ // })
1727
+
1728
+ })