• 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

1.09
/test/integration/methods.test.js
1
"use strict";
2

3
const { ServiceBroker, Context } = require("moleculer");
1✔
4
const { MoleculerClientError, ValidationError } = require("moleculer").Errors;
1✔
5
const { EntityNotFoundError } = require("../../src/errors");
1✔
6
const { addExpectAnyFields } = require("./utils");
1✔
7
const { Stream } = require("stream");
1✔
8
const DbService = require("../..").Service;
1✔
9

10
const TEST_DOCS = {
1✔
11
        johnDoe: {
12
                name: "John Doe",
13
                age: 42,
14
                status: true,
15
                dob: Date.parse("1980-10-07T00:00:00"),
16
                roles: ["admin", "user"]
17
        },
18

19
        janeDoe: {
20
                name: "Jane Doe",
21
                age: 35,
22
                status: false,
23
                dob: Date.parse("1986-03-03T00:00:00"),
24
                roles: ["moderator"]
25
        },
26

27
        bobSmith: {
28
                name: "Bob Smith",
29
                age: 58,
30
                status: true,
31
                dob: Date.parse("1964-04-22T00:00:00"),
32
                roles: ["user"]
33
        },
34

35
        kevinJames: {
36
                name: "Kevin James",
37
                age: 49,
38
                status: false,
39
                dob: Date.parse("1976-12-10T00:00:00"),
40
                roles: ["guest"]
41
        }
42
};
43

