@nocobase/plugin-acl 0.7.0-alpha.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.
Files changed (98) hide show
  1. package/LICENSE +201 -0
  2. package/esm/actions/available-actions.d.ts +7 -0
  3. package/esm/actions/available-actions.js +26 -0
  4. package/esm/actions/available-actions.js.map +1 -0
  5. package/esm/actions/role-check.d.ts +1 -0
  6. package/esm/actions/role-check.js +38 -0
  7. package/esm/actions/role-check.js.map +1 -0
  8. package/esm/actions/role-collections.d.ts +7 -0
  9. package/esm/actions/role-collections.js +54 -0
  10. package/esm/actions/role-collections.js.map +1 -0
  11. package/esm/collections/roles.d.ts +3 -0
  12. package/esm/collections/roles.js +78 -0
  13. package/esm/collections/roles.js.map +1 -0
  14. package/esm/collections/rolesResources.d.ts +3 -0
  15. package/esm/collections/rolesResources.js +30 -0
  16. package/esm/collections/rolesResources.js.map +1 -0
  17. package/esm/collections/rolesResourcesActions.d.ts +3 -0
  18. package/esm/collections/rolesResourcesActions.js +27 -0
  19. package/esm/collections/rolesResourcesActions.js.map +1 -0
  20. package/esm/collections/rolesResourcesScopes.d.ts +3 -0
  21. package/esm/collections/rolesResourcesScopes.js +22 -0
  22. package/esm/collections/rolesResourcesScopes.js.map +1 -0
  23. package/esm/index.d.ts +1 -0
  24. package/esm/index.js +2 -0
  25. package/esm/index.js.map +1 -0
  26. package/esm/model/RoleModel.d.ts +7 -0
  27. package/esm/model/RoleModel.js +15 -0
  28. package/esm/model/RoleModel.js.map +1 -0
  29. package/esm/model/RoleResourceActionModel.d.ts +12 -0
  30. package/esm/model/RoleResourceActionModel.js +65 -0
  31. package/esm/model/RoleResourceActionModel.js.map +1 -0
  32. package/esm/model/RoleResourceModel.d.ts +16 -0
  33. package/esm/model/RoleResourceModel.js +55 -0
  34. package/esm/model/RoleResourceModel.js.map +1 -0
  35. package/esm/server.d.ts +33 -0
  36. package/esm/server.js +366 -0
  37. package/esm/server.js.map +1 -0
  38. package/lib/actions/available-actions.d.ts +7 -0
  39. package/lib/actions/available-actions.js +29 -0
  40. package/lib/actions/available-actions.js.map +1 -0
  41. package/lib/actions/role-check.d.ts +1 -0
  42. package/lib/actions/role-check.js +42 -0
  43. package/lib/actions/role-check.js.map +1 -0
  44. package/lib/actions/role-collections.d.ts +7 -0
  45. package/lib/actions/role-collections.js +57 -0
  46. package/lib/actions/role-collections.js.map +1 -0
  47. package/lib/collections/roles.d.ts +3 -0
  48. package/lib/collections/roles.js +80 -0
  49. package/lib/collections/roles.js.map +1 -0
  50. package/lib/collections/rolesResources.d.ts +3 -0
  51. package/lib/collections/rolesResources.js +32 -0
  52. package/lib/collections/rolesResources.js.map +1 -0
  53. package/lib/collections/rolesResourcesActions.d.ts +3 -0
  54. package/lib/collections/rolesResourcesActions.js +29 -0
  55. package/lib/collections/rolesResourcesActions.js.map +1 -0
  56. package/lib/collections/rolesResourcesScopes.d.ts +3 -0
  57. package/lib/collections/rolesResourcesScopes.js +24 -0
  58. package/lib/collections/rolesResourcesScopes.js.map +1 -0
  59. package/lib/index.d.ts +1 -0
  60. package/lib/index.js +9 -0
  61. package/lib/index.js.map +1 -0
  62. package/lib/model/RoleModel.d.ts +7 -0
  63. package/lib/model/RoleModel.js +19 -0
  64. package/lib/model/RoleModel.js.map +1 -0
  65. package/lib/model/RoleResourceActionModel.d.ts +12 -0
  66. package/lib/model/RoleResourceActionModel.js +69 -0
  67. package/lib/model/RoleResourceActionModel.js.map +1 -0
  68. package/lib/model/RoleResourceModel.d.ts +16 -0
  69. package/lib/model/RoleResourceModel.js +59 -0
  70. package/lib/model/RoleResourceModel.js.map +1 -0
  71. package/lib/server.d.ts +33 -0
  72. package/lib/server.js +371 -0
  73. package/lib/server.js.map +1 -0
  74. package/package.json +30 -0
  75. package/src/__tests__/acl.test.ts +533 -0
  76. package/src/__tests__/association-field.test.ts +297 -0
  77. package/src/__tests__/configuration.test.ts +45 -0
  78. package/src/__tests__/middleware.test.ts +233 -0
  79. package/src/__tests__/own.test.ts +140 -0
  80. package/src/__tests__/prepare.ts +39 -0
  81. package/src/__tests__/role-check.test.ts +35 -0
  82. package/src/__tests__/role-resource.test.ts +187 -0
  83. package/src/__tests__/role.test.ts +92 -0
  84. package/src/__tests__/scope.test.ts +51 -0
  85. package/src/actions/available-actions.ts +18 -0
  86. package/src/actions/role-check.ts +39 -0
  87. package/src/actions/role-collections.ts +55 -0
  88. package/src/collections/roles.ts +79 -0
  89. package/src/collections/rolesResources.ts +31 -0
  90. package/src/collections/rolesResourcesActions.ts +28 -0
  91. package/src/collections/rolesResourcesScopes.ts +23 -0
  92. package/src/index.ts +2 -0
  93. package/src/model/RoleModel.ts +21 -0
  94. package/src/model/RoleResourceActionModel.ts +80 -0
  95. package/src/model/RoleResourceModel.ts +61 -0
  96. package/src/server.ts +398 -0
  97. package/tsconfig.build.json +9 -0
  98. package/tsconfig.json +5 -0
