tachybase_todo/packages/plugins/acl/src/__tests__/association-field.test.ts
chenos 249dff16d3
refactor: plugin manager (#965)
* feat: improve code

* chore: update version

* feat: api service

* fix: api services

* feat: improve code

* feat: improve code

* feat: improve code

* feat: pm socket

* fix: test errors

* feat: add built-in plugins before upgrade

* feat: update docs

* feat: improve code

* fix: after load
2022-10-27 13:00:16 +08:00

309 lines
6.4 KiB
TypeScript

import { ACL } from '@nocobase/acl';
import { Database, HasManyRepository } from '@nocobase/database';
import UsersPlugin from '@nocobase/plugin-users';
import { MockServer } from '@nocobase/test';
import { prepareApp } from './prepare';
describe('association field acl', () => {
let app: MockServer;
let db: Database;
let acl: ACL;
let user;
let userAgent;
let admin;
let adminAgent;
afterEach(async () => {
await app.destroy();
});
beforeEach(async () => {
app = await prepareApp();
db = app.db;
acl = app.acl;
await db.getRepository('roles').create({
values: {
name: 'new',
allowConfigure: true,
},
});
await db.getRepository('roles').create({
values: {
name: 'testAdmin',
allowConfigure: true,
},
});
const UserRepo = db.getCollection('users').repository;
user = await UserRepo.create({
values: {
roles: ['new'],
},
});
admin = await UserRepo.create({
values: {
roles: ['testAdmin'],
},
});
const userPlugin = app.getPlugin('users') as UsersPlugin;
userAgent = app.agent().auth(
userPlugin.jwtService.sign({
userId: user.get('id'),
}),
{ type: 'bearer' },
);
adminAgent = app.agent().auth(
userPlugin.jwtService.sign({
userId: admin.get('id'),
}),
{ type: 'bearer' },
);
await db.getRepository('collections').create({
values: {
name: 'orders',
},
context: {},
});
await db.getRepository('collections.fields', 'users').create({
values: {
name: 'name',
type: 'string',
},
context: {},
});
await db.getRepository('collections.fields', 'users').create({
values: {
name: 'age',
type: 'integer',
},
context: {},
});
await db.getRepository('collections.fields', 'users').create({
values: {
interface: 'linkTo',
name: 'orders',
type: 'hasMany',
target: 'orders',
},
context: {},
});
await db.getRepository('collections.fields', 'orders').create({
values: {
name: 'content',
type: 'string',
},
context: {},
});
await adminAgent.resource('roles.resources', 'new').create({
values: {
name: 'users',
usingActionsConfig: true,
actions: [
{
name: 'create',
fields: ['orders'],
},
{
name: 'view',
fields: ['orders'],
},
],
},
});
});
it('should revoke target action on association action revoke', async () => {
expect(
acl.can({
role: 'new',
resource: 'orders',
action: 'list',
}),
).toMatchObject({
role: 'new',
resource: 'orders',
action: 'list',
});
await adminAgent.resource('roles.resources', 'new').update({
values: {
name: 'users',
usingActionsConfig: true,
actions: [],
},
});
expect(
acl.can({
role: 'new',
resource: 'orders',
action: 'list',
}),
).toBeNull();
});
it('should revoke association action on action revoke', async () => {
expect(
acl.can({
role: 'new',
resource: 'users.orders',
action: 'add',
}),
).toMatchObject({
role: 'new',
resource: 'users.orders',
action: 'add',
});
const viewAction = await db.getRepository('rolesResourcesActions').findOne({
filter: {
name: 'view',
},
});
const actionId = viewAction.get('id') as number;
const response = await adminAgent.resource('roles.resources', 'new').update({
values: {
name: 'users',
usingActionsConfig: true,
actions: [
{
id: actionId,
},
],
},
});
expect(response.statusCode).toEqual(200);
expect(
acl.can({
role: 'new',
resource: 'users.orders',
action: 'add',
}),
).toBeNull();
});
it('should revoke association action on field deleted', async () => {
await adminAgent.resource('roles.resources', 'new').update({
values: {
name: 'users',
usingActionsConfig: true,
actions: [
{
name: 'create',
fields: ['name', 'age'],
},
],
},
});
expect(
acl.can({
role: 'new',
resource: 'users',
action: 'create',
}),
).toMatchObject({
role: 'new',
resource: 'users',
action: 'create',
params: {
whitelist: ['age', 'name'],
},
});
const roleResource = await db.getRepository('rolesResources').findOne({
filter: {
name: 'users',
},
});
const action = await db
.getRepository<HasManyRepository>('rolesResources.actions', roleResource.get('id') as string)
.findOne({
filter: {
name: 'create',
},
});
expect(action.get('fields').includes('name')).toBeTruthy();
// remove field
await db.getRepository<HasManyRepository>('collections.fields', 'users').destroy({
filter: {
name: 'name',
},
context: {},
});
expect(
acl.can({
role: 'new',
resource: 'users',
action: 'create',
}),
).toMatchObject({
role: 'new',
resource: 'users',
action: 'create',
params: {
whitelist: ['age'],
},
});
});
it('should allow association fields access', async () => {
const createResponse = await userAgent.resource('users').create({
values: {
orders: [
{
content: 'apple',
},
],
},
});
expect(createResponse.statusCode).toEqual(200);
const user = await db.getRepository('users').findOne({
filterByTk: createResponse.body.data.id,
});
// @ts-ignore
expect(await user.countOrders()).toEqual(1);
expect(
acl.can({
role: 'new',
resource: 'users.orders',
action: 'list',
}),
).toMatchObject({
role: 'new',
resource: 'users.orders',
action: 'list',
});
expect(
acl.can({
role: 'new',
resource: 'orders',
action: 'list',
}),
).toMatchObject({
role: 'new',
resource: 'orders',
action: 'list',
});
});
});