44
module.exports = (getAdapter, adapterType) => {
1✔
45
        let expectedID;
UNCOV
46
        if (["Knex"].includes(adapterType)) {
×
UNCOV
47
                expectedID = expect.any(Number);
×
48
        } else {
UNCOV
49
                expectedID = expect.any(String);
×
50
        }
51

UNCOV
52
        describe("Test findEntity, findEntities & countEntities method", () => {
×
UNCOV
53
                const broker = new ServiceBroker({ logger: false });
×
UNCOV
54
                const svc = broker.createService({
×
55
                        name: "users",
56
                        mixins: [DbService({ adapter: getAdapter(), createActions: false })],
57

58
                        settings: {
59
                                fields: {
60
                                        id: { type: "string", primaryKey: true, columnName: "_id" },
61
                                        name: { type: "string", trim: true, required: true, columnName: "full_name" },
62
                                        age: { type: "number", columnType: "integer", columnName: "ages" },
63
                                        dob: {
64
                                                type: "number",
65
                                                columnType: "bigInteger",
UNCOV
66
                                                get: ({ value }) => (typeof value == "string" ? Number(value) : value)
×
67
                                        },
68
                                        roles: { type: "array", items: "string", columnType: "string" },
69
                                        status: {
70
                                                type: "boolean",
71
                                                default: true,
UNCOV
72
                                                get: adapterType == "Knex" ? ({ value }) => !!value : undefined
×
73
                                        },
74
                                        _score: { type: "number", readonly: true, virtual: true }
75
                                }
76
                        },
77

78
                        async started() {
UNCOV
79
                                const adapter = await this.getAdapter();
×
80

UNCOV
81
                                if (adapterType == "Knex") {
×
UNCOV
82
                                        await adapter.createTable();
×
UNCOV
83
                                } else if (adapterType == "MongoDB") {
×
UNCOV
84
                                        this.createIndex(adapter, {
×
85
                                                fields: { name: "text", age: "text", roles: "text" }
86
                                        });
87
                                }
88

UNCOV
89
                                await this.clearEntities();
×
90
                        }
91
                });
92

UNCOV
93
                beforeAll(() => broker.start());
×
UNCOV
94
                afterAll(() => broker.stop());
×
95

UNCOV
96
                const ctx = Context.create(broker, null, {});
×
UNCOV
97
                let docs = {};
×
98

UNCOV
99
                describe("Set up", () => {
×
UNCOV
100
                        it("should return empty array", async () => {
×
UNCOV
101
                                const rows = await svc.findEntities(ctx);
×
UNCOV
102
                                expect(rows).toEqual([]);
×
103

UNCOV
104
                                const count = await svc.countEntities(ctx);
×
UNCOV
105
                                expect(count).toEqual(0);
×
106
                        });
107

UNCOV
108
                        it("create test entities", async () => {
×
UNCOV
109
                                for (const [key, value] of Object.entries(TEST_DOCS)) {
×
UNCOV
110
                                        docs[key] = await svc.createEntity(ctx, Object.assign({}, value));
×
111
                                }
UNCOV
112
                                expect(docs.johnDoe).toEqual({ ...TEST_DOCS.johnDoe, id: expectedID });
×
UNCOV
113
                                expect(docs.janeDoe).toEqual({ ...TEST_DOCS.janeDoe, id: expectedID });
×
UNCOV
114
                                expect(docs.bobSmith).toEqual({ ...TEST_DOCS.bobSmith, id: expectedID });
×
UNCOV
115
                                expect(docs.kevinJames).toEqual({
×
116
                                        ...TEST_DOCS.kevinJames,
117
                                        id: expectedID
118
                                });
119
                        });
120
                });
121

UNCOV
122
                describe("Test sort, limit, offset", () => {
×
UNCOV
123
                        it("should return all rows", async () => {
×
UNCOV
124
                                const rows = await svc.findEntities(ctx, {});
×
UNCOV
125
                                expect(rows).toEqual(expect.arrayContaining(Object.values(docs)));
×
126

UNCOV
127
                                const count = await svc.countEntities(ctx, {});
×
UNCOV
128
                                expect(count).toEqual(4);
×
129
                        });
130

UNCOV
131
                        it("should sort & limit rows", async () => {
×
UNCOV
132
                                const params = { sort: "age", limit: 2 };
×
UNCOV
133
                                const rows = await svc.findEntities(ctx, params);
×
UNCOV
134
                                expect(rows).toEqual([docs.janeDoe, docs.johnDoe]);
×
135
                        });
136

UNCOV
137
                        it("should sort & limit & offset rows", async () => {
×
UNCOV
138
                                const params = { sort: "age", limit: 2, offset: 2 };
×
UNCOV
139
                                const rows = await svc.findEntities(ctx, params);
×
UNCOV
140
                                expect(rows).toEqual([docs.kevinJames, docs.bobSmith]);
×
141
                        });
142

143
                        // Test MSSQL using offset without sort.
144
                        // https://github.com/knex/knex/issues/1527
UNCOV
145
                        it("should limit & offset rows without sort", async () => {
×
UNCOV
146
                                const params = { limit: 2, offset: 2 };
×
UNCOV
147
                                const rows = await svc.findEntities(ctx, params);
×
UNCOV
148
                                expect(rows.length).toBe(2);
×
149
                        });
150

UNCOV
151
                        it("should negative sort the rows", async () => {
×
UNCOV
152
                                const rows = await svc.findEntities(ctx, { sort: "-dob" });
×
UNCOV
153
                                expect(rows).toEqual([docs.janeDoe, docs.johnDoe, docs.kevinJames, docs.bobSmith]);
×
154
                        });
155

UNCOV
156
                        it("should multiple sort the rows", async () => {
×
UNCOV
157
                                const rows = await svc.findEntities(ctx, { sort: ["status", "-age"] });
×
UNCOV
158
                                expect(rows).toEqual([docs.kevinJames, docs.janeDoe, docs.bobSmith, docs.johnDoe]);
×
159
                        });
160

UNCOV
161
                        it("should multiple sort the rows (reverse)", async () => {
×
UNCOV
162
                                const rows = await svc.findEntities(ctx, { sort: "-status,age" });
×
UNCOV
163
                                expect(rows).toEqual([docs.johnDoe, docs.bobSmith, docs.janeDoe, docs.kevinJames]);
×
164
                        });
165
                });
166

UNCOV
167
                describe("Test full-text search", () => {
×
UNCOV
168
                        it("should filter by searchText", async () => {
×
UNCOV
169
                                const params = { search: "Doe", searchFields: ["name"] };
×
UNCOV
170
                                const rows = await svc.findEntities(ctx, params);
×
UNCOV
171
                                if (adapterType == "MongoDB") {
×
UNCOV
172
                                        expect(rows).toEqual(
×
173
                                                expect.arrayContaining([
174
                                                        addExpectAnyFields(docs.janeDoe, { _score: Number }),
175
                                                        addExpectAnyFields(docs.johnDoe, { _score: Number })
176
                                                ])
177
                                        );
UNCOV
178
                                } else expect(rows).toEqual(expect.arrayContaining([docs.janeDoe, docs.johnDoe]));
×
179

UNCOV
180
                                const count = await svc.countEntities(ctx, params);
×
UNCOV
181
                                expect(count).toEqual(2);
×
182
                        });
183

UNCOV
184
                        it("should filter by searchText", async () => {
×
UNCOV
185
                                const params = { search: "user", searchFields: ["roles"] };
×
UNCOV
186
                                const rows = await svc.findEntities(ctx, params);
×
UNCOV
187
                                if (adapterType == "MongoDB") {
×
UNCOV
188
                                        expect(rows).toEqual(
×
189
                                                expect.arrayContaining([
190
                                                        addExpectAnyFields(docs.bobSmith, { _score: Number }),
191
                                                        addExpectAnyFields(docs.johnDoe, { _score: Number })
192
                                                ])
193
                                        );
UNCOV
194
                                } else expect(rows).toEqual(expect.arrayContaining([docs.johnDoe, docs.bobSmith]));
×
195

UNCOV
196
                                const count = await svc.countEntities(ctx, params);
×
UNCOV
197
                                expect(count).toEqual(2);
×
198
                        });
199

UNCOV
200
                        it("should filter by searchText & sort", async () => {
×
UNCOV
201
                                const params = {
×
202
                                        search: "user",
203
                                        searchFields: ["name", "roles"],
204
                                        sort: "-age"
205
                                };
UNCOV
206
                                const rows = await svc.findEntities(ctx, params);
×
UNCOV
207
                                if (adapterType == "MongoDB") {
×
UNCOV
208
                                        expect(rows).toEqual(
×
209
                                                expect.arrayContaining([
210
                                                        addExpectAnyFields(docs.bobSmith, { _score: Number }),
211
                                                        addExpectAnyFields(docs.johnDoe, { _score: Number })
212
                                                ])
213
                                        );
UNCOV
214
                                } else expect(rows).toEqual([docs.bobSmith, docs.johnDoe]);
×
215

UNCOV
216
                                const count = await svc.countEntities(ctx, params);
×
UNCOV
217
                                expect(count).toEqual(2);
×
218
                        });
219
                });
220

UNCOV
221
                describe("Test query", () => {
×
UNCOV
222
                        it("should filter by query", async () => {
×
UNCOV
223
                                const params = { query: { name: "Jane Doe" } };
×
UNCOV
224
                                const rows = await svc.findEntities(ctx, params);
×
UNCOV
225
                                expect(rows).toEqual([docs.janeDoe]);
×
226

UNCOV
227
                                const count = await svc.countEntities(ctx, params);
×
UNCOV
228
                                expect(count).toEqual(1);
×
229
                        });
230

UNCOV
231
                        it("should filter by multi query", async () => {
×
UNCOV
232
                                const params = { query: { status: true, age: 58 } };
×
UNCOV
233
                                const rows = await svc.findEntities(ctx, params);
×
UNCOV
234
                                expect(rows).toEqual([docs.bobSmith]);
×
235

UNCOV
236
                                const count = await svc.countEntities(ctx, params);
×
UNCOV
237
                                expect(count).toEqual(1);
×
238
                        });
239

UNCOV
240
                        it("should filter by query & limit & sort", async () => {
×
UNCOV
241
                                const params = {
×
242
                                        query: { status: false },
243
                                        sort: "-age",
244
                                        limit: 1
245
                                };
UNCOV
246
                                const rows = await svc.findEntities(ctx, params);
×
UNCOV
247
                                expect(rows).toEqual([docs.kevinJames]);
×
248

UNCOV
249
                                const count = await svc.countEntities(ctx, params);
×
UNCOV
250
                                expect(count).toEqual(2);
×
251
                        });
252

UNCOV
253
                        it("should filter by query & full-text search", async () => {
×
UNCOV
254
                                const params = {
×
255
                                        query: { status: false },
256
                                        search: "Doe",
257
                                        searchFields: ["name"]
258
                                };
UNCOV
259
                                const rows = await svc.findEntities(ctx, params);
×
UNCOV
260
                                if (adapterType == "MongoDB") {
×
UNCOV
261
                                        expect(rows).toEqual([addExpectAnyFields(docs.janeDoe, { _score: Number })]);
×
UNCOV
262
                                } else expect(rows).toEqual([docs.janeDoe]);
×
263

UNCOV
264
                                const count = await svc.countEntities(ctx, params);
×
UNCOV
265
                                expect(count).toEqual(1);
×
266
                        });
267

UNCOV
268
                        it("should filter by all", async () => {
×
UNCOV
269
                                docs.joeDoe = await svc.createEntity(ctx, {
×
270
                                        ...TEST_DOCS.janeDoe,
271
                                        name: "Joe Doe",
272
                                        status: false,
273
                                        age: 20
274
                                });
275

UNCOV
276
                                const params = {
×
277
                                        query: { status: false },
278
                                        search: "Doe",
279
                                        searchFields: ["name"],
280
                                        sort: "age",
281
                                        limit: 1
282
                                };
UNCOV
283
                                const rows = await svc.findEntities(ctx, params);
×
UNCOV
284
                                if (adapterType == "MongoDB") {
×
UNCOV
285
                                        expect(rows).toEqual([addExpectAnyFields(docs.joeDoe, { _score: Number })]);
×
UNCOV
286
                                } else expect(rows).toEqual([docs.joeDoe]);
×
287

UNCOV
288
                                const count = await svc.countEntities(ctx, params);
×
UNCOV
289
                                expect(count).toEqual(2);
×
290
                        });
291
                });
292

UNCOV
293
                describe("Test findEntity", () => {
×
UNCOV
294
                        it("should return the first row by query", async () => {
×
UNCOV
295
                                const params = { query: { id: docs.bobSmith.id } };
×
UNCOV
296
                                const row = await svc.findEntity(ctx, params);
×
UNCOV
297
                                expect(row).toEqual(docs.bobSmith);
×
298
                        });
UNCOV
299
                        it("should return the first row by query", async () => {
×
UNCOV
300
                                const params = { query: { name: "Jane Doe" } };
×
UNCOV
301
                                const row = await svc.findEntity(ctx, params);
×
UNCOV
302
                                expect(row).toEqual(docs.janeDoe);
×
303
                        });
304

UNCOV
305
                        it("should return the first row by query", async () => {
×
UNCOV
306
                                const params = { query: { status: true, age: 58 } };
×
UNCOV
307
                                const row = await svc.findEntity(ctx, params);
×
UNCOV
308
                                expect(row).toEqual(docs.bobSmith);
×
309
                        });
310

UNCOV
311
                        it("should return the first row by query & sort", async () => {
×
UNCOV
312
                                const params = { query: { status: false }, sort: "age" };
×
UNCOV
313
                                const row = await svc.findEntity(ctx, params);
×
UNCOV
314
                                expect(row).toEqual(docs.joeDoe);
×
315
                        });
316

UNCOV
317
                        it("should return the first row by query & sort desc", async () => {
×
UNCOV
318
                                const params = { query: { status: false }, sort: "-age" };
×
UNCOV
319
                                const row = await svc.findEntity(ctx, params);
×
UNCOV
320
                                expect(row).toEqual(docs.kevinJames);
×
321
                        });
322

UNCOV
323
                        it("should return null if no match", async () => {
×
UNCOV
324
                                const params = { query: { age: 88 } };
×
UNCOV
325
                                const row = await svc.findEntity(ctx, params);
×
UNCOV
326
                                expect(row == null).toBe(true);
×
327
                        });
328
                });
329

UNCOV
330
                if (["MongoDB"].indexOf(adapterType) !== -1) {
×
UNCOV
331
                        describe("Test streamEntities", () => {
×
UNCOV
332
                                it("should return all rows", async () => {
×
UNCOV
333
                                        const rows = [];
×
UNCOV
334
                                        const stream = await svc.streamEntities(ctx, {});
×
UNCOV
335
                                        expect.assertions(2);
×
336

UNCOV
337
                                        return new Promise((resolve, reject) => {
×
UNCOV
338
                                                expect(stream).toBeInstanceOf(Stream);
×
UNCOV
339
                                                stream.on("data", row => rows.push(row));
×
340

UNCOV
341
                                                expect.assertions(2);
×
UNCOV
342
                                                stream.on("error", reject);
×
UNCOV
343
                                                stream.on("end", () => {
×
UNCOV
344
                                                        expect(rows).toEqual(expect.arrayContaining(Object.values(docs)));
×
UNCOV
345
                                                        resolve();
×
346
                                                });
347
                                        });
348
                                });
349
                        });
350
                }
351
        });
352

UNCOV
353
        describe("Test createEntity & createEntities & resolveEntities method", () => {
×
UNCOV
354
                const broker = new ServiceBroker({ logger: false });
×
UNCOV
355
                const svc = broker.createService({
×
356
                        name: "users",
357
                        mixins: [DbService({ adapter: getAdapter(), createActions: false })],
358

359
                        settings: {
360
                                fields: {
361
                                        id: { type: "string", primaryKey: true, columnName: "_id" },
362
                                        name: { type: "string", trim: true, required: true },
363
                                        age: { type: "number", columnType: "integer" },
364
                                        dob: {
365
                                                type: "number",
366
                                                columnType: "bigInteger",
UNCOV
367
                                                get: ({ value }) => (typeof value == "string" ? Number(value) : value)
×
368
                                        },
369
                                        roles: { type: "array", items: "string", columnType: "string" },
370
                                        status: {
371
                                                type: "boolean",
372
                                                default: true,
UNCOV
373
                                                get: adapterType == "Knex" ? ({ value }) => !!value : undefined
×
374
                                        }
375
                                }
376
                        },
377

378
                        async started() {
UNCOV
379
                                const adapter = await this.getAdapter();
×
380

UNCOV
381
                                if (adapterType == "Knex") {
×
UNCOV
382
                                        await adapter.createTable();
×
383
                                }
384

UNCOV
385
                                await this.clearEntities();
×
386
                        }
387
                });
UNCOV
388
                beforeAll(() => broker.start());
×
UNCOV
389
                afterAll(() => broker.stop());
×
390

UNCOV
391
                const ctx = Context.create(broker, null, {});
×
UNCOV
392
                let docs = {};
×
UNCOV
393
                jest.spyOn(ctx, "broadcast");
×
394

UNCOV
395
                it("should return empty array", async () => {
×
UNCOV
396
                        const rows = await svc.findEntities(ctx);
×
UNCOV
397
                        expect(rows).toEqual([]);
×
398

UNCOV
399
                        const count = await svc.countEntities(ctx);
×
UNCOV
400
                        expect(count).toEqual(0);
×
401
                });
402

UNCOV
403
                it("create an entity", async () => {
×
UNCOV
404
                        ctx.broadcast.mockClear();
×
UNCOV
405
                        docs.johnDoe = await svc.createEntity(ctx, TEST_DOCS.johnDoe);
×
406

UNCOV
407
                        expect(docs.johnDoe).toEqual({ ...TEST_DOCS.johnDoe, id: expectedID });
×
408

UNCOV
409
                        expect(ctx.broadcast).toBeCalledTimes(2);
×
UNCOV
410
                        expect(ctx.broadcast).toBeCalledWith("cache.clean.users", {
×
411
                                type: "create",
412
                                data: docs.johnDoe,
413
                                opts: {}
414
                        });
UNCOV
415
                        expect(ctx.broadcast).toBeCalledWith("users.created", {
×
416
                                type: "create",
417
                                data: docs.johnDoe,
418
                                opts: {}
419
                        });
420
                });
421

UNCOV
422
                it("create multiple entities", async () => {
×
UNCOV
423
                        ctx.broadcast.mockClear();
×
UNCOV
424
                        const res = await svc.createEntities(
×
425
                                ctx,
426
                                [TEST_DOCS.janeDoe, TEST_DOCS.bobSmith, TEST_DOCS.kevinJames],
427
                                { returnEntities: true }
428
                        );
429

UNCOV
430
                        expect(res.length).toBe(3);
×
UNCOV
431
                        docs.janeDoe = res.find(e => e.name == "Jane Doe");
×
UNCOV
432
                        docs.bobSmith = res.find(e => e.name == "Bob Smith");
×
UNCOV
433
                        docs.kevinJames = res.find(e => e.name == "Kevin James");
×
434

UNCOV
435
                        expect(docs.janeDoe).toEqual({ ...TEST_DOCS.janeDoe, id: expectedID });
×
UNCOV
436
                        expect(docs.bobSmith).toEqual({ ...TEST_DOCS.bobSmith, id: expectedID });
×
UNCOV
437
                        expect(docs.kevinJames).toEqual({
×
438
                                ...TEST_DOCS.kevinJames,
439
                                id: expectedID
440
                        });
441

UNCOV
442
                        expect(ctx.broadcast).toBeCalledTimes(2);
×
UNCOV
443
                        expect(ctx.broadcast).toBeCalledWith("cache.clean.users", {
×
444
                                type: "create",
445
                                data: res,
446
                                opts: { batch: true, returnEntities: true }
447
                        });
UNCOV
448
                        expect(ctx.broadcast).toBeCalledWith("users.created", {
×
449
                                type: "create",
450
                                data: res,
451
                                opts: { batch: true, returnEntities: true }
452
                        });
453
                });
454

UNCOV
455
                describe("Test resolveEntities method", () => {
×
UNCOV
456
                        it("resolve entities by IDs", async () => {
×
UNCOV
457
                                const res = await svc.resolveEntities(ctx, { id: docs.janeDoe.id });
×
UNCOV
458
                                expect(res).toEqual(docs.janeDoe);
×
459

UNCOV
460
                                const res2 = await svc.resolveEntities(ctx, {
×
461
                                        id: [docs.johnDoe.id, docs.bobSmith.id]
462
                                });
UNCOV
463
                                expect(res2).toEqual([docs.johnDoe, docs.bobSmith]);
×
464
                        });
465

UNCOV
466
                        it("resolve entities by IDs with mapping", async () => {
×
UNCOV
467
                                const res = await svc.resolveEntities(ctx, {
×
468
                                        id: docs.janeDoe.id,
469
                                        mapping: true
470
                                });
UNCOV
471
                                expect(res).toEqual({ [docs.janeDoe.id]: docs.janeDoe });
×
472

UNCOV
473
                                const res2 = await svc.resolveEntities(ctx, {
×
474
                                        id: [docs.johnDoe.id, docs.bobSmith.id],
475
                                        mapping: true
476
                                });
UNCOV
477
                                expect(res2).toEqual({
×
478
                                        [docs.johnDoe.id]: docs.johnDoe,
479
                                        [docs.bobSmith.id]: docs.bobSmith
480
                                });
481
                        });
482

UNCOV
483
                        it("resolve entities by IDs with reordering", async () => {
×
UNCOV
484
                                const res = await svc.resolveEntities(
×
485
                                        ctx,
486
                                        {
487
                                                id: [
488
                                                        docs.johnDoe.id,
489
                                                        docs.bobSmith.id,
490
                                                        docs.kevinJames.id,
491
                                                        null,
492
                                                        docs.janeDoe.id,
493
                                                        "123456879"
494
                                                ]
495
                                        },
496
                                        { reorderResult: true }
497
                                );
UNCOV
498
                                expect(res).toEqual([
×
499
                                        docs.johnDoe,
500
                                        docs.bobSmith,
501
                                        docs.kevinJames,
502
                                        null,
503
                                        docs.janeDoe,
504
                                        null
505
                                ]);
506

UNCOV
507
                                const res2 = await svc.resolveEntities(
×
508
                                        ctx,
509
                                        {
510
                                                id: [
511
                                                        "123456879",
512
                                                        docs.janeDoe.id,
513
                                                        null,
514
                                                        docs.kevinJames.id,
515
                                                        docs.bobSmith.id,
516
                                                        docs.johnDoe.id
517
                                                ]
518
                                        },
519
                                        { reorderResult: true }
520
                                );
UNCOV
521
                                expect(res2).toEqual([
×
522
                                        null,
523
                                        docs.janeDoe,
524
                                        null,
525
                                        docs.kevinJames,
526
                                        docs.bobSmith,
527
                                        docs.johnDoe
528
                                ]);
529
                        });
530

UNCOV
531
                        it("throw Missing ID", async () => {
×
UNCOV
532
                                expect.assertions(4);
×
UNCOV
533
                                try {
×
UNCOV
534
                                        await svc.resolveEntities(ctx, { a: 5 });
×
535
                                } catch (err) {
UNCOV
536
                                        expect(err).toBeInstanceOf(MoleculerClientError);
×
UNCOV
537
                                        expect(err.type).toEqual("MISSING_ID");
×
UNCOV
538
                                        expect(err.code).toEqual(400);
×
UNCOV
539
                                        expect(err.data).toEqual({ params: { a: 5 } });
×
540
                                }
541
                        });
542

UNCOV
543
                        it("should not throw EntityNotFound", async () => {
×
UNCOV
544
                                const res = await svc.resolveEntities(ctx, { id: "123456879" });
×
UNCOV
545
                                expect(res == null).toBeTruthy();
×
546

UNCOV
547
                                const res2 = await svc.resolveEntities(ctx, {
×
548
                                        id: ["123456879", "234567890"]
549
                                });
UNCOV
550
                                expect(res2).toEqual([]);
×
551
                        });
552

UNCOV
553
                        it("throw EntityNotFound", async () => {
×
UNCOV
554
                                expect.assertions(2);
×
UNCOV
555
                                try {
×
UNCOV
556
                                        await svc.resolveEntities(ctx, { id: "123456879" }, { throwIfNotExist: true });
×
557
                                } catch (err) {
UNCOV
558
                                        expect(err).toBeInstanceOf(EntityNotFoundError);
×
UNCOV
559
                                        expect(err.data).toEqual({ id: "123456879" });
×
560
                                }
561
                        });
562

UNCOV
563
                        it("throw EntityNotFound", async () => {
×
UNCOV
564
                                expect.assertions(2);
×
UNCOV
565
                                try {
×
UNCOV
566
                                        await svc.resolveEntities(
×
567
                                                ctx,
568
                                                {
569
                                                        id: ["123456879", "234567890"]
570
                                                },
571
                                                { throwIfNotExist: true }
572
                                        );
573
                                } catch (err) {
UNCOV
574
                                        expect(err).toBeInstanceOf(EntityNotFoundError);
×
UNCOV
575
                                        expect(err.data).toEqual({
×
576
                                                id: ["123456879", "234567890"]
577
                                        });
578
                                }
579
                        });
580
                });
581
        });
582

UNCOV
583
        describe("Test updateEntity & replaceEntity method", () => {
×
UNCOV
584
                const broker = new ServiceBroker({ logger: false });
×
UNCOV
585
                const svc = broker.createService({
×
586
                        name: "users",
587
                        mixins: [DbService({ adapter: getAdapter(), createActions: false })],
588

589
                        settings: {
590
                                fields: {
591
                                        id: {
592
                                                type: "string",
593
                                                primaryKey: true,
594
                                                columnName: "_id",
595
                                                columnType: "integer"
596
                                        },
597
                                        name: { type: "string", trim: true, required: true },
598
                                        age: { type: "number", columnType: "integer" },
599
                                        dob: {
600
                                                type: "number",
601
                                                columnType: "bigInteger",
UNCOV
602
                                                get: ({ value }) => (typeof value == "string" ? Number(value) : value)
×
603
                                        },
604
                                        height: { type: "number", columnType: "integer" },
605
                                        roles: { type: "array", items: "string", columnType: "string" },
606
                                        status: {
607
                                                type: "boolean",
608
                                                default: true,
UNCOV
609
                                                get: adapterType == "Knex" ? ({ value }) => !!value : undefined
×
610
                                        }
611
                                }
612
                        },
613

614
                        async started() {
UNCOV
615
                                const adapter = await this.getAdapter();
×
616

UNCOV
617
                                if (adapterType == "Knex") {
×
UNCOV
618
                                        await adapter.createTable();
×
619
                                }
620

UNCOV
621
                                await this.clearEntities();
×
622
                        }
623
                });
624

UNCOV
625
                beforeAll(() => broker.start());
×
UNCOV
626
                afterAll(() => broker.stop());
×
627

UNCOV
628
                const ctx = Context.create(broker, null, {});
×
UNCOV
629
                let docs = {};
×
UNCOV
630
                jest.spyOn(ctx, "broadcast");
×
631

UNCOV
632
                describe("Set up", () => {
×
UNCOV
633
                        it("should return empty array", async () => {
×
UNCOV
634
                                const rows = await svc.findEntities(ctx);
×
UNCOV
635
                                expect(rows).toEqual([]);
×
636

UNCOV
637
                                const count = await svc.countEntities(ctx);
×
UNCOV
638
                                expect(count).toEqual(0);
×
639
                        });
640

UNCOV
641
                        it("create test entities", async () => {
×
UNCOV
642
                                for (const [key, value] of Object.entries(TEST_DOCS)) {
×
UNCOV
643
                                        docs[key] = await svc.createEntity(ctx, value);
×
644
                                }
645
                        });
646
                });
647

UNCOV
648
                describe("Test updateEntity method", () => {
×
UNCOV
649
                        it("should update an entity", async () => {
×
UNCOV
650
                                ctx.broadcast.mockClear();
×
UNCOV
651
                                const row = await svc.updateEntity(ctx, {
×
652
                                        id: docs.janeDoe.id,
653
                                        status: true,
654
                                        age: 28,
655
                                        height: 168
656
                                });
UNCOV
657
                                expect(row).toEqual({
×
658
                                        id: docs.janeDoe.id,
659
                                        name: "Jane Doe",
660
                                        age: 28,
661
                                        dob: docs.janeDoe.dob,
662
                                        height: 168,
663
                                        roles: ["moderator"],
664
                                        status: true
665
                                });
666

UNCOV
667
                                expect(ctx.broadcast).toBeCalledTimes(2);
×
UNCOV
668
                                expect(ctx.broadcast).toBeCalledWith("cache.clean.users", {
×
669
                                        type: "update",
670
                                        data: row,
671
                                        opts: {}
672
                                });
UNCOV
673
                                expect(ctx.broadcast).toBeCalledWith("users.updated", {
×
674
                                        type: "update",
675
                                        data: row,
676
                                        opts: {}
677
                                });
678
                        });
679

UNCOV
680
                        if (adapterType == "MongoDB" || adapterType == "NeDB") {
×
UNCOV
681
                                it("should raw update an entity", async () => {
×
UNCOV
682
                                        ctx.broadcast.mockClear();
×
UNCOV
683
                                        const row = await svc.updateEntity(
×
684
                                                ctx,
685
                                                {
686
                                                        id: docs.johnDoe.id,
687

688
                                                        $set: {
689
                                                                status: false,
690
                                                                height: 192
691
                                                        },
692
                                                        $inc: {
693
                                                                age: 1
694
                                                        },
695
                                                        $unset: {
696
                                                                dob: true
697
                                                        }
698
                                                },
699
                                                { raw: true }
700
                                        );
UNCOV
701
                                        expect(row).toEqual({
×
702
                                                id: docs.johnDoe.id,
703
                                                name: "John Doe",
704
                                                age: 43,
705
                                                height: 192,
706
                                                roles: ["admin", "user"],
707
                                                status: false
708
                                        });
709

UNCOV
710
                                        expect(ctx.broadcast).toBeCalledTimes(2);
×
UNCOV
711
                                        expect(ctx.broadcast).toBeCalledWith("cache.clean.users", {
×
712
                                                type: "update",
713
                                                data: row,
714
                                                opts: { raw: true }
715
                                        });
UNCOV
716
                                        expect(ctx.broadcast).toBeCalledWith("users.updated", {
×
717
                                                type: "update",
718
                                                data: row,
719
                                                opts: { raw: true }
720
                                        });
721
                                });
722
                        }
723

UNCOV
724
                        it("throw Missing ID", async () => {
×
UNCOV
725
                                expect.assertions(4);
×
UNCOV
726
                                try {
×
UNCOV
727
                                        await svc.updateEntity(ctx, { a: 5 });
×
728
                                } catch (err) {
UNCOV
729
                                        expect(err).toBeInstanceOf(MoleculerClientError);
×
UNCOV
730
                                        expect(err.type).toEqual("MISSING_ID");
×
UNCOV
731
                                        expect(err.code).toEqual(400);
×
UNCOV
732
                                        expect(err.data).toEqual({ params: { a: 5 } });
×
733
                                }
734
                        });
735

UNCOV
736
                        it("throw EntityNotFound", async () => {
×
UNCOV
737
                                expect.assertions(2);
×
UNCOV
738
                                try {
×
UNCOV
739
                                        await svc.updateEntity(ctx, { id: "123456789" });
×
740
                                } catch (err) {
UNCOV
741
                                        expect(err).toBeInstanceOf(EntityNotFoundError);
×
UNCOV
742
                                        expect(err.data).toEqual({ id: "123456789" });
×
743
                                }
744
                        });
745
                });
746

UNCOV
747
                describe("Test replaceEntity method", () => {
×
UNCOV
748
                        if (adapterType == "MongoDB" || adapterType == "NeDB") {
×
UNCOV
749
                                it("should replace an entity", async () => {
×
UNCOV
750
                                        ctx.broadcast.mockClear();
×
UNCOV
751
                                        const row = await svc.replaceEntity(ctx, {
×
752
                                                id: docs.kevinJames.id,
753
                                                name: "Kevin",
754
                                                age: 72,
755
                                                height: 185
756
                                        });
UNCOV
757
                                        expect(row).toEqual({
×
758
                                                id: docs.kevinJames.id,
759
                                                name: "Kevin",
760
                                                age: 72,
761
                                                height: 185,
762
                                                status: true
763
                                        });
764

UNCOV
765
                                        expect(ctx.broadcast).toBeCalledTimes(2);
×
UNCOV
766
                                        expect(ctx.broadcast).toBeCalledWith("cache.clean.users", {
×
767
                                                type: "replace",
768
                                                data: row,
769
                                                opts: {}
770
                                        });
UNCOV
771
                                        expect(ctx.broadcast).toBeCalledWith("users.replaced", {
×
772
                                                type: "replace",
773
                                                data: row,
774
                                                opts: {}
775
                                        });
776
                                });
777
                        }
778

UNCOV
779
                        it("throw Missing ID", async () => {
×
UNCOV
780
                                expect.assertions(4);
×
UNCOV
781
                                try {
×
UNCOV
782
                                        await svc.replaceEntity(ctx, { a: 5 });
×
783
                                } catch (err) {
UNCOV
784
                                        expect(err).toBeInstanceOf(MoleculerClientError);
×
UNCOV
785
                                        expect(err.type).toEqual("MISSING_ID");
×
UNCOV
786
                                        expect(err.code).toEqual(400);
×
UNCOV
787
                                        expect(err.data).toEqual({ params: { a: 5 } });
×
788
                                }
789
                        });
790

UNCOV
791
                        it("throw EntityNotFound", async () => {
×
UNCOV
792
                                expect.assertions(2);
×
UNCOV
793
                                try {
×
UNCOV
794
                                        await svc.replaceEntity(ctx, { id: "123456789" });
×
795
                                } catch (err) {
UNCOV
796
                                        expect(err).toBeInstanceOf(EntityNotFoundError);
×
UNCOV
797
                                        expect(err.data).toEqual({ id: "123456789" });
×
798
                                }
799
                        });
800
                });
801
        });
802

UNCOV
803
        describe("Test removeEntity method", () => {
×
UNCOV
804
                const broker = new ServiceBroker({ logger: false });
×
UNCOV
805
                const svc = broker.createService({
×
806
                        name: "users",
807
                        mixins: [DbService({ adapter: getAdapter(), createActions: false })],
808

809
                        settings: {
810
                                fields: {
811
                                        id: {
812
                                                type: "string",
813
                                                primaryKey: true,
814

815
                                                columnName: "_id",
816
                                                columnType: "integer"
817
                                        },
818
                                        name: { type: "string", trim: true, required: true },
819
                                        age: { type: "number", columnType: "integer" },
820
                                        dob: {
821
                                                type: "number",
822
                                                columnType: "bigInteger",
UNCOV
823
                                                get: ({ value }) => (typeof value == "string" ? Number(value) : value)
×
824
                                        },
825
                                        height: { type: "number", columnType: "integer" },
826
                                        roles: { type: "array", items: "string", columnType: "string" },
827
                                        status: {
828
                                                type: "boolean",
829
                                                default: true,
UNCOV
830
                                                get: adapterType == "Knex" ? ({ value }) => !!value : undefined
×
831
                                        }
832
                                }
833
                        },
834

835
                        async started() {
UNCOV
836
                                const adapter = await this.getAdapter();
×
837

UNCOV
838
                                if (adapterType == "Knex") {
×
UNCOV
839
                                        await adapter.createTable();
×
840
                                }
841

UNCOV
842
                                await this.clearEntities();
×
843
                        }
844
                });
845

UNCOV
846
                beforeAll(() => broker.start());
×
UNCOV
847
                afterAll(() => broker.stop());
×
848

UNCOV
849
                const ctx = Context.create(broker, null, {});
×
UNCOV
850
                let docs = {};
×
UNCOV
851
                jest.spyOn(ctx, "broadcast");
×
852

UNCOV
853
                describe("Set up", () => {
×
UNCOV
854
                        it("should return empty array", async () => {
×
UNCOV
855
                                const rows = await svc.findEntities(ctx);
×
UNCOV
856
                                expect(rows).toEqual([]);
×
857

UNCOV
858
                                const count = await svc.countEntities(ctx);
×
UNCOV
859
                                expect(count).toEqual(0);
×
860
                        });
861

UNCOV
862
                        it("create test entities", async () => {
×
UNCOV
863
                                for (const [key, value] of Object.entries(TEST_DOCS)) {
×
UNCOV
864
                                        docs[key] = await svc.createEntity(ctx, value);
×
865
                                }
866
                        });
867
                });
868

UNCOV
869
                describe("Test removeEntity", () => {
×
UNCOV
870
                        it("should return all rows", async () => {
×
UNCOV
871
                                const rows = await svc.findEntities(ctx, {});
×
UNCOV
872
                                expect(rows).toEqual(expect.arrayContaining(Object.values(docs)));
×
873

UNCOV
874
                                const count = await svc.countEntities(ctx, {});
×
UNCOV
875
                                expect(count).toEqual(4);
×
876
                        });
877

UNCOV
878
                        it("should return the remaining rows", async () => {
×
UNCOV
879
                                ctx.broadcast.mockClear();
×
880

UNCOV
881
                                const res = await svc.removeEntity(ctx, { id: docs.janeDoe.id });
×
UNCOV
882
                                expect(res).toBe(docs.janeDoe.id);
×
883

UNCOV
884
                                const rows = await svc.findEntities(ctx, {});
×
UNCOV
885
                                expect(rows).toEqual(
×
886
                                        expect.arrayContaining([docs.johnDoe, docs.bobSmith, docs.kevinJames])
887
                                );
888

UNCOV
889
                                const count = await svc.countEntities(ctx, {});
×
UNCOV
890
                                expect(count).toEqual(3);
×
891

UNCOV
892
                                expect(ctx.broadcast).toBeCalledTimes(2);
×
UNCOV
893
                                expect(ctx.broadcast).toBeCalledWith("cache.clean.users", {
×
894
                                        type: "remove",
895
                                        data: docs.janeDoe,
896
                                        opts: { softDelete: false }
897
                                });
UNCOV
898
                                expect(ctx.broadcast).toBeCalledWith("users.removed", {
×
899
                                        type: "remove",
900
                                        data: docs.janeDoe,
901
                                        opts: { softDelete: false }
902
                                });
903
                        });
904

UNCOV
905
                        it("throw Missing ID", async () => {
×
UNCOV
906
                                expect.assertions(4);
×
UNCOV
907
                                try {
×
UNCOV
908
                                        await svc.removeEntity(ctx, { a: 5 });
×
909
                                } catch (err) {
UNCOV
910
                                        expect(err).toBeInstanceOf(MoleculerClientError);
×
UNCOV
911
                                        expect(err.type).toEqual("MISSING_ID");
×
UNCOV
912
                                        expect(err.code).toEqual(400);
×
UNCOV
913
                                        expect(err.data).toEqual({ params: { a: 5 } });
×
914
                                }
915
                        });
916

UNCOV
917
                        it("throw EntityNotFound", async () => {
×
UNCOV
918
                                expect.assertions(2);
×
UNCOV
919
                                try {
×
UNCOV
920
                                        await svc.removeEntity(ctx, { id: "123456789" });
×
921
                                } catch (err) {
UNCOV
922
                                        expect(err).toBeInstanceOf(EntityNotFoundError);
×
UNCOV
923
                                        expect(err.data).toEqual({ id: "123456789" });
×
924
                                }
925
                        });
926
                });
927
        });
928

UNCOV
929
        describe("Test updateMany & removeMany methods", () => {
×
UNCOV
930
                const broker = new ServiceBroker({ logger: false });
×
UNCOV
931
                const svc = broker.createService({
×
932
                        name: "users",
933
                        mixins: [DbService({ adapter: getAdapter(), createActions: false })],
934

935
                        settings: {
936
                                fields: {
937
                                        id: {
938
                                                type: "string",
939
                                                primaryKey: true,
940
                                                secure: true,
941
                                                columnName: "_id",
942
                                                columnType: "integer"
943
                                        },
944
                                        name: { type: "string", trim: true, required: true },
945
                                        age: { type: "number", columnType: "integer" },
946
                                        dob: {
947
                                                type: "number",
948
                                                columnType: "bigInteger",
UNCOV
949
                                                get: ({ value }) => (typeof value == "string" ? Number(value) : value)
×
950
                                        },
951
                                        height: { type: "number", columnType: "integer" },
952
                                        roles: { type: "array", items: "string", columnType: "string" },
953
                                        status: {
954
                                                type: "boolean",
955
                                                default: true,
UNCOV
956
                                                get: adapterType == "Knex" ? ({ value }) => !!value : undefined
×
957
                                        }
958
                                }
959
                        },
960

961
                        methods: {
962
                                encodeID(id) {
UNCOV
963
                                        return "secured-" + id;
×
964
                                },
965

966
                                decodeID(id) {
UNCOV
967
                                        return id.slice(8);
×
968
                                }
969
                        },
970

971
                        async started() {
UNCOV
972
                                const adapter = await this.getAdapter();
×
973

UNCOV
974
                                if (adapterType == "Knex") {
×
UNCOV
975
                                        await adapter.createTable();
×
976
                                }
977

UNCOV
978
                                await this.clearEntities();
×
979
                        }
980
                });
981

UNCOV
982
                beforeAll(() => broker.start());
×
UNCOV
983
                afterAll(() => broker.stop());
×
984

UNCOV
985
                const ctx = Context.create(broker, null, {});
×
UNCOV
986
                let docs = {};
×
UNCOV
987
                jest.spyOn(ctx, "broadcast");
×
988

UNCOV
989
                describe("Test updateEntities method", () => {
×
UNCOV
990
                        it("should return empty array", async () => {
×
UNCOV
991
                                const rows = await svc.findEntities(ctx);
×
UNCOV
992
                                expect(rows).toEqual([]);
×
993

UNCOV
994
                                const count = await svc.countEntities(ctx);
×
UNCOV
995
                                expect(count).toEqual(0);
×
996
                        });
997

UNCOV
998
                        it("create test entities", async () => {
×
UNCOV
999
                                for (const [key, value] of Object.entries(TEST_DOCS)) {
×
UNCOV
1000
                                        docs[key] = await svc.createEntity(ctx, value);
×
1001
                                }
1002
                        });
1003

UNCOV
1004
                        it("should update multiple entities", async () => {
×
UNCOV
1005
                                ctx.broadcast.mockClear();
×
UNCOV
1006
                                const rows = await svc.updateEntities(ctx, {
×
1007
                                        query: {
1008
                                                status: true,
1009
                                                age: { $gt: 40 }
1010
                                        },
1011
                                        changes: {
1012
                                                status: false,
1013
                                                age: 88
1014
                                        }
1015
                                });
UNCOV
1016
                                expect(rows).toEqual(
×
1017
                                        expect.arrayContaining([
1018
                                                {
1019
                                                        ...docs.bobSmith,
1020
                                                        age: 88,
1021
                                                        status: false
1022
                                                },
1023
                                                {
1024
                                                        ...docs.johnDoe,
1025
                                                        age: 88,
1026
                                                        status: false
1027
                                                }
1028
                                        ])
1029
                                );
1030

UNCOV
1031
                                expect(ctx.broadcast).toBeCalledTimes(4);
×
1032

UNCOV
1033
                                expect(ctx.broadcast).toBeCalledWith("cache.clean.users", {
×
1034
                                        type: "update",
1035
                                        data: rows[0],
1036
                                        opts: {}
1037
                                });
UNCOV
1038
                                expect(ctx.broadcast).toBeCalledWith("cache.clean.users", {
×
1039
                                        type: "update",
1040
                                        data: rows[1],
1041
                                        opts: {}
1042
                                });
1043

UNCOV
1044
                                expect(ctx.broadcast).toBeCalledWith("users.updated", {
×
1045
                                        type: "update",
1046
                                        data: rows[0],
1047
                                        opts: {}
1048
                                });
UNCOV
1049
                                expect(ctx.broadcast).toBeCalledWith("users.updated", {
×
1050
                                        type: "update",
1051
                                        data: rows[1],
1052
                                        opts: {}
1053
                                });
1054
                        });
1055

UNCOV
1056
                        it("should return the updated entities", async () => {
×
UNCOV
1057
                                const rows = await svc.findEntities(ctx, {
×
1058
                                        query: {
1059
                                                status: false,
1060
                                                age: 88
1061
                                        },
1062
                                        sort: "name"
1063
                                });
1064

UNCOV
1065
                                expect(rows).toEqual([
×
1066
                                        {
1067
                                                ...docs.bobSmith,
1068
                                                age: 88,
1069
                                                status: false
1070
                                        },
1071
                                        {
1072
                                                ...docs.johnDoe,
1073
                                                age: 88,
1074
                                                status: false
1075
                                        }
1076
                                ]);
1077
                        });
1078

UNCOV
1079
                        if (adapterType == "MongoDB" || adapterType == "NeDB") {
×
UNCOV
1080
                                it("should raw update an entity", async () => {
×
UNCOV
1081
                                        ctx.broadcast.mockClear();
×
UNCOV
1082
                                        const rows = await svc.updateEntities(
×
1083
                                                ctx,
1084
                                                {
1085
                                                        query: {
1086
                                                                age: 88
1087
                                                        },
1088
                                                        changes: {
1089
                                                                $inc: {
1090
                                                                        age: 1
1091
                                                                }
1092
                                                        }
1093
                                                },
1094
                                                { raw: true }
1095
                                        );
UNCOV
1096
                                        expect(rows).toEqual(
×
1097
                                                expect.arrayContaining([
1098
                                                        {
1099
                                                                ...docs.bobSmith,
1100
                                                                age: 89,
1101
                                                                status: false
1102
                                                        },
1103
                                                        {
1104
                                                                ...docs.johnDoe,
1105
                                                                age: 89,
1106
                                                                status: false
1107
                                                        }
1108
                                                ])
1109
                                        );
1110

UNCOV
1111
                                        expect(ctx.broadcast).toBeCalledTimes(4);
×
1112

UNCOV
1113
                                        expect(ctx.broadcast).toBeCalledWith("cache.clean.users", {
×
1114
                                                type: "update",
1115
                                                data: rows[0],
1116
                                                opts: { raw: true }
1117
                                        });
UNCOV
1118
                                        expect(ctx.broadcast).toBeCalledWith("cache.clean.users", {
×
1119
                                                type: "update",
1120
                                                data: rows[1],
1121
                                                opts: { raw: true }
1122
                                        });
1123

UNCOV
1124
                                        expect(ctx.broadcast).toBeCalledWith("users.updated", {
×
1125
                                                type: "update",
1126
                                                data: rows[0],
1127
                                                opts: { raw: true }
1128
                                        });
UNCOV
1129
                                        expect(ctx.broadcast).toBeCalledWith("users.updated", {
×
1130
                                                type: "update",
1131
                                                data: rows[1],
1132
                                                opts: { raw: true }
1133
                                        });
1134
                                });
1135
                        }
1136

UNCOV
1137
                        it("should return empty if no updated entities", async () => {
×
UNCOV
1138
                                ctx.broadcast.mockClear();
×
UNCOV
1139
                                const rows = await svc.updateEntities(ctx, {
×
1140
                                        query: {
1141
                                                status: false,
1142
                                                age: { $lt: 10 }
1143
                                        },
1144
                                        changes: {
1145
                                                status: true,
1146
                                                age: 33
1147
                                        }
1148
                                });
UNCOV
1149
                                expect(rows).toEqual([]);
×
1150

UNCOV
1151
                                expect(ctx.broadcast).toBeCalledTimes(0);
×
1152
                        });
1153
                });
1154

UNCOV
1155
                describe("Test removeEntities method", () => {
×
UNCOV
1156
                        it("should return empty array", async () => {
×
UNCOV
1157
                                await svc.clearEntities();
×
1158

UNCOV
1159
                                const rows = await svc.findEntities(ctx);
×
UNCOV
1160
                                expect(rows).toEqual([]);
×
1161

UNCOV
1162
                                const count = await svc.countEntities(ctx);
×
UNCOV
1163
                                expect(count).toEqual(0);
×
1164
                        });
1165

UNCOV
1166
                        it("create test entities", async () => {
×
UNCOV
1167
                                for (const [key, value] of Object.entries(TEST_DOCS)) {
×
UNCOV
1168
                                        docs[key] = await svc.createEntity(ctx, value);
×
1169
                                }
1170
                        });
1171

UNCOV
1172
                        it("should remove multiple entities", async () => {
×
UNCOV
1173
                                ctx.broadcast.mockClear();
×
UNCOV
1174
                                const rows = await svc.removeEntities(ctx, {
×
1175
                                        query: {
1176
                                                status: true,
1177
                                                age: { $gt: 40 }
1178
                                        }
1179
                                });
UNCOV
1180
                                expect(rows).toEqual(expect.arrayContaining([docs.bobSmith.id, docs.johnDoe.id]));
×
UNCOV
1181
                                expect(rows[0].startsWith("secured-")).toBeTruthy();
×
1182

UNCOV
1183
                                expect(ctx.broadcast).toBeCalledTimes(4);
×
1184

UNCOV
1185
                                expect(ctx.broadcast).toBeCalledWith("cache.clean.users", {
×
1186
                                        type: "remove",
1187
                                        data: docs.bobSmith,
1188
                                        opts: { softDelete: false }
1189
                                });
UNCOV
1190
                                expect(ctx.broadcast).toBeCalledWith("cache.clean.users", {
×
1191
                                        type: "remove",
1192
                                        data: docs.johnDoe,
1193
                                        opts: { softDelete: false }
1194
                                });
1195

UNCOV
1196
                                expect(ctx.broadcast).toBeCalledWith("users.removed", {
×
1197
                                        type: "remove",
1198
                                        data: docs.bobSmith,
1199
                                        opts: { softDelete: false }
1200
                                });
UNCOV
1201
                                expect(ctx.broadcast).toBeCalledWith("users.removed", {
×
1202
                                        type: "remove",
1203
                                        data: docs.johnDoe,
1204
                                        opts: { softDelete: false }
1205
                                });
1206
                        });
1207

UNCOV
1208
                        it("should return the remaining entities", async () => {
×
UNCOV
1209
                                const rows = await svc.findEntities(ctx, { sort: "name" });
×
UNCOV
1210
                                expect(rows).toEqual([docs.janeDoe, docs.kevinJames]);
×
1211
                        });
1212

UNCOV
1213
                        it("should return empty if no updated entities", async () => {
×
UNCOV
1214
                                ctx.broadcast.mockClear();
×
UNCOV
1215
                                const rows = await svc.removeEntities(ctx, {
×
1216
                                        query: {
1217
                                                status: false,
1218
                                                age: { $lt: 10 }
1219
                                        }
1220
                                });
UNCOV
1221
                                expect(rows).toEqual([]);
×
1222

UNCOV
1223
                                expect(ctx.broadcast).toBeCalledTimes(0);
×
1224
                        });
1225
                });
1226
        });
1227

UNCOV
1228
        describe("Test soft delete feature", () => {
×
UNCOV
1229
                const broker = new ServiceBroker({ logger: false });
×
UNCOV
1230
                const svc = broker.createService({
×
1231
                        name: "users",
1232
                        mixins: [DbService({ adapter: getAdapter(), createActions: false })],
1233

1234
                        settings: {
1235
                                fields: {
1236
                                        id: {
1237
                                                type: "string",
1238
                                                primaryKey: true,
1239

1240
                                                columnName: "_id",
1241
                                                columnType: "integer"
1242
                                        },
1243
                                        name: { type: "string", trim: true, required: true },
1244
                                        age: { type: "number", columnType: "integer" },
1245
                                        status: {
1246
                                                type: "boolean",
1247
                                                default: true,
UNCOV
1248
                                                get: adapterType == "Knex" ? ({ value }) => !!value : undefined
×
1249
                                        },
1250
                                        createdAt: {
1251
                                                type: "number",
1252
                                                readonly: true,
1253
                                                columnType: "bigInteger",
UNCOV
1254
                                                onCreate: () => Date.now()
×
1255
                                        },
1256
                                        updatedAt: {
1257
                                                type: "number",
1258
                                                readonly: true,
1259
                                                columnType: "bigInteger",
1260
                                                onUpdate: () => Date.now()
×
1261
                                        },
1262
                                        deletedAt: {
1263
                                                type: "number",
1264
                                                readonly: true,
1265
                                                columnType: "bigInteger",
1266
                                                hidden: "byDefault",
1267
                                                default: null,
UNCOV
1268
                                                onRemove: () => Date.now()
×
1269
                                        }
1270
                                },
1271

1272
                                scopes: {
1273
                                        notDeleted: { deletedAt: null }
1274
                                },
1275

1276
                                defaultScopes: ["notDeleted"]
1277
                        },
1278

1279
                        async started() {
UNCOV
1280
                                const adapter = await this.getAdapter();
×
1281

UNCOV
1282
                                if (adapterType == "Knex") {
×
UNCOV
1283
                                        await adapter.createTable();
×
1284
                                }
1285

UNCOV
1286
                                await this.clearEntities();
×
1287
                        }
1288
                });
1289

UNCOV
1290
                beforeAll(() => broker.start());
×
UNCOV
1291
                afterAll(() => broker.stop());
×
1292

UNCOV
1293
                const ctx = Context.create(broker, null, {});
×
UNCOV
1294
                let docs = {};
×
UNCOV
1295
                jest.spyOn(ctx, "broadcast");
×
1296

UNCOV
1297
                describe("Set up", () => {
×
UNCOV
1298
                        it("should return empty array", async () => {
×
UNCOV
1299
                                const rows = await svc.findEntities(ctx);
×
UNCOV
1300
                                expect(rows).toEqual([]);
×
1301

UNCOV
1302
                                const count = await svc.countEntities(ctx);
×
UNCOV
1303
                                expect(count).toEqual(0);
×
1304

UNCOV
1305
                                expect(svc.$softDelete).toBe(true);
×
1306
                        });
1307

UNCOV
1308
                        it("create test entities", async () => {
×
UNCOV
1309
                                for (const [key, value] of Object.entries(TEST_DOCS)) {
×
UNCOV
1310
                                        docs[key] = await svc.createEntity(ctx, value);
×
1311
                                }
1312
                        });
1313
                });
1314

UNCOV
1315
                describe("Test removeEntity", () => {
×
UNCOV
1316
                        it("should return all rows", async () => {
×
UNCOV
1317
                                const rows = await svc.findEntities(ctx, {});
×
UNCOV
1318
                                expect(rows).toEqual(expect.arrayContaining(Object.values(docs)));
×
1319

UNCOV
1320
                                const count = await svc.countEntities(ctx, {});
×
UNCOV
1321
                                expect(count).toEqual(4);
×
1322
                        });
1323

UNCOV
1324
                        it("should soft delete a record", async () => {
×
UNCOV
1325
                                ctx.broadcast.mockClear();
×
1326

UNCOV
1327
                                const res = await svc.removeEntity(ctx, { id: docs.janeDoe.id });
×
UNCOV
1328
                                expect(res).toBe(docs.janeDoe.id);
×
1329

UNCOV
1330
                                const rows = await svc.findEntities(ctx, {});
×
UNCOV
1331
                                expect(rows).toEqual(
×
1332
                                        expect.arrayContaining([docs.johnDoe, docs.bobSmith, docs.kevinJames])
1333
                                );
1334

UNCOV
1335
                                const count = await svc.countEntities(ctx, {});
×
UNCOV
1336
                                expect(count).toEqual(3);
×
1337

UNCOV
1338
                                expect(ctx.broadcast).toBeCalledTimes(2);
×
UNCOV
1339
                                expect(ctx.broadcast).toBeCalledWith("cache.clean.users", {
×
1340
                                        type: "remove",
1341
                                        data: docs.janeDoe,
1342
                                        opts: { softDelete: true }
1343
                                });
UNCOV
1344
                                expect(ctx.broadcast).toBeCalledWith("users.removed", {
×
1345
                                        type: "remove",
1346
                                        data: docs.janeDoe,
1347
                                        opts: { softDelete: true }
1348
                                });
1349
                        });
1350

UNCOV
1351
                        it("should find the deleted record if scope is disabled", async () => {
×
UNCOV
1352
                                const rows = await svc.findEntities(ctx, { scope: false });
×
UNCOV
1353
                                expect(rows).toEqual(
×
1354
                                        expect.arrayContaining([
1355
                                                docs.johnDoe,
1356
                                                docs.janeDoe,
1357
                                                docs.bobSmith,
1358
                                                docs.kevinJames
1359
                                        ])
1360
                                );
1361

UNCOV
1362
                                const count = await svc.countEntities(ctx, { scope: false });
×
UNCOV
1363
                                expect(count).toEqual(4);
×
1364
                        });
1365
                });
1366

UNCOV
1367
                describe("Test removeEntities", () => {
×
UNCOV
1368
                        it("should soft delete multiple records", async () => {
×
UNCOV
1369
                                ctx.broadcast.mockClear();
×
1370

UNCOV
1371
                                const res = await svc.removeEntities(ctx, { query: { status: true } });
×
UNCOV
1372
                                expect(res).toEqual(expect.arrayContaining([docs.johnDoe.id, docs.bobSmith.id]));
×
1373

UNCOV
1374
                                const rows = await svc.findEntities(ctx, {});
×
UNCOV
1375
                                expect(rows).toEqual(expect.arrayContaining([docs.kevinJames]));
×
1376

UNCOV
1377
                                const count = await svc.countEntities(ctx, {});
×
UNCOV
1378
                                expect(count).toEqual(1);
×
1379

UNCOV
1380
                                expect(ctx.broadcast).toBeCalledTimes(4);
×
UNCOV
1381
                                expect(ctx.broadcast).toBeCalledWith("cache.clean.users", {
×
1382
                                        type: "remove",
1383
                                        data: docs.johnDoe,
1384
                                        opts: { softDelete: true }
1385
                                });
UNCOV
1386
                                expect(ctx.broadcast).toBeCalledWith("cache.clean.users", {
×
1387
                                        type: "remove",
1388
                                        data: docs.bobSmith,
1389
                                        opts: { softDelete: true }
1390
                                });
1391

UNCOV
1392
                                expect(ctx.broadcast).toBeCalledWith("users.removed", {
×
1393
                                        type: "remove",
1394
                                        data: docs.johnDoe,
1395
                                        opts: { softDelete: true }
1396
                                });
UNCOV
1397
                                expect(ctx.broadcast).toBeCalledWith("users.removed", {
×
1398
                                        type: "remove",
1399
                                        data: docs.bobSmith,
1400
                                        opts: { softDelete: true }
1401
                                });
1402
                        });
1403

UNCOV
1404
                        it("should find the deleted record if scope is disabled", async () => {
×
UNCOV
1405
                                const rows = await svc.findEntities(ctx, { scope: false });
×
UNCOV
1406
                                expect(rows).toEqual(
×
1407
                                        expect.arrayContaining([
1408
                                                docs.johnDoe,
1409
                                                docs.janeDoe,
1410
                                                docs.bobSmith,
1411
                                                docs.kevinJames
1412
                                        ])
1413
                                );
1414

UNCOV
1415
                                const count = await svc.countEntities(ctx, { scope: false });
×
UNCOV
1416
                                expect(count).toEqual(4);
×
1417
                        });
1418
                });
1419

UNCOV
1420
                describe("Test softDelete disabling", () => {
×
UNCOV
1421
                        it("should real delete a record", async () => {
×
UNCOV
1422
                                ctx.broadcast.mockClear();
×
1423

UNCOV
1424
                                const res = await svc.removeEntity(
×
1425
                                        ctx,
1426
                                        { id: docs.janeDoe.id },
1427
                                        { softDelete: false, scope: false }
1428
                                );
UNCOV
1429
                                expect(res).toBe(docs.janeDoe.id);
×
1430

UNCOV
1431
                                const rows = await svc.findEntities(ctx, {});
×
UNCOV
1432
                                expect(rows).toEqual(expect.arrayContaining([docs.kevinJames]));
×
1433

UNCOV
1434
                                const count = await svc.countEntities(ctx, {});
×
UNCOV
1435
                                expect(count).toEqual(1);
×
1436

UNCOV
1437
                                expect(ctx.broadcast).toBeCalledTimes(2);
×
UNCOV
1438
                                expect(ctx.broadcast).toBeCalledWith("cache.clean.users", {
×
1439
                                        type: "remove",
1440
                                        data: docs.janeDoe,
1441
                                        opts: { scope: false, softDelete: false }
1442
                                });
UNCOV
1443
                                expect(ctx.broadcast).toBeCalledWith("users.removed", {
×
1444
                                        type: "remove",
1445
                                        data: docs.janeDoe,
1446
                                        opts: { scope: false, softDelete: false }
1447
                                });
1448
                        });
1449

UNCOV
1450
                        it("should not find the deleted record if scope is disabled", async () => {
×
UNCOV
1451
                                const rows = await svc.findEntities(ctx, { scope: false });
×
UNCOV
1452
                                expect(rows).toEqual(
×
1453
                                        expect.arrayContaining([docs.johnDoe, docs.bobSmith, docs.kevinJames])
1454
                                );
1455

UNCOV
1456
                                const count = await svc.countEntities(ctx, { scope: false });
×
UNCOV
1457
                                expect(count).toEqual(3);
×
1458
                        });
1459

UNCOV
1460
                        it("should real delete multiple records", async () => {
×
UNCOV
1461
                                ctx.broadcast.mockClear();
×
1462

UNCOV
1463
                                const res = await svc.removeEntities(
×
1464
                                        ctx,
1465
                                        { query: { status: true }, scope: false },
1466
                                        { softDelete: false }
1467
                                );
UNCOV
1468
                                expect(res).toEqual(expect.arrayContaining([docs.johnDoe.id, docs.bobSmith.id]));
×
1469

UNCOV
1470
                                const rows = await svc.findEntities(ctx, {});
×
UNCOV
1471
                                expect(rows).toEqual(expect.arrayContaining([docs.kevinJames]));
×
1472

UNCOV
1473
                                const count = await svc.countEntities(ctx, {});
×
UNCOV
1474
                                expect(count).toEqual(1);
×
1475

UNCOV
1476
                                expect(ctx.broadcast).toBeCalledTimes(4);
×
UNCOV
1477
                                expect(ctx.broadcast).toBeCalledWith("cache.clean.users", {
×
1478
                                        type: "remove",
1479
                                        data: docs.johnDoe,
1480
                                        opts: { scope: false, softDelete: false }
1481
                                });
UNCOV
1482
                                expect(ctx.broadcast).toBeCalledWith("cache.clean.users", {
×
1483
                                        type: "remove",
1484
                                        data: docs.bobSmith,
1485
                                        opts: { scope: false, softDelete: false }
1486
                                });
1487

UNCOV
1488
                                expect(ctx.broadcast).toBeCalledWith("users.removed", {
×
1489
                                        type: "remove",
1490
                                        data: docs.johnDoe,
1491
                                        opts: { scope: false, softDelete: false }
1492
                                });
UNCOV
1493
                                expect(ctx.broadcast).toBeCalledWith("users.removed", {
×
1494
                                        type: "remove",
1495
                                        data: docs.bobSmith,
1496
                                        opts: { scope: false, softDelete: false }
1497
                                });
1498
                        });
1499

UNCOV
1500
                        it("should find the deleted record if scope is disabled", async () => {
×
UNCOV
1501
                                const rows = await svc.findEntities(ctx, { scope: false });
×
UNCOV
1502
                                expect(rows).toEqual(expect.arrayContaining([docs.kevinJames]));
×
1503

UNCOV
1504
                                const count = await svc.countEntities(ctx, { scope: false });
×
UNCOV
1505
                                expect(count).toEqual(1);
×
1506
                        });
1507
                });
1508
        });
1509

UNCOV
1510
        describe("Test methods withouth 'ctx' (and entityChangedOldEntity)", () => {
×
UNCOV
1511
                const broker = new ServiceBroker({ logger: false });
×
UNCOV
1512
                const svc = broker.createService({
×
1513
                        name: "users",
1514
                        mixins: [
1515
                                DbService({
1516
                                        adapter: getAdapter(),
1517
                                        createActions: false,
1518
                                        entityChangedEventType: "emit",
1519
                                        entityChangedOldEntity: true
1520
                                })
1521
                        ],
1522
                        settings: {
1523
                                fields: {
1524
                                        id: {
1525
                                                type: "string",
1526
                                                primaryKey: true,
1527
                                                columnName: "_id",
1528
                                                columnType: "integer"
1529
                                        },
1530
                                        name: { type: "string", required: true },
1531
                                        email: { type: "string", required: true },
1532
                                        age: {
1533
                                                type: "number",
1534
                                                integer: true,
1535
                                                positive: true,
1536
                                                required: true,
1537
                                                columnType: "integer"
1538
                                        }
1539
                                }
1540
                        },
1541
                        async started() {
UNCOV
1542
                                const adapter = await this.getAdapter();
×
1543

UNCOV
1544
                                if (adapterType == "Knex") {
×
UNCOV
1545
                                        await adapter.createTable();
×
1546
                                }
1547

UNCOV
1548
                                await this.clearEntities();
×
1549
                        }
1550
                });
1551

UNCOV
1552
                beforeAll(() => broker.start());
×
UNCOV
1553
                afterAll(() => broker.stop());
×
1554

UNCOV
1555
                jest.spyOn(broker, "emit");
×
1556

1557
                let entity;
1558

UNCOV
1559
                it("setup", async () => {
×
UNCOV
1560
                        const rows = await svc.findEntities(null, {});
×
UNCOV
1561
                        expect(rows).toEqual([]);
×
1562

UNCOV
1563
                        const count = await svc.countEntities(null, {});
×
UNCOV
1564
                        expect(count).toEqual(0);
×
1565
                });
1566

UNCOV
1567
                it("should throw error if missing a field", async () => {
×
UNCOV
1568
                        expect.assertions(2);
×
UNCOV
1569
                        try {
×
UNCOV
1570
                                await svc.createEntity(null, {
×
1571
                                        name: "John Doe",
1572
                                        email: "john.doe@moleculer.services"
1573
                                });
1574
                        } catch (err) {
UNCOV
1575
                                expect(err).toBeInstanceOf(ValidationError);
×
UNCOV
1576
                                expect(err.data).toEqual([
×
1577
                                        {
1578
                                                actual: undefined,
1579
                                                field: "age",
1580
                                                message: "The 'age' field is required.",
1581
                                                type: "required"
1582
                                        }
1583
                                ]);
1584
                        }
1585
                });
1586

UNCOV
1587
                it("should create entity", async () => {
×
UNCOV
1588
                        broker.emit.mockClear();
×
1589

UNCOV
1590
                        entity = await svc.createEntity(null, {
×
1591
                                name: "John Doe",
1592
                                email: "john.doe@moleculer.services",
1593
                                age: 30
1594
                        });
1595

UNCOV
1596
                        expect(entity).toEqual({
×
1597
                                id: expectedID,
1598
                                name: "John Doe",
1599
                                email: "john.doe@moleculer.services",
1600
                                age: 30
1601
                        });
1602

UNCOV
1603
                        expect(broker.emit).toBeCalledTimes(1);
×
UNCOV
1604
                        expect(broker.emit).toBeCalledWith("users.created", {
×
1605
                                type: "create",
1606
                                data: entity,
1607
                                oldData: null,
1608
                                opts: {}
1609
                        });
1610
                });
1611

UNCOV
1612
                it("should update entity", async () => {
×
UNCOV
1613
                        broker.emit.mockClear();
×
1614

UNCOV
1615
                        const res = await svc.updateEntity(null, {
×
1616
                                id: entity.id,
1617
                                name: "Dr. John Doe",
1618
                                age: 33
1619
                        });
1620

UNCOV
1621
                        expect(res).toEqual({
×
1622
                                id: entity.id,
1623
                                name: "Dr. John Doe",
1624
                                email: "john.doe@moleculer.services",
1625
                                age: 33
1626
                        });
1627

UNCOV
1628
                        expect(broker.emit).toBeCalledTimes(1);
×
UNCOV
1629
                        expect(broker.emit).toBeCalledWith("users.updated", {
×
1630
                                type: "update",
1631
                                data: res,
1632
                                oldData: {
1633
                                        id: entity.id,
1634
                                        name: "John Doe",
1635
                                        email: "john.doe@moleculer.services",
1636
                                        age: 30
1637
                                },
1638
                                opts: {}
1639
                        });
1640

UNCOV
1641
                        entity = res;
×
1642
                });
1643

UNCOV
1644
                it("should find entities", async () => {
×
UNCOV
1645
                        const rows = await svc.findEntities(null, {});
×
UNCOV
1646
                        expect(rows).toEqual([
×
1647
                                {
1648
                                        id: entity.id,
1649
                                        name: "Dr. John Doe",
1650
                                        email: "john.doe@moleculer.services",
1651
                                        age: 33
1652
                                }
1653
                        ]);
1654
                });
1655

UNCOV
1656
                it("should count entities", async () => {
×
UNCOV
1657
                        const rows = await svc.countEntities(null, {});
×
UNCOV
1658
                        expect(rows).toBe(1);
×
1659
                });
1660

UNCOV
1661
                it("should replace entity", async () => {
×
UNCOV
1662
                        broker.emit.mockClear();
×
1663

UNCOV
1664
                        const res = await svc.replaceEntity(null, {
×
1665
                                id: entity.id,
1666
                                name: "Mr. John Doe",
1667
                                email: "john.doe@moleculer.services",
1668
                                age: 44
1669
                        });
1670

UNCOV
1671
                        expect(res).toEqual({
×
1672
                                id: entity.id,
1673
                                name: "Mr. John Doe",
1674
                                email: "john.doe@moleculer.services",
1675
                                age: 44
1676
                        });
1677

UNCOV
1678
                        expect(broker.emit).toBeCalledTimes(1);
×
UNCOV
1679
                        expect(broker.emit).toBeCalledWith("users.replaced", {
×
1680
                                type: "replace",
1681
                                data: res,
1682
                                oldData: {
1683
                                        id: entity.id,
1684
                                        name: "Dr. John Doe",
1685
                                        email: "john.doe@moleculer.services",
1686
                                        age: 33
1687
                                },
1688
                                opts: {}
1689
                        });
1690

UNCOV
1691
                        entity = res;
×
1692
                });
1693

UNCOV
1694
                it("should remove entity", async () => {
×
UNCOV
1695
                        broker.emit.mockClear();
×
1696

UNCOV
1697
                        const res = await svc.removeEntity(null, { id: entity.id });
×
1698

UNCOV
1699
                        expect(res).toEqual(entity.id);
×
1700

UNCOV
1701
                        expect(broker.emit).toBeCalledTimes(1);
×
UNCOV
1702
                        expect(broker.emit).toBeCalledWith("users.removed", {
×
1703
                                type: "remove",
1704
                                data: entity,
1705
                                oldData: null,
1706
                                opts: { softDelete: false }
1707
                        });
1708
                });
1709

UNCOV
1710
                it("should clear entities", async () => {
×
UNCOV
1711
                        broker.emit.mockClear();
×
1712

UNCOV
1713
                        const res = await svc.clearEntities();
×
1714

UNCOV
1715
                        expect(res).toEqual(0);
×
1716

UNCOV
1717
                        expect(broker.emit).toBeCalledTimes(1);
×
UNCOV
1718
                        expect(broker.emit).toBeCalledWith("users.cleared", {
×
1719
                                type: "clear",
1720
                                data: null,
1721
                                oldData: null,
1722
                                opts: {}
1723
                        });
1724
                });
1725
        });
1726

UNCOV
1727
        describe("Test custom service hooks", () => {
×
UNCOV
1728
                const broker = new ServiceBroker({ logger: false });
×
1729

UNCOV
1730
                const adapterConnected = jest.fn();
×
UNCOV
1731
                const adapterDisconnected = jest.fn();
×
UNCOV
1732
                const afterResolveEntities1 = jest.fn();
×
UNCOV
1733
                const afterResolveEntities2 = jest.fn();
×
1734

UNCOV
1735
                const DbServiceAdapterDef = getAdapter();
×
1736

UNCOV
1737
                const svc = broker.createService({
×
1738
                        name: "users",
1739
                        mixins: [DbService({ adapter: DbServiceAdapterDef })],
1740

1741
                        hooks: {
1742
                                customs: {
1743
                                        adapterConnected,
1744
                                        adapterDisconnected,
1745
                                        afterResolveEntities: [afterResolveEntities1, afterResolveEntities2]
1746
                                }
1747
                        },
1748

1749
                        settings: {
1750
                                fields: {
1751
                                        id: { type: "string", primaryKey: true, columnName: "_id" },
1752
                                        name: { type: "string", trim: true, required: true, columnName: "full_name" },
1753
                                        status: {
1754
                                                type: "boolean",
1755
                                                default: true,
UNCOV
1756
                                                get: adapterType == "Knex" ? ({ value }) => !!value : undefined
×
1757
                                        }
1758
                                }
1759
                        },
1760

1761
                        async started() {
UNCOV
1762
                                const adapter = await this.getAdapter();
×
1763

UNCOV
1764
                                if (adapterType == "Knex") {
×
UNCOV
1765
                                        await adapter.createTable();
×
1766
                                }
1767

UNCOV
1768
                                await this.clearEntities();
×
1769
                        }
1770
                });
1771

UNCOV
1772
                beforeAll(() => broker.start());
×
UNCOV
1773
                afterAll(() => broker.stop());
×
1774

UNCOV
1775
                let docs = {};
×
1776

UNCOV
1777
                describe("Set up", () => {
×
UNCOV
1778
                        it("create test entities", async () => {
×
UNCOV
1779
                                for (const [key, value] of Object.entries(TEST_DOCS)) {
×
UNCOV
1780
                                        docs[key] = await broker.call("users.create", Object.assign({}, value));
×
1781
                                }
1782
                        });
1783
                });
1784

UNCOV
1785
                describe("Test hooks", () => {
×
UNCOV
1786
                        it("should called adapterConnected", async () => {
×
UNCOV
1787
                                const adapter = await svc.getAdapter();
×
1788

UNCOV
1789
                                expect(adapterConnected).toBeCalledTimes(1);
×
UNCOV
1790
                                expect(adapterConnected).toBeCalledWith(adapter, "default", DbServiceAdapterDef);
×
1791
                        });
1792

UNCOV
1793
                        it("should call both afterResolveEntities", async () => {
×
UNCOV
1794
                                const rawEntity = await svc.resolveEntities(
×
1795
                                        null,
1796
                                        { id: docs.janeDoe.id },
1797
                                        { transform: false }
1798
                                );
UNCOV
1799
                                afterResolveEntities1.mockClear();
×
UNCOV
1800
                                afterResolveEntities2.mockClear();
×
1801

UNCOV
1802
                                const res = await broker.call("users.resolve", { id: docs.janeDoe.id });
×
UNCOV
1803
                                expect(res).toEqual(docs.janeDoe);
×
1804

UNCOV
1805
                                expect(afterResolveEntities1).toBeCalledTimes(1);
×
UNCOV
1806
                                expect(afterResolveEntities1).toBeCalledWith(
×
1807
                                        expect.any(Context),
1808
                                        "" + docs.janeDoe.id,
1809
                                        rawEntity,
1810
                                        { id: "" + docs.janeDoe.id },
1811
                                        { throwIfNotExist: undefined }
1812
                                );
1813

UNCOV
1814
                                expect(afterResolveEntities2).toBeCalledTimes(1);
×
UNCOV
1815
                                expect(afterResolveEntities2).toBeCalledWith(
×
1816
                                        expect.any(Context),
1817
                                        "" + docs.janeDoe.id,
1818
                                        rawEntity,
1819
                                        { id: "" + docs.janeDoe.id },
1820
                                        { throwIfNotExist: undefined }
1821
                                );
1822
                        });
1823

UNCOV
1824
                        it("should call both afterResolveEntities with multi ID", async () => {
×
UNCOV
1825
                                const rawEntities = await svc.resolveEntities(
×
1826
                                        null,
1827
                                        { id: [docs.janeDoe.id, docs.kevinJames.id] },
1828
                                        { transform: false }
1829
                                );
UNCOV
1830
                                afterResolveEntities1.mockClear();
×
UNCOV
1831
                                afterResolveEntities2.mockClear();
×
1832

UNCOV
1833
                                const res = await broker.call("users.resolve", {
×
1834
                                        id: [docs.janeDoe.id, docs.kevinJames.id]
1835
                                });
UNCOV
1836
                                expect(res).toEqual(expect.arrayContaining([docs.janeDoe, docs.kevinJames]));
×
1837

UNCOV
1838
                                expect(afterResolveEntities1).toBeCalledTimes(1);
×
UNCOV
1839
                                expect(afterResolveEntities1).toBeCalledWith(
×
1840
                                        expect.any(Context),
1841
                                        ["" + docs.janeDoe.id, "" + docs.kevinJames.id],
1842
                                        expect.arrayContaining(rawEntities),
1843
                                        { id: ["" + docs.janeDoe.id, "" + docs.kevinJames.id] },
1844
                                        { throwIfNotExist: undefined }
1845
                                );
1846

UNCOV
1847
                                expect(afterResolveEntities2).toBeCalledTimes(1);
×
UNCOV
1848
                                expect(afterResolveEntities2).toBeCalledWith(
×
1849
                                        expect.any(Context),
1850
                                        ["" + docs.janeDoe.id, "" + docs.kevinJames.id],
1851
                                        expect.arrayContaining(rawEntities),
1852
                                        { id: ["" + docs.janeDoe.id, "" + docs.kevinJames.id] },
1853
                                        { throwIfNotExist: undefined }
1854
                                );
1855
                        });
1856

UNCOV
1857
                        it("should called adapterDisconnected", async () => {
×
UNCOV
1858
                                const adapter = await svc.getAdapter();
×
1859

UNCOV
1860
                                await svc._disconnectAll();
×
1861

UNCOV
1862
                                expect(adapterDisconnected).toBeCalledTimes(1);
×
UNCOV
1863
                                expect(adapterDisconnected).toBeCalledWith(adapter, "default");
×
1864
                        });
1865
                });
1866
        });
1867
};
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