@@ -0,0 +1,297 @@
1
+ import { ACL } from '@nocobase/acl';
2
+ import { Database, HasManyRepository, Model } from '@nocobase/database';
3
+ import { MockServer } from '@nocobase/test';
4
+ import { prepareApp } from './prepare';
5
+
6
+ describe('association field acl', () => {
7
+ let app: MockServer;
8
+ let db: Database;
9
+ let acl: ACL;
10
+
11
+ let role: Model;
12
+
13
+ afterEach(async () => {
14
+ await app.destroy();
15
+ });
16
+
17
+ beforeEach(async () => {
18
+ app = await prepareApp();
19
+ db = app.db;
20
+ acl = app.acl;
21
+
22
+ role = await db.getRepository('roles').create({
23
+ values: {
24
+ name: 'admin',
25
+ title: 'Admin User',
26
+ allowConfigure: true,
27
+ },
28
+ });
29
+
30
+ await db.getRepository('collections').create({
31
+ values: {
32
+ name: 'users',
33
+ },
34
+ context: {},
35
+ });
36
+
37
+ await db.getRepository('collections').create({
38
+ values: {
39
+ name: 'orders',
40
+ },
41
+ context: {},
42
+ });
43
+
44
+ await db.getRepository('collections.fields', 'users').create({
45
+ values: {
46
+ name: 'name',
47
+ type: 'string',
48
+ },
49
+ context: {},
50
+ });
51
+
52
+ await db.getRepository('collections.fields', 'users').create({
53
+ values: {
54
+ name: 'age',
55
+ type: 'integer',
56
+ },
57
+ context: {},
58
+ });
59
+
60
+ await db.getRepository('collections.fields', 'users').create({
61
+ values: {
62
+ interface: 'linkTo',
63
+ name: 'orders',
64
+ type: 'hasMany',
65
+ target: 'orders',
66
+ },
67
+ context: {},
68
+ });
69
+
70
+ await db.getRepository('collections.fields', 'orders').create({
71
+ values: {
72
+ name: 'content',
73
+ type: 'string',
74
+ },
75
+ context: {},
76
+ });
77
+
78
+ await app
79
+ .agent()
80
+ .resource('roles.resources')
81
+ .create({
82
+ associatedIndex: 'admin',
83
+ values: {
84
+ name: 'users',
85
+ usingActionsConfig: true,
86
+ actions: [
87
+ {
88
+ name: 'create',
89
+ fields: ['orders'],
90
+ },
91
+ {
92
+ name: 'view',
93
+ fields: ['orders'],
94
+ },
95
+ ],
96
+ },
97
+ });
98
+ });
99
+
100
+ it('should revoke target action on association action revoke', async () => {
101
+ expect(
102
+ acl.can({
103
+ role: 'admin',
104
+ resource: 'orders',
105
+ action: 'list',
106
+ }),
107
+ ).toMatchObject({
108
+ role: 'admin',
109
+ resource: 'orders',
110
+ action: 'list',
111
+ });
112
+
113
+ await app
114
+ .agent()
115
+ .resource('roles.resources')
116
+ .update({
117
+ associatedIndex: 'admin',
118
+ values: {
119
+ name: 'users',
120
+ usingActionsConfig: true,
121
+ actions: [],
122
+ },
123
+ });
124
+
125
+ expect(
126
+ acl.can({
127
+ role: 'admin',
128
+ resource: 'orders',
129
+ action: 'list',
130
+ }),
131
+ ).toBeNull();
132
+ });
133
+
134
+ it('should revoke association action on action revoke', async () => {
135
+ expect(
136
+ acl.can({
137
+ role: 'admin',
138
+ resource: 'users.orders',
139
+ action: 'add',
140
+ }),
141
+ ).toMatchObject({
142
+ role: 'admin',
143
+ resource: 'users.orders',
144
+ action: 'add',
145
+ });
146
+
147
+ const viewAction = await db.getRepository('rolesResourcesActions').findOne({
148
+ filter: {
149
+ name: 'view',
150
+ },
151
+ });
152
+
153
+ const actionId = viewAction.get('id') as number;
154
+
155
+ const response = await app
156
+ .agent()
157
+ .resource('roles.resources')
158
+ .update({
159
+ associatedIndex: 'admin',
160
+ values: {
161
+ name: 'users',
162
+ usingActionsConfig: true,
163
+ actions: [
164
+ {
165
+ id: actionId,
166
+ },
167
+ ],
168
+ },
169
+ });
170
+
171
+ expect(response.statusCode).toEqual(200);
172
+
173
+ expect(
174
+ acl.can({
175
+ role: 'admin',
176
+ resource: 'users.orders',
177
+ action: 'add',
178
+ }),
179
+ ).toBeNull();
180
+ });
181
+
182
+ it('should revoke association action on field deleted', async () => {
183
+ await app
184
+ .agent()
185
+ .resource('roles.resources')
186
+ .update({
187
+ associatedIndex: 'admin',
188
+ values: {
189
+ name: 'users',
190
+ usingActionsConfig: true,
191
+ actions: [
192
+ {
193
+ name: 'create',
194
+ fields: ['name', 'age'],
195
+ },
196
+ ],
197
+ },
198
+ });
199
+ expect(
200
+ acl.can({
201
+ role: 'admin',
202
+ resource: 'users',
203
+ action: 'create',
204
+ }),
205
+ ).toMatchObject({
206
+ role: 'admin',
207
+ resource: 'users',
208
+ action: 'create',
209
+ params: {
210
+ whitelist: ['age', 'name'],
211
+ },
212
+ });
213
+ const roleResource = await db.getRepository('rolesResources').findOne({
214
+ filter: {
215
+ name: 'users',
216
+ },
217
+ });
218
+
219
+ const action = await db
220
+ .getRepository<HasManyRepository>('rolesResources.actions', roleResource.get('id') as string)
221
+ .findOne({
222
+ filter: {
223
+ name: 'create',
224
+ },
225
+ });
226
+
227
+ expect(action.get('fields').includes('name')).toBeTruthy();
228
+
229
+ // remove field
230
+ await db.getRepository<HasManyRepository>('collections.fields', 'users').destroy({
231
+ filter: {
232
+ name: 'name',
233
+ },
234
+ context: {},
235
+ });
236
+
237
+ expect(
238
+ acl.can({
239
+ role: 'admin',
240
+ resource: 'users',
241
+ action: 'create',
242
+ }),
243
+ ).toMatchObject({
244
+ role: 'admin',
245
+ resource: 'users',
246
+ action: 'create',
247
+ params: {
248
+ whitelist: ['age'],
249
+ },
250
+ });
251
+ });
252
+
253
+ it('should allow association fields access', async () => {
254
+ const createResponse = await app
255
+ .agent()
256
+ .resource('users')
257
+ .create({
258
+ values: {
259
+ orders: [
260
+ {
261
+ content: 'apple',
262
+ },
263
+ ],
264
+ },
265
+ });
266
+
267
+ expect(createResponse.statusCode).toEqual(200);
268
+
269
+ const user = await db.getRepository('users').findOne();
270
+ // @ts-ignore
271
+ expect(await user.countOrders()).toEqual(1);
272
+
273
+ expect(
274
+ acl.can({
275
+ role: 'admin',
276
+ resource: 'users.orders',
277
+ action: 'list',
278
+ }),
279
+ ).toMatchObject({
280
+ role: 'admin',
281
+ resource: 'users.orders',
282
+ action: 'list',
283
+ });
284
+
285
+ expect(
286
+ acl.can({
287
+ role: 'admin',
288
+ resource: 'orders',
289
+ action: 'list',
290
+ }),
291
+ ).toMatchObject({
292
+ role: 'admin',
293
+ resource: 'orders',
294
+ action: 'list',
295
+ });
296
+ });
297
+ });
@@ -0,0 +1,45 @@
1
+ import { MockServer } from '@nocobase/test';
2
+ import { Database } from '@nocobase/database';
3
+ import { ACL } from '@nocobase/acl';
4
+ import { UiSchemaRepository } from '@nocobase/plugin-ui-schema-storage';
5
+ import { changeMockRole, prepareApp } from './prepare';
6
+
7
+ describe('configuration', () => {
8
+ let app: MockServer;
9
+ let db: Database;
10
+ let acl: ACL;
11
+
12
+ let uiSchemaRepository: UiSchemaRepository;
13
+
14
+ afterEach(async () => {
15
+ await app.destroy();
16
+ });
17
+
18
+ beforeEach(async () => {
19
+ app = await prepareApp();
20
+ db = app.db;
21
+ acl = app.acl;
22
+
23
+ uiSchemaRepository = db.getRepository('uiSchemas');
24
+ });
25
+
26
+ it('should list collections', async () => {
27
+ expect((await app.agent().resource('collections').create()).statusCode).toEqual(403);
28
+ expect((await app.agent().resource('collections').list()).statusCode).toEqual(200);
29
+ });
30
+
31
+ it('should allow when role has allowConfigure with true value', async () => {
32
+ await db.getRepository('roles').create({
33
+ values: {
34
+ name: 'admin1',
35
+ title: 'admin allowConfigure',
36
+ allowConfigure: true,
37
+ },
38
+ });
39
+
40
+ changeMockRole('admin1');
41
+
42
+ expect((await app.agent().resource('collections').create()).statusCode).toEqual(200);
43
+ expect((await app.agent().resource('collections').list()).statusCode).toEqual(200);
44
+ });
45
+ });
@@ -0,0 +1,233 @@
1
+ import { ACL } from '@nocobase/acl';
2
+ import { Database, Model } from '@nocobase/database';
3
+ import { MockServer } from '@nocobase/test';
4
+ import { changeMockUser, prepareApp } from './prepare';
5
+
6
+ describe('middleware', () => {
7
+ let app: MockServer;
8
+ let role: Model;
9
+ let db: Database;
10
+ let acl: ACL;
11
+
12
+ beforeEach(async () => {
13
+ app = await prepareApp();
14
+ db = app.db;
15
+ acl = app.acl;
16
+
17
+ await db.getRepository('roles').create({
18
+ values: {
19
+ name: 'admin',
20
+ title: 'Admin User',
21
+ allowConfigure: true,
22
+ },
23
+ });
24
+
25
+ role = await db.getRepository('roles').findOne({
26
+ filter: {
27
+ name: 'admin',
28
+ },
29
+ });
30
+
31
+ await db.getRepository('collections').create({
32
+ values: {
33
+ name: 'posts',
34
+ },
35
+ context: {},
36
+ });
37
+
38
+ await db.getRepository('collections.fields', 'posts').create({
39
+ values: {
40
+ name: 'title',
41
+ type: 'string',
42
+ },
43
+ context: {},
44
+ });
45
+
46
+ await db.getRepository('collections.fields', 'posts').create({
47
+ values: {
48
+ name: 'description',
49
+ type: 'string',
50
+ },
51
+ context: {},
52
+ });
53
+
54
+ await db.getRepository('collections.fields', 'posts').create({
55
+ values: {
56
+ name: 'createdById',
57
+ type: 'integer',
58
+ },
59
+ context: {},
60
+ });
61
+ });
62
+
63
+ afterEach(async () => {
64
+ await app.destroy();
65
+ });
66
+
67
+ it('should throw 403 when no permission', async () => {
68
+ const response = await app.agent().resource('posts').create({
69
+ values: {},
70
+ });
71
+
72
+ expect(response.statusCode).toEqual(403);
73
+ });
74
+
75
+ it('should return 200 when role has permission', async () => {
76
+ await db.getRepository('roles').update({
77
+ filterByTk: 'admin',
78
+ values: {
79
+ strategy: {
80
+ actions: ['create:all'],
81
+ },
82
+ },
83
+ });
84
+
85
+ const response = await app.agent().resource('posts').create({
86
+ values: {},
87
+ });
88
+
89
+ expect(response.statusCode).toEqual(200);
90
+ });
91
+
92
+ it('should limit fields on view actions', async () => {
93
+ await app
94
+ .agent()
95
+ .resource('roles.resources', role.get('name'))
96
+ .create({
97
+ values: {
98
+ name: 'posts',
99
+ usingActionsConfig: true,
100
+ actions: [
101
+ {
102
+ name: 'create',
103
+ fields: ['title', 'description'],
104
+ },
105
+ {
106
+ name: 'view',
107
+ fields: ['title'],
108
+ },
109
+ ],
110
+ },
111
+ });
112
+
113
+ await app
114
+ .agent()
115
+ .resource('posts')
116
+ .create({
117
+ values: {
118
+ title: 'post-title',
119
+ description: 'post-description',
120
+ },
121
+ });
122
+
123
+ const post = await db.getRepository('posts').findOne();
124
+ expect(post.get('title')).toEqual('post-title');
125
+ expect(post.get('description')).toEqual('post-description');
126
+
127
+ const response = await app.agent().resource('posts').list({});
128
+ expect(response.statusCode).toEqual(200);
129
+
130
+ const data = response.body.data[0];
131
+
132
+ expect(data['id']).not.toBeUndefined();
133
+ expect(data['title']).toEqual('post-title');
134
+ expect(data['description']).toBeUndefined();
135
+ });
136
+
137
+ it('should parse template value on action params', async () => {
138
+ changeMockUser({
139
+ id: 2,
140
+ });
141
+
142
+ const res = await app
143
+ .agent()
144
+ .resource('rolesResourcesScopes')
145
+ .create({
146
+ values: {
147
+ name: 'own',
148
+ scope: {
149
+ createdById: '{{ ctx.state.currentUser.id }}',
150
+ },
151
+ },
152
+ });
153
+
154
+ await app
155
+ .agent()
156
+ .resource('roles.resources', role.get('name'))
157
+ .create({
158
+ values: {
159
+ name: 'posts',
160
+ usingActionsConfig: true,
161
+ actions: [
162
+ {
163
+ name: 'create',
164
+ fields: ['title', 'description', 'createdById'],
165
+ },
166
+ {
167
+ name: 'view',
168
+ fields: ['title'],
169
+ scope: res.body.data.id,
170
+ },
171
+ ],
172
+ },
173
+ });
174
+
175
+ await app
176
+ .agent()
177
+ .resource('posts')
178
+ .create({
179
+ values: {
180
+ title: 't1',
181
+ description: 'd1',
182
+ createdById: 1,
183
+ },
184
+ });
185
+
186
+ await app
187
+ .agent()
188
+ .resource('posts')
189
+ .create({
190
+ values: {
191
+ title: 't2',
192
+ description: 'p2',
193
+ createdById: 2,
194
+ },
195
+ });
196
+
197
+ const response = await app.agent().resource('posts').list();
198
+ const data = response.body.data;
199
+ expect(data.length).toEqual(1);
200
+ });
201
+
202
+ it('should change fields params to whitelist in create action', async () => {
203
+ await app
204
+ .agent()
205
+ .resource('roles.resources', role.get('name'))
206
+ .create({
207
+ values: {
208
+ name: 'posts',
209
+ usingActionsConfig: true,
210
+ actions: [
211
+ {
212
+ name: 'create',
213
+ fields: ['title'],
214
+ },
215
+ ],
216
+ },
217
+ });
218
+
219
+ await app
220
+ .agent()
221
+ .resource('posts')
222
+ .create({
223
+ values: {
224
+ title: 'post-title',
225
+ description: 'post-description',
226
+ },
227
+ });
228
+
229
+ const post = await db.getRepository('posts').findOne();
230
+ expect(post.get('title')).toEqual('post-title');
231
+ expect(post.get('description')).toBeNull();
232
+ });
233
+ });
@@ -0,0 +1,140 @@
1
+ import { mockServer, MockServer } from '@nocobase/test';
2
+ import { Database } from '@nocobase/database';
3
+ import { ACL } from '@nocobase/acl';
4
+ import { UiSchemaRepository } from '@nocobase/plugin-ui-schema-storage';
5
+ import PluginUiSchema from '@nocobase/plugin-ui-schema-storage';
6
+ import PluginCollectionManager from '@nocobase/plugin-collection-manager';
7
+ import PluginACL from '@nocobase/plugin-acl';
8
+ import PluginUser from '@nocobase/plugin-users';
9
+ import supertest from 'supertest';
10
+
11
+ describe('own test', () => {
12
+ let app: MockServer;
13
+ let db: Database;
14
+ let acl: ACL;
15
+
16
+ let pluginUser: PluginUser;
17
+ let adminToken: string;
18
+ let userToken: string;
19
+
20
+ let admin;
21
+ let user;
22
+
23
+ let role;
24
+ let agent;
25
+
26
+ afterEach(async () => {
27
+ await app.destroy();
28
+ });
29
+
30
+ beforeEach(async () => {
31
+ app = mockServer({
32
+ registerActions: true,
33
+ });
34
+
35
+ await app.cleanDb();
36
+
37
+ app.plugin(PluginUiSchema);
38
+ app.plugin(PluginCollectionManager);
39
+ app.plugin(PluginUser, {
40
+ jwt: {
41
+ secret: process.env.JWT_SECRET || '09f26e402586e2faa8da4c98a35f1b20d6b033c60',
42
+ },
43
+ });
44
+
45
+ app.plugin(PluginACL);
46
+ await app.loadAndInstall();
47
+ db = app.db;
48
+
49
+ const PostCollection = db.collection({
50
+ name: 'posts',
51
+ fields: [
52
+ { type: 'string', name: 'title' },
53
+ { type: 'belongsToMany', name: 'tags' },
54
+ ],
55
+ createdBy: true,
56
+ });
57
+
58
+ const TagCollection = db.collection({
59
+ name: 'tags',
60
+ fields: [
61
+ { type: 'string', name: 'name' },
62
+ { type: 'belongsToMany', name: 'posts' },
63
+ ],
64
+ createdBy: true,
65
+ });
66
+
67
+ const TestCollection = db.collection({
68
+ name: 'tests',
69
+ fields: [{ type: 'string', name: 'name' }],
70
+ });
71
+
72
+ await app.db.sync();
73
+
74
+ agent = supertest.agent(app.callback());
75
+
76
+ acl = app.acl;
77
+
78
+ role = await db.getRepository('roles').findOne({
79
+ filter: {
80
+ name: 'admin',
81
+ },
82
+ });
83
+
84
+ admin = await db.getRepository('users').findOne();
85
+
86
+ pluginUser = app.getPlugin('@nocobase/plugin-users');
87
+
88
+ adminToken = pluginUser.jwtService.sign({ userId: admin.get('id') });
89
+
90
+ user = await db.getRepository('users').create({
91
+ values: {
92
+ nickname: 'test',
93
+ roles: ['admin'],
94
+ },
95
+ });
96
+
97
+ userToken = pluginUser.jwtService.sign({ userId: user.get('id') });
98
+ });
99
+
100
+ it('should list without createBy', async () => {
101
+ let response = await agent
102
+ .patch('/roles/admin')
103
+ .send({
104
+ strategy: {
105
+ actions: ['view:own'],
106
+ },
107
+ })
108
+ .set({ Authorization: 'Bearer ' + adminToken });
109
+
110
+ response = await agent.get('/tests:list').set({ Authorization: 'Bearer ' + userToken });
111
+ expect(response.statusCode).toEqual(200);
112
+ });
113
+
114
+ it('should delete with createdBy', async () => {
115
+ let response = await agent
116
+ .patch('/roles/admin')
117
+ .send({
118
+ strategy: {
119
+ actions: ['view:own', 'create', 'destroy:own'],
120
+ },
121
+ })
122
+ .set({ Authorization: 'Bearer ' + adminToken });
123
+
124
+ response = await agent
125
+ .get('/posts:create')
126
+ .send({
127
+ title: 't1',
128
+ })
129
+ .set({ Authorization: 'Bearer ' + userToken });
130
+
131
+ expect(response.statusCode).toEqual(200);
132
+
133
+ const data = response.body;
134
+ const id = data.data['id'];
135
+
136
+ response = await agent.delete(`/posts/${id}`).set({ Authorization: 'Bearer ' + userToken });
137
+ expect(response.statusCode).toEqual(200);
138
+ expect(await db.getRepository('posts').count()).toEqual(0);
139
+ });
140
+ });