• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

moleculerjs / database / #178

12 Nov 2023 04:51PM UTC coverage: 38.137% (-56.5%) from 94.594%
#178

push

icebob
Fix #53

690 of 1512 branches covered (0.0%)

Branch coverage included in aggregate %.

44 of 45 new or added lines in 2 files covered. (97.78%)

2662 existing lines in 19 files now uncovered.

1517 of 4275 relevant lines covered (35.49%)

50.35 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.58
/test/integration/validation.test.js
1
"use strict";
2

3
const { ServiceBroker, Context } = require("moleculer");
1✔
4
const ObjectId = require("mongodb").ObjectId;
1✔
5
const { ValidationError } = require("moleculer").Errors;
1✔
6
const DbService = require("../..").Service;
1✔
7

8
module.exports = (getAdapter, adapterType) => {
1✔
9
        let expectedID;
UNCOV
10
        if (getAdapter.IdColumnType == "integer") {
×
UNCOV
11
                expectedID = expect.any(Number);
×
12
        } else {
UNCOV
13
                expectedID = expect.any(String);
×
14
        }
15

UNCOV
16
        if (getAdapter.isNoSQL) {
×
UNCOV
17
                describe("Test field processing without fields", () => {
×
UNCOV
18
                        const broker = new ServiceBroker({ logger: false });
×
UNCOV
19
                        const svc = broker.createService({
×
20
                                name: "users",
21
                                mixins: [
22
                                        DbService({
23
                                                adapter: getAdapter(),
24
                                                createActions: true
25
                                        })
26
                                ],
27
                                settings: {}
28
                        });
29

UNCOV
30
                        beforeAll(async () => {
×
UNCOV
31
                                await broker.start();
×
UNCOV
32
                                await svc.clearEntities();
×
33
                        });
UNCOV
34
                        afterAll(() => broker.stop());
×
35

UNCOV
36
                        describe("Test create, update, replace", () => {
×
UNCOV
37
                                let entity = {
×
38
                                        username: "John",
39
                                        password: "john1234",
40
                                        age: 42,
41
                                        status: true
42
                                };
UNCOV
43
                                it("should save all fields", async () => {
×
UNCOV
44
                                        const res = await broker.call("users.create", entity);
×
UNCOV
45
                                        expect(res).toStrictEqual({
×
46
                                                ...entity,
47
                                                _id: expectedID
48
                                        });
UNCOV
49
                                        entity = res;
×
50
                                });
51

UNCOV
52
                                it("should update fields", async () => {
×
UNCOV
53
                                        const res = await broker.call("users.update", {
×
54
                                                _id: entity._id,
55
                                                username: 123,
56
                                                password: true,
57
                                                country: "USA"
58
                                        });
UNCOV
59
                                        expect(res).toStrictEqual({
×
60
                                                _id: entity._id,
61
                                                age: 42,
62
                                                country: "USA",
63
                                                password: true,
64
                                                status: true,
65
                                                username: 123
66
                                        });
67
                                });
68

UNCOV
69
                                it("should replace fields", async () => {
×
UNCOV
70
                                        const res = await broker.call("users.replace", {
×
71
                                                ...entity,
72
                                                _id: entity._id
73
                                        });
UNCOV
74
                                        expect(res).toStrictEqual({
×
75
                                                _id: entity._id,
76
                                                username: "John",
77
                                                password: "john1234",
78
                                                age: 42,
79
                                                status: true
80
                                        });
81
                                });
82
                        });
83
                });
84
        }
85

UNCOV
86
        describe("Test required", () => {
×
UNCOV
87
                const broker = new ServiceBroker({ logger: false });
×
UNCOV
88
                const svc = broker.createService({
×
89
                        name: "users",
90
                        mixins: [
91
                                DbService({
92
                                        adapter: getAdapter(),
93
                                        createActions: true
94
                                })
95
                        ],
96
                        settings: {
97
                                fields: {
98
                                        id: {
99
                                                type: "string",
100
                                                primaryKey: true,
101
                                                columnName: "_id",
102
                                                columnType: getAdapter.IdColumnType
103
                                        },
104
                                        name: { type: "string", required: true }
105
                                }
106
                        },
107
                        async started() {
UNCOV
108
                                const adapter = await this.getAdapter();
×
UNCOV
109
                                if (adapterType == "Knex") {
×
UNCOV
110
                                        await adapter.createTable();
×
111
                                }
112

UNCOV
113
                                await this.clearEntities();
×
114
                        }
115
                });
116

UNCOV
117
                beforeAll(() => broker.start());
×
UNCOV
118
                afterAll(() => broker.stop());
×
119

UNCOV
120
                describe("Test create, update, replace", () => {
×
121
                        let entity;
122

UNCOV
123
                        it("should throw error at create", async () => {
×
UNCOV
124
                                expect.assertions(6);
×
UNCOV
125
                                try {
×
UNCOV
126
                                        await broker.call("users.create", {});
×
127
                                } catch (err) {
UNCOV
128
                                        expect(err).toBeInstanceOf(ValidationError);
×
UNCOV
129
                                        expect(err.name).toBe("ValidationError");
×
UNCOV
130
                                        expect(err.message).toBe("Parameters validation error!");
×
UNCOV
131
                                        expect(err.type).toBe("VALIDATION_ERROR");
×
UNCOV
132
                                        expect(err.code).toBe(422);
×
UNCOV
133
                                        expect(err.data).toEqual([
×
134
                                                {
135
                                                        actual: undefined,
136
                                                        field: "name",
137
                                                        message: "The 'name' field is required.",
138
                                                        type: "required",
139
                                                        action: "users.create",
140
                                                        nodeID: broker.nodeID
141
                                                }
142
                                        ]);
143
                                }
144
                        });
145

UNCOV
146
                        it("should create entity", async () => {
×
UNCOV
147
                                const res = await broker.call("users.create", { name: "John" });
×
UNCOV
148
                                expect(res).toStrictEqual({
×
149
                                        id: expectedID,
150
                                        name: "John"
151
                                });
UNCOV
152
                                entity = res;
×
153
                        });
154

UNCOV
155
                        it("should not throw error at update (all properties optional)", async () => {
×
UNCOV
156
                                const res = await broker.call("users.update", { id: entity.id });
×
UNCOV
157
                                expect(res).toStrictEqual({
×
158
                                        id: entity.id,
159
                                        name: "John"
160
                                });
UNCOV
161
                                entity = res;
×
162
                        });
163

UNCOV
164
                        it("should update entity", async () => {
×
UNCOV
165
                                const res = await broker.call("users.update", {
×
166
                                        id: entity.id,
167
                                        name: "John Doe"
168
                                });
UNCOV
169
                                expect(res).toStrictEqual({
×
170
                                        id: entity.id,
171
                                        name: "John Doe"
172
                                });
UNCOV
173
                                entity = res;
×
174
                        });
175

UNCOV
176
                        it("should throw error at replace", async () => {
×
UNCOV
177
                                expect.assertions(6);
×
UNCOV
178
                                try {
×
UNCOV
179
                                        await broker.call("users.replace", {
×
180
                                                id: entity.id
181
                                        });
182
                                } catch (err) {
UNCOV
183
                                        expect(err).toBeInstanceOf(ValidationError);
×
UNCOV
184
                                        expect(err.name).toBe("ValidationError");
×
UNCOV
185
                                        expect(err.message).toBe("Parameters validation error!");
×
UNCOV
186
                                        expect(err.type).toBe("VALIDATION_ERROR");
×
UNCOV
187
                                        expect(err.code).toBe(422);
×
UNCOV
188
                                        expect(err.data).toEqual([
×
189
                                                {
190
                                                        actual: undefined,
191
                                                        field: "name",
192
                                                        message: "The 'name' field is required.",
193
                                                        type: "required",
194
                                                        action: "users.replace",
195
                                                        nodeID: broker.nodeID
196
                                                }
197
                                        ]);
198
                                }
199
                        });
200

UNCOV
201
                        it("should replace entity", async () => {
×
UNCOV
202
                                const res = await broker.call("users.replace", {
×
203
                                        id: entity.id,
204
                                        name: "Jane Doe"
205
                                });
UNCOV
206
                                expect(res).toStrictEqual({
×
207
                                        id: entity.id,
208
                                        name: "Jane Doe"
209
                                });
UNCOV
210
                                entity = res;
×
211
                        });
212
                });
213
        });
214

UNCOV
215
        let userPermission = "";
×
216
        let docWithPerm, docWithReadPerm, docWithoutPerm;
217

218
        async function checkResponseByPermission(broker, perm, readPerm) {
UNCOV
219
                it("should 'get' return non-permission field", async () => {
×
UNCOV
220
                        userPermission = "";
×
UNCOV
221
                        const res = await broker.call("users.get", { id: docWithPerm.id });
×
UNCOV
222
                        expect(res).toStrictEqual(docWithoutPerm);
×
223
                });
224

UNCOV
225
                it("should 'get' return fields with permission", async () => {
×
UNCOV
226
                        userPermission = perm;
×
UNCOV
227
                        const res = await broker.call("users.get", { id: docWithPerm.id });
×
UNCOV
228
                        expect(res).toStrictEqual({
×
229
                                ...(getAdapter.isSQL ? { password: null } : {}),
×
230
                                ...docWithPerm
231
                        });
232
                });
233

UNCOV
234
                if (readPerm) {
×
UNCOV
235
                        it("should 'get' return field with read permission", async () => {
×
UNCOV
236
                                userPermission = readPerm;
×
UNCOV
237
                                const res = await broker.call("users.get", { id: docWithPerm.id });
×
UNCOV
238
                                expect(res).toStrictEqual(docWithReadPerm);
×
239
                        });
240
                }
241

UNCOV
242
                it("should 'resolve' return non-permission fields", async () => {
×
UNCOV
243
                        userPermission = "";
×
UNCOV
244
                        const res = await broker.call("users.resolve", { id: docWithPerm.id });
×
UNCOV
245
                        expect(res).toStrictEqual(docWithoutPerm);
×
246
                });
247

UNCOV
248
                it("should 'resolve' return fields with permission", async () => {
×
UNCOV
249
                        userPermission = perm;
×
UNCOV
250
                        const res = await broker.call("users.resolve", { id: docWithPerm.id });
×
UNCOV
251
                        expect(res).toStrictEqual({
×
252
                                ...(getAdapter.isSQL ? { password: null } : {}),
×
253
                                ...docWithPerm
254
                        });
255
                });
256

UNCOV
257
                if (readPerm) {
×
UNCOV
258
                        it("should 'resolve' return field with read permission", async () => {
×
UNCOV
259
                                userPermission = readPerm;
×
UNCOV
260
                                const res = await broker.call("users.resolve", { id: docWithPerm.id });
×
UNCOV
261
                                expect(res).toStrictEqual(docWithReadPerm);
×
262
                        });
263
                }
264

UNCOV
265
                it("should 'find' return non-permission fields", async () => {
×
UNCOV
266
                        userPermission = "";
×
UNCOV
267
                        const res = await broker.call("users.find");
×
UNCOV
268
                        expect(res).toStrictEqual([docWithoutPerm]);
×
269
                });
270

UNCOV
271
                it("should 'find' return fields with permission", async () => {
×
UNCOV
272
                        userPermission = perm;
×
UNCOV
273
                        const res = await broker.call("users.find");
×
UNCOV
274
                        expect(res).toStrictEqual([
×
275
                                {
276
                                        ...(getAdapter.isSQL ? { password: null } : {}),
×
277
                                        ...docWithPerm
278
                                }
279
                        ]);
280
                });
281

UNCOV
282
                if (readPerm) {
×
UNCOV
283
                        it("should 'find' return field with read permission", async () => {
×
UNCOV
284
                                userPermission = readPerm;
×
UNCOV
285
                                const res = await broker.call("users.find");
×
UNCOV
286
                                expect(res).toStrictEqual([docWithReadPerm]);
×
287
                        });
288
                }
289

UNCOV
290
                it("should 'list' return non-permission fields", async () => {
×
UNCOV
291
                        userPermission = "";
×
UNCOV
292
                        const res = await broker.call("users.list");
×
UNCOV
293
                        expect(res).toStrictEqual({
×
294
                                rows: [docWithoutPerm],
295
                                total: 1,
296
                                page: 1,
297
                                pageSize: 10,
298
                                totalPages: 1
299
                        });
300
                });
301

UNCOV
302
                it("should 'list' return fields with permission", async () => {
×
UNCOV
303
                        userPermission = perm;
×
UNCOV
304
                        const res = await broker.call("users.list");
×
UNCOV
305
                        expect(res).toStrictEqual({
×
306
                                rows: [
307
                                        {
308
                                                ...(getAdapter.isSQL ? { password: null } : {}),
×
309
                                                ...docWithPerm
310
                                        }
311
                                ],
312
                                total: 1,
313
                                page: 1,
314
                                pageSize: 10,
315
                                totalPages: 1
316
                        });
317
                });
318

UNCOV
319
                if (readPerm) {
×
UNCOV
320
                        it("should 'list' return fields with read permission", async () => {
×
UNCOV
321
                                userPermission = perm;
×
UNCOV
322
                                const res = await broker.call("users.list");
×
UNCOV
323
                                expect(res).toStrictEqual({
×
324
                                        rows: [docWithReadPerm],
325
                                        total: 1,
326
                                        page: 1,
327
                                        pageSize: 10,
328
                                        totalPages: 1
329
                                });
330
                        });
331
                }
332
        }
333

UNCOV
334
        describe("Test field permission", () => {
×
UNCOV
335
                const broker = new ServiceBroker({ logger: false });
×
UNCOV
336
                const svc = broker.createService({
×
337
                        name: "users",
338
                        mixins: [
339
                                DbService({
340
                                        adapter: getAdapter(),
341
                                        createActions: true
342
                                })
343
                        ],
344
                        settings: {
345
                                fields: {
346
                                        id: {
347
                                                type: "string",
348
                                                primaryKey: true,
349
                                                columnName: "_id",
350
                                                columnType: getAdapter.IdColumnType
351
                                        },
352
                                        name: "string",
353
                                        password: { type: "string", permission: "admin" }
354
                                }
355
                        },
356
                        methods: {
357
                                checkFieldAuthority(ctx, permission, params, field) {
UNCOV
358
                                        if (typeof permission == "string")
×
UNCOV
359
                                                return this.Promise.resolve(permission == userPermission);
×
360
                                        return this.Promise.resolve(permission.includes(userPermission));
×
361
                                }
362
                        },
363

364
                        async started() {
UNCOV
365
                                const adapter = await this.getAdapter();
×
UNCOV
366
                                if (adapterType == "Knex") {
×
UNCOV
367
                                        await adapter.createTable();
×
368
                                }
369

UNCOV
370
                                await this.clearEntities();
×
371
                        }
372
                });
373

UNCOV
374
                beforeAll(async () => {
×
UNCOV
375
                        await broker.start();
×
UNCOV
376
                        await svc.clearEntities();
×
377
                });
UNCOV
378
                afterAll(() => broker.stop());
×
379

UNCOV
380
                describe("Test if no permission for action", () => {
×
UNCOV
381
                        describe("create", () => {
×
UNCOV
382
                                it("should create entity with 'name' only", async () => {
×
UNCOV
383
                                        userPermission = "";
×
UNCOV
384
                                        const res = await broker.call("users.create", {
×
385
                                                name: "John",
386
                                                password: "john1234"
387
                                        });
UNCOV
388
                                        expect(res).toStrictEqual({
×
389
                                                id: expectedID,
390
                                                name: "John"
391
                                        });
UNCOV
392
                                        docWithPerm = res;
×
UNCOV
393
                                        docWithoutPerm = res;
×
394
                                });
395

UNCOV
396
                                checkResponseByPermission(broker, "admin");
×
397
                        });
398

UNCOV
399
                        describe("update", () => {
×
UNCOV
400
                                it("should update only name field", async () => {
×
UNCOV
401
                                        userPermission = "";
×
UNCOV
402
                                        const res = await broker.call("users.update", {
×
403
                                                id: docWithPerm.id,
404
                                                name: "John Doe",
405
                                                password: "john123456"
406
                                        });
UNCOV
407
                                        expect(res).toStrictEqual({
×
408
                                                id: expectedID,
409
                                                name: "John Doe"
410
                                        });
UNCOV
411
                                        docWithPerm = res;
×
UNCOV
412
                                        docWithoutPerm = res;
×
413
                                });
UNCOV
414
                                checkResponseByPermission(broker, "admin");
×
415
                        });
416

UNCOV
417
                        describe("replace", () => {
×
UNCOV
418
                                it("should replace only name field", async () => {
×
UNCOV
419
                                        userPermission = "";
×
UNCOV
420
                                        const res = await broker.call("users.replace", {
×
421
                                                id: docWithPerm.id,
422
                                                name: "Replaced",
423
                                                password: "john123456"
424
                                        });
UNCOV
425
                                        expect(res).toStrictEqual({
×
426
                                                id: expectedID,
427
                                                name: "Replaced"
428
                                        });
UNCOV
429
                                        docWithPerm = res;
×
UNCOV
430
                                        docWithoutPerm = res;
×
431
                                });
UNCOV
432
                                checkResponseByPermission(broker, "admin");
×
433
                        });
434

UNCOV
435
                        it("remove entity", async () => {
×
UNCOV
436
                                await broker.call("users.remove", { id: docWithPerm.id });
×
437
                        });
438
                });
439

UNCOV
440
                describe("Test if has permission for action", () => {
×
UNCOV
441
                        describe("create", () => {
×
UNCOV
442
                                it("should create entity with all fields", async () => {
×
UNCOV
443
                                        userPermission = "admin";
×
UNCOV
444
                                        const res = await broker.call("users.create", {
×
445
                                                name: "John",
446
                                                password: "john1234"
447
                                        });
UNCOV
448
                                        expect(res).toStrictEqual({
×
449
                                                id: expectedID,
450
                                                name: "John",
451
                                                password: "john1234"
452
                                        });
UNCOV
453
                                        docWithPerm = res;
×
UNCOV
454
                                        docWithoutPerm = { id: res.id, name: "John" };
×
455
                                });
456

UNCOV
457
                                checkResponseByPermission(broker, "admin");
×
458
                        });
459

UNCOV
460
                        describe("update", () => {
×
UNCOV
461
                                it("should update all fields", async () => {
×
UNCOV
462
                                        userPermission = "admin";
×
UNCOV
463
                                        const res = await broker.call("users.update", {
×
464
                                                id: docWithPerm.id,
465
                                                name: "John Doe",
466
                                                password: "john123456"
467
                                        });
UNCOV
468
                                        expect(res).toStrictEqual({
×
469
                                                id: expectedID,
470
                                                name: "John Doe",
471
                                                password: "john123456"
472
                                        });
UNCOV
473
                                        docWithPerm = res;
×
UNCOV
474
                                        docWithoutPerm = { id: res.id, name: "John Doe" };
×
475
                                });
476

UNCOV
477
                                checkResponseByPermission(broker, "admin");
×
478
                        });
479

UNCOV
480
                        describe("replace", () => {
×
UNCOV
481
                                it("should replace all fields", async () => {
×
UNCOV
482
                                        userPermission = "admin";
×
UNCOV
483
                                        const res = await broker.call("users.replace", {
×
484
                                                id: docWithPerm.id,
485
                                                name: "Replaced",
486
                                                password: "john123456"
487
                                        });
UNCOV
488
                                        expect(res).toStrictEqual({
×
489
                                                id: expectedID,
490
                                                name: "Replaced",
491
                                                password: "john123456"
492
                                        });
UNCOV
493
                                        docWithPerm = res;
×
UNCOV
494
                                        docWithoutPerm = { id: res.id, name: "Replaced" };
×
495
                                });
496

UNCOV
497
                                checkResponseByPermission(broker, "admin");
×
498
                        });
499

UNCOV
500
                        it("remove entity", async () => {
×
UNCOV
501
                                await broker.call("users.remove", { id: docWithPerm.id });
×
502
                        });
503
                });
504
        });
505

UNCOV
506
        describe("Test field readPermission", () => {
×
UNCOV
507
                const broker = new ServiceBroker({ logger: false });
×
UNCOV
508
                const svc = broker.createService({
×
509
                        name: "users",
510
                        mixins: [
511
                                DbService({
512
                                        adapter: getAdapter(),
513
                                        createActions: true
514
                                })
515
                        ],
516
                        settings: {
517
                                fields: {
518
                                        id: {
519
                                                type: "string",
520
                                                primaryKey: true,
521
                                                columnName: "_id",
522
                                                columnType: getAdapter.IdColumnType
523
                                        },
524
                                        name: "string",
525
                                        password: {
526
                                                type: "string",
527
                                                readPermission: ["owner", "admin"],
528
                                                permission: "admin"
529
                                        }
530
                                }
531
                        },
532
                        methods: {
533
                                checkFieldAuthority(ctx, permission, params, field) {
UNCOV
534
                                        if (typeof permission == "string")
×
UNCOV
535
                                                return this.Promise.resolve(permission == userPermission);
×
UNCOV
536
                                        return this.Promise.resolve(permission.includes(userPermission));
×
537
                                }
538
                        },
539

540
                        async started() {
UNCOV
541
                                const adapter = await this.getAdapter();
×
UNCOV
542
                                if (adapterType == "Knex") {
×
UNCOV
543
                                        await adapter.createTable();
×
544
                                }
545

UNCOV
546
                                await this.clearEntities();
×
547
                        }
548
                });
549

UNCOV
550
                beforeAll(async () => {
×
UNCOV
551
                        await broker.start();
×
UNCOV
552
                        await svc.clearEntities();
×
553
                });
UNCOV
554
                afterAll(() => broker.stop());
×
555

UNCOV
556
                describe("create", () => {
×
UNCOV
557
                        it("should create entity", async () => {
×
UNCOV
558
                                userPermission = "admin";
×
UNCOV
559
                                const res = await broker.call("users.create", {
×
560
                                        name: "John",
561
                                        password: "john1234"
562
                                });
UNCOV
563
                                expect(res).toStrictEqual({
×
564
                                        id: expectedID,
565
                                        name: "John",
566
                                        password: "john1234"
567
                                });
UNCOV
568
                                docWithPerm = res;
×
UNCOV
569
                                docWithReadPerm = res;
×
UNCOV
570
                                docWithoutPerm = { id: res.id, name: "John" };
×
571
                        });
572

UNCOV
573
                        checkResponseByPermission(broker, "admin", "owner");
×
574
                });
575

UNCOV
576
                describe("update", () => {
×
UNCOV
577
                        it("should update all fields", async () => {
×
UNCOV
578
                                userPermission = "admin";
×
UNCOV
579
                                const res = await broker.call("users.update", {
×
580
                                        id: docWithPerm.id,
581
                                        name: "John Doe",
582
                                        password: "john123456"
583
                                });
UNCOV
584
                                expect(res).toStrictEqual({
×
585
                                        id: expectedID,
586
                                        name: "John Doe",
587
                                        password: "john123456"
588
                                });
UNCOV
589
                                docWithPerm = res;
×
UNCOV
590
                                docWithReadPerm = res;
×
UNCOV
591
                                docWithoutPerm = { id: res.id, name: "John Doe" };
×
592
                        });
593

UNCOV
594
                        checkResponseByPermission(broker, "admin", "owner");
×
595
                });
596

UNCOV
597
                describe("replace", () => {
×
UNCOV
598
                        it("should replace all fields", async () => {
×
UNCOV
599
                                userPermission = "admin";
×
UNCOV
600
                                const res = await broker.call("users.replace", {
×
601
                                        id: docWithPerm.id,
602
                                        name: "Replaced",
603
                                        password: "john123456"
604
                                });
UNCOV
605
                                expect(res).toStrictEqual({
×
606
                                        id: expectedID,
607
                                        name: "Replaced",
608
                                        password: "john123456"
609
                                });
UNCOV
610
                                docWithPerm = res;
×
UNCOV
611
                                docWithReadPerm = res;
×
UNCOV
612
                                docWithoutPerm = { id: res.id, name: "Replaced" };
×
613
                        });
614

UNCOV
615
                        checkResponseByPermission(broker, "admin", "owner");
×
616
                });
617

UNCOV
618
                it("remove entity", async () => {
×
UNCOV
619
                        await broker.call("users.remove", { id: docWithPerm.id });
×
620
                });
621
        });
622

UNCOV
623
        describe("Test readonly field", () => {
×
UNCOV
624
                const broker = new ServiceBroker({ logger: false });
×
UNCOV
625
                const svc = broker.createService({
×
626
                        name: "users",
627
                        mixins: [
628
                                DbService({
629
                                        adapter: getAdapter(),
630
                                        createActions: true
631
                                })
632
                        ],
633
                        settings: {
634
                                fields: {
635
                                        id: {
636
                                                type: "string",
637
                                                primaryKey: true,
638
                                                columnName: "_id",
639
                                                columnType: getAdapter.IdColumnType
640
                                        },
641
                                        name: "string",
642
                                        role: { type: "string", readonly: true }
643
                                }
644
                        },
645

646
                        async started() {
UNCOV
647
                                const adapter = await this.getAdapter();
×
UNCOV
648
                                if (adapterType == "Knex") {
×
UNCOV
649
                                        await adapter.createTable();
×
650
                                }
651

UNCOV
652
                                await this.clearEntities();
×
653
                        }
654
                });
655

UNCOV
656
                beforeAll(async () => {
×
UNCOV
657
                        await broker.start();
×
UNCOV
658
                        await svc.clearEntities();
×
659
                });
UNCOV
660
                afterAll(() => broker.stop());
×
661

UNCOV
662
                describe("Test create, update, replace", () => {
×
UNCOV
663
                        let entity = {
×
664
                                name: "John",
665
                                role: "administrator"
666
                        };
667

UNCOV
668
                        it("should skip role field at create", async () => {
×
UNCOV
669
                                const res = await broker.call("users.create", entity);
×
UNCOV
670
                                expect(res).toStrictEqual({
×
671
                                        id: expectedID,
672
                                        name: "John",
673
                                        ...(getAdapter.isSQL ? { role: null } : {})
×
674
                                });
UNCOV
675
                                entity = res;
×
676

UNCOV
677
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
678
                                expect(res2).toStrictEqual(entity);
×
679
                        });
680

UNCOV
681
                        it("should skip role field at update", async () => {
×
UNCOV
682
                                const res = await broker.call("users.update", {
×
683
                                        id: "" + entity.id,
684
                                        name: "John Doe",
685
                                        role: "moderator"
686
                                });
UNCOV
687
                                expect(res).toStrictEqual({
×
688
                                        id: expectedID,
689
                                        name: "John Doe",
690
                                        ...(getAdapter.isSQL ? { role: null } : {})
×
691
                                });
UNCOV
692
                                entity = res;
×
693

UNCOV
694
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
695
                                expect(res2).toStrictEqual(entity);
×
696
                        });
697

UNCOV
698
                        it("should skip role field at replace", async () => {
×
UNCOV
699
                                const res = await broker.call("users.replace", {
×
700
                                        id: "" + entity.id,
701
                                        name: "Jane Doe",
702
                                        role: "guest"
703
                                });
UNCOV
704
                                expect(res).toStrictEqual({
×
705
                                        id: expectedID,
706
                                        name: "Jane Doe",
707
                                        ...(getAdapter.isSQL ? { role: null } : {})
×
708
                                });
UNCOV
709
                                entity = res;
×
710

UNCOV
711
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
712
                                expect(res2).toStrictEqual(entity);
×
713
                        });
714
                });
715

UNCOV
716
                describe("Test with permissive option", () => {
×
UNCOV
717
                        let entity = {
×
718
                                name: "John",
719
                                role: "administrator"
720
                        };
721

UNCOV
722
                        it("should update role field at create", async () => {
×
UNCOV
723
                                const res = await svc.createEntity(null, entity, { permissive: true });
×
UNCOV
724
                                expect(res).toStrictEqual({
×
725
                                        id: expectedID,
726
                                        name: "John",
727
                                        role: "administrator"
728
                                });
UNCOV
729
                                entity = res;
×
730

UNCOV
731
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
732
                                expect(res2).toStrictEqual(entity);
×
733
                        });
734

UNCOV
735
                        it("should update role field at update", async () => {
×
UNCOV
736
                                const res = await svc.updateEntity(
×
737
                                        null,
738
                                        {
739
                                                id: "" + entity.id,
740
                                                name: "John Doe",
741
                                                role: "moderator"
742
                                        },
743
                                        { permissive: true }
744
                                );
UNCOV
745
                                expect(res).toStrictEqual({
×
746
                                        id: expectedID,
747
                                        name: "John Doe",
748
                                        role: "moderator"
749
                                });
UNCOV
750
                                entity = res;
×
751

UNCOV
752
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
753
                                expect(res2).toStrictEqual(entity);
×
754
                        });
755

UNCOV
756
                        it("should update role field at replace", async () => {
×
UNCOV
757
                                const res = await svc.replaceEntity(
×
758
                                        null,
759
                                        {
760
                                                id: "" + entity.id,
761
                                                name: "Jane Doe",
762
                                                role: "guest"
763
                                        },
764
                                        { permissive: true }
765
                                );
UNCOV
766
                                expect(res).toStrictEqual({
×
767
                                        id: expectedID,
768
                                        name: "Jane Doe",
769
                                        role: "guest"
770
                                });
UNCOV
771
                                entity = res;
×
772

UNCOV
773
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
774
                                expect(res2).toStrictEqual(entity);
×
775
                        });
776
                });
777
        });
778

UNCOV
779
        describe("Test immutable field", () => {
×
UNCOV
780
                const broker = new ServiceBroker({ logger: false });
×
UNCOV
781
                const svc = broker.createService({
×
782
                        name: "users",
783
                        mixins: [
784
                                DbService({
785
                                        adapter: getAdapter(),
786
                                        createActions: true
787
                                })
788
                        ],
789
                        settings: {
790
                                fields: {
791
                                        id: {
792
                                                type: "string",
793
                                                primaryKey: true,
794
                                                columnName: "_id",
795
                                                columnType: getAdapter.IdColumnType
796
                                        },
797
                                        name: "string",
798
                                        role: { type: "string", immutable: true }
799
                                }
800
                        },
801

802
                        async started() {
UNCOV
803
                                const adapter = await this.getAdapter();
×
UNCOV
804
                                if (adapterType == "Knex") {
×
UNCOV
805
                                        await adapter.createTable();
×
806
                                }
807

UNCOV
808
                                await this.clearEntities();
×
809
                        }
810
                });
811

UNCOV
812
                beforeAll(async () => {
×
UNCOV
813
                        await broker.start();
×
UNCOV
814
                        await svc.clearEntities();
×
815
                });
UNCOV
816
                afterAll(() => broker.stop());
×
817

UNCOV
818
                describe("Test create, update, replace (set value in create)", () => {
×
UNCOV
819
                        let entity = {
×
820
                                name: "John",
821
                                role: "administrator"
822
                        };
823

UNCOV
824
                        it("should store role field at create", async () => {
×
UNCOV
825
                                const res = await broker.call("users.create", entity);
×
UNCOV
826
                                expect(res).toStrictEqual({
×
827
                                        id: expectedID,
828
                                        name: "John",
829
                                        role: "administrator"
830
                                });
UNCOV
831
                                entity = res;
×
832

UNCOV
833
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
834
                                expect(res2).toStrictEqual(entity);
×
835
                        });
836

UNCOV
837
                        it("should skip role field at update", async () => {
×
UNCOV
838
                                const res = await broker.call("users.update", {
×
839
                                        id: entity.id,
840
                                        name: "John Doe",
841
                                        role: "moderator"
842
                                });
UNCOV
843
                                expect(res).toStrictEqual({
×
844
                                        id: expectedID,
845
                                        name: "John Doe",
846
                                        role: "administrator"
847
                                });
UNCOV
848
                                entity = res;
×
849

UNCOV
850
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
851
                                expect(res2).toStrictEqual(entity);
×
852
                        });
853

UNCOV
854
                        it("should skip role field at replace", async () => {
×
UNCOV
855
                                const res = await broker.call("users.replace", {
×
856
                                        id: entity.id,
857
                                        name: "Jane Doe",
858
                                        role: "guest"
859
                                });
UNCOV
860
                                expect(res).toStrictEqual({
×
861
                                        id: expectedID,
862
                                        name: "Jane Doe",
863
                                        role: "administrator"
864
                                });
UNCOV
865
                                entity = res;
×
866

UNCOV
867
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
868
                                expect(res2).toStrictEqual(entity);
×
869
                        });
870
                });
871

UNCOV
872
                describe("Test create, update, replace (set value in update)", () => {
×
UNCOV
873
                        let entity = {
×
874
                                name: "John"
875
                        };
876

UNCOV
877
                        it("should store role field at create", async () => {
×
UNCOV
878
                                const res = await broker.call("users.create", entity);
×
UNCOV
879
                                expect(res).toStrictEqual({
×
880
                                        id: expectedID,
881
                                        name: "John",
882
                                        ...(getAdapter.isSQL ? { role: null } : {})
×
883
                                });
UNCOV
884
                                entity = res;
×
885

UNCOV
886
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
887
                                expect(res2).toStrictEqual(entity);
×
888
                        });
889

UNCOV
890
                        it("should skip role field at update", async () => {
×
UNCOV
891
                                const res = await broker.call("users.update", {
×
892
                                        id: "" + entity.id,
893
                                        name: "John Doe",
894
                                        role: "moderator"
895
                                });
UNCOV
896
                                expect(res).toStrictEqual({
×
897
                                        id: expectedID,
898
                                        name: "John Doe",
899
                                        role: "moderator"
900
                                });
UNCOV
901
                                entity = res;
×
902

UNCOV
903
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
904
                                expect(res2).toStrictEqual(entity);
×
905
                        });
906
                });
907

UNCOV
908
                describe("Test create, update, replace (set value in replace)", () => {
×
UNCOV
909
                        let entity = {
×
910
                                name: "John"
911
                        };
912

UNCOV
913
                        it("should store role field at create", async () => {
×
UNCOV
914
                                const res = await broker.call("users.create", entity);
×
UNCOV
915
                                expect(res).toStrictEqual({
×
916
                                        id: expectedID,
917
                                        name: "John",
918
                                        ...(getAdapter.isSQL ? { role: null } : {})
×
919
                                });
UNCOV
920
                                entity = res;
×
921

UNCOV
922
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
923
                                expect(res2).toStrictEqual(entity);
×
924
                        });
925

UNCOV
926
                        it("should set role field at replace because it not set yet", async () => {
×
UNCOV
927
                                const res = await broker.call("users.replace", {
×
928
                                        id: "" + entity.id,
929
                                        name: "Jane Doe",
930
                                        role: "moderator"
931
                                });
UNCOV
932
                                expect(res).toStrictEqual({
×
933
                                        id: expectedID,
934
                                        name: "Jane Doe",
935
                                        role: "moderator"
936
                                });
UNCOV
937
                                entity = res;
×
938

UNCOV
939
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
940
                                expect(res2).toStrictEqual(entity);
×
941
                        });
942
                });
943

UNCOV
944
                describe("Test with permissive option", () => {
×
UNCOV
945
                        let entity = {
×
946
                                name: "John",
947
                                role: "administrator"
948
                        };
949

UNCOV
950
                        it("should store role field at create", async () => {
×
UNCOV
951
                                const res = await broker.call("users.create", entity);
×
UNCOV
952
                                expect(res).toStrictEqual({
×
953
                                        id: expectedID,
954
                                        name: "John",
955
                                        role: "administrator"
956
                                });
UNCOV
957
                                entity = res;
×
958

UNCOV
959
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
960
                                expect(res2).toStrictEqual(entity);
×
961
                        });
962

UNCOV
963
                        it("should update role field at update", async () => {
×
UNCOV
964
                                const res = await svc.updateEntity(
×
965
                                        null,
966
                                        {
967
                                                id: entity.id,
968
                                                name: "John Doe",
969
                                                role: "moderator"
970
                                        },
971
                                        { permissive: true }
972
                                );
UNCOV
973
                                expect(res).toStrictEqual({
×
974
                                        id: expectedID,
975
                                        name: "John Doe",
976
                                        role: "moderator"
977
                                });
UNCOV
978
                                entity = res;
×
979

UNCOV
980
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
981
                                expect(res2).toStrictEqual(entity);
×
982
                        });
983

UNCOV
984
                        it("should replace role field at replace", async () => {
×
UNCOV
985
                                const res = await svc.replaceEntity(
×
986
                                        null,
987
                                        {
988
                                                id: entity.id,
989
                                                name: "Jane Doe",
990
                                                role: "guest"
991
                                        },
992
                                        { permissive: true }
993
                                );
UNCOV
994
                                expect(res).toStrictEqual({
×
995
                                        id: expectedID,
996
                                        name: "Jane Doe",
997
                                        role: "guest"
998
                                });
UNCOV
999
                                entity = res;
×
1000

UNCOV
1001
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
1002
                                expect(res2).toStrictEqual(entity);
×
1003
                        });
1004
                });
1005
        });
1006

UNCOV
1007
        describe("Test hooks", () => {
×
UNCOV
1008
                const onCreate = jest.fn(async () => "Created now");
×
UNCOV
1009
                const onUpdate = jest.fn(async () => "Updated now");
×
UNCOV
1010
                const onReplace = jest.fn(async () => "Replaced now");
×
UNCOV
1011
                const onRemove = jest.fn(async () => "Removed now");
×
1012

UNCOV
1013
                const broker = new ServiceBroker({ logger: false });
×
UNCOV
1014
                const svc = broker.createService({
×
1015
                        name: "users",
1016
                        mixins: [
1017
                                DbService({
1018
                                        adapter: getAdapter(),
1019
                                        createActions: true
1020
                                })
1021
                        ],
1022
                        settings: {
1023
                                fields: {
1024
                                        id: {
1025
                                                type: "string",
1026
                                                primaryKey: true,
1027
                                                columnName: "_id",
1028
                                                columnType: getAdapter.IdColumnType
1029
                                        },
1030
                                        name: "string",
1031
                                        createdAt: { onCreate, columnType: "string" },
1032
                                        createdBy: { onCreate: "Creator", columnType: "string" },
1033
                                        updatedAt: { onUpdate, columnType: "string" },
1034
                                        updatedBy: { onUpdate: "Updater", columnType: "string" },
1035
                                        replacedAt: { onReplace, columnType: "string" },
1036
                                        replacedBy: { onReplace: "Replacer", columnType: "string" },
1037
                                        removedAt: { onRemove, columnType: "string" },
1038
                                        removedBy: { onRemove: "Remover", columnType: "string" }
1039
                                }
1040
                        },
1041

1042
                        actions: {
1043
                                updateWithoutHooks: {
1044
                                        handler(ctx) {
UNCOV
1045
                                                return this.updateEntity(ctx, ctx.params, { skipOnHooks: true });
×
1046
                                        }
1047
                                }
1048
                        },
1049

1050
                        async started() {
UNCOV
1051
                                const adapter = await this.getAdapter();
×
UNCOV
1052
                                if (adapterType == "Knex") {
×
UNCOV
1053
                                        await adapter.createTable();
×
1054
                                }
1055

UNCOV
1056
                                await this.clearEntities();
×
1057
                        }
1058
                });
1059

UNCOV
1060
                beforeAll(async () => {
×
UNCOV
1061
                        await broker.start();
×
UNCOV
1062
                        await svc.clearEntities();
×
1063
                });
UNCOV
1064
                afterAll(() => broker.stop());
×
1065

UNCOV
1066
                describe("Test create, update, replace, remove", () => {
×
UNCOV
1067
                        let entity = {
×
1068
                                name: "John"
1069
                        };
1070

UNCOV
1071
                        it("should call onCreate hook", async () => {
×
UNCOV
1072
                                const res = await broker.call("users.create", entity);
×
UNCOV
1073
                                expect(res).toStrictEqual({
×
1074
                                        id: expectedID,
1075
                                        name: "John",
1076
                                        createdAt: "Created now",
1077
                                        createdBy: "Creator",
1078
                                        ...(getAdapter.isSQL
×
1079
                                                ? {
1080
                                                                updatedAt: null,
1081
                                                                updatedBy: null,
1082
                                                                replacedAt: null,
1083
                                                                replacedBy: null,
1084
                                                                removedAt: null,
1085
                                                                removedBy: null
1086
                                                  }
1087
                                                : {})
1088
                                });
UNCOV
1089
                                entity = res;
×
1090

UNCOV
1091
                                expect(onCreate).toBeCalledTimes(1);
×
UNCOV
1092
                                expect(onCreate).toBeCalledWith({
×
1093
                                        operation: "create",
1094
                                        ctx: expect.any(Context),
1095
                                        value: undefined,
1096
                                        params: { name: "John" },
1097
                                        root: { name: "John" },
1098
                                        entity: undefined,
1099
                                        field: svc.$fields[2],
1100
                                        id: undefined
1101
                                });
1102

UNCOV
1103
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
1104
                                expect(res2).toStrictEqual(entity);
×
1105
                        });
1106

UNCOV
1107
                        it("should skip calling onUpdate hook", async () => {
×
UNCOV
1108
                                const res = await broker.call("users.updateWithoutHooks", {
×
1109
                                        id: entity.id,
1110
                                        name: "John Doe",
1111
                                        updatedAt: "Past"
1112
                                });
UNCOV
1113
                                expect(res).toStrictEqual({
×
1114
                                        id: entity.id,
1115
                                        name: "John Doe",
1116
                                        createdAt: "Created now",
1117
                                        createdBy: "Creator",
1118
                                        updatedAt: "Past",
1119
                                        ...(getAdapter.isSQL
×
1120
                                                ? {
1121
                                                                updatedBy: null,
1122
                                                                replacedAt: null,
1123
                                                                replacedBy: null,
1124
                                                                removedAt: null,
1125
                                                                removedBy: null
1126
                                                  }
1127
                                                : {})
1128
                                });
UNCOV
1129
                                entity = res;
×
1130

UNCOV
1131
                                expect(onUpdate).toBeCalledTimes(0);
×
1132

UNCOV
1133
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
1134
                                expect(res2).toStrictEqual(entity);
×
1135
                        });
1136

UNCOV
1137
                        it("should call onUpdate hook", async () => {
×
UNCOV
1138
                                const res = await broker.call("users.update", {
×
1139
                                        id: entity.id,
1140
                                        name: "John Doe",
1141
                                        updatedAt: "Past"
1142
                                });
UNCOV
1143
                                expect(res).toStrictEqual({
×
1144
                                        id: entity.id,
1145
                                        name: "John Doe",
1146
                                        createdAt: "Created now",
1147
                                        createdBy: "Creator",
1148
                                        updatedAt: "Updated now",
1149
                                        updatedBy: "Updater",
1150
                                        ...(getAdapter.isSQL
×
1151
                                                ? {
1152
                                                                replacedAt: null,
1153
                                                                replacedBy: null,
1154
                                                                removedAt: null,
1155
                                                                removedBy: null
1156
                                                  }
1157
                                                : {})
1158
                                });
UNCOV
1159
                                entity = res;
×
1160

UNCOV
1161
                                expect(onUpdate).toBeCalledTimes(1);
×
UNCOV
1162
                                expect(onUpdate).toBeCalledWith({
×
1163
                                        operation: "update",
1164
                                        ctx: expect.any(Context),
1165
                                        value: "Past",
1166
                                        params: {
1167
                                                id: "" + entity.id,
1168
                                                name: "John Doe",
1169
                                                updatedAt: "Past"
1170
                                        },
1171
                                        root: {
1172
                                                id: "" + entity.id,
1173
                                                name: "John Doe",
1174
                                                updatedAt: "Past"
1175
                                        },
1176
                                        entity: {
1177
                                                _id: ["MongoDB"].includes(adapterType) ? expect.any(ObjectId) : entity.id,
×
1178
                                                name: "John Doe",
1179
                                                createdAt: "Created now",
1180
                                                createdBy: "Creator",
1181
                                                updatedAt: "Past",
1182
                                                ...(getAdapter.isSQL
×
1183
                                                        ? {
1184
                                                                        updatedBy: null,
1185
                                                                        replacedAt: null,
1186
                                                                        replacedBy: null,
1187
                                                                        removedAt: null,
1188
                                                                        removedBy: null
1189
                                                          }
1190
                                                        : {})
1191
                                        },
1192
                                        field: svc.$fields[4],
1193
                                        id: "" + entity.id
1194
                                });
1195

UNCOV
1196
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
1197
                                expect(res2).toStrictEqual(entity);
×
1198
                        });
1199

UNCOV
1200
                        it("should call onReplace hook", async () => {
×
UNCOV
1201
                                const res = await broker.call("users.replace", {
×
1202
                                        ...entity,
1203
                                        name: "Jane Doe"
1204
                                });
UNCOV
1205
                                expect(res).toStrictEqual({
×
1206
                                        id: entity.id,
1207
                                        name: "Jane Doe",
1208
                                        createdAt: "Created now",
1209
                                        createdBy: "Creator",
1210
                                        updatedAt: "Updated now",
1211
                                        updatedBy: "Updater",
1212
                                        replacedAt: "Replaced now",
1213
                                        replacedBy: "Replacer",
1214
                                        ...(getAdapter.isSQL
×
1215
                                                ? {
1216
                                                                removedAt: null,
1217
                                                                removedBy: null
1218
                                                  }
1219
                                                : {})
1220
                                });
UNCOV
1221
                                entity = res;
×
1222

UNCOV
1223
                                expect(onReplace).toBeCalledTimes(1);
×
UNCOV
1224
                                expect(onReplace).toBeCalledWith({
×
1225
                                        operation: "replace",
1226
                                        ctx: expect.any(Context),
1227
                                        value: getAdapter.isSQL ? null : undefined,
×
1228
                                        params: {
1229
                                                id: "" + entity.id,
1230
                                                name: "Jane Doe",
1231
                                                createdAt: "Created now",
1232
                                                createdBy: "Creator",
1233
                                                updatedAt: "Updated now",
1234
                                                updatedBy: "Updater",
1235
                                                ...(getAdapter.isSQL
×
1236
                                                        ? {
1237
                                                                        replacedAt: null,
1238
                                                                        replacedBy: null,
1239
                                                                        removedAt: null,
1240
                                                                        removedBy: null
1241
                                                          }
1242
                                                        : {})
1243
                                        },
1244
                                        root: {
1245
                                                id: "" + entity.id,
1246
                                                name: "Jane Doe",
1247
                                                createdAt: "Created now",
1248
                                                createdBy: "Creator",
1249
                                                updatedAt: "Updated now",
1250
                                                updatedBy: "Updater",
1251
                                                ...(getAdapter.isSQL
×
1252
                                                        ? {
1253
                                                                        replacedAt: null,
1254
                                                                        replacedBy: null,
1255
                                                                        removedAt: null,
1256
                                                                        removedBy: null
1257
                                                          }
1258
                                                        : {})
1259
                                        },
1260
                                        entity: {
1261
                                                _id: ["MongoDB"].includes(adapterType) ? expect.any(ObjectId) : entity.id,
×
1262
                                                name: "John Doe",
1263
                                                createdAt: "Created now",
1264
                                                createdBy: "Creator",
1265
                                                updatedAt: "Updated now",
1266
                                                updatedBy: "Updater",
1267
                                                ...(getAdapter.isSQL
×
1268
                                                        ? {
1269
                                                                        replacedAt: null,
1270
                                                                        replacedBy: null,
1271
                                                                        removedAt: null,
1272
                                                                        removedBy: null
1273
                                                          }
1274
                                                        : {})
1275
                                        },
1276
                                        field: svc.$fields[6],
1277
                                        id: "" + entity.id
1278
                                });
1279

UNCOV
1280
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
1281
                                expect(res2).toStrictEqual(entity);
×
1282
                        });
1283

UNCOV
1284
                        it("should call onRemove hook", async () => {
×
UNCOV
1285
                                const res = await broker.call("users.remove", {
×
1286
                                        id: entity.id
1287
                                });
UNCOV
1288
                                expect(res).toBe("" + entity.id);
×
1289

UNCOV
1290
                                expect(onRemove).toBeCalledTimes(1);
×
UNCOV
1291
                                expect(onRemove).toBeCalledWith({
×
1292
                                        operation: "remove",
1293
                                        ctx: expect.any(Context),
1294
                                        value: undefined,
1295
                                        params: {
1296
                                                id: "" + entity.id
1297
                                        },
1298
                                        root: {
1299
                                                id: "" + entity.id
1300
                                        },
1301
                                        entity: {
1302
                                                _id: ["MongoDB"].includes(adapterType) ? expect.any(ObjectId) : entity.id,
×
1303
                                                name: "Jane Doe",
1304
                                                createdAt: "Created now",
1305
                                                createdBy: "Creator",
1306
                                                updatedAt: "Updated now",
1307
                                                updatedBy: "Updater",
1308
                                                replacedAt: "Replaced now",
1309
                                                replacedBy: "Replacer",
1310
                                                ...(getAdapter.isSQL
×
1311
                                                        ? {
1312
                                                                        removedAt: null,
1313
                                                                        removedBy: null
1314
                                                          }
1315
                                                        : {})
1316
                                        },
1317
                                        field: svc.$fields[8],
1318
                                        id: "" + entity.id
1319
                                });
1320

UNCOV
1321
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
1322
                                expect(res2).toStrictEqual({
×
1323
                                        id: entity.id,
1324
                                        name: "Jane Doe",
1325
                                        createdAt: "Created now",
1326
                                        createdBy: "Creator",
1327
                                        updatedAt: "Updated now",
1328
                                        updatedBy: "Updater",
1329
                                        replacedAt: "Replaced now",
1330
                                        replacedBy: "Replacer",
1331
                                        removedAt: "Removed now",
1332
                                        removedBy: "Remover"
1333
                                });
1334
                        });
1335
                });
1336
        });
1337

UNCOV
1338
        describe("Test custom validator", () => {
×
UNCOV
1339
                const customValidate = jest.fn(({ value }) => value.length > 2 || "Too short");
×
1340

UNCOV
1341
                const broker = new ServiceBroker({ logger: false });
×
UNCOV
1342
                const svc = broker.createService({
×
1343
                        name: "users",
1344
                        mixins: [
1345
                                DbService({
1346
                                        adapter: getAdapter(),
1347
                                        createActions: true
1348
                                })
1349
                        ],
1350
                        settings: {
1351
                                fields: {
1352
                                        id: {
1353
                                                type: "string",
1354
                                                primaryKey: true,
1355
                                                columnName: "_id",
1356
                                                columnType: getAdapter.IdColumnType
1357
                                        },
1358
                                        name: { type: "string", required: true, validate: customValidate },
1359
                                        age: { type: "number", columnType: "integer", validate: "checkAge" }
1360
                                }
1361
                        },
1362

1363
                        methods: {
1364
                                checkAge({ value }) {
UNCOV
1365
                                        return value > 99 ? "Too old" : true;
×
1366
                                }
1367
                        },
1368

1369
                        async started() {
UNCOV
1370
                                const adapter = await this.getAdapter();
×
UNCOV
1371
                                if (adapterType == "Knex") {
×
UNCOV
1372
                                        await adapter.createTable();
×
1373
                                }
1374

UNCOV
1375
                                await this.clearEntities();
×
1376
                        }
1377
                });
1378

UNCOV
1379
                beforeAll(async () => {
×
UNCOV
1380
                        await broker.start();
×
UNCOV
1381
                        await svc.clearEntities();
×
1382
                });
UNCOV
1383
                afterAll(() => broker.stop());
×
1384

UNCOV
1385
                describe("Test with custom function", () => {
×
1386
                        let entity;
1387

UNCOV
1388
                        it("should throw error at create", async () => {
×
UNCOV
1389
                                expect.assertions(6);
×
UNCOV
1390
                                try {
×
UNCOV
1391
                                        await broker.call("users.create", { name: "Al" });
×
1392
                                } catch (err) {
UNCOV
1393
                                        expect(err).toBeInstanceOf(ValidationError);
×
UNCOV
1394
                                        expect(err.name).toBe("ValidationError");
×
UNCOV
1395
                                        expect(err.message).toBe("Too short");
×
UNCOV
1396
                                        expect(err.type).toBe("VALIDATION_ERROR");
×
UNCOV
1397
                                        expect(err.code).toBe(422);
×
UNCOV
1398
                                        expect(err.data).toEqual({
×
1399
                                                field: "name",
1400
                                                value: "Al"
1401
                                        });
1402
                                }
1403
                        });
1404

UNCOV
1405
                        it("should create entity", async () => {
×
UNCOV
1406
                                const res = await broker.call("users.create", { name: "John" });
×
UNCOV
1407
                                expect(res).toStrictEqual({
×
1408
                                        id: expectedID,
1409
                                        name: "John",
1410
                                        ...(getAdapter.isSQL
×
1411
                                                ? {
1412
                                                                age: null
1413
                                                  }
1414
                                                : {})
1415
                                });
UNCOV
1416
                                entity = res;
×
1417
                        });
1418

UNCOV
1419
                        it("should throw error at update", async () => {
×
UNCOV
1420
                                expect.assertions(6);
×
UNCOV
1421
                                try {
×
UNCOV
1422
                                        await broker.call("users.update", { id: entity.id, name: "Al" });
×
1423
                                } catch (err) {
UNCOV
1424
                                        expect(err).toBeInstanceOf(ValidationError);
×
UNCOV
1425
                                        expect(err.name).toBe("ValidationError");
×
UNCOV
1426
                                        expect(err.message).toBe("Too short");
×
UNCOV
1427
                                        expect(err.type).toBe("VALIDATION_ERROR");
×
UNCOV
1428
                                        expect(err.code).toBe(422);
×
UNCOV
1429
                                        expect(err.data).toEqual({
×
1430
                                                field: "name",
1431
                                                value: "Al"
1432
                                        });
1433
                                }
1434
                        });
1435

UNCOV
1436
                        it("should update entity", async () => {
×
UNCOV
1437
                                const res = await broker.call("users.update", {
×
1438
                                        id: entity.id,
1439
                                        name: "John Doe"
1440
                                });
UNCOV
1441
                                expect(res).toStrictEqual({
×
1442
                                        id: entity.id,
1443
                                        name: "John Doe",
1444
                                        ...(getAdapter.isSQL
×
1445
                                                ? {
1446
                                                                age: null
1447
                                                  }
1448
                                                : {})
1449
                                });
UNCOV
1450
                                entity = res;
×
1451
                        });
1452

UNCOV
1453
                        it("should throw error at replace", async () => {
×
UNCOV
1454
                                expect.assertions(6);
×
UNCOV
1455
                                try {
×
UNCOV
1456
                                        await broker.call("users.replace", {
×
1457
                                                ...entity,
1458
                                                name: "Al"
1459
                                        });
1460
                                } catch (err) {
UNCOV
1461
                                        expect(err).toBeInstanceOf(ValidationError);
×
UNCOV
1462
                                        expect(err.name).toBe("ValidationError");
×
UNCOV
1463
                                        expect(err.message).toBe("Too short");
×
UNCOV
1464
                                        expect(err.type).toBe("VALIDATION_ERROR");
×
UNCOV
1465
                                        expect(err.code).toBe(422);
×
UNCOV
1466
                                        expect(err.data).toEqual({
×
1467
                                                field: "name",
1468
                                                value: "Al"
1469
                                        });
1470
                                }
1471
                        });
1472

UNCOV
1473
                        it("should replace entity", async () => {
×
UNCOV
1474
                                const res = await broker.call("users.replace", {
×
1475
                                        ...entity,
1476
                                        name: "Jane Doe"
1477
                                });
UNCOV
1478
                                expect(res).toStrictEqual({
×
1479
                                        id: entity.id,
1480
                                        name: "Jane Doe",
1481
                                        ...(getAdapter.isSQL
×
1482
                                                ? {
1483
                                                                age: null
1484
                                                  }
1485
                                                : {})
1486
                                });
UNCOV
1487
                                entity = res;
×
1488
                        });
1489
                });
1490

UNCOV
1491
                describe("Test with method name", () => {
×
1492
                        let entity;
1493

UNCOV
1494
                        it("should throw error at create", async () => {
×
UNCOV
1495
                                expect.assertions(6);
×
UNCOV
1496
                                try {
×
UNCOV
1497
                                        await broker.call("users.create", { name: "John", age: 120 });
×
1498
                                } catch (err) {
UNCOV
1499
                                        expect(err).toBeInstanceOf(ValidationError);
×
UNCOV
1500
                                        expect(err.name).toBe("ValidationError");
×
UNCOV
1501
                                        expect(err.message).toBe("Too old");
×
UNCOV
1502
                                        expect(err.type).toBe("VALIDATION_ERROR");
×
UNCOV
1503
                                        expect(err.code).toBe(422);
×
UNCOV
1504
                                        expect(err.data).toEqual({
×
1505
                                                field: "age",
1506
                                                value: 120
1507
                                        });
1508
                                }
1509
                        });
1510

UNCOV
1511
                        it("should create entity", async () => {
×
UNCOV
1512
                                const res = await broker.call("users.create", { name: "John", age: 33 });
×
UNCOV
1513
                                expect(res).toStrictEqual({
×
1514
                                        id: expectedID,
1515
                                        name: "John",
1516
                                        age: 33
1517
                                });
UNCOV
1518
                                entity = res;
×
1519
                        });
1520

UNCOV
1521
                        it("should throw error at update", async () => {
×
UNCOV
1522
                                expect.assertions(6);
×
UNCOV
1523
                                try {
×
UNCOV
1524
                                        await broker.call("users.update", { id: entity.id, age: 130 });
×
1525
                                } catch (err) {
UNCOV
1526
                                        expect(err).toBeInstanceOf(ValidationError);
×
UNCOV
1527
                                        expect(err.name).toBe("ValidationError");
×
UNCOV
1528
                                        expect(err.message).toBe("Too old");
×
UNCOV
1529
                                        expect(err.type).toBe("VALIDATION_ERROR");
×
UNCOV
1530
                                        expect(err.code).toBe(422);
×
UNCOV
1531
                                        expect(err.data).toEqual({
×
1532
                                                field: "age",
1533
                                                value: 130
1534
                                        });
1535
                                }
1536
                        });
1537

UNCOV
1538
                        it("should update entity", async () => {
×
UNCOV
1539
                                const res = await broker.call("users.update", {
×
1540
                                        id: entity.id,
1541
                                        age: 80
1542
                                });
UNCOV
1543
                                expect(res).toStrictEqual({
×
1544
                                        id: entity.id,
1545
                                        name: "John",
1546
                                        age: 80
1547
                                });
UNCOV
1548
                                entity = res;
×
1549
                        });
1550

UNCOV
1551
                        it("should throw error at replace", async () => {
×
UNCOV
1552
                                expect.assertions(6);
×
UNCOV
1553
                                try {
×
UNCOV
1554
                                        await broker.call("users.replace", {
×
1555
                                                ...entity,
1556
                                                name: "John",
1557
                                                age: 150
1558
                                        });
1559
                                } catch (err) {
UNCOV
1560
                                        expect(err).toBeInstanceOf(ValidationError);
×
UNCOV
1561
                                        expect(err.name).toBe("ValidationError");
×
UNCOV
1562
                                        expect(err.message).toBe("Too old");
×
UNCOV
1563
                                        expect(err.type).toBe("VALIDATION_ERROR");
×
UNCOV
1564
                                        expect(err.code).toBe(422);
×
UNCOV
1565
                                        expect(err.data).toEqual({
×
1566
                                                field: "age",
1567
                                                value: 150
1568
                                        });
1569
                                }
1570
                        });
1571

UNCOV
1572
                        it("should replace entity", async () => {
×
UNCOV
1573
                                const res = await broker.call("users.replace", {
×
1574
                                        ...entity,
1575
                                        name: "Jane",
1576
                                        age: 22
1577
                                });
UNCOV
1578
                                expect(res).toStrictEqual({
×
1579
                                        id: entity.id,
1580
                                        name: "Jane",
1581
                                        age: 22
1582
                                });
UNCOV
1583
                                entity = res;
×
1584
                        });
1585
                });
1586
        });
1587

UNCOV
1588
        describe("Test custom formatters", () => {
×
UNCOV
1589
                const getter = jest.fn(({ entity }) => `${entity.firstName} ${entity.lastName}`);
×
UNCOV
1590
                const setter = jest.fn(({ value, params }) => {
×
UNCOV
1591
                        [params.firstName, params.lastName] = value.split(" ");
×
UNCOV
1592
                        return null;
×
1593
                });
1594

UNCOV
1595
                const broker = new ServiceBroker({ logger: false });
×
UNCOV
1596
                const svc = broker.createService({
×
1597
                        name: "users",
1598
                        mixins: [
1599
                                DbService({
1600
                                        adapter: getAdapter(),
1601
                                        createActions: true
1602
                                })
1603
                        ],
1604
                        settings: {
1605
                                fields: {
1606
                                        id: {
1607
                                                type: "string",
1608
                                                primaryKey: true,
1609
                                                columnName: "_id",
1610
                                                columnType: getAdapter.IdColumnType
1611
                                        },
1612
                                        name: { type: "string", set: setter },
1613
                                        fullName: { type: "string", get: getter, virtual: true },
1614
                                        firstName: { type: "string" },
1615
                                        lastName: { type: "string" }
1616
                                }
1617
                        },
1618

1619
                        async started() {
UNCOV
1620
                                const adapter = await this.getAdapter();
×
UNCOV
1621
                                if (adapterType == "Knex") {
×
UNCOV
1622
                                        await adapter.createTable();
×
1623
                                }
1624

UNCOV
1625
                                await this.clearEntities();
×
1626
                        }
1627
                });
1628

UNCOV
1629
                beforeAll(async () => {
×
UNCOV
1630
                        await broker.start();
×
UNCOV
1631
                        await svc.clearEntities();
×
1632
                });
UNCOV
1633
                afterAll(() => broker.stop());
×
1634

UNCOV
1635
                describe("Test create, update, replace", () => {
×
1636
                        let entity;
1637

UNCOV
1638
                        it("should create entity", async () => {
×
UNCOV
1639
                                const res = await broker.call("users.create", { name: "John Doe" });
×
UNCOV
1640
                                expect(res).toStrictEqual({
×
1641
                                        id: expectedID,
1642
                                        fullName: "John Doe",
1643
                                        firstName: "John",
1644
                                        lastName: "Doe",
1645
                                        name: null
1646
                                });
UNCOV
1647
                                entity = res;
×
1648

UNCOV
1649
                                expect(setter).toBeCalledTimes(1);
×
UNCOV
1650
                                expect(setter).toBeCalledWith({
×
1651
                                        ctx: expect.any(Context),
1652
                                        operation: "create",
1653
                                        id: undefined,
1654
                                        value: "John Doe",
1655
                                        params: { firstName: "John", lastName: "Doe", name: "John Doe" },
1656
                                        root: { firstName: "John", lastName: "Doe", name: "John Doe" },
1657
                                        field: {
1658
                                                columnName: "name",
1659
                                                columnType: "string",
1660
                                                name: "name",
1661
                                                required: false,
1662
                                                set: expect.any(Function),
1663
                                                type: "string"
1664
                                        }
1665
                                });
1666

UNCOV
1667
                                expect(getter).toBeCalledTimes(1);
×
UNCOV
1668
                                expect(getter).toBeCalledWith({
×
1669
                                        value: undefined,
1670
                                        entity: { _id: entity.id, firstName: "John", lastName: "Doe", name: null },
1671
                                        field: {
1672
                                                columnName: "fullName",
1673
                                                columnType: "string",
1674
                                                get: expect.any(Function),
1675
                                                name: "fullName",
1676
                                                required: false,
1677
                                                type: "string",
1678
                                                virtual: true
1679
                                        },
1680
                                        ctx: expect.any(Context)
1681
                                });
1682

UNCOV
1683
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
1684
                                expect(res2).toStrictEqual(entity);
×
1685
                        });
1686

UNCOV
1687
                        it("should update entity", async () => {
×
UNCOV
1688
                                const res = await broker.call("users.update", {
×
1689
                                        id: entity.id,
1690
                                        name: "Jane Doe"
1691
                                });
UNCOV
1692
                                expect(res).toStrictEqual({
×
1693
                                        id: entity.id,
1694
                                        fullName: "Jane Doe",
1695
                                        firstName: "Jane",
1696
                                        lastName: "Doe",
1697
                                        name: null
1698
                                });
UNCOV
1699
                                entity = res;
×
1700

UNCOV
1701
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
1702
                                expect(res2).toStrictEqual(entity);
×
1703
                        });
1704

UNCOV
1705
                        it("should replace entity", async () => {
×
UNCOV
1706
                                const res = await broker.call("users.replace", {
×
1707
                                        ...entity,
1708
                                        name: "Adam Smith"
1709
                                });
UNCOV
1710
                                expect(res).toStrictEqual({
×
1711
                                        id: entity.id,
1712
                                        fullName: "Adam Smith",
1713
                                        firstName: "Adam",
1714
                                        lastName: "Smith",
1715
                                        name: null
1716
                                });
UNCOV
1717
                                entity = res;
×
1718

UNCOV
1719
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
1720
                                expect(res2).toStrictEqual(entity);
×
1721
                        });
1722
                });
1723
        });
1724

UNCOV
1725
        describe("Test default value", () => {
×
UNCOV
1726
                const getDefaultRole = jest.fn(() => "member");
×
1727

UNCOV
1728
                const broker = new ServiceBroker({ logger: false });
×
UNCOV
1729
                const svc = broker.createService({
×
1730
                        name: "users",
1731
                        mixins: [
1732
                                DbService({
1733
                                        adapter: getAdapter(),
1734
                                        createActions: true
1735
                                })
1736
                        ],
1737
                        settings: {
1738
                                fields: {
1739
                                        id: {
1740
                                                type: "string",
1741
                                                primaryKey: true,
1742
                                                columnName: "_id",
1743
                                                columnType: getAdapter.IdColumnType
1744
                                        },
1745
                                        name: { type: "string" },
1746
                                        role: { type: "string", default: getDefaultRole },
1747
                                        status: { type: "number", default: 5, columnType: "integer" }
1748
                                }
1749
                        },
1750

1751
                        async started() {
UNCOV
1752
                                const adapter = await this.getAdapter();
×
UNCOV
1753
                                if (adapterType == "Knex") {
×
UNCOV
1754
                                        await adapter.createTable();
×
1755
                                }
1756

UNCOV
1757
                                await this.clearEntities();
×
1758
                        }
1759
                });
1760

UNCOV
1761
                beforeAll(async () => {
×
UNCOV
1762
                        await broker.start();
×
UNCOV
1763
                        await svc.clearEntities();
×
1764
                });
UNCOV
1765
                afterAll(() => broker.stop());
×
1766

UNCOV
1767
                describe("Test create, replace", () => {
×
1768
                        let entity;
UNCOV
1769
                        it("should create entity without default fields", async () => {
×
UNCOV
1770
                                const res = await broker.call("users.create", {
×
1771
                                        name: "John Doe",
1772
                                        role: "admin",
1773
                                        status: 0
1774
                                });
UNCOV
1775
                                expect(res).toStrictEqual({
×
1776
                                        id: expectedID,
1777
                                        name: "John Doe",
1778
                                        role: "admin",
1779
                                        status: 0
1780
                                });
UNCOV
1781
                                entity = res;
×
1782

UNCOV
1783
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
1784
                                expect(res2).toStrictEqual(entity);
×
1785

UNCOV
1786
                                expect(getDefaultRole).toBeCalledTimes(0);
×
1787
                        });
1788

UNCOV
1789
                        it("should replace entity without default fields", async () => {
×
UNCOV
1790
                                const res = await broker.call("users.replace", {
×
1791
                                        id: entity.id,
1792
                                        name: "Jane Doe",
1793
                                        role: "guest",
1794
                                        status: 2
1795
                                });
UNCOV
1796
                                expect(res).toStrictEqual({
×
1797
                                        id: expectedID,
1798
                                        name: "Jane Doe",
1799
                                        role: "guest",
1800
                                        status: 2
1801
                                });
UNCOV
1802
                                entity = res;
×
1803

UNCOV
1804
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
1805
                                expect(res2).toStrictEqual(entity);
×
1806

UNCOV
1807
                                expect(getDefaultRole).toBeCalledTimes(0);
×
1808
                        });
1809

UNCOV
1810
                        it("should create entity with default fields", async () => {
×
UNCOV
1811
                                const res = await broker.call("users.create", {
×
1812
                                        name: "John Doe"
1813
                                });
UNCOV
1814
                                expect(res).toStrictEqual({
×
1815
                                        id: expectedID,
1816
                                        name: "John Doe",
1817
                                        role: "member",
1818
                                        status: 5
1819
                                });
UNCOV
1820
                                entity = res;
×
1821

UNCOV
1822
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
1823
                                expect(res2).toStrictEqual(entity);
×
1824

UNCOV
1825
                                expect(getDefaultRole).toBeCalledTimes(1);
×
UNCOV
1826
                                expect(getDefaultRole).toBeCalledWith({
×
1827
                                        operation: "create",
1828
                                        ctx: expect.any(Context),
1829
                                        value: undefined,
1830
                                        params: {
1831
                                                name: "John Doe",
1832
                                                status: 5
1833
                                        },
1834
                                        root: {
1835
                                                name: "John Doe",
1836
                                                status: 5
1837
                                        },
1838
                                        id: undefined,
1839
                                        entity: undefined,
1840
                                        field: svc.$fields[2]
1841
                                });
1842
                        });
1843

UNCOV
1844
                        it("should replace entity with default fields", async () => {
×
UNCOV
1845
                                getDefaultRole.mockClear();
×
UNCOV
1846
                                const res = await broker.call("users.replace", {
×
1847
                                        id: entity.id,
1848
                                        name: "Jane Doe"
1849
                                });
UNCOV
1850
                                expect(res).toStrictEqual({
×
1851
                                        id: expectedID,
1852
                                        name: "Jane Doe",
1853
                                        role: "member",
1854
                                        status: 5
1855
                                });
UNCOV
1856
                                entity = res;
×
1857

UNCOV
1858
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
1859
                                expect(res2).toStrictEqual(entity);
×
1860

UNCOV
1861
                                expect(getDefaultRole).toBeCalledTimes(1);
×
UNCOV
1862
                                expect(getDefaultRole).toBeCalledWith({
×
1863
                                        operation: "replace",
1864
                                        ctx: expect.any(Context),
1865
                                        value: undefined,
1866
                                        params: {
1867
                                                id: "" + entity.id,
1868
                                                name: "Jane Doe",
1869
                                                status: 5
1870
                                        },
1871
                                        root: {
1872
                                                id: "" + entity.id,
1873
                                                name: "Jane Doe",
1874
                                                status: 5
1875
                                        },
1876
                                        id: "" + entity.id,
1877
                                        entity: {
1878
                                                _id: ["MongoDB"].includes(adapterType) ? expect.any(ObjectId) : entity.id,
×
1879
                                                name: "John Doe",
1880
                                                role: "member",
1881
                                                status: 5
1882
                                        },
1883
                                        field: svc.$fields[2]
1884
                                });
1885
                        });
1886
                });
1887
        });
1888

UNCOV
1889
        describe("Test secure field", () => {
×
UNCOV
1890
                const broker = new ServiceBroker({ logger: false });
×
UNCOV
1891
                const svc = broker.createService({
×
1892
                        name: "users",
1893
                        mixins: [
1894
                                DbService({
1895
                                        adapter: getAdapter(),
1896
                                        createActions: true
1897
                                })
1898
                        ],
1899
                        settings: {
1900
                                fields: {
1901
                                        id: {
1902
                                                type: "string",
1903
                                                primaryKey: true,
1904
                                                secure: true,
1905
                                                columnName: "_id",
1906
                                                columnType: getAdapter.IdColumnType
1907
                                        },
1908
                                        name: { type: "string" }
1909
                                }
1910
                        },
1911
                        methods: {
1912
                                encodeID(id) {
UNCOV
1913
                                        return `SECURE-${id}`;
×
1914
                                },
1915
                                decodeID(id) {
UNCOV
1916
                                        if (!id.startsWith("SECURE-")) throw new Error("No secured ID");
×
UNCOV
1917
                                        return id.substring(7);
×
1918
                                }
1919
                        },
1920

1921
                        async started() {
UNCOV
1922
                                const adapter = await this.getAdapter();
×
UNCOV
1923
                                if (adapterType == "Knex") {
×
UNCOV
1924
                                        await adapter.createTable();
×
1925
                                }
1926

UNCOV
1927
                                await this.clearEntities();
×
1928
                        }
1929
                });
1930

UNCOV
1931
                beforeAll(async () => {
×
UNCOV
1932
                        await broker.start();
×
UNCOV
1933
                        await svc.clearEntities();
×
1934
                });
UNCOV
1935
                afterAll(() => broker.stop());
×
1936

UNCOV
1937
                describe("Test create, update, replace, remove", () => {
×
1938
                        let entity;
UNCOV
1939
                        it("should create entity", async () => {
×
UNCOV
1940
                                const res = await broker.call("users.create", {
×
1941
                                        name: "John"
1942
                                });
UNCOV
1943
                                expect(res).toStrictEqual({
×
1944
                                        id: expect.any(String),
1945
                                        name: "John"
1946
                                });
UNCOV
1947
                                expect(res.id.startsWith("SECURE-")).toBeTruthy();
×
UNCOV
1948
                                entity = res;
×
1949

UNCOV
1950
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
1951
                                expect(res2).toStrictEqual(entity);
×
1952
                        });
1953

UNCOV
1954
                        it("should update entity", async () => {
×
UNCOV
1955
                                const res = await broker.call("users.update", {
×
1956
                                        id: entity.id,
1957
                                        name: "John Doe"
1958
                                });
UNCOV
1959
                                expect(res).toStrictEqual({
×
1960
                                        id: expect.any(String),
1961
                                        name: "John Doe"
1962
                                });
UNCOV
1963
                                entity = res;
×
1964

UNCOV
1965
                                const res2 = await broker.call("users.resolve", { id: entity.id });
×
UNCOV
1966
                                expect(res2).toStrictEqual(entity);
×
1967
                        });
1968

UNCOV
1969
                        it("should replace entity", async () => {
×
UNCOV
1970
                                const res = await broker.call("users.replace", {
×
1971
                                        id: entity.id,
1972
                                        name: "Jane Doe"
1973
                                });
UNCOV
1974
                                expect(res).toStrictEqual({
×
1975
                                        id: expect.any(String),
1976
                                        name: "Jane Doe"
1977
                                });
UNCOV
1978
                                entity = res;
×
1979

UNCOV
1980
                                const res2 = await broker.call("users.resolve", { id: entity.id });
×
UNCOV
1981
                                expect(res2).toStrictEqual(entity);
×
1982
                        });
1983

UNCOV
1984
                        it("should remove entity", async () => {
×
UNCOV
1985
                                const res = await broker.call("users.remove", {
×
1986
                                        id: entity.id
1987
                                });
UNCOV
1988
                                expect(res).toBe(entity.id);
×
1989
                        });
1990
                });
1991
        });
1992

UNCOV
1993
        describe("Test with nested fields", () => {
×
UNCOV
1994
                const broker = new ServiceBroker({ logger: false });
×
UNCOV
1995
                const svc = broker.createService({
×
1996
                        name: "users",
1997
                        mixins: [
1998
                                DbService({
1999
                                        adapter: getAdapter(),
2000
                                        createActions: true
2001
                                })
2002
                        ],
2003
                        settings: {
2004
                                fields: {
2005
                                        id: {
2006
                                                type: "string",
2007
                                                primaryKey: true,
2008
                                                columnName: "_id",
2009
                                                columnType: getAdapter.IdColumnType
2010
                                        },
2011
                                        name: { type: "string" },
2012
                                        email: { type: "string" },
2013
                                        address: {
2014
                                                type: "object",
2015
                                                columnType: "string",
2016
                                                columnLength: 1000,
2017
                                                properties: {
2018
                                                        zip: { type: "number" },
2019
                                                        street: { type: "string" },
2020
                                                        state: { type: "string", optional: true },
2021
                                                        city: { type: "string", required: true },
2022
                                                        country: { type: "string" },
2023
                                                        primary: { type: "boolean", default: true }
2024
                                                }
2025
                                        },
2026
                                        roles: {
2027
                                                type: "array",
2028
                                                columnType: "string",
2029
                                                columnLength: 1000,
2030
                                                max: 3,
2031
                                                items: { type: "string" }
2032
                                        },
2033

2034
                                        phones: {
2035
                                                type: "array",
2036
                                                columnType: "string",
2037
                                                columnLength: 1000,
2038
                                                items: {
2039
                                                        type: "object",
2040
                                                        properties: {
2041
                                                                type: "string",
2042
                                                                number: { type: "string", required: true },
2043
                                                                primary: { type: "boolean", default: false }
2044
                                                        }
2045
                                                }
2046
                                        }
2047
                                }
2048
                        },
2049

2050
                        async started() {
UNCOV
2051
                                const adapter = await this.getAdapter();
×
UNCOV
2052
                                if (adapterType == "Knex") {
×
UNCOV
2053
                                        await adapter.createTable();
×
2054
                                }
2055

UNCOV
2056
                                await this.clearEntities();
×
2057
                        }
2058
                });
2059

UNCOV
2060
                beforeAll(async () => {
×
UNCOV
2061
                        await broker.start();
×
UNCOV
2062
                        await svc.clearEntities();
×
2063
                });
UNCOV
2064
                afterAll(() => broker.stop());
×
2065

UNCOV
2066
                describe("Test nested object", () => {
×
2067
                        let entity;
2068

UNCOV
2069
                        it("should throw error if a nested field is missing", async () => {
×
UNCOV
2070
                                expect.assertions(2);
×
UNCOV
2071
                                try {
×
UNCOV
2072
                                        await broker.call("users.create", {
×
2073
                                                name: "John Doe",
2074
                                                email: "john.doe@moleculer.services",
2075
                                                address: {
2076
                                                        zip: "1234"
2077
                                                }
2078
                                        });
2079
                                } catch (err) {
UNCOV
2080
                                        expect(err).toBeInstanceOf(ValidationError);
×
UNCOV
2081
                                        expect(err.data).toEqual([
×
2082
                                                {
2083
                                                        actual: undefined,
2084
                                                        field: "address.city",
2085
                                                        message: "The 'address.city' field is required.",
2086
                                                        type: "required",
2087
                                                        action: "users.create",
2088
                                                        nodeID: broker.nodeID
2089
                                                }
2090
                                        ]);
2091
                                }
2092
                        });
2093

UNCOV
2094
                        it("should throw error if an array is not array", async () => {
×
UNCOV
2095
                                expect.assertions(2);
×
UNCOV
2096
                                try {
×
UNCOV
2097
                                        await broker.call("users.create", {
×
2098
                                                name: "John Doe",
2099
                                                email: "john.doe@moleculer.services",
2100
                                                roles: "admin"
2101
                                        });
2102
                                } catch (err) {
UNCOV
2103
                                        expect(err).toBeInstanceOf(ValidationError);
×
UNCOV
2104
                                        expect(err.data).toEqual([
×
2105
                                                {
2106
                                                        actual: "admin",
2107
                                                        field: "roles",
2108
                                                        message: "The 'roles' field must be an array.",
2109
                                                        type: "array",
2110
                                                        action: "users.create",
2111
                                                        nodeID: broker.nodeID
2112
                                                }
2113
                                        ]);
2114
                                }
2115
                        });
2116

UNCOV
2117
                        it("should throw error if an object is not valid in the array", async () => {
×
UNCOV
2118
                                expect.assertions(2);
×
UNCOV
2119
                                try {
×
UNCOV
2120
                                        await broker.call("users.create", {
×
2121
                                                name: "John Doe",
2122
                                                email: "john.doe@moleculer.services",
2123
                                                phones: [{ type: "home" }]
2124
                                        });
2125
                                } catch (err) {
UNCOV
2126
                                        expect(err).toBeInstanceOf(ValidationError);
×
UNCOV
2127
                                        expect(err.data).toEqual([
×
2128
                                                {
2129
                                                        actual: undefined,
2130
                                                        field: "phones[0].number",
2131
                                                        message: "The 'phones[0].number' field is required.",
2132
                                                        type: "required",
2133
                                                        action: "users.create",
2134
                                                        nodeID: broker.nodeID
2135
                                                }
2136
                                        ]);
2137
                                }
2138
                        });
2139

UNCOV
2140
                        it("create test entity", async () => {
×
UNCOV
2141
                                const res = await broker.call("users.create", {
×
2142
                                        name: "John Doe",
2143
                                        email: "john.doe@moleculer.services",
2144
                                        address: {
2145
                                                zip: "1234",
2146
                                                street: "Main Street 15",
2147
                                                city: "London",
2148
                                                country: "England",
2149
                                                extra: "some"
2150
                                        },
2151
                                        roles: ["admin", 1234],
2152
                                        phones: [
2153
                                                { type: "home", number: "+1-555-1234", primary: true },
2154
                                                { type: "mobile", number: "+1-555-9999" }
2155
                                        ]
2156
                                });
UNCOV
2157
                                expect(res).toStrictEqual({
×
2158
                                        id: expectedID,
2159
                                        name: "John Doe",
2160
                                        email: "john.doe@moleculer.services",
2161
                                        address: {
2162
                                                zip: 1234,
2163
                                                street: "Main Street 15",
2164
                                                city: "London",
2165
                                                country: "England",
2166
                                                primary: true
2167
                                        },
2168
                                        roles: ["admin", "1234"],
2169
                                        phones: [
2170
                                                { type: "home", number: "+1-555-1234", primary: true },
2171
                                                { type: "mobile", number: "+1-555-9999", primary: false }
2172
                                        ]
2173
                                });
UNCOV
2174
                                entity = res;
×
2175

UNCOV
2176
                                const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
2177
                                expect(res2).toStrictEqual(entity);
×
2178
                        });
2179

UNCOV
2180
                        if (getAdapter.isNoSQL) {
×
UNCOV
2181
                                it("update a nested property in the entity", async () => {
×
UNCOV
2182
                                        const res = await broker.call("users.update", {
×
2183
                                                id: entity.id,
2184
                                                name: "Dr. John Doe",
2185
                                                address: {
2186
                                                        zip: "9999"
2187
                                                }
2188
                                        });
2189

UNCOV
2190
                                        expect(res).toStrictEqual({
×
2191
                                                id: expectedID,
2192
                                                name: "Dr. John Doe",
2193
                                                email: "john.doe@moleculer.services",
2194
                                                address: {
2195
                                                        zip: 9999,
2196
                                                        street: "Main Street 15",
2197
                                                        city: "London",
2198
                                                        country: "England",
2199
                                                        primary: true
2200
                                                },
2201
                                                roles: ["admin", "1234"],
2202
                                                phones: [
2203
                                                        { type: "home", number: "+1-555-1234", primary: true },
2204
                                                        { type: "mobile", number: "+1-555-9999", primary: false }
2205
                                                ]
2206
                                        });
UNCOV
2207
                                        entity = res;
×
2208

UNCOV
2209
                                        const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
2210
                                        expect(res2).toStrictEqual(entity);
×
2211
                                });
2212
                        }
2213
                });
2214
        });
2215

UNCOV
2216
        describe("Test with very strict schema", () => {
×
UNCOV
2217
                const broker = new ServiceBroker({ logger: false });
×
UNCOV
2218
                const svc = broker.createService({
×
2219
                        name: "users",
2220
                        mixins: [
2221
                                DbService({
2222
                                        adapter: getAdapter(),
2223
                                        createActions: true,
2224
                                        strict: true
2225
                                })
2226
                        ],
2227
                        settings: {
2228
                                fields: {
2229
                                        id: {
2230
                                                type: "string",
2231
                                                primaryKey: true,
2232
                                                columnName: "_id",
2233
                                                columnType: getAdapter.IdColumnType
2234
                                        },
2235
                                        name: { type: "string" },
2236
                                        email: { type: "string" }
2237
                                }
2238
                        },
2239

2240
                        async started() {
UNCOV
2241
                                const adapter = await this.getAdapter();
×
UNCOV
2242
                                if (adapterType == "Knex") {
×
UNCOV
2243
                                        await adapter.createTable();
×
2244
                                }
2245

UNCOV
2246
                                await this.clearEntities();
×
2247
                        }
2248
                });
2249

UNCOV
2250
                beforeAll(async () => {
×
UNCOV
2251
                        await broker.start();
×
UNCOV
2252
                        await svc.clearEntities();
×
2253
                });
UNCOV
2254
                afterAll(() => broker.stop());
×
2255

2256
                let entity;
2257

UNCOV
2258
                it("should throw error if it contains extra field", async () => {
×
UNCOV
2259
                        expect.assertions(2);
×
UNCOV
2260
                        try {
×
UNCOV
2261
                                await broker.call("users.create", {
×
2262
                                        name: "John Doe",
2263
                                        email: "john.doe@moleculer.services",
2264
                                        age: 30
2265
                                });
2266
                        } catch (err) {
UNCOV
2267
                                expect(err).toBeInstanceOf(ValidationError);
×
UNCOV
2268
                                expect(err.data).toEqual([
×
2269
                                        {
2270
                                                actual: "age",
2271
                                                expected: "name, email",
2272
                                                field: undefined,
2273
                                                message: "The object '' contains forbidden keys: 'age'.",
2274
                                                type: "objectStrict",
2275
                                                action: "users.create",
2276
                                                nodeID: broker.nodeID
2277
                                        }
2278
                                ]);
2279
                        }
2280
                });
2281

UNCOV
2282
                it("create test entity", async () => {
×
UNCOV
2283
                        const res = await broker.call("users.create", {
×
2284
                                name: "John Doe",
2285
                                email: "john.doe@moleculer.services"
2286
                        });
UNCOV
2287
                        expect(res).toStrictEqual({
×
2288
                                id: expectedID,
2289
                                name: "John Doe",
2290
                                email: "john.doe@moleculer.services"
2291
                        });
UNCOV
2292
                        entity = res;
×
2293

UNCOV
2294
                        const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
2295
                        expect(res2).toStrictEqual(entity);
×
2296
                });
2297

UNCOV
2298
                it("should throw error when update with an extra property", async () => {
×
UNCOV
2299
                        expect.assertions(2);
×
UNCOV
2300
                        try {
×
UNCOV
2301
                                await broker.call("users.update", {
×
2302
                                        id: entity.id,
2303
                                        name: "Dr. John Doe",
2304
                                        age: 30
2305
                                });
2306
                        } catch (err) {
UNCOV
2307
                                expect(err).toBeInstanceOf(ValidationError);
×
UNCOV
2308
                                expect(err.data).toEqual([
×
2309
                                        {
2310
                                                actual: "age",
2311
                                                expected: "id, name, email",
2312
                                                field: undefined,
2313
                                                message: "The object '' contains forbidden keys: 'age'.",
2314
                                                type: "objectStrict",
2315
                                                action: "users.update",
2316
                                                nodeID: broker.nodeID
2317
                                        }
2318
                                ]);
2319
                        }
2320
                });
2321

UNCOV
2322
                it("update entity", async () => {
×
UNCOV
2323
                        const res = await broker.call("users.update", {
×
2324
                                id: entity.id,
2325
                                name: "Dr. John Doe"
2326
                        });
2327

UNCOV
2328
                        expect(res).toStrictEqual({
×
2329
                                id: expectedID,
2330
                                name: "Dr. John Doe",
2331
                                email: "john.doe@moleculer.services"
2332
                        });
UNCOV
2333
                        entity = res;
×
2334

UNCOV
2335
                        const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
2336
                        expect(res2).toStrictEqual(entity);
×
2337
                });
2338

UNCOV
2339
                it("should throw error when replace with an extra property", async () => {
×
UNCOV
2340
                        expect.assertions(2);
×
UNCOV
2341
                        try {
×
UNCOV
2342
                                await broker.call("users.replace", {
×
2343
                                        id: entity.id,
2344
                                        name: "Mr. John Doe",
2345
                                        email: "john.doe@moleculer.services",
2346
                                        age: 30
2347
                                });
2348
                        } catch (err) {
UNCOV
2349
                                expect(err).toBeInstanceOf(ValidationError);
×
UNCOV
2350
                                expect(err.data).toEqual([
×
2351
                                        {
2352
                                                actual: "age",
2353
                                                expected: "id, name, email",
2354
                                                field: undefined,
2355
                                                message: "The object '' contains forbidden keys: 'age'.",
2356
                                                type: "objectStrict",
2357
                                                action: "users.replace",
2358
                                                nodeID: broker.nodeID
2359
                                        }
2360
                                ]);
2361
                        }
2362
                });
2363

UNCOV
2364
                it("replace entity", async () => {
×
UNCOV
2365
                        const res = await broker.call("users.replace", {
×
2366
                                id: entity.id,
2367
                                name: "Mr. John Doe",
2368
                                email: "john.doe@moleculer.services"
2369
                        });
2370

UNCOV
2371
                        expect(res).toStrictEqual({
×
2372
                                id: expectedID,
2373
                                name: "Mr. John Doe",
2374
                                email: "john.doe@moleculer.services"
2375
                        });
UNCOV
2376
                        entity = res;
×
2377

UNCOV
2378
                        const res2 = await broker.call("users.get", { id: entity.id });
×
UNCOV
2379
                        expect(res2).toStrictEqual(entity);
×
2380
                });
2381
        });
2382

UNCOV
2383
        describe("Test generated validator schemas in action definitions", () => {
×
UNCOV
2384
                const broker = new ServiceBroker({ logger: false });
×
UNCOV
2385
                const svc = broker.createService({
×
2386
                        name: "users",
2387
                        mixins: [
2388
                                DbService({
2389
                                        adapter: getAdapter(),
2390
                                        createActions: true,
2391
                                        cache: {
2392
                                                additionalKeys: ["#userID"]
2393
                                        }
2394
                                })
2395
                        ],
2396
                        settings: {
2397
                                fields: {
2398
                                        key: {
2399
                                                type: "string",
2400
                                                primaryKey: true,
2401
                                                columnName: "_id",
2402
                                                columnType: getAdapter.IdColumnType
2403
                                        },
2404
                                        name: "string|required",
2405
                                        email: "email|columnType:string",
2406
                                        address: {
2407
                                                type: "object",
2408
                                                columnType: "string",
2409
                                                strict: true,
2410
                                                properties: {
2411
                                                        zip: { type: "number" },
2412
                                                        street: { type: "string" },
2413
                                                        state: { type: "string", optional: true },
2414
                                                        city: { type: "string", required: true },
2415
                                                        country: { type: "string" },
2416
                                                        primary: { type: "boolean", default: true }
2417
                                                }
2418
                                        },
2419
                                        roles: {
2420
                                                type: "array",
2421
                                                columnType: "string",
2422
                                                max: 3,
2423
                                                items: { type: "string" }
2424
                                        },
2425

2426
                                        phones: {
2427
                                                type: "array",
2428
                                                columnType: "string",
2429
                                                items: {
2430
                                                        type: "object",
2431
                                                        properties: {
2432
                                                                type: "string",
2433
                                                                number: { type: "string", required: true },
2434
                                                                primary: { type: "boolean", default: false }
2435
                                                        }
2436
                                                }
2437
                                        },
2438

2439
                                        status: { type: "boolean", default: true }
2440
                                }
2441
                        },
2442

2443
                        async started() {
UNCOV
2444
                                const adapter = await this.getAdapter();
×
UNCOV
2445
                                if (adapterType == "Knex") {
×
UNCOV
2446
                                        await adapter.createTable();
×
2447
                                }
2448

UNCOV
2449
                                await this.clearEntities();
×
2450
                        }
2451
                });
2452

UNCOV
2453
                beforeAll(async () => {
×
UNCOV
2454
                        await broker.start();
×
UNCOV
2455
                        await svc.clearEntities();
×
2456
                });
UNCOV
2457
                afterAll(() => broker.stop());
×
2458

UNCOV
2459
                it("check 'create' action", async () => {
×
UNCOV
2460
                        expect(svc.schema.actions.create).toEqual({
×
2461
                                handler: expect.any(Function),
2462
                                rest: "POST /",
2463
                                visibility: "published",
2464
                                params: {
2465
                                        $$strict: "remove",
2466
                                        name: { convert: true, type: "string" },
2467
                                        email: { optional: true, type: "email", columnType: "string" },
2468
                                        address: {
2469
                                                optional: true,
2470
                                                columnType: "string",
2471
                                                properties: {
2472
                                                        city: { convert: true, type: "string" },
2473
                                                        country: { convert: true, optional: true, type: "string" },
2474
                                                        primary: {
2475
                                                                convert: true,
2476
                                                                default: true,
2477
                                                                optional: true,
2478
                                                                type: "boolean"
2479
                                                        },
2480
                                                        state: { convert: true, optional: true, type: "string" },
2481
                                                        street: { convert: true, optional: true, type: "string" },
2482
                                                        zip: { convert: true, optional: true, type: "number" }
2483
                                                },
2484
                                                strict: "remove",
2485
                                                type: "object"
2486
                                        },
2487
                                        phones: {
2488
                                                items: {
2489
                                                        optional: true,
2490
                                                        properties: {
2491
                                                                number: { convert: true, type: "string" },
2492
                                                                primary: {
2493
                                                                        convert: true,
2494
                                                                        default: false,
2495
                                                                        optional: true,
2496
                                                                        type: "boolean"
2497
                                                                },
2498
                                                                type: { convert: true, optional: true, type: "string" }
2499
                                                        },
2500
                                                        strict: "remove",
2501
                                                        type: "object"
2502
                                                },
2503
                                                optional: true,
2504
                                                columnType: "string",
2505
                                                type: "array"
2506
                                        },
2507
                                        roles: {
2508
                                                items: { convert: true, optional: true, type: "string" },
2509
                                                max: 3,
2510
                                                optional: true,
2511
                                                columnType: "string",
2512
                                                type: "array"
2513
                                        },
2514
                                        status: { convert: true, default: true, optional: true, type: "boolean" }
2515
                                }
2516
                        });
2517
                });
2518

UNCOV
2519
                it("check 'update' action", async () => {
×
UNCOV
2520
                        expect(svc.schema.actions.update).toEqual({
×
2521
                                handler: expect.any(Function),
2522
                                rest: "PATCH /:key",
2523
                                visibility: "published",
2524
                                params: {
2525
                                        $$strict: "remove",
2526
                                        key: {
2527
                                                convert: true,
2528
                                                optional: false,
2529
                                                type: "string",
2530
                                                columnType: getAdapter.IdColumnType
2531
                                        },
2532
                                        name: { convert: true, optional: true, type: "string" },
2533
                                        email: { optional: true, type: "email", columnType: "string" },
2534
                                        address: {
2535
                                                optional: true,
2536
                                                columnType: "string",
2537
                                                properties: {
2538
                                                        city: { convert: true, optional: true, type: "string" },
2539
                                                        country: { convert: true, optional: true, type: "string" },
2540
                                                        primary: { convert: true, optional: true, type: "boolean" },
2541
                                                        state: { convert: true, optional: true, type: "string" },
2542
                                                        street: { convert: true, optional: true, type: "string" },
2543
                                                        zip: { convert: true, optional: true, type: "number" }
2544
                                                },
2545
                                                strict: "remove",
2546
                                                type: "object"
2547
                                        },
2548
                                        phones: {
2549
                                                items: {
2550
                                                        optional: true,
2551
                                                        properties: {
2552
                                                                number: { convert: true, optional: true, type: "string" },
2553
                                                                primary: { convert: true, optional: true, type: "boolean" },
2554
                                                                type: { convert: true, optional: true, type: "string" }
2555
                                                        },
2556
                                                        strict: "remove",
2557
                                                        type: "object"
2558
                                                },
2559
                                                optional: true,
2560
                                                columnType: "string",
2561
                                                type: "array"
2562
                                        },
2563
                                        roles: {
2564
                                                items: { convert: true, optional: true, type: "string" },
2565
                                                max: 3,
2566
                                                optional: true,
2567
                                                columnType: "string",
2568
                                                type: "array"
2569
                                        },
2570
                                        status: { convert: true, optional: true, type: "boolean" }
2571
                                }
2572
                        });
2573
                });
2574

UNCOV
2575
                it("check 'replace' action", async () => {
×
UNCOV
2576
                        expect(svc.schema.actions.replace).toEqual({
×
2577
                                handler: expect.any(Function),
2578
                                rest: "PUT /:key",
2579
                                visibility: "published",
2580
                                params: {
2581
                                        $$strict: "remove",
2582
                                        key: {
2583
                                                convert: true,
2584
                                                optional: false,
2585
                                                type: "string",
2586
                                                columnType: getAdapter.IdColumnType
2587
                                        },
2588
                                        name: { convert: true, type: "string" },
2589
                                        email: { optional: true, type: "email", columnType: "string" },
2590
                                        address: {
2591
                                                optional: true,
2592
                                                columnType: "string",
2593
                                                properties: {
2594
                                                        city: { convert: true, type: "string" },
2595
                                                        country: { convert: true, optional: true, type: "string" },
2596
                                                        primary: {
2597
                                                                convert: true,
2598
                                                                default: true,
2599
                                                                optional: true,
2600
                                                                type: "boolean"
2601
                                                        },
2602
                                                        state: { convert: true, optional: true, type: "string" },
2603
                                                        street: { convert: true, optional: true, type: "string" },
2604
                                                        zip: { convert: true, optional: true, type: "number" }
2605
                                                },
2606
                                                strict: "remove",
2607
                                                type: "object"
2608
                                        },
2609
                                        phones: {
2610
                                                items: {
2611
                                                        optional: true,
2612
                                                        properties: {
2613
                                                                number: { convert: true, type: "string" },
2614
                                                                primary: {
2615
                                                                        convert: true,
2616
                                                                        default: false,
2617
                                                                        optional: true,
2618
                                                                        type: "boolean"
2619
                                                                },
2620
                                                                type: { convert: true, optional: true, type: "string" }
2621
                                                        },
2622
                                                        strict: "remove",
2623
                                                        type: "object"
2624
                                                },
2625
                                                optional: true,
2626
                                                columnType: "string",
2627
                                                type: "array"
2628
                                        },
2629
                                        roles: {
2630
                                                items: { convert: true, optional: true, type: "string" },
2631
                                                max: 3,
2632
                                                optional: true,
2633
                                                columnType: "string",
2634
                                                type: "array"
2635
                                        },
2636
                                        status: { convert: true, default: true, optional: true, type: "boolean" }
2637
                                }
2638
                        });
2639
                });
2640

UNCOV
2641
                it("check 'get' action", async () => {
×
UNCOV
2642
                        expect(svc.schema.actions.get).toEqual({
×
2643
                                handler: expect.any(Function),
2644
                                cache: { enabled: true, keys: ["key", "fields", "scope", "populate", "#userID"] },
2645
                                rest: "GET /:key",
2646
                                visibility: "published",
2647
                                params: {
2648
                                        fields: [
2649
                                                { optional: true, type: "string" },
2650
                                                { items: "string", optional: true, type: "array" }
2651
                                        ],
2652
                                        key: { type: "string", convert: true },
2653
                                        populate: [
2654
                                                { optional: true, type: "string" },
2655
                                                { items: "string", optional: true, type: "array" }
2656
                                        ],
2657
                                        scope: [
2658
                                                { optional: true, type: "boolean" },
2659
                                                { optional: true, type: "string" },
2660
                                                { items: "string", optional: true, type: "array" }
2661
                                        ]
2662
                                }
2663
                        });
2664
                });
2665

UNCOV
2666
                it("check 'resolve' action", async () => {
×
UNCOV
2667
                        expect(svc.schema.actions.resolve).toEqual({
×
2668
                                handler: expect.any(Function),
2669
                                cache: {
2670
                                        enabled: true,
2671
                                        keys: [
2672
                                                "key",
2673
                                                "fields",
2674
                                                "scope",
2675
                                                "populate",
2676
                                                "mapping",
2677
                                                "throwIfNotExist",
2678
                                                "reorderResult",
2679
                                                "#userID"
2680
                                        ]
2681
                                },
2682
                                visibility: "published",
2683
                                params: {
2684
                                        fields: [
2685
                                                { optional: true, type: "string" },
2686
                                                { items: "string", optional: true, type: "array" }
2687
                                        ],
2688
                                        key: [
2689
                                                { items: { type: "string", convert: true }, type: "array" },
2690
                                                { type: "string", convert: true }
2691
                                        ],
2692
                                        mapping: { optional: true, type: "boolean" },
2693
                                        populate: [
2694
                                                { optional: true, type: "string" },
2695
                                                { items: "string", optional: true, type: "array" }
2696
                                        ],
2697
                                        scope: [
2698
                                                { optional: true, type: "boolean" },
2699
                                                { optional: true, type: "string" },
2700
                                                { items: "string", optional: true, type: "array" }
2701
                                        ],
2702
                                        throwIfNotExist: { optional: true, type: "boolean" },
2703
                                        reorderResult: { optional: true, type: "boolean" }
2704
                                }
2705
                        });
2706
                });
2707

UNCOV
2708
                it("check 'remove' action", async () => {
×
UNCOV
2709
                        expect(svc.schema.actions.remove).toEqual({
×
2710
                                handler: expect.any(Function),
2711
                                rest: "DELETE /:key",
2712
                                visibility: "published",
2713
                                params: {
2714
                                        key: {
2715
                                                type: "string",
2716
                                                convert: true
2717
                                        }
2718
                                }
2719
                        });
2720
                });
2721

UNCOV
2722
                it("check 'find' action", async () => {
×
UNCOV
2723
                        expect(svc.schema.actions.find).toEqual({
×
2724
                                handler: expect.any(Function),
2725
                                rest: "GET /all",
2726
                                visibility: "published",
2727
                                cache: {
2728
                                        enabled: true,
2729
                                        keys: [
2730
                                                "limit",
2731
                                                "offset",
2732
                                                "fields",
2733
                                                "sort",
2734
                                                "search",
2735
                                                "searchFields",
2736
                                                "collation",
2737
                                                "scope",
2738
                                                "populate",
2739
                                                "query",
2740
                                                "#userID"
2741
                                        ]
2742
                                },
2743
                                params: {
2744
                                        collation: { optional: true, type: "object" },
2745
                                        fields: [
2746
                                                { optional: true, type: "string" },
2747
                                                { items: "string", optional: true, type: "array" }
2748
                                        ],
2749
                                        limit: {
2750
                                                convert: true,
2751
                                                integer: true,
2752
                                                max: null,
2753
                                                min: 0,
2754
                                                optional: true,
2755
                                                type: "number"
2756
                                        },
2757
                                        offset: {
2758
                                                convert: true,
2759
                                                integer: true,
2760
                                                min: 0,
2761
                                                optional: true,
2762
                                                type: "number"
2763
                                        },
2764
                                        populate: [
2765
                                                { optional: true, type: "string" },
2766
                                                { items: "string", optional: true, type: "array" }
2767
                                        ],
2768
                                        query: [
2769
                                                { optional: true, type: "object" },
2770
                                                { optional: true, type: "string" }
2771
                                        ],
2772
                                        scope: [
2773
                                                { optional: true, type: "boolean" },
2774
                                                { optional: true, type: "string" },
2775
                                                { items: "string", optional: true, type: "array" }
2776
                                        ],
2777
                                        search: { optional: true, type: "string" },
2778
                                        searchFields: [
2779
                                                { optional: true, type: "string" },
2780
                                                { items: "string", optional: true, type: "array" }
2781
                                        ],
2782
                                        sort: [
2783
                                                { optional: true, type: "string" },
2784
                                                { items: "string", optional: true, type: "array" }
2785
                                        ]
2786
                                }
2787
                        });
2788
                });
2789

UNCOV
2790
                it("check 'list' action", async () => {
×
UNCOV
2791
                        expect(svc.schema.actions.list).toEqual({
×
2792
                                handler: expect.any(Function),
2793
                                rest: "GET /",
2794
                                visibility: "published",
2795
                                cache: {
2796
                                        enabled: true,
2797
                                        keys: [
2798
                                                "page",
2799
                                                "pageSize",
2800
                                                "fields",
2801
                                                "sort",
2802
                                                "search",
2803
                                                "searchFields",
2804
                                                "collation",
2805
                                                "scope",
2806
                                                "populate",
2807
                                                "query",
2808
                                                "#userID"
2809
                                        ]
2810
                                },
2811
                                params: {
2812
                                        collation: { optional: true, type: "object" },
2813
                                        fields: [
2814
                                                { optional: true, type: "string" },
2815
                                                { items: "string", optional: true, type: "array" }
2816
                                        ],
2817
                                        page: { convert: true, integer: true, min: 1, optional: true, type: "number" },
2818
                                        pageSize: {
2819
                                                convert: true,
2820
                                                integer: true,
2821
                                                max: null,
2822
                                                min: 1,
2823
                                                optional: true,
2824
                                                type: "number"
2825
                                        },
2826
                                        populate: [
2827
                                                { optional: true, type: "string" },
2828
                                                { items: "string", optional: true, type: "array" }
2829
                                        ],
2830
                                        query: [
2831
                                                { optional: true, type: "object" },
2832
                                                { optional: true, type: "string" }
2833
                                        ],
2834
                                        scope: [
2835
                                                { optional: true, type: "boolean" },
2836
                                                { optional: true, type: "string" },
2837
                                                { items: "string", optional: true, type: "array" }
2838
                                        ],
2839
                                        search: { optional: true, type: "string" },
2840
                                        searchFields: [
2841
                                                { optional: true, type: "string" },
2842
                                                { items: "string", optional: true, type: "array" }
2843
                                        ],
2844
                                        sort: [
2845
                                                { optional: true, type: "string" },
2846
                                                { items: "string", optional: true, type: "array" }
2847
                                        ]
2848
                                }
2849
                        });
2850
                });
2851

UNCOV
2852
                it("check 'count' action", async () => {
×
UNCOV
2853
                        expect(svc.schema.actions.count).toEqual({
×
2854
                                handler: expect.any(Function),
2855
                                cache: {
2856
                                        enabled: true,
2857
                                        keys: ["search", "searchFields", "scope", "query", "#userID"]
2858
                                },
2859
                                rest: "GET /count",
2860
                                visibility: "published",
2861
                                params: {
2862
                                        query: [
2863
                                                { optional: true, type: "object" },
2864
                                                { optional: true, type: "string" }
2865
                                        ],
2866
                                        scope: [
2867
                                                { optional: true, type: "boolean" },
2868
                                                { optional: true, type: "string" },
2869
                                                { items: "string", optional: true, type: "array" }
2870
                                        ],
2871
                                        search: { optional: true, type: "string" },
2872
                                        searchFields: [
2873
                                                { optional: true, type: "string" },
2874
                                                { items: "string", optional: true, type: "array" }
2875
                                        ]
2876
                                }
2877
                        });
2878
                });
2879
        });
2880
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc