@drax/crud-back 3.6.0 → 3.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/controllers/AbstractFastifyController.js +20 -8
- package/dist/regexs/QueryFilterRegex.js +1 -1
- package/dist/schemas/FindSchema.js +1 -1
- package/dist/schemas/GroupBySchema.js +1 -1
- package/dist/schemas/PaginateSchema.js +1 -1
- package/package.json +4 -4
- package/src/controllers/AbstractFastifyController.ts +24 -12
- package/src/regexs/QueryFilterRegex.ts +1 -1
- package/src/schemas/FindSchema.ts +1 -1
- package/src/schemas/GroupBySchema.ts +1 -1
- package/src/schemas/PaginateSchema.ts +1 -1
- package/test/controllers/PersonController.test.ts +64 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/types/controllers/AbstractFastifyController.d.ts +1 -0
- package/types/controllers/AbstractFastifyController.d.ts.map +1 -1
- package/types/regexs/QueryFilterRegex.d.ts.map +1 -1
|
@@ -42,9 +42,9 @@ class AbstractFastifyController extends CommonController {
|
|
|
42
42
|
const filterArray = stringFilters.split("|");
|
|
43
43
|
const filters = [];
|
|
44
44
|
filterArray.forEach((filter) => {
|
|
45
|
-
const [field, operator, value] = filter.split(";");
|
|
45
|
+
const [field, operator, value, orGroup] = filter.split(";");
|
|
46
46
|
if (field && operator && (operator === 'empty' || (value !== undefined && value !== ''))) {
|
|
47
|
-
filters.push({ field, operator, value });
|
|
47
|
+
filters.push({ field, operator, value, orGroup: orGroup || undefined });
|
|
48
48
|
}
|
|
49
49
|
});
|
|
50
50
|
return filters;
|
|
@@ -260,6 +260,10 @@ class AbstractFastifyController extends CommonController {
|
|
|
260
260
|
async postUpdatePartial(request, item) {
|
|
261
261
|
return item;
|
|
262
262
|
}
|
|
263
|
+
//Sobrescribir este metodo para manipular filtros en operaciones de lectura
|
|
264
|
+
async preRead(request, filters) {
|
|
265
|
+
return filters;
|
|
266
|
+
}
|
|
263
267
|
//Sobrescribir este metodo para manipular items a devolver en operaciones de lectura
|
|
264
268
|
async postRead(request, item) {
|
|
265
269
|
return item;
|
|
@@ -414,8 +418,9 @@ class AbstractFastifyController extends CommonController {
|
|
|
414
418
|
const orderBy = request.query.orderBy;
|
|
415
419
|
const order = request.query.order;
|
|
416
420
|
const search = (_a = request.query).search ?? (_a.search = undefined);
|
|
417
|
-
|
|
421
|
+
let filters = this.parseFilters(request.query.filters);
|
|
418
422
|
this.applyUserAndTenantFilters(filters, request.rbac);
|
|
423
|
+
filters = await this.preRead(request, filters);
|
|
419
424
|
let items = await this.service.find({ search, filters, order, orderBy, limit });
|
|
420
425
|
items = await this.postReadItems(request, items);
|
|
421
426
|
return items;
|
|
@@ -429,7 +434,8 @@ class AbstractFastifyController extends CommonController {
|
|
|
429
434
|
try {
|
|
430
435
|
request.rbac.assertPermission(this.permission.View);
|
|
431
436
|
const search = (_a = request.query).search ?? (_a.search = undefined);
|
|
432
|
-
|
|
437
|
+
let filters = this.parseFilters(request.query.filters);
|
|
438
|
+
filters = await this.preRead(request, filters);
|
|
433
439
|
this.applyUserAndTenantFilters(filters, request.rbac);
|
|
434
440
|
let item = await this.service.findOne({ search, filters });
|
|
435
441
|
item = await this.postReadItem(request, item);
|
|
@@ -451,6 +457,7 @@ class AbstractFastifyController extends CommonController {
|
|
|
451
457
|
const value = request.params.value;
|
|
452
458
|
let filters = [];
|
|
453
459
|
this.applyUserAndTenantFilters(filters, request.rbac);
|
|
460
|
+
filters = await this.preRead(request, filters);
|
|
454
461
|
let items = await this.service.findBy(field, value, limit, filters);
|
|
455
462
|
items = await this.postReadItems(request, items);
|
|
456
463
|
return items;
|
|
@@ -470,6 +477,7 @@ class AbstractFastifyController extends CommonController {
|
|
|
470
477
|
const value = request.params.value;
|
|
471
478
|
let filters = [];
|
|
472
479
|
this.applyUserAndTenantFilters(filters, request.rbac);
|
|
480
|
+
filters = await this.preRead(request, filters);
|
|
473
481
|
let item = await this.service.findOneBy(field, value, filters);
|
|
474
482
|
item = await this.postReadItem(request, item);
|
|
475
483
|
return item;
|
|
@@ -482,9 +490,10 @@ class AbstractFastifyController extends CommonController {
|
|
|
482
490
|
try {
|
|
483
491
|
request.rbac.assertPermission(this.permission.View);
|
|
484
492
|
const search = request.query.search;
|
|
485
|
-
|
|
493
|
+
let filters = [];
|
|
486
494
|
const limit = this.defaultLimit;
|
|
487
495
|
this.applyUserAndTenantFilters(filters, request.rbac);
|
|
496
|
+
filters = await this.preRead(request, filters);
|
|
488
497
|
let items = await this.service.search(search, limit, filters);
|
|
489
498
|
items = await this.postReadItems(request, items);
|
|
490
499
|
return items;
|
|
@@ -504,8 +513,9 @@ class AbstractFastifyController extends CommonController {
|
|
|
504
513
|
const orderBy = request.query.orderBy;
|
|
505
514
|
const order = request.query.order;
|
|
506
515
|
const search = request.query.search;
|
|
507
|
-
|
|
516
|
+
let filters = this.parseFilters(request.query.filters);
|
|
508
517
|
this.applyUserAndTenantFilters(filters, request.rbac);
|
|
518
|
+
filters = await this.preRead(request, filters);
|
|
509
519
|
let paginateResult = await this.service.paginate({ page, limit, orderBy, order, search, filters });
|
|
510
520
|
paginateResult = await this.postReadPaginate(request, paginateResult);
|
|
511
521
|
return paginateResult;
|
|
@@ -526,8 +536,9 @@ class AbstractFastifyController extends CommonController {
|
|
|
526
536
|
const orderBy = request.query.orderBy;
|
|
527
537
|
const order = request.query.order;
|
|
528
538
|
const search = request.query.search;
|
|
529
|
-
|
|
539
|
+
let filters = this.parseFilters(request.query.filters);
|
|
530
540
|
this.applyUserAndTenantFilters(filters, request.rbac);
|
|
541
|
+
filters = await this.preRead(request, filters);
|
|
531
542
|
const year = (new Date().getFullYear()).toString();
|
|
532
543
|
const month = (new Date().getMonth() + 1).toString().padStart(2, '0');
|
|
533
544
|
const exportPath = 'exports';
|
|
@@ -568,8 +579,9 @@ class AbstractFastifyController extends CommonController {
|
|
|
568
579
|
if (fields.length === 0) {
|
|
569
580
|
throw new BadRequestError('At least one field is required for grouping');
|
|
570
581
|
}
|
|
571
|
-
|
|
582
|
+
let filters = this.parseFilters(request.query.filters);
|
|
572
583
|
this.applyUserAndTenantFilters(filters, request.rbac);
|
|
584
|
+
filters = await this.preRead(request, filters);
|
|
573
585
|
const result = await this.service.groupBy({ fields, filters, dateFormat });
|
|
574
586
|
return result;
|
|
575
587
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
const QueryFilterRegex = /^(?:[a-zA-Z0-9_.\-]+;(?:eq|like|ne|in|nin|gt|gte|lt|lte|empty);[a-zA-Z0-9_.\-:\., áéíóúÁÉÍÓÚ]*)(?:\|[a-zA-Z0-9_.\-]+;(?:eq|like|ne|in|nin|gt|gte|lt|lte|empty);[a-zA-Z0-9_.\-:\., áéíóúÁÉÍÓÚ]*)*$/;
|
|
1
|
+
const QueryFilterRegex = /^(?:[a-zA-Z0-9_.\-]+;(?:eq|like|ne|in|nin|gt|gte|lt|lte|empty);[a-zA-Z0-9_.\-:\., áéíóúÁÉÍÓÚ]*(?:;[a-zA-Z0-9_.\-]+)?)(?:\|[a-zA-Z0-9_.\-]+;(?:eq|like|ne|in|nin|gt|gte|lt|lte|empty);[a-zA-Z0-9_.\-:\., áéíóúÁÉÍÓÚ]*(?:;[a-zA-Z0-9_.\-]+)?)*$/;
|
|
2
2
|
export default QueryFilterRegex;
|
|
3
3
|
export { QueryFilterRegex };
|
|
@@ -4,6 +4,6 @@ const FindQuerySchema = z.object({
|
|
|
4
4
|
orderBy: z.string().optional(),
|
|
5
5
|
order: z.enum(["asc", "desc"]).optional(),
|
|
6
6
|
search: z.string().optional(),
|
|
7
|
-
filters: z.string().regex(QueryFilterRegex).optional().describe("Format: field;operator;value|field;operator;value|..."),
|
|
7
|
+
filters: z.string().regex(QueryFilterRegex).optional().describe("Format: field;operator;value[;orGroup]|field;operator;value[;orGroup]|..."),
|
|
8
8
|
});
|
|
9
9
|
export { FindQuerySchema };
|
|
@@ -2,6 +2,6 @@ import z from "zod";
|
|
|
2
2
|
import QueryFilterRegex from "../regexs/QueryFilterRegex.js";
|
|
3
3
|
const GroupByQuerySchema = z.object({
|
|
4
4
|
fields: z.array(z.string()).min(1).max(10),
|
|
5
|
-
filters: z.string().regex(QueryFilterRegex).optional().describe("Format: field;operator;value|field;operator;value|..."),
|
|
5
|
+
filters: z.string().regex(QueryFilterRegex).optional().describe("Format: field;operator;value[;orGroup]|field;operator;value[;orGroup]|..."),
|
|
6
6
|
});
|
|
7
7
|
export { GroupByQuerySchema };
|
|
@@ -6,7 +6,7 @@ const PaginateQuerySchema = z.object({
|
|
|
6
6
|
orderBy: z.string().optional(),
|
|
7
7
|
order: z.enum(["asc", "desc"]).optional(),
|
|
8
8
|
search: z.string().optional(),
|
|
9
|
-
filters: z.string().regex(QueryFilterRegex).optional().describe("Format: field;operator;value|field;operator;value|..."),
|
|
9
|
+
filters: z.string().regex(QueryFilterRegex).optional().describe("Format: field;operator;value[;orGroup]|field;operator;value[;orGroup]|..."),
|
|
10
10
|
});
|
|
11
11
|
const PaginateBodyResponseSchema = z.object({
|
|
12
12
|
page: z.number(),
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "3.
|
|
6
|
+
"version": "3.10.0",
|
|
7
7
|
"description": "Crud utils across modules",
|
|
8
8
|
"main": "dist/index.js",
|
|
9
9
|
"types": "types/index.d.ts",
|
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
"author": "Cristian Incarnato & Drax Team",
|
|
23
23
|
"license": "ISC",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@drax/common-back": "^3.
|
|
25
|
+
"@drax/common-back": "^3.10.0",
|
|
26
26
|
"@drax/common-share": "^3.0.0",
|
|
27
27
|
"@drax/identity-share": "^3.0.0",
|
|
28
|
-
"@drax/media-back": "^3.
|
|
28
|
+
"@drax/media-back": "^3.10.0",
|
|
29
29
|
"@graphql-tools/load-files": "^7.0.0",
|
|
30
30
|
"@graphql-tools/merge": "^9.0.4",
|
|
31
31
|
"mongoose": "^8.23.0",
|
|
@@ -47,5 +47,5 @@
|
|
|
47
47
|
"typescript": "^5.9.3",
|
|
48
48
|
"vitest": "^3.2.4"
|
|
49
49
|
},
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "063b6aba11e891c5374c2d3de6546a3ff120b4c9"
|
|
51
51
|
}
|
|
@@ -112,10 +112,10 @@ class AbstractFastifyController<T, C, U> extends CommonController {
|
|
|
112
112
|
const filterArray = stringFilters.split("|")
|
|
113
113
|
const filters: IDraxFieldFilter[] = []
|
|
114
114
|
filterArray.forEach((filter) => {
|
|
115
|
-
const [field, operator, value] = filter.split(";")
|
|
115
|
+
const [field, operator, value, orGroup] = filter.split(";")
|
|
116
116
|
|
|
117
117
|
if (field && operator && (operator === 'empty' || (value !== undefined && value !== ''))) {
|
|
118
|
-
filters.push({field, operator, value})
|
|
118
|
+
filters.push({field, operator, value, orGroup: orGroup || undefined})
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
})
|
|
@@ -367,6 +367,11 @@ class AbstractFastifyController<T, C, U> extends CommonController {
|
|
|
367
367
|
return item
|
|
368
368
|
}
|
|
369
369
|
|
|
370
|
+
//Sobrescribir este metodo para manipular filtros en operaciones de lectura
|
|
371
|
+
async preRead(request: CustomRequest, filters: IDraxFieldFilter[]):Promise<IDraxFieldFilter[]> {
|
|
372
|
+
return filters
|
|
373
|
+
}
|
|
374
|
+
|
|
370
375
|
//Sobrescribir este metodo para manipular items a devolver en operaciones de lectura
|
|
371
376
|
async postRead(request: CustomRequest, item: T) {
|
|
372
377
|
return item
|
|
@@ -562,11 +567,11 @@ class AbstractFastifyController<T, C, U> extends CommonController {
|
|
|
562
567
|
const orderBy = request.query.orderBy
|
|
563
568
|
const order = request.query.order
|
|
564
569
|
const search = request.query.search ??= undefined
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
570
|
+
let filters = this.parseFilters(request.query.filters)
|
|
568
571
|
this.applyUserAndTenantFilters(filters, request.rbac);
|
|
569
572
|
|
|
573
|
+
filters = await this.preRead(request, filters)
|
|
574
|
+
|
|
570
575
|
let items = await this.service.find({search, filters, order, orderBy, limit})
|
|
571
576
|
|
|
572
577
|
items = await this.postReadItems(request, items)
|
|
@@ -582,7 +587,8 @@ class AbstractFastifyController<T, C, U> extends CommonController {
|
|
|
582
587
|
request.rbac.assertPermission(this.permission.View)
|
|
583
588
|
|
|
584
589
|
const search = request.query.search ??= undefined
|
|
585
|
-
|
|
590
|
+
let filters = this.parseFilters(request.query.filters)
|
|
591
|
+
filters = await this.preRead(request, filters)
|
|
586
592
|
|
|
587
593
|
this.applyUserAndTenantFilters(filters, request.rbac);
|
|
588
594
|
|
|
@@ -610,6 +616,7 @@ class AbstractFastifyController<T, C, U> extends CommonController {
|
|
|
610
616
|
|
|
611
617
|
let filters = []
|
|
612
618
|
this.applyUserAndTenantFilters(filters, request.rbac);
|
|
619
|
+
filters = await this.preRead(request, filters)
|
|
613
620
|
|
|
614
621
|
let items = await this.service.findBy(field, value, limit, filters)
|
|
615
622
|
|
|
@@ -635,6 +642,7 @@ class AbstractFastifyController<T, C, U> extends CommonController {
|
|
|
635
642
|
|
|
636
643
|
let filters = []
|
|
637
644
|
this.applyUserAndTenantFilters(filters, request.rbac);
|
|
645
|
+
filters = await this.preRead(request, filters)
|
|
638
646
|
|
|
639
647
|
let item = await this.service.findOneBy(field, value, filters)
|
|
640
648
|
|
|
@@ -652,10 +660,11 @@ class AbstractFastifyController<T, C, U> extends CommonController {
|
|
|
652
660
|
try {
|
|
653
661
|
request.rbac.assertPermission(this.permission.View)
|
|
654
662
|
const search = request.query.search
|
|
655
|
-
|
|
663
|
+
let filters = []
|
|
656
664
|
const limit = this.defaultLimit
|
|
657
665
|
|
|
658
666
|
this.applyUserAndTenantFilters(filters, request.rbac);
|
|
667
|
+
filters = await this.preRead(request, filters)
|
|
659
668
|
|
|
660
669
|
let items = await this.service.search(search, limit, filters)
|
|
661
670
|
items = await this.postReadItems(request, items)
|
|
@@ -679,9 +688,9 @@ class AbstractFastifyController<T, C, U> extends CommonController {
|
|
|
679
688
|
const orderBy = request.query.orderBy
|
|
680
689
|
const order = request.query.order
|
|
681
690
|
const search = request.query.search
|
|
682
|
-
|
|
691
|
+
let filters: IDraxFieldFilter[] = this.parseFilters(request.query.filters)
|
|
683
692
|
this.applyUserAndTenantFilters(filters, request.rbac);
|
|
684
|
-
|
|
693
|
+
filters = await this.preRead(request, filters)
|
|
685
694
|
|
|
686
695
|
let paginateResult = await this.service.paginate({page, limit, orderBy, order, search, filters})
|
|
687
696
|
paginateResult = await this.postReadPaginate(request, paginateResult)
|
|
@@ -705,9 +714,12 @@ class AbstractFastifyController<T, C, U> extends CommonController {
|
|
|
705
714
|
const orderBy = request.query.orderBy
|
|
706
715
|
const order = request.query.order
|
|
707
716
|
const search = request.query.search
|
|
708
|
-
|
|
717
|
+
let filters = this.parseFilters(request.query.filters)
|
|
709
718
|
|
|
710
719
|
this.applyUserAndTenantFilters(filters, request.rbac);
|
|
720
|
+
filters = await this.preRead(request, filters)
|
|
721
|
+
|
|
722
|
+
|
|
711
723
|
|
|
712
724
|
const year = (new Date().getFullYear()).toString()
|
|
713
725
|
const month = (new Date().getMonth() + 1).toString().padStart(2, '0')
|
|
@@ -760,9 +772,9 @@ class AbstractFastifyController<T, C, U> extends CommonController {
|
|
|
760
772
|
throw new BadRequestError('At least one field is required for grouping')
|
|
761
773
|
}
|
|
762
774
|
|
|
763
|
-
|
|
775
|
+
let filters: IDraxFieldFilter[] = this.parseFilters(request.query.filters)
|
|
764
776
|
this.applyUserAndTenantFilters(filters, request.rbac)
|
|
765
|
-
|
|
777
|
+
filters = await this.preRead(request, filters)
|
|
766
778
|
|
|
767
779
|
const result = await this.service.groupBy({fields, filters, dateFormat})
|
|
768
780
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const QueryFilterRegex = /^(?:[a-zA-Z0-9_.\-]+;(?:eq|like|ne|in|nin|gt|gte|lt|lte|empty);[a-zA-Z0-9_.\-:\., áéíóúÁÉÍÓÚ]*)(?:\|[a-zA-Z0-9_.\-]+;(?:eq|like|ne|in|nin|gt|gte|lt|lte|empty);[a-zA-Z0-9_.\-:\., áéíóúÁÉÍÓÚ]*)*$/
|
|
1
|
+
const QueryFilterRegex = /^(?:[a-zA-Z0-9_.\-]+;(?:eq|like|ne|in|nin|gt|gte|lt|lte|empty);[a-zA-Z0-9_.\-:\., áéíóúÁÉÍÓÚ]*(?:;[a-zA-Z0-9_.\-]+)?)(?:\|[a-zA-Z0-9_.\-]+;(?:eq|like|ne|in|nin|gt|gte|lt|lte|empty);[a-zA-Z0-9_.\-:\., áéíóúÁÉÍÓÚ]*(?:;[a-zA-Z0-9_.\-]+)?)*$/
|
|
2
2
|
|
|
3
3
|
export default QueryFilterRegex
|
|
4
4
|
export {QueryFilterRegex}
|
|
@@ -6,7 +6,7 @@ const FindQuerySchema = z.object({
|
|
|
6
6
|
orderBy: z.string().optional(),
|
|
7
7
|
order: z.enum(["asc", "desc"]).optional(),
|
|
8
8
|
search: z.string().optional(),
|
|
9
|
-
filters: z.string().regex(QueryFilterRegex).optional().describe("Format: field;operator;value|field;operator;value|..."),
|
|
9
|
+
filters: z.string().regex(QueryFilterRegex).optional().describe("Format: field;operator;value[;orGroup]|field;operator;value[;orGroup]|..."),
|
|
10
10
|
});
|
|
11
11
|
|
|
12
12
|
|
|
@@ -3,7 +3,7 @@ import QueryFilterRegex from "../regexs/QueryFilterRegex.js";
|
|
|
3
3
|
|
|
4
4
|
const GroupByQuerySchema = z.object({
|
|
5
5
|
fields: z.array(z.string()).min(1).max(10),
|
|
6
|
-
filters: z.string().regex(QueryFilterRegex).optional().describe("Format: field;operator;value|field;operator;value|..."),
|
|
6
|
+
filters: z.string().regex(QueryFilterRegex).optional().describe("Format: field;operator;value[;orGroup]|field;operator;value[;orGroup]|..."),
|
|
7
7
|
});
|
|
8
8
|
|
|
9
9
|
|
|
@@ -7,7 +7,7 @@ const PaginateQuerySchema = z.object({
|
|
|
7
7
|
orderBy: z.string().optional(),
|
|
8
8
|
order: z.enum(["asc", "desc"]).optional(),
|
|
9
9
|
search: z.string().optional(),
|
|
10
|
-
filters: z.string().regex(QueryFilterRegex).optional().describe("Format: field;operator;value|field;operator;value|..."),
|
|
10
|
+
filters: z.string().regex(QueryFilterRegex).optional().describe("Format: field;operator;value[;orGroup]|field;operator;value[;orGroup]|..."),
|
|
11
11
|
});
|
|
12
12
|
|
|
13
13
|
|
|
@@ -466,6 +466,70 @@ describe("Person Controller Test", function () {
|
|
|
466
466
|
expect(findByResult[0].fullname).toBe("Active Person")
|
|
467
467
|
})
|
|
468
468
|
|
|
469
|
+
it("should create and find people with filters grouped by orGroup", async () => {
|
|
470
|
+
const { accessToken } = await testSetup.rootUserLogin()
|
|
471
|
+
await testSetup.dropCollection('Person')
|
|
472
|
+
|
|
473
|
+
const entityData = [
|
|
474
|
+
{ fullname: "Hero Person", race: "human", live: true, address: defaultAddress },
|
|
475
|
+
{ fullname: "Mage Person", race: "elf", live: true, address: defaultAddress },
|
|
476
|
+
{ fullname: "Hidden Hero", race: "orc", live: false, address: defaultAddress },
|
|
477
|
+
{ fullname: "Hidden Rogue", race: "human", live: false, address: defaultAddress }
|
|
478
|
+
]
|
|
479
|
+
|
|
480
|
+
for (const data of entityData) {
|
|
481
|
+
await testSetup.fastifyInstance.inject({
|
|
482
|
+
method: 'POST',
|
|
483
|
+
url: '/api/person',
|
|
484
|
+
payload: data,
|
|
485
|
+
headers: { Authorization: `Bearer ${accessToken}` }
|
|
486
|
+
})
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
const findByResp = await testSetup.fastifyInstance.inject({
|
|
490
|
+
method: 'GET',
|
|
491
|
+
url: '/api/person/find?filters=fullname;like;Hero;group1|race;eq;elf;group1|live;eq;true',
|
|
492
|
+
headers: { Authorization: `Bearer ${accessToken}` }
|
|
493
|
+
})
|
|
494
|
+
|
|
495
|
+
const findByResult = await findByResp.json()
|
|
496
|
+
expect(findByResp.statusCode).toBe(200)
|
|
497
|
+
expect(findByResult.length).toBe(2)
|
|
498
|
+
expect(findByResult.map((item: any) => item.fullname).sort()).toEqual(["Hero Person", "Mage Person"])
|
|
499
|
+
})
|
|
500
|
+
|
|
501
|
+
it("should combine search with orGroup filters without overriding either condition", async () => {
|
|
502
|
+
const { accessToken } = await testSetup.rootUserLogin()
|
|
503
|
+
await testSetup.dropCollection('Person')
|
|
504
|
+
|
|
505
|
+
const entityData = [
|
|
506
|
+
{ fullname: "Searchable Hero", race: "human", live: true, address: defaultAddress },
|
|
507
|
+
{ fullname: "Searchable Elf", race: "elf", live: true, address: defaultAddress },
|
|
508
|
+
{ fullname: "Hidden Elf", race: "elf", live: true, address: defaultAddress },
|
|
509
|
+
{ fullname: "Searchable Rogue", race: "human", live: false, address: defaultAddress }
|
|
510
|
+
]
|
|
511
|
+
|
|
512
|
+
for (const data of entityData) {
|
|
513
|
+
await testSetup.fastifyInstance.inject({
|
|
514
|
+
method: 'POST',
|
|
515
|
+
url: '/api/person',
|
|
516
|
+
payload: data,
|
|
517
|
+
headers: { Authorization: `Bearer ${accessToken}` }
|
|
518
|
+
})
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
const paginateResp = await testSetup.fastifyInstance.inject({
|
|
522
|
+
method: 'GET',
|
|
523
|
+
url: '/api/person?search=Searchable&filters=fullname;like;Hero;group1|race;eq;elf;group1|live;eq;true',
|
|
524
|
+
headers: { Authorization: `Bearer ${accessToken}` }
|
|
525
|
+
})
|
|
526
|
+
|
|
527
|
+
const paginateResult = await paginateResp.json()
|
|
528
|
+
expect(paginateResp.statusCode).toBe(200)
|
|
529
|
+
expect(paginateResult.total).toBe(2)
|
|
530
|
+
expect(paginateResult.items.map((item: any) => item.fullname).sort()).toEqual(["Searchable Elf", "Searchable Hero"])
|
|
531
|
+
})
|
|
532
|
+
|
|
469
533
|
// 8. Create and Group By
|
|
470
534
|
it("should create and groupBy for people", async () => {
|
|
471
535
|
const { accessToken } = await testSetup.rootUserLogin()
|