UNPKG

@xrengine/server-core

Version:

Shared components for XREngine server

487 lines (446 loc) 15.1 kB
import { Paginated } from '@feathersjs/feathers' import appRootPath from 'app-root-path' import assert from 'assert' import path from 'path' import { ProjectPermissionInterface } from '@xrengine/common/src/interfaces/ProjectPermissionInterface' import { UserInterface } from '@xrengine/common/src/interfaces/User' import { Application } from '../../../declarations' import { createFeathersExpressApp } from '../../createApp' import { deleteFolderRecursive } from '../../util/fsHelperFunctions' const newProjectName1 = 'ProjectTest_test_project_name_1' const cleanup = async (app: Application) => { const project1Dir = path.resolve(appRootPath.path, `packages/projects/projects/${newProjectName1}/`) deleteFolderRecursive(project1Dir) try { await app.service('project').Model.destroy({ where: { name: newProjectName1 } }) } catch (e) {} } /** * @todo * - refactor storage provider to be create as part of createFeathersExpressApp() to eliminate global scope * - use this to force a local storage provider and test specific files in the upload folder * - add tests for all combinations of state for projects * * - figure out how to mock git clone functionality (maybe override the function?) */ describe('project-permission.test', () => { let app: Application let user1: UserInterface let user2: UserInterface let user3: UserInterface let user4: UserInterface let project1, project1Permission1, project1Permission2, project1Permission4 before(async () => { app = createFeathersExpressApp() await app.setup() await cleanup(app) const avatarName = 'CyberbotGreen' const avatar = await app.service('avatar').create({ name: avatarName }) user1 = (await app.service('user').create({ name: `Test #${Math.random()}`, avatarId: avatar.id, isGuest: false })) as UserInterface user2 = (await app.service('user').create({ name: `Test #${Math.random()}`, avatarId: avatar.id, isGuest: false })) as UserInterface user3 = (await app.service('user').create({ name: `Test #${Math.random()}`, avatarId: avatar.id, isGuest: false })) as UserInterface user4 = (await app.service('user').create({ name: `Test #${Math.random()}`, avatarId: avatar.id, isGuest: false })) as UserInterface user1.apiKey = await app.service('user-api-key').Model.findOne({ where: { userId: user1.id } }) user2.apiKey = await app.service('user-api-key').Model.findOne({ where: { userId: user2.id } }) user3.apiKey = await app.service('user-api-key').Model.findOne({ where: { userId: user3.id } }) user4.apiKey = await app.service('user-api-key').Model.findOne({ where: { userId: user4.id } }) await app.service('scope').create({ type: 'editor:write', userId: user1.id }) await app.service('scope').create({ type: 'editor:write', userId: user2.id }) await app.service('scope').create({ type: 'editor:write', userId: user3.id }) await app.service('scope').create({ type: 'editor:write', userId: user4.id }) await app.service('scope').create({ type: 'admin:admin', userId: user4.id }) }) describe("'project-permission' service'", () => { describe('create', () => { it('should add a new project owned by creating user', async function () { const params = { headers: { authorization: `Bearer ${user1.apiKey.token}` }, provider: 'rest' } project1 = await app.service('project').create( { name: newProjectName1 }, params ) const projectPermission = (await app.service('project-permission').find({ query: { projectId: project1.id, userId: user1.id }, ...params })) as Paginated<ProjectPermissionInterface> project1Permission1 = projectPermission.data[0] assert.strictEqual(projectPermission.total, 1) assert.strictEqual(project1Permission1.userId, user1.id) assert.strictEqual(project1Permission1.projectId, project1.id) assert.strictEqual(project1Permission1.type, 'owner') }) it('should create a new project-permission if requested by the owner', async function () { const params = { headers: { authorization: `Bearer ${user1.apiKey.token}` }, provider: 'rest' } project1Permission2 = (await app.service('project-permission').create( { projectId: project1.id, userId: user2.id }, params )) as ProjectPermissionInterface assert.ok(project1Permission2) assert.strictEqual(project1Permission2.userId, user2.id) assert.strictEqual(project1Permission2.projectId, project1.id) assert.strictEqual(project1Permission2.type, 'user') }) it('should return the same project-permission if another create request for a project/user combination is made', async function () { const params = { headers: { authorization: `Bearer ${user1.apiKey.token}` }, provider: 'rest' } const duplicate = (await app.service('project-permission').create( { projectId: project1.id, userId: user2.id }, params )) as ProjectPermissionInterface assert.ok(duplicate) assert.strictEqual(project1Permission2.id, duplicate.id) }) it('should throw an error if the projectId is invalid', async function () { const params = { headers: { authorization: `Bearer ${user1.apiKey.token}` }, provider: 'rest' } assert.rejects( async () => { await app.service('project-permission').create( { projectId: 'abcdefg', userId: user2.id }, params ) }, { message: 'Invalid project ID' } ) }) it('should throw an error if the userId is invalid', async function () { const params = { headers: { authorization: `Bearer ${user1.apiKey.token}` }, provider: 'rest' } assert.rejects( async () => { await app.service('project-permission').create( { projectId: project1.id, userId: 'abcdefg' }, params ) }, { message: 'Invalid user ID and/or user invite code' } ) }) it('should not allow a user who does not have owner permission on a project to create new permissions for that project', async function () { const params = { headers: { authorization: `Bearer ${user2.apiKey.token}` }, provider: 'rest' } assert.rejects( async () => { try { const res = await app.service('project-permission').create( { projectId: project1.id, userId: user3.id }, params ) } catch (err) { throw err } }, { message: 'You are not an owner of this project' } ) }) it('should not allow a user with no permission on a project to create new permissions for that project', async function () { const params = { headers: { authorization: `Bearer ${user3.apiKey.token}` }, provider: 'rest' } assert.rejects( async () => { await app.service('project-permission').create( { projectId: project1.id, userId: user3.id }, params ) }, { message: 'You are not an owner of this project' } ) }) it('should allow an admin user to create new permissions for a project', async function () { const params = { headers: { authorization: `Bearer ${user4.apiKey.token}` }, provider: 'rest' } project1Permission4 = (await app.service('project-permission').create( { projectId: project1.id, userId: user4.id, type: 'owner' }, params )) as ProjectPermissionInterface const permissions = await app.service('project-permission').Model.findAll({ where: { projectId: project1.id } }) assert.ok(project1Permission4) assert.strictEqual(project1Permission4.userId, user4.id) assert.strictEqual(project1Permission4.projectId, project1.id) assert.strictEqual(project1Permission4.type, 'owner') }) }) describe('patch', () => { it('should only update the type when patching a project-permission', async function () { const params = { headers: { authorization: `Bearer ${user1.apiKey.token}` }, provider: 'rest' } const update = await app.service('project-permission').patch( project1Permission2.id, { projectId: project1.id, userId: 'abcdefg', type: 'owner' }, params ) assert.strictEqual(update.type, 'owner') assert.strictEqual(update.userId, user2.id) }) it('should allow an admin user to patch permissions for that project', async function () { const params = { headers: { authorization: `Bearer ${user4.apiKey.token}` }, provider: 'rest' } const update = await app.service('project-permission').patch( project1Permission2.id, { projectId: project1.id, userId: user2.id, type: 'user' }, params ) assert.strictEqual(update.type, 'user') assert.strictEqual(update.userId, user2.id) }) it('should not allow a user who does not have owner permission on a project to patch permissions for that project', async function () { const params = { headers: { authorization: `Bearer ${user2.apiKey.token}` }, provider: 'rest' } assert.rejects( async () => { await app.service('project-permission').patch( project1Permission2.id, { projectId: project1.id, userId: user3.id }, params ) }, { message: 'You are not an owner of this project' } ) }) it('should not allow a user with no permission on a project to patch permissions for that project', async function () { const params = { headers: { authorization: `Bearer ${user3.apiKey.token}` }, provider: 'rest' } const permissions = await app.service('project-permission').Model.findAll({ where: { projectId: project1.id } }) assert.rejects( async () => { await app.service('project-permission').patch( project1Permission2.id, { projectId: project1.id, userId: user3.id }, params ) }, { message: 'You are not an owner of this project' } ) }) }) describe('remove', () => { it('should not allow a user who does not have owner permission on a project to remove permissions for that project', async function () { const params = { headers: { authorization: `Bearer ${user2.apiKey.token}` }, provider: 'rest' } assert.rejects( async () => { await app.service('project-permission').remove(project1Permission2.id, params) }, { message: 'You are not an owner of this project' } ) }) it('should not allow a user with no permission on a project to remove permissions for that project', async function () { const params = { headers: { authorization: `Bearer ${user3.apiKey.token}` }, provider: 'rest' } assert.rejects( async () => { await app.service('project-permission').remove(project1Permission2.id, params) }, { message: 'You are not an owner of this project' } ) }) it('should allow an owner to remove permissions for that project, and if the last owner permission is removed, a user permission should be made the owner', async function () { const params = { headers: { authorization: `Bearer ${user1.apiKey.token}` }, provider: 'rest' } await app.service('project-permission').remove(project1Permission4.id, params) const permissions = (await app.service('project-permission').find({ query: { projectId: project1.id }, ...params })) as Paginated<ProjectPermissionInterface> assert.strictEqual(permissions.total, 2) }) it('should upgrade a user permission to owner if the last owner permission is deleted', async function () { const params = { headers: { authorization: `Bearer ${user1.apiKey.token}` }, provider: 'rest' } await app.service('project-permission').remove(project1Permission1.id, params) const permissions = await app.service('project-permission').Model.findAll({ where: { projectId: project1.id } }) assert.strictEqual(permissions.length, 1) assert.strictEqual(permissions[0].id, project1Permission2.id) assert.strictEqual(permissions[0].type, 'owner') }) it('should allow an admin user to remove permissions for that project', async function () { const params = { headers: { authorization: `Bearer ${user4.apiKey.token}` }, provider: 'rest' } await app.service('project-permission').remove(project1Permission2.id, params) const permissions = (await app.service('project-permission').find({ query: { projectId: project1.id }, ...params })) as Paginated<ProjectPermissionInterface> assert.strictEqual(permissions.total, 0) }) }) after(async () => { await cleanup(app) }) }) })