@flowerforce/flowerbase 1.0.1-beta.3
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/CHANGELOG.md +0 -0
- package/LICENSE +3 -0
- package/README.md +18 -0
- package/dist/auth/controller.d.ts +8 -0
- package/dist/auth/controller.d.ts.map +1 -0
- package/dist/auth/controller.js +76 -0
- package/dist/auth/dtos.d.ts +6 -0
- package/dist/auth/dtos.d.ts.map +1 -0
- package/dist/auth/dtos.js +2 -0
- package/dist/auth/plugins/jwt.d.ts +14 -0
- package/dist/auth/plugins/jwt.d.ts.map +1 -0
- package/dist/auth/plugins/jwt.js +68 -0
- package/dist/auth/providers/local-userpass/controller.d.ts +8 -0
- package/dist/auth/providers/local-userpass/controller.d.ts.map +1 -0
- package/dist/auth/providers/local-userpass/controller.js +184 -0
- package/dist/auth/providers/local-userpass/dtos.d.ts +35 -0
- package/dist/auth/providers/local-userpass/dtos.d.ts.map +1 -0
- package/dist/auth/providers/local-userpass/dtos.js +2 -0
- package/dist/auth/utils.d.ts +126 -0
- package/dist/auth/utils.d.ts.map +1 -0
- package/dist/auth/utils.js +122 -0
- package/dist/constants.d.ts +18 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +34 -0
- package/dist/features/endpoints/index.d.ts +10 -0
- package/dist/features/endpoints/index.d.ts.map +1 -0
- package/dist/features/endpoints/index.js +31 -0
- package/dist/features/endpoints/interface.d.ts +27 -0
- package/dist/features/endpoints/interface.d.ts.map +1 -0
- package/dist/features/endpoints/interface.js +2 -0
- package/dist/features/endpoints/utils.d.ts +31 -0
- package/dist/features/endpoints/utils.d.ts.map +1 -0
- package/dist/features/endpoints/utils.js +85 -0
- package/dist/features/functions/controller.d.ts +9 -0
- package/dist/features/functions/controller.d.ts.map +1 -0
- package/dist/features/functions/controller.js +88 -0
- package/dist/features/functions/dtos.d.ts +34 -0
- package/dist/features/functions/dtos.d.ts.map +1 -0
- package/dist/features/functions/dtos.js +2 -0
- package/dist/features/functions/index.d.ts +9 -0
- package/dist/features/functions/index.d.ts.map +1 -0
- package/dist/features/functions/index.js +28 -0
- package/dist/features/functions/interface.d.ts +32 -0
- package/dist/features/functions/interface.d.ts.map +1 -0
- package/dist/features/functions/interface.js +2 -0
- package/dist/features/functions/utils.d.ts +23 -0
- package/dist/features/functions/utils.d.ts.map +1 -0
- package/dist/features/functions/utils.js +75 -0
- package/dist/features/rules/index.d.ts +1 -0
- package/dist/features/rules/index.d.ts.map +1 -0
- package/dist/features/rules/index.js +1 -0
- package/dist/features/rules/interface.d.ts +22 -0
- package/dist/features/rules/interface.d.ts.map +1 -0
- package/dist/features/rules/interface.js +2 -0
- package/dist/features/rules/utils.d.ts +3 -0
- package/dist/features/rules/utils.d.ts.map +1 -0
- package/dist/features/rules/utils.js +31 -0
- package/dist/features/triggers/dtos.d.ts +9 -0
- package/dist/features/triggers/dtos.d.ts.map +1 -0
- package/dist/features/triggers/dtos.js +2 -0
- package/dist/features/triggers/index.d.ts +10 -0
- package/dist/features/triggers/index.d.ts.map +1 -0
- package/dist/features/triggers/index.js +57 -0
- package/dist/features/triggers/interface.d.ts +44 -0
- package/dist/features/triggers/interface.d.ts.map +1 -0
- package/dist/features/triggers/interface.js +2 -0
- package/dist/features/triggers/utils.d.ts +16 -0
- package/dist/features/triggers/utils.d.ts.map +1 -0
- package/dist/features/triggers/utils.js +153 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +84 -0
- package/dist/model.d.ts +2 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +2 -0
- package/dist/services/api/index.d.ts +36 -0
- package/dist/services/api/index.d.ts.map +1 -0
- package/dist/services/api/index.js +36 -0
- package/dist/services/api/model.d.ts +33 -0
- package/dist/services/api/model.d.ts.map +1 -0
- package/dist/services/api/model.js +2 -0
- package/dist/services/api/utils.d.ts +16 -0
- package/dist/services/api/utils.d.ts.map +1 -0
- package/dist/services/api/utils.js +45 -0
- package/dist/services/aws/index.d.ts +13 -0
- package/dist/services/aws/index.d.ts.map +1 -0
- package/dist/services/aws/index.js +50 -0
- package/dist/services/index.d.ts +41 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +14 -0
- package/dist/services/interface.d.ts +3 -0
- package/dist/services/interface.d.ts.map +1 -0
- package/dist/services/interface.js +2 -0
- package/dist/services/mongodb-atlas/index.d.ts +4 -0
- package/dist/services/mongodb-atlas/index.d.ts.map +1 -0
- package/dist/services/mongodb-atlas/index.js +483 -0
- package/dist/services/mongodb-atlas/model.d.ts +39 -0
- package/dist/services/mongodb-atlas/model.d.ts.map +1 -0
- package/dist/services/mongodb-atlas/model.js +2 -0
- package/dist/services/mongodb-atlas/utils.d.ts +8 -0
- package/dist/services/mongodb-atlas/utils.d.ts.map +1 -0
- package/dist/services/mongodb-atlas/utils.js +33 -0
- package/dist/state.d.ts +6 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +18 -0
- package/dist/utils/context/helpers.d.ts +74 -0
- package/dist/utils/context/helpers.d.ts.map +1 -0
- package/dist/utils/context/helpers.js +60 -0
- package/dist/utils/context/index.d.ts +14 -0
- package/dist/utils/context/index.d.ts.map +1 -0
- package/dist/utils/context/index.js +50 -0
- package/dist/utils/context/interface.d.ts +18 -0
- package/dist/utils/context/interface.d.ts.map +1 -0
- package/dist/utils/context/interface.js +2 -0
- package/dist/utils/crypto/index.d.ts +19 -0
- package/dist/utils/crypto/index.d.ts.map +1 -0
- package/dist/utils/crypto/index.js +50 -0
- package/dist/utils/helpers/someAsync.d.ts +12 -0
- package/dist/utils/helpers/someAsync.d.ts.map +1 -0
- package/dist/utils/helpers/someAsync.js +56 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +11 -0
- package/dist/utils/initializer/exposeRoutes.d.ts +8 -0
- package/dist/utils/initializer/exposeRoutes.d.ts.map +1 -0
- package/dist/utils/initializer/exposeRoutes.js +41 -0
- package/dist/utils/initializer/registerPlugins.d.ts +19 -0
- package/dist/utils/initializer/registerPlugins.d.ts.map +1 -0
- package/dist/utils/initializer/registerPlugins.js +84 -0
- package/dist/utils/roles/helpers.d.ts +4 -0
- package/dist/utils/roles/helpers.d.ts.map +1 -0
- package/dist/utils/roles/helpers.js +47 -0
- package/dist/utils/roles/interface.d.ts +33 -0
- package/dist/utils/roles/interface.d.ts.map +1 -0
- package/dist/utils/roles/interface.js +2 -0
- package/dist/utils/roles/machines/commonValidators.d.ts +6 -0
- package/dist/utils/roles/machines/commonValidators.d.ts.map +1 -0
- package/dist/utils/roles/machines/commonValidators.js +34 -0
- package/dist/utils/roles/machines/index.d.ts +14 -0
- package/dist/utils/roles/machines/index.d.ts.map +1 -0
- package/dist/utils/roles/machines/index.js +27 -0
- package/dist/utils/roles/machines/interface.d.ts +46 -0
- package/dist/utils/roles/machines/interface.d.ts.map +1 -0
- package/dist/utils/roles/machines/interface.js +2 -0
- package/dist/utils/roles/machines/machine.d.ts +15 -0
- package/dist/utils/roles/machines/machine.d.ts.map +1 -0
- package/dist/utils/roles/machines/machine.js +97 -0
- package/dist/utils/roles/machines/read/A/index.d.ts +3 -0
- package/dist/utils/roles/machines/read/A/index.d.ts.map +1 -0
- package/dist/utils/roles/machines/read/A/index.js +27 -0
- package/dist/utils/roles/machines/read/B/index.d.ts +3 -0
- package/dist/utils/roles/machines/read/B/index.d.ts.map +1 -0
- package/dist/utils/roles/machines/read/B/index.js +36 -0
- package/dist/utils/roles/machines/read/C/index.d.ts +3 -0
- package/dist/utils/roles/machines/read/C/index.d.ts.map +1 -0
- package/dist/utils/roles/machines/read/C/index.js +38 -0
- package/dist/utils/roles/machines/read/D/index.d.ts +3 -0
- package/dist/utils/roles/machines/read/D/index.d.ts.map +1 -0
- package/dist/utils/roles/machines/read/D/index.js +26 -0
- package/dist/utils/roles/machines/read/D/validators.d.ts +4 -0
- package/dist/utils/roles/machines/read/D/validators.d.ts.map +1 -0
- package/dist/utils/roles/machines/read/D/validators.js +24 -0
- package/dist/utils/roles/machines/read/index.d.ts +2 -0
- package/dist/utils/roles/machines/read/index.d.ts.map +1 -0
- package/dist/utils/roles/machines/read/index.js +8 -0
- package/dist/utils/roles/machines/utils.d.ts +37 -0
- package/dist/utils/roles/machines/utils.d.ts.map +1 -0
- package/dist/utils/roles/machines/utils.js +54 -0
- package/dist/utils/roles/machines/write/A/index.d.ts +3 -0
- package/dist/utils/roles/machines/write/A/index.d.ts.map +1 -0
- package/dist/utils/roles/machines/write/A/index.js +29 -0
- package/dist/utils/roles/machines/write/B/index.d.ts +3 -0
- package/dist/utils/roles/machines/write/B/index.d.ts.map +1 -0
- package/dist/utils/roles/machines/write/B/index.js +47 -0
- package/dist/utils/roles/machines/write/C/index.d.ts +3 -0
- package/dist/utils/roles/machines/write/C/index.d.ts.map +1 -0
- package/dist/utils/roles/machines/write/C/index.js +26 -0
- package/dist/utils/roles/machines/write/C/validators.d.ts +4 -0
- package/dist/utils/roles/machines/write/C/validators.d.ts.map +1 -0
- package/dist/utils/roles/machines/write/C/validators.js +24 -0
- package/dist/utils/roles/machines/write/index.d.ts +2 -0
- package/dist/utils/roles/machines/write/index.d.ts.map +1 -0
- package/dist/utils/roles/machines/write/index.js +7 -0
- package/dist/utils/rules-matcher/interface.d.ts +338 -0
- package/dist/utils/rules-matcher/interface.d.ts.map +1 -0
- package/dist/utils/rules-matcher/interface.js +26 -0
- package/dist/utils/rules-matcher/utils.d.ts +11 -0
- package/dist/utils/rules-matcher/utils.d.ts.map +1 -0
- package/dist/utils/rules-matcher/utils.js +214 -0
- package/dist/utils/rules.d.ts +2 -0
- package/dist/utils/rules.d.ts.map +1 -0
- package/dist/utils/rules.js +22 -0
- package/jest.config.ts +24 -0
- package/package.json +63 -0
- package/project.json +10 -0
- package/rollup.config.js +17 -0
- package/src/auth/controller.ts +78 -0
- package/src/auth/dtos.ts +6 -0
- package/src/auth/plugins/jwt.ts +68 -0
- package/src/auth/providers/local-userpass/controller.ts +226 -0
- package/src/auth/providers/local-userpass/dtos.ts +40 -0
- package/src/auth/utils.ts +165 -0
- package/src/babel.config.json +3 -0
- package/src/constants.ts +22 -0
- package/src/fastify.d.ts +28 -0
- package/src/features/endpoints/index.ts +27 -0
- package/src/features/endpoints/interface.ts +29 -0
- package/src/features/endpoints/utils.ts +72 -0
- package/src/features/functions/controller.ts +102 -0
- package/src/features/functions/dtos.ts +41 -0
- package/src/features/functions/index.ts +21 -0
- package/src/features/functions/interface.ts +38 -0
- package/src/features/functions/utils.ts +82 -0
- package/src/features/rules/index.tsx +0 -0
- package/src/features/rules/interface.ts +24 -0
- package/src/features/rules/utils.ts +20 -0
- package/src/features/triggers/dtos.ts +9 -0
- package/src/features/triggers/index.ts +34 -0
- package/src/features/triggers/interface.ts +44 -0
- package/src/features/triggers/utils.ts +157 -0
- package/src/global.d.ts +0 -0
- package/src/index.ts +75 -0
- package/src/model.ts +1 -0
- package/src/services/api/index.ts +50 -0
- package/src/services/api/model.ts +38 -0
- package/src/services/api/utils.ts +39 -0
- package/src/services/aws/index.ts +48 -0
- package/src/services/index.ts +9 -0
- package/src/services/interface.ts +3 -0
- package/src/services/mongodb-atlas/index.ts +569 -0
- package/src/services/mongodb-atlas/model.ts +67 -0
- package/src/services/mongodb-atlas/utils.ts +44 -0
- package/src/state.ts +24 -0
- package/src/utils/__tests__/STEP_A_STATES.test.ts +54 -0
- package/src/utils/__tests__/STEP_B_STATES.test.ts +113 -0
- package/src/utils/__tests__/STEP_C_STATES.test.ts +87 -0
- package/src/utils/__tests__/STEP_D_STATES.test.ts +93 -0
- package/src/utils/__tests__/checkAdditionalFieldsFn.test.ts +45 -0
- package/src/utils/__tests__/checkApplyWhen.test.ts +49 -0
- package/src/utils/__tests__/checkFieldsPropertyExists.test.ts +47 -0
- package/src/utils/__tests__/checkIsValidFieldNameFn.test.ts +190 -0
- package/src/utils/__tests__/comparePassword.test.ts +38 -0
- package/src/utils/__tests__/evaluateDocumentsFiltersReadFn.test.ts +57 -0
- package/src/utils/__tests__/evaluateDocumentsFiltersWriteFn.test.ts +57 -0
- package/src/utils/__tests__/evaluateTopLevelReadFn.test.ts +58 -0
- package/src/utils/__tests__/evaluateTopLevelWriteFn.test.ts +66 -0
- package/src/utils/__tests__/exposeRoutes.test.ts +65 -0
- package/src/utils/__tests__/generateContextData.test.ts +75 -0
- package/src/utils/__tests__/getDefaultRule.test.ts +29 -0
- package/src/utils/__tests__/getKey.test.ts +12 -0
- package/src/utils/__tests__/getKeys.test.ts +11 -0
- package/src/utils/__tests__/getWinningRole.test.ts +66 -0
- package/src/utils/__tests__/hashPassword.test.ts +28 -0
- package/src/utils/__tests__/isEmpty.test.ts +17 -0
- package/src/utils/__tests__/logMachineInfo.test.ts +15 -0
- package/src/utils/__tests__/operators.test.ts +99 -0
- package/src/utils/__tests__/readFileContent.test.ts +35 -0
- package/src/utils/__tests__/registerPlugins.test.ts +59 -0
- package/src/utils/__tests__/rule.test.ts +51 -0
- package/src/utils/__tests__/rulesMatcherInterfaces.test.ts +57 -0
- package/src/utils/__tests__/rulesMatcherUtils.test.ts +56 -0
- package/src/utils/__tests__/someAsync.test.ts +55 -0
- package/src/utils/context/helpers.ts +71 -0
- package/src/utils/context/index.ts +52 -0
- package/src/utils/context/interface.ts +19 -0
- package/src/utils/crypto/index.ts +36 -0
- package/src/utils/helpers/someAsync.ts +24 -0
- package/src/utils/index.ts +5 -0
- package/src/utils/initializer/exposeRoutes.ts +26 -0
- package/src/utils/initializer/registerPlugins.ts +97 -0
- package/src/utils/roles/helpers.ts +47 -0
- package/src/utils/roles/interface.ts +42 -0
- package/src/utils/roles/machines/commonValidators.ts +24 -0
- package/src/utils/roles/machines/index.ts +20 -0
- package/src/utils/roles/machines/interface.ts +46 -0
- package/src/utils/roles/machines/machine.ts +85 -0
- package/src/utils/roles/machines/read/A/index.ts +19 -0
- package/src/utils/roles/machines/read/B/index.ts +31 -0
- package/src/utils/roles/machines/read/C/index.ts +30 -0
- package/src/utils/roles/machines/read/D/index.ts +20 -0
- package/src/utils/roles/machines/read/D/validators.ts +24 -0
- package/src/utils/roles/machines/read/index.ts +6 -0
- package/src/utils/roles/machines/utils.ts +54 -0
- package/src/utils/roles/machines/write/A/index.ts +25 -0
- package/src/utils/roles/machines/write/B/index.ts +43 -0
- package/src/utils/roles/machines/write/C/index.ts +20 -0
- package/src/utils/roles/machines/write/C/validators.ts +24 -0
- package/src/utils/roles/machines/write/index.ts +5 -0
- package/src/utils/rules-matcher/interface.ts +365 -0
- package/src/utils/rules-matcher/utils.ts +281 -0
- package/src/utils/rules.ts +19 -0
- package/tsconfig.json +28 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { ObjectId } from 'bson';
|
|
2
|
+
import { User } from '../../fastify';
|
|
3
|
+
import { Role } from '../roles/interface';
|
|
4
|
+
import { MachineContext } from '../roles/machines/interface'
|
|
5
|
+
import { checkIsValidFieldNameFn } from '../roles/machines/read/D/validators';
|
|
6
|
+
|
|
7
|
+
const mockUser = {} as User
|
|
8
|
+
const mockId = new ObjectId()
|
|
9
|
+
|
|
10
|
+
describe('checkIsValidFieldNameFn', () => {
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
jest.clearAllMocks();
|
|
13
|
+
});
|
|
14
|
+
it('should return filtered fields based on role permissions, without excluding _id', () => {
|
|
15
|
+
const mockedRole = {
|
|
16
|
+
name: "test",
|
|
17
|
+
apply_when: {
|
|
18
|
+
"%%true": true
|
|
19
|
+
},
|
|
20
|
+
fields: {
|
|
21
|
+
name: { read: true, write: false },
|
|
22
|
+
email: { read: false, write: true },
|
|
23
|
+
},
|
|
24
|
+
additional_fields: {},
|
|
25
|
+
} as Role
|
|
26
|
+
const context = {
|
|
27
|
+
user: mockUser,
|
|
28
|
+
role: mockedRole,
|
|
29
|
+
params: {
|
|
30
|
+
cursor: { _id: mockId, name: 'Alice', email: 'alice@example.com', age: 25 },
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const result = checkIsValidFieldNameFn(context as MachineContext);
|
|
35
|
+
expect(result).toEqual({ name: 'Alice', email: 'alice@example.com', _id: mockId });
|
|
36
|
+
});
|
|
37
|
+
it("should exclude _id if role doesn't allows it", () => {
|
|
38
|
+
const mockedRole = {
|
|
39
|
+
name: "test",
|
|
40
|
+
apply_when: {
|
|
41
|
+
"%%true": true
|
|
42
|
+
},
|
|
43
|
+
fields: {
|
|
44
|
+
_id: { read: false, write: false },
|
|
45
|
+
name: { read: true, write: false },
|
|
46
|
+
},
|
|
47
|
+
additional_fields: {},
|
|
48
|
+
} as Role
|
|
49
|
+
const context = {
|
|
50
|
+
user: mockUser,
|
|
51
|
+
role: mockedRole,
|
|
52
|
+
params: {
|
|
53
|
+
cursor: { _id: mockId, name: 'Alice' },
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const result = checkIsValidFieldNameFn(context as MachineContext);
|
|
58
|
+
|
|
59
|
+
expect(result).toEqual({ name: 'Alice' });
|
|
60
|
+
});
|
|
61
|
+
it("should include _id if write role allows it", () => {
|
|
62
|
+
const mockedRole = {
|
|
63
|
+
name: "test",
|
|
64
|
+
apply_when: {
|
|
65
|
+
"%%true": true
|
|
66
|
+
},
|
|
67
|
+
fields: {
|
|
68
|
+
_id: { read: false, write: true },
|
|
69
|
+
name: { read: true, write: false },
|
|
70
|
+
},
|
|
71
|
+
additional_fields: {},
|
|
72
|
+
} as Role
|
|
73
|
+
const context = {
|
|
74
|
+
user: mockUser,
|
|
75
|
+
role: mockedRole,
|
|
76
|
+
params: {
|
|
77
|
+
cursor: { _id: mockId, name: 'Alice' },
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const result = checkIsValidFieldNameFn(context as MachineContext);
|
|
82
|
+
|
|
83
|
+
expect(result).toEqual({ _id: mockId, name: 'Alice' });
|
|
84
|
+
});
|
|
85
|
+
it("should include _id if read role allows it", () => {
|
|
86
|
+
const mockedRole = {
|
|
87
|
+
name: "test",
|
|
88
|
+
apply_when: {
|
|
89
|
+
"%%true": true
|
|
90
|
+
},
|
|
91
|
+
fields: {
|
|
92
|
+
_id: { read: true, write: false },
|
|
93
|
+
name: { read: true, write: false },
|
|
94
|
+
},
|
|
95
|
+
additional_fields: {},
|
|
96
|
+
} as Role
|
|
97
|
+
const context = {
|
|
98
|
+
user: mockUser,
|
|
99
|
+
role: mockedRole,
|
|
100
|
+
params: {
|
|
101
|
+
cursor: { _id: mockId, name: 'Alice' },
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const result = checkIsValidFieldNameFn(context as MachineContext);
|
|
106
|
+
|
|
107
|
+
expect(result).toEqual({ _id: mockId, name: 'Alice' });
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
it('should return an empty object if no fields are readable/writable', () => {
|
|
112
|
+
const mockedRole = {
|
|
113
|
+
name: "test",
|
|
114
|
+
apply_when: {
|
|
115
|
+
"%%true": true
|
|
116
|
+
},
|
|
117
|
+
fields: {
|
|
118
|
+
name: { read: false, write: false },
|
|
119
|
+
},
|
|
120
|
+
additional_fields: {},
|
|
121
|
+
} as Role
|
|
122
|
+
const context = {
|
|
123
|
+
role: mockedRole,
|
|
124
|
+
params: {
|
|
125
|
+
cursor: { name: 'Charlie', email: 'charlie@example.com' },
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const result = checkIsValidFieldNameFn(context as MachineContext);
|
|
130
|
+
|
|
131
|
+
expect(result).toEqual({});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('should handle additional_fields correctly for read permission', () => {
|
|
135
|
+
const mockedRole = {
|
|
136
|
+
name: "test",
|
|
137
|
+
apply_when: {
|
|
138
|
+
"%%true": true
|
|
139
|
+
},
|
|
140
|
+
fields: {},
|
|
141
|
+
additional_fields: { phone: { read: true, write: false } },
|
|
142
|
+
} as Role
|
|
143
|
+
const context = {
|
|
144
|
+
role: mockedRole,
|
|
145
|
+
params: {
|
|
146
|
+
cursor: { _id: mockId, phone: '123456789', address: 'Unknown' },
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const result = checkIsValidFieldNameFn(context as MachineContext);
|
|
151
|
+
expect(result).toEqual({ _id: mockId, phone: '123456789' });
|
|
152
|
+
});
|
|
153
|
+
it('should handle additional_fields correctly for write permission', () => {
|
|
154
|
+
const mockedRole = {
|
|
155
|
+
name: "test",
|
|
156
|
+
apply_when: {
|
|
157
|
+
"%%true": true
|
|
158
|
+
},
|
|
159
|
+
fields: {},
|
|
160
|
+
additional_fields: { phone: { read: false, write: true }, address: { read: false, write: true } },
|
|
161
|
+
} as Role
|
|
162
|
+
const context = {
|
|
163
|
+
role: mockedRole,
|
|
164
|
+
params: {
|
|
165
|
+
cursor: { _id: mockId, phone: '123456789', address: 'Unknown' },
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
const result = checkIsValidFieldNameFn(context as MachineContext);
|
|
170
|
+
expect(result).toEqual({ _id: mockId, phone: '123456789', address: 'Unknown' });
|
|
171
|
+
});
|
|
172
|
+
it('should return only the _id if fields and additional fields are not defined', () => {
|
|
173
|
+
const mockedRole = {
|
|
174
|
+
name: "test",
|
|
175
|
+
apply_when: {
|
|
176
|
+
"%%true": true
|
|
177
|
+
}
|
|
178
|
+
} as Role
|
|
179
|
+
const context = {
|
|
180
|
+
role: mockedRole,
|
|
181
|
+
params: {
|
|
182
|
+
cursor: { _id: mockId, phone: '123456789', address: 'Unknown' },
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
const result = checkIsValidFieldNameFn(context as MachineContext);
|
|
187
|
+
expect(result).toEqual({ _id: mockId });
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
|
|
2
|
+
import crypto from 'crypto';
|
|
3
|
+
import { promisify } from 'node:util'
|
|
4
|
+
import { comparePassword } from '../crypto';
|
|
5
|
+
|
|
6
|
+
const scrypt = promisify(crypto.scrypt);
|
|
7
|
+
|
|
8
|
+
describe('comparePassword', () => {
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
jest.clearAllMocks();
|
|
11
|
+
});
|
|
12
|
+
it('should return true for matching passwords', async () => {
|
|
13
|
+
const plaintext = 'mySecretPassword';
|
|
14
|
+
const salt = crypto.randomBytes(16).toString('hex');
|
|
15
|
+
const hashBuffer = (await scrypt(plaintext, salt, 64)) as Buffer;
|
|
16
|
+
const storedPassword = `${hashBuffer.toString('hex')}.${salt}`;
|
|
17
|
+
const result = await comparePassword(plaintext, storedPassword);
|
|
18
|
+
expect(result).toBe(true);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should return false for non-matching passwords', async () => {
|
|
22
|
+
const plaintext = 'mySecretPassword';
|
|
23
|
+
const wrongPassword = 'wrongPassword';
|
|
24
|
+
|
|
25
|
+
const salt = crypto.randomBytes(16).toString('hex');
|
|
26
|
+
const hashBuffer = (await scrypt(plaintext, salt, 64)) as Buffer;
|
|
27
|
+
const storedPassword = `${hashBuffer.toString('hex')}.${salt}`;
|
|
28
|
+
|
|
29
|
+
const result = await comparePassword(wrongPassword, storedPassword);
|
|
30
|
+
expect(result).toBe(false);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('should throw an error if storedPassword format is incorrect', async () => {
|
|
34
|
+
await expect(comparePassword('anyPassword', 'invalidFormat'))
|
|
35
|
+
.rejects
|
|
36
|
+
.toThrow();
|
|
37
|
+
});
|
|
38
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { someAsync } from '../helpers/someAsync';
|
|
2
|
+
import { evaluateExpression } from '../roles/helpers';
|
|
3
|
+
import { MachineContext } from '../roles/machines/interface';
|
|
4
|
+
import { evaluateDocumentFiltersReadFn } from '../roles/machines/read/B/validators';
|
|
5
|
+
|
|
6
|
+
const mockContext = {
|
|
7
|
+
params: { type: 'read' },
|
|
8
|
+
role: { document_filters: { read: 'someFilterExpression' } },
|
|
9
|
+
user: { id: 'user123', name: 'Test User' },
|
|
10
|
+
} as unknown as MachineContext;
|
|
11
|
+
|
|
12
|
+
jest.mock('../helpers/someAsync', () => ({
|
|
13
|
+
someAsync: jest.fn().mockImplementation(async (array: Array<unknown>, callback: (item: unknown) => Promise<boolean>) => {
|
|
14
|
+
for (const item of array) {
|
|
15
|
+
if (await callback(item)) return true;
|
|
16
|
+
}
|
|
17
|
+
return false;
|
|
18
|
+
})
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
jest.mock('../roles/helpers', () => ({
|
|
22
|
+
evaluateExpression: jest.fn(),
|
|
23
|
+
}));
|
|
24
|
+
|
|
25
|
+
describe('evaluateDocumentFiltersReadFn', () => {
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
jest.clearAllMocks();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('should return true if at least one filter evaluates to true', async () => {
|
|
31
|
+
(evaluateExpression as jest.Mock).mockResolvedValue(true);
|
|
32
|
+
const result = await evaluateDocumentFiltersReadFn(mockContext);
|
|
33
|
+
expect(result).toBe(true);
|
|
34
|
+
expect(evaluateExpression).toHaveBeenCalledWith(mockContext.params, mockContext.role.document_filters?.read, mockContext.user);
|
|
35
|
+
expect(someAsync).toHaveBeenCalled();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should return false if no filters evaluate to true', async () => {
|
|
39
|
+
(evaluateExpression as jest.Mock).mockResolvedValue(false);
|
|
40
|
+
const result = await evaluateDocumentFiltersReadFn(mockContext);
|
|
41
|
+
expect(result).toBe(false);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should return false if role has no read filter', async () => {
|
|
45
|
+
mockContext.role.document_filters = {};
|
|
46
|
+
const result = await evaluateDocumentFiltersReadFn(mockContext);
|
|
47
|
+
expect(result).toBe(false);
|
|
48
|
+
expect(evaluateExpression).not.toHaveBeenCalled();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should return false if type is not in readOnly', async () => {
|
|
52
|
+
mockContext.params.type = 'write';
|
|
53
|
+
const result = await evaluateDocumentFiltersReadFn(mockContext);
|
|
54
|
+
expect(result).toBe(false);
|
|
55
|
+
expect(evaluateExpression).not.toHaveBeenCalled();
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { someAsync } from '../helpers/someAsync';
|
|
2
|
+
import { evaluateExpression } from '../roles/helpers';
|
|
3
|
+
import { MachineContext } from '../roles/machines/interface';
|
|
4
|
+
import { evaluateDocumentFiltersWriteFn } from '../roles/machines/read/B/validators';
|
|
5
|
+
|
|
6
|
+
const mockContext = {
|
|
7
|
+
params: { type: 'write' },
|
|
8
|
+
role: { document_filters: { write: 'someFilterExpression' } },
|
|
9
|
+
user: { id: 'user123', name: 'Test User' },
|
|
10
|
+
} as unknown as MachineContext;
|
|
11
|
+
|
|
12
|
+
jest.mock('../helpers/someAsync', () => ({
|
|
13
|
+
someAsync: jest.fn().mockImplementation(async (array: Array<unknown>, callback: (item: unknown) => Promise<boolean>) => {
|
|
14
|
+
for (const item of array) {
|
|
15
|
+
if (await callback(item)) return true;
|
|
16
|
+
}
|
|
17
|
+
return false;
|
|
18
|
+
})
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
jest.mock('../roles/helpers', () => ({
|
|
22
|
+
evaluateExpression: jest.fn(),
|
|
23
|
+
}));
|
|
24
|
+
|
|
25
|
+
describe('evaluateDocumentFiltersWriteFn', () => {
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
jest.clearAllMocks();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('should return true if at least one filter evaluates to true', async () => {
|
|
31
|
+
(evaluateExpression as jest.Mock).mockResolvedValue(true);
|
|
32
|
+
const result = await evaluateDocumentFiltersWriteFn(mockContext);
|
|
33
|
+
expect(result).toBe(true);
|
|
34
|
+
expect(evaluateExpression).toHaveBeenCalledWith(mockContext.params, mockContext.role.document_filters?.write, mockContext.user);
|
|
35
|
+
expect(someAsync).toHaveBeenCalled();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should return false if no filters evaluate to true', async () => {
|
|
39
|
+
(evaluateExpression as jest.Mock).mockResolvedValue(false);
|
|
40
|
+
const result = await evaluateDocumentFiltersWriteFn(mockContext);
|
|
41
|
+
expect(result).toBe(false);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should return false if type is not in valid', async () => {
|
|
45
|
+
const mockClone = { ...mockContext, params: { type: 'test' as MachineContext["params"]["type"] } } as MachineContext
|
|
46
|
+
const result = await evaluateDocumentFiltersWriteFn(mockClone);
|
|
47
|
+
expect(result).toBe(false);
|
|
48
|
+
expect(evaluateExpression).not.toHaveBeenCalled();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should return false if role has no write filter', async () => {
|
|
52
|
+
const mockClone = { ...mockContext, role: { ...mockContext.role, document_filters: {} } } as MachineContext
|
|
53
|
+
const result = await evaluateDocumentFiltersWriteFn(mockClone);
|
|
54
|
+
expect(result).toBe(false);
|
|
55
|
+
expect(evaluateExpression).not.toHaveBeenCalled();
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { evaluateExpression } from '../roles/helpers';
|
|
2
|
+
import { Params, Role } from '../roles/interface';
|
|
3
|
+
import { evaluateTopLevelReadFn } from '../roles/machines/read/C/validators';
|
|
4
|
+
|
|
5
|
+
jest.mock('../roles/helpers', () => ({
|
|
6
|
+
evaluateExpression: jest.fn(),
|
|
7
|
+
}));
|
|
8
|
+
|
|
9
|
+
const mockedRole = {} as Role
|
|
10
|
+
|
|
11
|
+
const mockUser = {}
|
|
12
|
+
const mockParams = {
|
|
13
|
+
type: "read"
|
|
14
|
+
} as Params
|
|
15
|
+
|
|
16
|
+
describe('evaluateTopLevelReadFn', () => {
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
jest.clearAllMocks();
|
|
19
|
+
});
|
|
20
|
+
it('should return false if type is different from read', async () => {
|
|
21
|
+
const isValid = await evaluateTopLevelReadFn({
|
|
22
|
+
role: mockedRole,
|
|
23
|
+
user: mockUser,
|
|
24
|
+
params: { type: "write" } as Params
|
|
25
|
+
})
|
|
26
|
+
expect(isValid).toBe(false)
|
|
27
|
+
expect(evaluateExpression).not.toHaveBeenCalled()
|
|
28
|
+
});
|
|
29
|
+
it('should return undefined if type is read and role read is not defined', async () => {
|
|
30
|
+
const isValid = await evaluateTopLevelReadFn({
|
|
31
|
+
role: mockedRole,
|
|
32
|
+
user: mockUser,
|
|
33
|
+
params: mockParams
|
|
34
|
+
})
|
|
35
|
+
expect(isValid).toBe(undefined)
|
|
36
|
+
expect(evaluateExpression).not.toHaveBeenCalled()
|
|
37
|
+
});
|
|
38
|
+
it('should return false if type is read and role read defined but evaluate expression returns false', async () => {
|
|
39
|
+
(evaluateExpression as jest.Mock).mockResolvedValueOnce(false)
|
|
40
|
+
const isValid = await evaluateTopLevelReadFn({
|
|
41
|
+
role: { ...mockedRole, read: false },
|
|
42
|
+
user: mockUser,
|
|
43
|
+
params: mockParams
|
|
44
|
+
})
|
|
45
|
+
expect(isValid).toBe(false)
|
|
46
|
+
expect(evaluateExpression).toHaveBeenCalledWith(mockParams, false, mockUser)
|
|
47
|
+
});
|
|
48
|
+
it('should return true if type is read and role read defined and evaluate expression returns true', async () => {
|
|
49
|
+
(evaluateExpression as jest.Mock).mockResolvedValueOnce(true)
|
|
50
|
+
const isValid = await evaluateTopLevelReadFn({
|
|
51
|
+
role: { ...mockedRole, read: false },
|
|
52
|
+
user: mockUser,
|
|
53
|
+
params: mockParams
|
|
54
|
+
})
|
|
55
|
+
expect(isValid).toBe(true)
|
|
56
|
+
expect(evaluateExpression).toHaveBeenCalledWith(mockParams, false, mockUser)
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { evaluateExpression } from '../roles/helpers';
|
|
2
|
+
import { Params, Role } from '../roles/interface';
|
|
3
|
+
import { evaluateTopLevelWriteFn } from '../roles/machines/read/C/validators';
|
|
4
|
+
|
|
5
|
+
jest.mock('../roles/helpers', () => ({
|
|
6
|
+
evaluateExpression: jest.fn(),
|
|
7
|
+
}));
|
|
8
|
+
|
|
9
|
+
const mockedRole = {} as Role
|
|
10
|
+
|
|
11
|
+
const mockUser = {}
|
|
12
|
+
const mockParams = {
|
|
13
|
+
type: "read"
|
|
14
|
+
} as Params
|
|
15
|
+
|
|
16
|
+
describe('evaluateTopLevelWriteFn', () => {
|
|
17
|
+
it('should return undefined if type is different from read and write', async () => {
|
|
18
|
+
const isValid = await evaluateTopLevelWriteFn({
|
|
19
|
+
role: mockedRole,
|
|
20
|
+
user: mockUser,
|
|
21
|
+
params: { type: "delete" } as Params
|
|
22
|
+
})
|
|
23
|
+
expect(isValid).toBe(undefined)
|
|
24
|
+
expect(evaluateExpression).not.toHaveBeenCalled()
|
|
25
|
+
});
|
|
26
|
+
it('should return false if type is read but evaluate expression returns false', async () => {
|
|
27
|
+
(evaluateExpression as jest.Mock).mockResolvedValueOnce(false)
|
|
28
|
+
const isValid = await evaluateTopLevelWriteFn({
|
|
29
|
+
role: { ...mockedRole, write: false },
|
|
30
|
+
user: mockUser,
|
|
31
|
+
params: mockParams
|
|
32
|
+
})
|
|
33
|
+
expect(isValid).toBe(false)
|
|
34
|
+
expect(evaluateExpression).toHaveBeenCalledWith(mockParams, false, mockUser)
|
|
35
|
+
});
|
|
36
|
+
it('should return true if type is read and evaluate expression returns true', async () => {
|
|
37
|
+
(evaluateExpression as jest.Mock).mockResolvedValueOnce(true)
|
|
38
|
+
const isValid = await evaluateTopLevelWriteFn({
|
|
39
|
+
role: { ...mockedRole, write: false },
|
|
40
|
+
user: mockUser,
|
|
41
|
+
params: mockParams
|
|
42
|
+
})
|
|
43
|
+
expect(isValid).toBe(true)
|
|
44
|
+
expect(evaluateExpression).toHaveBeenCalledWith(mockParams, false, mockUser)
|
|
45
|
+
});
|
|
46
|
+
it('should return false if type is write but evaluate expression returns false', async () => {
|
|
47
|
+
(evaluateExpression as jest.Mock).mockResolvedValueOnce(false)
|
|
48
|
+
const isValid = await evaluateTopLevelWriteFn({
|
|
49
|
+
role: { ...mockedRole, write: false },
|
|
50
|
+
user: mockUser,
|
|
51
|
+
params: { type: "write" } as Params
|
|
52
|
+
})
|
|
53
|
+
expect(isValid).toBe(false)
|
|
54
|
+
expect(evaluateExpression).toHaveBeenCalledWith(mockParams, false, mockUser)
|
|
55
|
+
});
|
|
56
|
+
it('should return true if type is write and evaluate expression returns true', async () => {
|
|
57
|
+
(evaluateExpression as jest.Mock).mockResolvedValueOnce(true)
|
|
58
|
+
const isValid = await evaluateTopLevelWriteFn({
|
|
59
|
+
role: { ...mockedRole, write: false },
|
|
60
|
+
user: mockUser,
|
|
61
|
+
params: { type: "write" } as Params
|
|
62
|
+
})
|
|
63
|
+
expect(isValid).toBe(true)
|
|
64
|
+
expect(evaluateExpression).toHaveBeenCalledWith(mockParams, false, mockUser)
|
|
65
|
+
});
|
|
66
|
+
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import Fastify, { FastifyInstance } from 'fastify'
|
|
2
|
+
import { API_VERSION } from '../../constants'
|
|
3
|
+
import { exposeRoutes } from '../initializer/exposeRoutes'
|
|
4
|
+
|
|
5
|
+
jest.mock('../../constants', () => ({
|
|
6
|
+
API_VERSION: '/api/client/v2'
|
|
7
|
+
}))
|
|
8
|
+
|
|
9
|
+
const config: {
|
|
10
|
+
app?: FastifyInstance
|
|
11
|
+
} = {}
|
|
12
|
+
|
|
13
|
+
describe('exposeRoutes', () => {
|
|
14
|
+
|
|
15
|
+
beforeAll(async () => {
|
|
16
|
+
config.app = Fastify()
|
|
17
|
+
await exposeRoutes(config.app)
|
|
18
|
+
await config.app.ready()
|
|
19
|
+
jest.clearAllMocks();
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
afterAll(async () => {
|
|
23
|
+
await config.app!.close()
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('GET /health should return status ok and uptime', async () => {
|
|
27
|
+
const response = await config.app!.inject({
|
|
28
|
+
method: 'GET',
|
|
29
|
+
url: '/health',
|
|
30
|
+
})
|
|
31
|
+
expect(response.statusCode).toBe(200)
|
|
32
|
+
const body = JSON.parse(response.body)
|
|
33
|
+
expect(body).toHaveProperty('status', 'ok')
|
|
34
|
+
expect(body).toHaveProperty('uptime')
|
|
35
|
+
expect(typeof body.uptime).toBe('number')
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it(`GET ${API_VERSION}/app/:appId/location should return correct location data`, async () => {
|
|
39
|
+
const appId = 'it'
|
|
40
|
+
const response = await config.app!.inject({
|
|
41
|
+
method: 'GET',
|
|
42
|
+
url: `${API_VERSION}/app/${appId}/location`,
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
expect(response.statusCode).toBe(200)
|
|
46
|
+
expect(JSON.parse(response.body)).toEqual({
|
|
47
|
+
deployment_model: 'LOCAL',
|
|
48
|
+
location: 'IE',
|
|
49
|
+
hostname: 'http://localhost:3000',
|
|
50
|
+
ws_hostname: 'wss://localhost:3000'
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('exposeRoutes should handle errors in the catch block', async () => {
|
|
55
|
+
const mockedApp = Fastify()
|
|
56
|
+
// Forced fail on get method
|
|
57
|
+
jest.spyOn(mockedApp, 'get').mockImplementation(() => {
|
|
58
|
+
throw new Error('Route registration failed')
|
|
59
|
+
})
|
|
60
|
+
const mockErrorLog = jest.spyOn(console, 'error').mockImplementation(() => { })
|
|
61
|
+
await exposeRoutes(mockedApp)
|
|
62
|
+
expect(mockErrorLog).toHaveBeenCalledWith('Error while exposing routes', 'Route registration failed')
|
|
63
|
+
mockErrorLog.mockRestore()
|
|
64
|
+
})
|
|
65
|
+
})
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import Fastify from 'fastify'
|
|
2
|
+
import { User } from '../../auth/dtos';
|
|
3
|
+
import { Functions } from '../../features/functions/interface';
|
|
4
|
+
import { Rules } from '../../features/rules/interface'
|
|
5
|
+
import { services } from "../../services";
|
|
6
|
+
import { generateContextData } from "../context/helpers";
|
|
7
|
+
|
|
8
|
+
const originalEnv = process.env;
|
|
9
|
+
|
|
10
|
+
jest.mock('../../services', () => ({
|
|
11
|
+
services: {
|
|
12
|
+
api: jest.fn(),
|
|
13
|
+
aws: jest.fn(),
|
|
14
|
+
'mongodb-atlas': jest.fn(),
|
|
15
|
+
},
|
|
16
|
+
}));
|
|
17
|
+
|
|
18
|
+
const mockFunctions = {
|
|
19
|
+
test: {
|
|
20
|
+
name: "test",
|
|
21
|
+
code: "test"
|
|
22
|
+
}
|
|
23
|
+
} as Functions
|
|
24
|
+
|
|
25
|
+
const currentFunction = mockFunctions.test
|
|
26
|
+
const GenerateContextMock = jest.fn()
|
|
27
|
+
const mockUser = {} as User
|
|
28
|
+
const mockRules = {} as Rules
|
|
29
|
+
const mockEnv = {
|
|
30
|
+
...originalEnv,
|
|
31
|
+
test: "someTestVariable",
|
|
32
|
+
NODE_ENV: "dev",
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
describe('generateContextData', () => {
|
|
37
|
+
beforeEach(() => {
|
|
38
|
+
jest.resetModules();
|
|
39
|
+
process.env = mockEnv
|
|
40
|
+
jest.clearAllMocks();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
afterEach(() => {
|
|
44
|
+
process.env = originalEnv;
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('should return an object with context configuration', async () => {
|
|
48
|
+
|
|
49
|
+
const mockApp = Fastify()
|
|
50
|
+
const { context, console: contextConsole } = generateContextData({ services, app: mockApp, functionsList: mockFunctions, currentFunction, GenerateContext: GenerateContextMock, user: mockUser, rules: mockRules })
|
|
51
|
+
expect(context.user).toEqual(mockUser)
|
|
52
|
+
|
|
53
|
+
const testVariable = context.values.get("test")
|
|
54
|
+
expect(testVariable).toBe(mockEnv.test)
|
|
55
|
+
|
|
56
|
+
expect(context.environment.tag).toBe(mockEnv.NODE_ENV)
|
|
57
|
+
|
|
58
|
+
expect(context.user).toEqual(mockUser)
|
|
59
|
+
|
|
60
|
+
const mockedLog = jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
61
|
+
contextConsole.log('Test', 'generateContextData')
|
|
62
|
+
expect(mockedLog).toHaveBeenCalledWith('Test', 'generateContextData');
|
|
63
|
+
mockedLog.mockRestore();
|
|
64
|
+
|
|
65
|
+
context.services.get("api")
|
|
66
|
+
expect(services.api).toHaveBeenCalled()
|
|
67
|
+
const mockErrorLog = jest.spyOn(console, 'error').mockImplementation(() => { })
|
|
68
|
+
context.services.get("notfound" as keyof typeof services)
|
|
69
|
+
expect(mockErrorLog).toHaveBeenCalled()
|
|
70
|
+
mockErrorLog.mockRestore()
|
|
71
|
+
|
|
72
|
+
context.functions.execute("test")
|
|
73
|
+
expect(GenerateContextMock).toHaveBeenCalled()
|
|
74
|
+
});
|
|
75
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import rulesMatcherUtils from "../rules-matcher/utils";
|
|
2
|
+
|
|
3
|
+
describe('getDefaultRule', () => {
|
|
4
|
+
|
|
5
|
+
it('should return the default rule', () => {
|
|
6
|
+
expect(rulesMatcherUtils.getDefaultRule(2)).toEqual({ op: '$eq', value: 2 })
|
|
7
|
+
expect(rulesMatcherUtils.getDefaultRule("test")).toEqual({ op: '$eq', value: "test" })
|
|
8
|
+
expect(rulesMatcherUtils.getDefaultRule(true)).toEqual({ op: '$exists', value: true })
|
|
9
|
+
expect(rulesMatcherUtils.getDefaultRule(["test"])).toEqual({ op: '$in', value: ["test"] })
|
|
10
|
+
expect(rulesMatcherUtils.getDefaultRule({ name: "John" })).toEqual({
|
|
11
|
+
name: "John",
|
|
12
|
+
op: "name",
|
|
13
|
+
value: "John"
|
|
14
|
+
})
|
|
15
|
+
expect(rulesMatcherUtils.getDefaultRule({ name: "John", value: "test" })).toEqual({
|
|
16
|
+
name: "John",
|
|
17
|
+
op: "name",
|
|
18
|
+
value: "test"
|
|
19
|
+
})
|
|
20
|
+
expect(rulesMatcherUtils.getDefaultRule({ name: "John", value: "test", op: "$in" })).toEqual({
|
|
21
|
+
name: "John",
|
|
22
|
+
op: "$in",
|
|
23
|
+
value: "test"
|
|
24
|
+
})
|
|
25
|
+
expect(rulesMatcherUtils.getDefaultRule(undefined)).toEqual({ op: '$eq', value: undefined })
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import rulesMatcherUtils from "../rules-matcher/utils";
|
|
2
|
+
|
|
3
|
+
describe('getKey function', () => {
|
|
4
|
+
it('should handle a basic rule correctly', () => {
|
|
5
|
+
const mockKeys = {}
|
|
6
|
+
const mockOptions = { prefix: 'user' }
|
|
7
|
+
const block = { name: { $eq: 'John' } };
|
|
8
|
+
const response = rulesMatcherUtils.getKey(block, mockKeys, mockOptions);
|
|
9
|
+
expect(response).toBe(true)
|
|
10
|
+
expect(mockKeys).toEqual({ "user.name": true })
|
|
11
|
+
});
|
|
12
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import rulesMatcherUtils from "../rules-matcher/utils";
|
|
2
|
+
|
|
3
|
+
describe('getKeys', () => {
|
|
4
|
+
|
|
5
|
+
it('should handle $and operator correctly', () => {
|
|
6
|
+
expect(rulesMatcherUtils.getKeys(undefined)).toBe(null)
|
|
7
|
+
expect(rulesMatcherUtils.getKeys(() => { })).toEqual([])
|
|
8
|
+
// NOTE -> this cast is forced to test a case that should never be verified
|
|
9
|
+
expect(rulesMatcherUtils.getKeys("test" as unknown as Record<string, unknown>)).toEqual(null)
|
|
10
|
+
});
|
|
11
|
+
});
|