Files
speckle-server/packages/server/modules/workspaces/tests/integration/repositories.spec.ts
T
Chuck Driesler e703bb7415 WEB-1140 manage user workspace membership services (#2460)
* feat(workspaces): drop createdByUserId from the dataschema

* feat(workspaces): repositories WIP

* merge

* protect against removing last admin in workspace

* quick impl and stub tests

* add tests

* services

* unit tests for role services

* fix(workspaces): maybe tests work like this

* fix(workspaces): dry

* fix(workspaces): initialize tests better

* fix(workspaces): so true

* fix(workspaces): right

* fix(workspaces): self nit

* fix(workspaces): better repository structure

* fix(workspaces): repair tests, use `example.org`

* fix(workspaces): add tests for new repo functions, repair other tests

* fix(workspaces): better distinction between service-level guarantees and repo-level guarantees

* fix(workspaces): review comments and stencil tests

* fix(workspaces): add tests

* fix(workspaces): tests work

---------

Co-authored-by: Gergő Jedlicska <gergo@jedlicska.com>
2024-07-09 18:26:59 +02:00

254 lines
8.4 KiB
TypeScript

import {
deleteWorkspaceRoleFactory,
getWorkspaceRoleForUserFactory,
getWorkspaceFactory,
upsertWorkspaceFactory,
upsertWorkspaceRoleFactory,
getWorkspaceRolesFactory,
getWorkspaceRolesForUserFactory
} from '@/modules/workspaces/repositories/workspaces'
import db from '@/db/knex'
import cryptoRandomString from 'crypto-random-string'
import { expect } from 'chai'
import { Workspace, WorkspaceAcl } from '@/modules/workspaces/domain/types'
import { expectToThrow } from '@/test/assertionHelper'
import { BasicTestUser, createTestUser } from '@/test/authHelper'
const getWorkspace = getWorkspaceFactory({ db })
const upsertWorkspace = upsertWorkspaceFactory({ db })
const deleteWorkspaceRole = deleteWorkspaceRoleFactory({ db })
const getWorkspaceRoles = getWorkspaceRolesFactory({ db })
const getWorkspaceRoleForUser = getWorkspaceRoleForUserFactory({ db })
const getWorkspaceRolesForUser = getWorkspaceRolesForUserFactory({ db })
const upsertWorkspaceRole = upsertWorkspaceRoleFactory({ db })
const createAndStoreTestUser = async (): Promise<BasicTestUser> => {
const testId = cryptoRandomString({ length: 6 })
const userRecord: BasicTestUser = {
name: `test-user-${testId}`,
email: `test-user-${testId}@example.org`,
password: '',
id: '',
role: 'server:user'
}
await createTestUser(userRecord)
return userRecord
}
const createAndStoreTestWorkspace = async (): Promise<Workspace> => {
const workspace: Workspace = {
id: cryptoRandomString({ length: 10 }),
name: cryptoRandomString({ length: 10 }),
createdAt: new Date(),
updatedAt: new Date(),
description: null,
logoUrl: null
}
await upsertWorkspace({ workspace })
return workspace
}
describe('Workspace repositories', () => {
describe('getWorkspaceFactory creates a function, that', () => {
it('returns null if the workspace is not found', async () => {
const workspace = await getWorkspace({
workspaceId: cryptoRandomString({ length: 10 })
})
expect(workspace).to.be.null
})
// not testing get here, we're going to use that for testing upsert
})
describe('upsertWorkspaceFactory creates a function, that', () => {
it('upserts the workspace', async () => {
const testWorkspace = await createAndStoreTestWorkspace()
const storedWorkspace = await getWorkspace({ workspaceId: testWorkspace.id })
expect(storedWorkspace).to.deep.equal(testWorkspace)
const modifiedTestWorkspace: Workspace = {
...testWorkspace,
description: 'now im adding a description to the workspace'
}
await upsertWorkspace({ workspace: modifiedTestWorkspace })
const modifiedStoredWorkspace = await getWorkspace({
workspaceId: testWorkspace.id
})
expect(modifiedStoredWorkspace).to.deep.equal(modifiedTestWorkspace)
})
it('updates only relevant workspace fields', async () => {
const testWorkspace = await createAndStoreTestWorkspace()
const storedWorkspace = await getWorkspace({ workspaceId: testWorkspace.id })
expect(storedWorkspace).to.deep.equal(testWorkspace)
await upsertWorkspace({
workspace: {
...testWorkspace,
id: cryptoRandomString({ length: 13 }),
createdAt: new Date()
}
})
const modifiedStoredWorkspace = await getWorkspace({
workspaceId: testWorkspace.id
})
expect(modifiedStoredWorkspace).to.deep.equal(testWorkspace)
})
})
describe('deleteWorkspaceRoleFactory creates a function, that', () => {
it('deletes specified workspace role', async () => {
const { id: userId } = await createAndStoreTestUser()
const { id: workspaceId } = await createAndStoreTestWorkspace()
await upsertWorkspaceRole({ userId, workspaceId, role: 'workspace:member' })
await deleteWorkspaceRole({ userId, workspaceId })
const role = await getWorkspaceRoleForUser({ userId, workspaceId })
expect(role).to.be.null
})
it('returns deleted workspace role', async () => {
const { id: userId } = await createAndStoreTestUser()
const { id: workspaceId } = await createAndStoreTestWorkspace()
const createdRole: WorkspaceAcl = {
userId,
workspaceId,
role: 'workspace:member'
}
await upsertWorkspaceRole(createdRole)
const deletedRole = await deleteWorkspaceRole({ userId, workspaceId })
expect(deletedRole).to.deep.equal(createdRole)
})
it('return null if role does not exist', async () => {
const deletedRole = await deleteWorkspaceRole({ userId: '', workspaceId: '' })
expect(deletedRole).to.be.null
})
})
describe('getWorkspaceRolesFactory creates a function, that', () => {
it('returns all roles in a given workspace', async () => {
const { id: workspaceId } = await createAndStoreTestWorkspace()
const { id: userIdA } = await createAndStoreTestUser()
const { id: userIdB } = await createAndStoreTestUser()
await upsertWorkspaceRole({
workspaceId,
userId: userIdA,
role: 'workspace:admin'
})
await upsertWorkspaceRole({
workspaceId,
userId: userIdB,
role: 'workspace:admin'
})
const workspaceRoles = await getWorkspaceRoles({ workspaceId })
expect(workspaceRoles.length).to.equal(2)
expect(workspaceRoles.some(({ userId }) => userId === userIdA)).to.be.true
expect(workspaceRoles.some(({ userId }) => userId === userIdB)).to.be.true
})
})
describe('getWorkspaceRoleForUserFactory creates a function, that', () => {
it('returns the current role for a given user in a given workspace', async () => {
const { id: userId } = await createAndStoreTestUser()
const { id: workspaceId } = await createAndStoreTestWorkspace()
await upsertWorkspaceRole({ workspaceId, userId, role: 'workspace:admin' })
const workspaceRole = await getWorkspaceRoleForUser({ userId, workspaceId })
expect(workspaceRole).to.not.be.null
expect(workspaceRole?.userId).to.equal(userId)
})
it('returns `null` if the given user does not have a role in the given workspace', async () => {
const workspaceRole = await getWorkspaceRoleForUser({
userId: 'invalid-user-id',
workspaceId: 'invalid-workspace-id'
})
expect(workspaceRole).to.be.null
})
})
describe('getWorkspaceRolesForUserFactory creates a function, that', () => {
it('returns the current role for a given user across all workspaces', async () => {
const { id: userId } = await createAndStoreTestUser()
const { id: workspaceIdA } = await createAndStoreTestWorkspace()
const { id: workspaceIdB } = await createAndStoreTestWorkspace()
await upsertWorkspaceRole({
workspaceId: workspaceIdA,
userId,
role: 'workspace:admin'
})
await upsertWorkspaceRole({
workspaceId: workspaceIdB,
userId,
role: 'workspace:admin'
})
const workspaceRoles = await getWorkspaceRolesForUser({ userId })
expect(workspaceRoles.length).to.equal(2)
expect(workspaceRoles.some(({ workspaceId }) => workspaceId === workspaceIdA)).to
.be.true
expect(workspaceRoles.some(({ workspaceId }) => workspaceId === workspaceIdB)).to
.be.true
})
it('returns the current role for workspaces specified by the workspace id filter, if provided', async () => {
const { id: userId } = await createAndStoreTestUser()
const { id: workspaceIdA } = await createAndStoreTestWorkspace()
const { id: workspaceIdB } = await createAndStoreTestWorkspace()
await upsertWorkspaceRole({
workspaceId: workspaceIdA,
userId,
role: 'workspace:admin'
})
await upsertWorkspaceRole({
workspaceId: workspaceIdB,
userId,
role: 'workspace:admin'
})
const workspaceRoles = await getWorkspaceRolesForUser(
{ userId },
{ workspaceIdFilter: [workspaceIdA] }
)
expect(workspaceRoles.length).to.equal(1)
expect(workspaceRoles[0].workspaceId).to.equal(workspaceIdA)
})
})
describe('upsertWorkspaceRoleFactory creates a function, that', () => {
it('throws if an unknown role is provided', async () => {
const role: WorkspaceAcl = {
// @ts-expect-error type asserts valid values for `role`
role: 'fake-role',
userId: '',
workspaceId: ''
}
await expectToThrow(() => upsertWorkspaceRole(role))
})
})
})