@strapi/strapi 4.10.0 → 4.10.1
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/coverage/clover.xml +1613 -0
- package/coverage/coverage-final.json +48 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/commands/__tests__/data-transfer/shared/index.html +116 -0
- package/coverage/lcov-report/commands/__tests__/data-transfer/shared/transfer.test.utils.js.html +133 -0
- package/coverage/lcov-report/commands/admin-create.js.html +424 -0
- package/coverage/lcov-report/commands/admin-reset.js.html +241 -0
- package/coverage/lcov-report/commands/generate-template.js.html +373 -0
- package/coverage/lcov-report/commands/index.html +146 -0
- package/coverage/lcov-report/commands/transfer/export.js.html +619 -0
- package/coverage/lcov-report/commands/transfer/import.js.html +562 -0
- package/coverage/lcov-report/commands/transfer/index.html +146 -0
- package/coverage/lcov-report/commands/transfer/transfer.js.html +532 -0
- package/coverage/lcov-report/commands/utils/helpers.js.html +430 -0
- package/coverage/lcov-report/commands/utils/index.html +116 -0
- package/coverage/lcov-report/core/registries/custom-fields.js.html +301 -0
- package/coverage/lcov-report/core/registries/index.html +116 -0
- package/coverage/lcov-report/core-api/controller/collection-type.js.html +418 -0
- package/coverage/lcov-report/core-api/controller/index.html +161 -0
- package/coverage/lcov-report/core-api/controller/index.js.html +220 -0
- package/coverage/lcov-report/core-api/controller/single-type.js.html +274 -0
- package/coverage/lcov-report/core-api/controller/transform.js.html +376 -0
- package/coverage/lcov-report/core-api/service/collection-type.js.html +325 -0
- package/coverage/lcov-report/core-api/service/index.html +161 -0
- package/coverage/lcov-report/core-api/service/index.js.html +220 -0
- package/coverage/lcov-report/core-api/service/pagination.js.html +460 -0
- package/coverage/lcov-report/core-api/service/single-type.js.html +301 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +386 -0
- package/coverage/lcov-report/load/filepath-to-prop-path.js.html +151 -0
- package/coverage/lcov-report/load/index.html +116 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/services/content-api/index.html +116 -0
- package/coverage/lcov-report/services/content-api/index.js.html +307 -0
- package/coverage/lcov-report/services/content-api/permissions/engine.js.html +100 -0
- package/coverage/lcov-report/services/content-api/permissions/index.html +131 -0
- package/coverage/lcov-report/services/content-api/permissions/index.js.html +529 -0
- package/coverage/lcov-report/services/content-api/permissions/providers/action.js.html +142 -0
- package/coverage/lcov-report/services/content-api/permissions/providers/condition.js.html +142 -0
- package/coverage/lcov-report/services/content-api/permissions/providers/index.html +146 -0
- package/coverage/lcov-report/services/content-api/permissions/providers/index.js.html +112 -0
- package/coverage/lcov-report/services/core-store.js.html +520 -0
- package/coverage/lcov-report/services/entity-service/attributes/index.html +131 -0
- package/coverage/lcov-report/services/entity-service/attributes/index.js.html +178 -0
- package/coverage/lcov-report/services/entity-service/attributes/transforms.js.html +145 -0
- package/coverage/lcov-report/services/entity-service/components.js.html +1246 -0
- package/coverage/lcov-report/services/entity-service/index.html +146 -0
- package/coverage/lcov-report/services/entity-service/index.js.html +1120 -0
- package/coverage/lcov-report/services/entity-service/params.js.html +112 -0
- package/coverage/lcov-report/services/entity-validator/__tests__/relations/utils/index.html +116 -0
- package/coverage/lcov-report/services/entity-validator/__tests__/relations/utils/relations.testdata.js.html +544 -0
- package/coverage/lcov-report/services/entity-validator/index.html +131 -0
- package/coverage/lcov-report/services/entity-validator/index.js.html +1231 -0
- package/coverage/lcov-report/services/entity-validator/validators.js.html +733 -0
- package/coverage/lcov-report/services/event-hub.js.html +319 -0
- package/coverage/lcov-report/services/fs.js.html +259 -0
- package/coverage/lcov-report/services/index.html +161 -0
- package/coverage/lcov-report/services/metrics/admin-user-hash.js.html +148 -0
- package/coverage/lcov-report/services/metrics/index.html +206 -0
- package/coverage/lcov-report/services/metrics/index.js.html +265 -0
- package/coverage/lcov-report/services/metrics/is-truthy.js.html +112 -0
- package/coverage/lcov-report/services/metrics/middleware.js.html +184 -0
- package/coverage/lcov-report/services/metrics/rate-limiter.js.html +166 -0
- package/coverage/lcov-report/services/metrics/sender.js.html +394 -0
- package/coverage/lcov-report/services/metrics/stringify-deep.js.html +151 -0
- package/coverage/lcov-report/services/utils/index.html +116 -0
- package/coverage/lcov-report/services/utils/upload-files.js.html +322 -0
- package/coverage/lcov-report/services/worker-queue.js.html +262 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +196 -0
- package/coverage/lcov-report/utils/convert-custom-field-type.js.html +151 -0
- package/coverage/lcov-report/utils/index.html +146 -0
- package/coverage/lcov-report/utils/machine-id.js.html +127 -0
- package/coverage/lcov-report/utils/url-from-segments.js.html +121 -0
- package/lib/commands/__tests__/commands.test.js +20 -0
- package/lib/commands/__tests__/commands.test.utils.js +16 -0
- package/lib/commands/actions/admin/create-user/__tests__/admin.create-user.test.js +450 -0
- package/lib/commands/actions/admin/reset-user-password/__tests__/admin.reset-user-password.test.js +145 -0
- package/lib/commands/actions/build/action.js +18 -0
- package/lib/commands/actions/build/command.js +15 -0
- package/lib/commands/actions/export/__tests__/export.test.js +175 -0
- package/lib/commands/actions/import/__tests__/import.test.js +143 -0
- package/lib/commands/actions/templates/generate/__tests__/templates.generate.js +118 -0
- package/lib/commands/actions/transfer/__tests__/transfer.test.js +178 -0
- package/lib/core/registries/__tests__/custom-fields.test.js +152 -0
- package/lib/core-api/__tests__/controller.test.js +39 -0
- package/lib/core-api/controller/__tests__/transform.test.js +226 -0
- package/lib/core-api/service/__tests__/index.test.js +127 -0
- package/lib/core-api/service/__tests__/pagination.test.js +275 -0
- package/lib/load/__tests__/filepath-to-prop-path.test.js +30 -0
- package/lib/middlewares/__tests__/errors.test.js +21 -0
- package/lib/services/__tests__/content-api-permissions.test.js +291 -0
- package/lib/services/__tests__/core-store.test.js +148 -0
- package/lib/services/__tests__/event-hub.test.js +126 -0
- package/lib/services/__tests__/fs.test.js +78 -0
- package/lib/services/__tests__/worker-queue.test.js +47 -0
- package/lib/services/entity-service/__tests__/entity-service-events.test.js +117 -0
- package/lib/services/entity-service/__tests__/entity-service.test.js +587 -0
- package/lib/services/entity-validator/__tests__/biginteger-validators.test.js +220 -0
- package/lib/services/entity-validator/__tests__/date-validators.test.js +183 -0
- package/lib/services/entity-validator/__tests__/datetime-validators.test.js +183 -0
- package/lib/services/entity-validator/__tests__/email-validators.test.js +56 -0
- package/lib/services/entity-validator/__tests__/enumeration-validators.test.js +43 -0
- package/lib/services/entity-validator/__tests__/float-validators.test.js +278 -0
- package/lib/services/entity-validator/__tests__/index.test.js +609 -0
- package/lib/services/entity-validator/__tests__/integer-validators.test.js +278 -0
- package/lib/services/entity-validator/__tests__/relations/attribute-level.test.js +123 -0
- package/lib/services/entity-validator/__tests__/relations/component-level.test.js +275 -0
- package/lib/services/entity-validator/__tests__/relations/dynamic-zone-level.test.js +159 -0
- package/lib/services/entity-validator/__tests__/relations/media-level.test.js +74 -0
- package/lib/services/entity-validator/__tests__/relations/utils/relations.testdata.js +153 -0
- package/lib/services/entity-validator/__tests__/string-validators.test.js +374 -0
- package/lib/services/entity-validator/__tests__/time-validators.test.js +183 -0
- package/lib/services/entity-validator/__tests__/timestamp-validators.test.js +204 -0
- package/lib/services/entity-validator/__tests__/uid-validators.test.js +229 -0
- package/lib/services/metrics/__tests__/admin-user-hash.test.js +41 -0
- package/lib/services/metrics/__tests__/index.test.js +157 -0
- package/lib/services/metrics/__tests__/is-truthy.js +33 -0
- package/lib/services/metrics/__tests__/middleware.test.js +60 -0
- package/lib/services/metrics/__tests__/rate-limiter.test.js +50 -0
- package/lib/services/metrics/__tests__/stringify-deep.test.js +27 -0
- package/lib/utils/__tests__/convert-custom-field-type.test.js +69 -0
- package/lib/utils/__tests__/url-from-segments.test.js +40 -0
- package/package.json +15 -15
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const _ = require('lodash');
|
|
4
|
+
const { getPaginationInfo } = require('../pagination');
|
|
5
|
+
|
|
6
|
+
const maxLimit = 50;
|
|
7
|
+
const defaultLimit = 20;
|
|
8
|
+
|
|
9
|
+
describe('Pagination service', () => {
|
|
10
|
+
describe('With maxLimit set globally', () => {
|
|
11
|
+
beforeAll(() => {
|
|
12
|
+
global.strapi = {
|
|
13
|
+
config: {
|
|
14
|
+
get(path, defaultValue) {
|
|
15
|
+
return _.get(this, path, defaultValue);
|
|
16
|
+
},
|
|
17
|
+
api: {
|
|
18
|
+
rest: {
|
|
19
|
+
defaultLimit,
|
|
20
|
+
maxLimit,
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('Uses default limit', () => {
|
|
28
|
+
const pagination = {};
|
|
29
|
+
const paginationInfo = getPaginationInfo({ pagination });
|
|
30
|
+
|
|
31
|
+
expect(paginationInfo).toEqual({
|
|
32
|
+
page: 1,
|
|
33
|
+
pageSize: defaultLimit,
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe('Paged pagination', () => {
|
|
38
|
+
test('Uses specified pageSize', () => {
|
|
39
|
+
const pagination = { pageSize: 5 };
|
|
40
|
+
const paginationInfo = getPaginationInfo({ pagination });
|
|
41
|
+
|
|
42
|
+
expect(paginationInfo).toEqual({
|
|
43
|
+
page: 1,
|
|
44
|
+
pageSize: pagination.pageSize,
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test('Uses maxLimit as pageSize', () => {
|
|
49
|
+
const pagination = { pageSize: 999 };
|
|
50
|
+
const paginationInfo = getPaginationInfo({ pagination });
|
|
51
|
+
|
|
52
|
+
expect(paginationInfo).toEqual({
|
|
53
|
+
page: 1,
|
|
54
|
+
pageSize: maxLimit,
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test('Uses 1 as pageSize', () => {
|
|
59
|
+
const pagination = { pageSize: 0 };
|
|
60
|
+
const paginationInfo = getPaginationInfo({ pagination });
|
|
61
|
+
|
|
62
|
+
expect(paginationInfo).toEqual({
|
|
63
|
+
page: 1,
|
|
64
|
+
pageSize: 1,
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('Uses 1 as pageSize', () => {
|
|
69
|
+
const pagination = { pageSize: -1 };
|
|
70
|
+
const paginationInfo = getPaginationInfo({ pagination });
|
|
71
|
+
|
|
72
|
+
expect(paginationInfo).toEqual({
|
|
73
|
+
page: 1,
|
|
74
|
+
pageSize: 1,
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test('Uses 1 as pageSize', () => {
|
|
79
|
+
const pagination = { pageSize: -2 };
|
|
80
|
+
const paginationInfo = getPaginationInfo({ pagination });
|
|
81
|
+
|
|
82
|
+
expect(paginationInfo).toEqual({
|
|
83
|
+
page: 1,
|
|
84
|
+
pageSize: 1,
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
describe('Offset pagination', () => {
|
|
90
|
+
test('Uses specified limit', () => {
|
|
91
|
+
const pagination = { limit: 5 };
|
|
92
|
+
const paginationInfo = getPaginationInfo({ pagination });
|
|
93
|
+
|
|
94
|
+
expect(paginationInfo).toEqual({
|
|
95
|
+
start: 0,
|
|
96
|
+
limit: pagination.limit,
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test('Uses maxLimit as limit', () => {
|
|
101
|
+
const pagination = { limit: 999 };
|
|
102
|
+
const paginationInfo = getPaginationInfo({ pagination });
|
|
103
|
+
|
|
104
|
+
expect(paginationInfo).toEqual({
|
|
105
|
+
start: 0,
|
|
106
|
+
limit: maxLimit,
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test('Uses 1 as limit', () => {
|
|
111
|
+
const pagination = { limit: 0 };
|
|
112
|
+
const paginationInfo = getPaginationInfo({ pagination });
|
|
113
|
+
|
|
114
|
+
expect(paginationInfo).toEqual({
|
|
115
|
+
start: 0,
|
|
116
|
+
limit: 1,
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test('Uses maxLimit as limit', () => {
|
|
121
|
+
const pagination = { limit: -1 };
|
|
122
|
+
const paginationInfo = getPaginationInfo({ pagination });
|
|
123
|
+
|
|
124
|
+
expect(paginationInfo).toEqual({
|
|
125
|
+
start: 0,
|
|
126
|
+
limit: maxLimit,
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test('Uses 1 as limit', () => {
|
|
131
|
+
const pagination = { limit: -2 };
|
|
132
|
+
const paginationInfo = getPaginationInfo({ pagination });
|
|
133
|
+
|
|
134
|
+
expect(paginationInfo).toEqual({
|
|
135
|
+
start: 0,
|
|
136
|
+
limit: 1,
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// Setting global strapi api conf
|
|
143
|
+
|
|
144
|
+
describe('With maxLimit undefined', () => {
|
|
145
|
+
beforeAll(() => {
|
|
146
|
+
global.strapi = {
|
|
147
|
+
config: {
|
|
148
|
+
get(path, defaultValue) {
|
|
149
|
+
return _.get(this, path, defaultValue);
|
|
150
|
+
},
|
|
151
|
+
api: {
|
|
152
|
+
rest: {
|
|
153
|
+
defaultLimit,
|
|
154
|
+
maxLimit: undefined,
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
test('Uses default limit', () => {
|
|
162
|
+
const pagination = {};
|
|
163
|
+
const paginationInfo = getPaginationInfo({ pagination });
|
|
164
|
+
|
|
165
|
+
expect(paginationInfo).toEqual({
|
|
166
|
+
page: 1,
|
|
167
|
+
pageSize: defaultLimit,
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
describe('Paged pagination', () => {
|
|
172
|
+
test('Uses specified pageSize', () => {
|
|
173
|
+
const pagination = { pageSize: 5 };
|
|
174
|
+
const paginationInfo = getPaginationInfo({ pagination });
|
|
175
|
+
|
|
176
|
+
expect(paginationInfo).toEqual({
|
|
177
|
+
page: 1,
|
|
178
|
+
pageSize: pagination.pageSize,
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
test('Uses specified pageSize', () => {
|
|
183
|
+
const pagination = { pageSize: 999 };
|
|
184
|
+
const paginationInfo = getPaginationInfo({ pagination });
|
|
185
|
+
|
|
186
|
+
expect(paginationInfo).toEqual({
|
|
187
|
+
page: 1,
|
|
188
|
+
pageSize: pagination.pageSize,
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
test('Uses 1 as pageSize', () => {
|
|
193
|
+
const pagination = { pageSize: 0 };
|
|
194
|
+
const paginationInfo = getPaginationInfo({ pagination });
|
|
195
|
+
|
|
196
|
+
expect(paginationInfo).toEqual({
|
|
197
|
+
page: 1,
|
|
198
|
+
pageSize: 1,
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
test('Uses 1 as pageSize', () => {
|
|
203
|
+
const pagination = { pageSize: -1 };
|
|
204
|
+
const paginationInfo = getPaginationInfo({ pagination });
|
|
205
|
+
|
|
206
|
+
expect(paginationInfo).toEqual({
|
|
207
|
+
page: 1,
|
|
208
|
+
pageSize: 1,
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
test('Uses 1 as pageSize', () => {
|
|
213
|
+
const pagination = { pageSize: -2 };
|
|
214
|
+
const paginationInfo = getPaginationInfo({ pagination });
|
|
215
|
+
|
|
216
|
+
expect(paginationInfo).toEqual({
|
|
217
|
+
page: 1,
|
|
218
|
+
pageSize: 1,
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
describe('Offset pagination', () => {
|
|
224
|
+
test('Uses specified limit', () => {
|
|
225
|
+
const pagination = { limit: 5 };
|
|
226
|
+
const paginationInfo = getPaginationInfo({ pagination });
|
|
227
|
+
|
|
228
|
+
expect(paginationInfo).toEqual({
|
|
229
|
+
start: 0,
|
|
230
|
+
limit: pagination.limit,
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
test('Uses specified limit', () => {
|
|
235
|
+
const pagination = { limit: 999 };
|
|
236
|
+
const paginationInfo = getPaginationInfo({ pagination });
|
|
237
|
+
|
|
238
|
+
expect(paginationInfo).toEqual({
|
|
239
|
+
start: 0,
|
|
240
|
+
limit: pagination.limit,
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
test('Uses 1 as limit', () => {
|
|
245
|
+
const pagination = { limit: 0 };
|
|
246
|
+
const paginationInfo = getPaginationInfo({ pagination });
|
|
247
|
+
|
|
248
|
+
expect(paginationInfo).toEqual({
|
|
249
|
+
start: 0,
|
|
250
|
+
limit: 1,
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
test('Uses -1 as limit', () => {
|
|
255
|
+
const pagination = { limit: -1 };
|
|
256
|
+
const paginationInfo = getPaginationInfo({ pagination });
|
|
257
|
+
|
|
258
|
+
expect(paginationInfo).toEqual({
|
|
259
|
+
start: 0,
|
|
260
|
+
limit: -1,
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
test('Uses 1 as limit', () => {
|
|
265
|
+
const pagination = { limit: -2 };
|
|
266
|
+
const paginationInfo = getPaginationInfo({ pagination });
|
|
267
|
+
|
|
268
|
+
expect(paginationInfo).toEqual({
|
|
269
|
+
start: 0,
|
|
270
|
+
limit: 1,
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const filePathToPropPath = require('../filepath-to-prop-path');
|
|
4
|
+
|
|
5
|
+
const commonCases = [
|
|
6
|
+
['./config/test.js', ['config', 'test']],
|
|
7
|
+
['./config/test.json', ['config', 'test']],
|
|
8
|
+
['./config/test.settings.js', ['config', 'test']],
|
|
9
|
+
['./config/test.settings.json', ['config', 'test']],
|
|
10
|
+
['config/test.settings.json', ['config', 'test']],
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
describe('filePathToPropPath', () => {
|
|
14
|
+
test.each(commonCases)('File %s becomes %p', (input, expected) => {
|
|
15
|
+
expect(filePathToPropPath(input)).toEqual(expected);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
// uses dots to create path
|
|
19
|
+
test('Uses dots for key separation', () => {
|
|
20
|
+
expect(filePathToPropPath('./config/file.key.js')).toEqual(['config', 'file', 'key']);
|
|
21
|
+
|
|
22
|
+
expect(filePathToPropPath('./config/file.key.json')).toEqual(['config', 'file', 'key']);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// removes the last prop of the path
|
|
26
|
+
test('Disable file name key', () => {
|
|
27
|
+
expect(filePathToPropPath('./config/test.js', false)).toEqual(['config']);
|
|
28
|
+
expect(filePathToPropPath('./config/test.key.js', false)).toEqual(['config', 'test']);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Koa = require('koa');
|
|
4
|
+
const request = require('supertest');
|
|
5
|
+
|
|
6
|
+
describe('Errors middleware', () => {
|
|
7
|
+
test('_explicitStatus still exists', async () => {
|
|
8
|
+
// Since we are using an internal variable of koa in our code,
|
|
9
|
+
// we check that it doesn't change in newer updates
|
|
10
|
+
const app = new Koa();
|
|
11
|
+
|
|
12
|
+
app.use(async (ctx) => {
|
|
13
|
+
ctx.body = 'hello';
|
|
14
|
+
expect(ctx.response._explicitStatus).toBe(true);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
expect.assertions(1);
|
|
18
|
+
|
|
19
|
+
await request(app.callback()).get('/');
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const createContentAPI = require('../content-api');
|
|
4
|
+
|
|
5
|
+
describe('Content API - Permissions', () => {
|
|
6
|
+
const bindToContentAPI = (action) => {
|
|
7
|
+
Object.assign(action, { [Symbol.for('__type__')]: ['content-api'] });
|
|
8
|
+
return action;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
describe('Get Actions Map', () => {
|
|
12
|
+
test('When no API are defined, it should return an empty object', () => {
|
|
13
|
+
global.strapi = {};
|
|
14
|
+
|
|
15
|
+
const contentAPI = createContentAPI(global.strapi);
|
|
16
|
+
const actionsMap = contentAPI.permissions.getActionsMap();
|
|
17
|
+
|
|
18
|
+
expect(actionsMap).toEqual({});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('When no controller are defined for an API, it should ignore the API', () => {
|
|
22
|
+
global.strapi = {
|
|
23
|
+
api: {
|
|
24
|
+
foo: {},
|
|
25
|
+
bar: {},
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const contentAPI = createContentAPI(global.strapi);
|
|
30
|
+
const actionsMap = contentAPI.permissions.getActionsMap();
|
|
31
|
+
|
|
32
|
+
expect(actionsMap).toEqual({});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test(`Do not register controller if they're not bound to the content API`, () => {
|
|
36
|
+
const actionC = () => {};
|
|
37
|
+
Object.assign(actionC, { [Symbol.for('__type__')]: ['admin-api'] });
|
|
38
|
+
|
|
39
|
+
global.strapi = {
|
|
40
|
+
api: {
|
|
41
|
+
foo: {
|
|
42
|
+
controllers: {
|
|
43
|
+
controllerA: {
|
|
44
|
+
actionA: bindToContentAPI(() => {}),
|
|
45
|
+
actionB() {},
|
|
46
|
+
actionC,
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const contentAPI = createContentAPI(global.strapi);
|
|
54
|
+
const actionsMap = contentAPI.permissions.getActionsMap();
|
|
55
|
+
|
|
56
|
+
expect(actionsMap).toEqual({
|
|
57
|
+
'api::foo': { controllers: { controllerA: ['actionA'] } },
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('Creates and populate a map of actions from APIs and plugins', () => {
|
|
62
|
+
global.strapi = {
|
|
63
|
+
api: {
|
|
64
|
+
foo: {
|
|
65
|
+
controllers: {
|
|
66
|
+
controllerA: {
|
|
67
|
+
actionA: bindToContentAPI(() => {}),
|
|
68
|
+
actionB: bindToContentAPI(() => {}),
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
bar: {
|
|
73
|
+
controllers: {
|
|
74
|
+
controllerA: {
|
|
75
|
+
actionA: bindToContentAPI(() => {}),
|
|
76
|
+
actionB: bindToContentAPI(() => {}),
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
foobar: {
|
|
81
|
+
controllers: {
|
|
82
|
+
controllerA: {
|
|
83
|
+
actionA: bindToContentAPI(() => {}),
|
|
84
|
+
actionB: bindToContentAPI(() => {}),
|
|
85
|
+
},
|
|
86
|
+
controllerB: {
|
|
87
|
+
actionC: bindToContentAPI(() => {}),
|
|
88
|
+
actionD: bindToContentAPI(() => {}),
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
plugins: {
|
|
94
|
+
foo: {
|
|
95
|
+
controllers: {
|
|
96
|
+
controllerA: {
|
|
97
|
+
actionA: bindToContentAPI(() => {}),
|
|
98
|
+
actionB: bindToContentAPI(() => {}),
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
bar: {
|
|
103
|
+
controllers: {
|
|
104
|
+
controllerA: {
|
|
105
|
+
actionA: bindToContentAPI(() => {}),
|
|
106
|
+
actionB: bindToContentAPI(() => {}),
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const contentAPI = createContentAPI(global.strapi);
|
|
114
|
+
const actionsMap = contentAPI.permissions.getActionsMap();
|
|
115
|
+
|
|
116
|
+
expect(actionsMap).toEqual({
|
|
117
|
+
'api::foo': { controllers: { controllerA: ['actionA', 'actionB'] } },
|
|
118
|
+
'api::bar': { controllers: { controllerA: ['actionA', 'actionB'] } },
|
|
119
|
+
'api::foobar': {
|
|
120
|
+
controllers: {
|
|
121
|
+
controllerA: ['actionA', 'actionB'],
|
|
122
|
+
controllerB: ['actionC', 'actionD'],
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
'plugin::foo': { controllers: { controllerA: ['actionA', 'actionB'] } },
|
|
126
|
+
'plugin::bar': { controllers: { controllerA: ['actionA', 'actionB'] } },
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
describe('Register Actions', () => {
|
|
132
|
+
beforeEach(() => {
|
|
133
|
+
global.strapi = {
|
|
134
|
+
api: {
|
|
135
|
+
foo: {
|
|
136
|
+
controllers: {
|
|
137
|
+
controllerA: {
|
|
138
|
+
actionA: bindToContentAPI(() => {}),
|
|
139
|
+
actionB: bindToContentAPI(() => {}),
|
|
140
|
+
},
|
|
141
|
+
controllerB: {
|
|
142
|
+
actionC: bindToContentAPI(() => {}),
|
|
143
|
+
actionD: bindToContentAPI(() => {}),
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
plugins: {
|
|
149
|
+
foo: {
|
|
150
|
+
controllers: {
|
|
151
|
+
controllerA: {
|
|
152
|
+
actionA: bindToContentAPI(() => {}),
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
test('The action provider should holds every action from APIs and plugins', async () => {
|
|
161
|
+
const contentAPI = createContentAPI(global.strapi);
|
|
162
|
+
|
|
163
|
+
await contentAPI.permissions.registerActions();
|
|
164
|
+
|
|
165
|
+
const values = contentAPI.permissions.providers.action.values();
|
|
166
|
+
|
|
167
|
+
expect(values).toEqual([
|
|
168
|
+
{
|
|
169
|
+
uid: 'api::foo.controllerA.actionA',
|
|
170
|
+
api: 'api::foo',
|
|
171
|
+
controller: 'controllerA',
|
|
172
|
+
action: 'actionA',
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
uid: 'api::foo.controllerA.actionB',
|
|
176
|
+
api: 'api::foo',
|
|
177
|
+
controller: 'controllerA',
|
|
178
|
+
action: 'actionB',
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
uid: 'api::foo.controllerB.actionC',
|
|
182
|
+
api: 'api::foo',
|
|
183
|
+
controller: 'controllerB',
|
|
184
|
+
action: 'actionC',
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
uid: 'api::foo.controllerB.actionD',
|
|
188
|
+
api: 'api::foo',
|
|
189
|
+
controller: 'controllerB',
|
|
190
|
+
action: 'actionD',
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
uid: 'plugin::foo.controllerA.actionA',
|
|
194
|
+
api: 'plugin::foo',
|
|
195
|
+
controller: 'controllerA',
|
|
196
|
+
action: 'actionA',
|
|
197
|
+
},
|
|
198
|
+
]);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
test('Call registerActions twice should throw a duplicate error', async () => {
|
|
202
|
+
const contentAPI = createContentAPI(global.strapi);
|
|
203
|
+
|
|
204
|
+
await contentAPI.permissions.registerActions();
|
|
205
|
+
|
|
206
|
+
expect(() => contentAPI.permissions.registerActions()).rejects.toThrowError(
|
|
207
|
+
'Duplicated item key: api::foo.controllerA.actionA'
|
|
208
|
+
);
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
describe('Providers', () => {
|
|
213
|
+
test('You should not be able to register action once strapi is loaded', () => {
|
|
214
|
+
global.strapi.isLoaded = true;
|
|
215
|
+
|
|
216
|
+
const contentAPI = createContentAPI(global.strapi);
|
|
217
|
+
|
|
218
|
+
// Actions
|
|
219
|
+
expect(() =>
|
|
220
|
+
contentAPI.permissions.providers.action.register('foo', {})
|
|
221
|
+
).rejects.toThrowError(`You can't register new actions outside the bootstrap function.`);
|
|
222
|
+
|
|
223
|
+
// Conditions
|
|
224
|
+
expect(() =>
|
|
225
|
+
contentAPI.permissions.providers.condition.register({ name: 'myCondition' })
|
|
226
|
+
).rejects.toThrowError(`You can't register new conditions outside the bootstrap function.`);
|
|
227
|
+
|
|
228
|
+
// Register Actions
|
|
229
|
+
expect(() => contentAPI.permissions.registerActions()).rejects.toThrowError(
|
|
230
|
+
`You can't register new actions outside the bootstrap function.`
|
|
231
|
+
);
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
describe('Engine', () => {
|
|
236
|
+
test('Engine warns when registering an unknown action', async () => {
|
|
237
|
+
global.strapi = {
|
|
238
|
+
log: {
|
|
239
|
+
debug: jest.fn(),
|
|
240
|
+
},
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
const contentAPI = createContentAPI();
|
|
244
|
+
|
|
245
|
+
const ability = await contentAPI.permissions.engine.generateAbility([{ action: 'foo' }]);
|
|
246
|
+
|
|
247
|
+
expect(ability.rules).toHaveLength(0);
|
|
248
|
+
expect(global.strapi.log.debug).toHaveBeenCalledWith(
|
|
249
|
+
`Unknown action "foo" supplied when registering a new permission`
|
|
250
|
+
);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
test('Engine filter out invalid action when generating an ability', async () => {
|
|
254
|
+
global.strapi = {
|
|
255
|
+
log: {
|
|
256
|
+
debug: jest.fn(),
|
|
257
|
+
},
|
|
258
|
+
|
|
259
|
+
api: {
|
|
260
|
+
foo: {
|
|
261
|
+
controllers: {
|
|
262
|
+
bar: { foobar: bindToContentAPI(() => {}) },
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
const contentAPI = createContentAPI(global.strapi);
|
|
269
|
+
|
|
270
|
+
await contentAPI.permissions.registerActions();
|
|
271
|
+
|
|
272
|
+
const ability = await contentAPI.permissions.engine.generateAbility([
|
|
273
|
+
{ action: 'foo' },
|
|
274
|
+
{ action: 'api::foo.bar.foobar' },
|
|
275
|
+
]);
|
|
276
|
+
|
|
277
|
+
expect(ability.rules).toHaveLength(1);
|
|
278
|
+
expect(ability.rules).toEqual([
|
|
279
|
+
{
|
|
280
|
+
action: 'api::foo.bar.foobar',
|
|
281
|
+
subject: 'all',
|
|
282
|
+
},
|
|
283
|
+
]);
|
|
284
|
+
|
|
285
|
+
expect(global.strapi.log.debug).toHaveBeenCalledTimes(1);
|
|
286
|
+
expect(global.strapi.log.debug).toHaveBeenCalledWith(
|
|
287
|
+
`Unknown action "foo" supplied when registering a new permission`
|
|
288
|
+
);
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
});
|