feat(workspaces): add resolver to workspace for projectRoles

This commit is contained in:
Alessandro Magionami
2024-09-13 10:25:46 +02:00
parent 3777a43664
commit 090e8b8b3b
9 changed files with 232 additions and 10 deletions
@@ -1,7 +1,9 @@
import { db } from '@/db/knex'
import { StreamAclRecord, StreamRecord } from '@/modules/core/helpers/types'
import { getFeatureFlags } from '@/modules/shared/helpers/envHelper'
import { defineRequestDataloaders } from '@/modules/shared/helpers/graphqlHelper'
import {
getProjectRolesFactory,
getWorkspaceDomainsFactory,
getWorkspacesFactory
} from '@/modules/workspaces/repositories/workspaces'
@@ -21,6 +23,7 @@ declare module '@/modules/core/loaders' {
const dataLoadersDefinition = defineRequestDataloaders(({ ctx, createLoader }) => {
const getWorkspaces = getWorkspacesFactory({ db })
const getWorkspaceDomains = getWorkspaceDomainsFactory({ db })
const getProjectRoles = getProjectRolesFactory({ db })
return {
workspaces: {
@@ -35,7 +38,18 @@ const dataLoadersDefinition = defineRequestDataloaders(({ ctx, createLoader }) =
)
return ids.map((id) => results[id] || null)
}
)
),
getProjectRolesByWorkspaceId: createLoader<
{ workspaceId: string; userId: string },
(Pick<StreamAclRecord, 'role'> & { project: StreamRecord })[] | null
>(async (keys) => {
const workspaceId = keys[0].workspaceId
const userIds = keys.map(({ userId }) => userId)
const usersWithRoles = await getProjectRoles({ workspaceId, userIds })
return userIds.map(
(id) => usersWithRoles.find(({ userId }) => id === userId)?.projectRoles || []
)
})
},
workspaceDomains: {
/**
@@ -761,6 +761,12 @@ export = FF_WORKSPACES_MODULE_ENABLED
},
role: async (parent) => {
return parent.workspaceRole
},
projectRoles: async (parent, _args, ctx) => {
return await ctx.loaders.workspaces!.getProjectRolesByWorkspaceId.load({
workspaceId: parent.workspaceId,
userId: parent.id
})
}
},
PendingWorkspaceCollaborator: {
@@ -370,6 +370,150 @@ describe('Workspaces GQL CRUD', () => {
expect(res).to.not.haveGraphQLErrors()
expect(res.data?.workspace.team.totalCount).to.equal(6)
})
it('should return workspace team projectRoles', async () => {
const createRes = await apollo.execute(CreateWorkspaceDocument, {
input: { name: createRandomString() }
})
expect(createRes).to.not.haveGraphQLErrors()
const workspaceId = createRes.data!.workspaceMutations.create.id
const workspace = (await getWorkspaceFactory({ db })({
workspaceId
})) as unknown as BasicTestWorkspace
const member = {
id: createRandomString(),
name: createRandomPassword(),
email: createRandomEmail()
}
const guest = {
id: createRandomString(),
name: createRandomPassword(),
email: createRandomEmail()
}
await Promise.all([createTestUser(member), createTestUser(guest)])
await Promise.all([
assignToWorkspace(workspace, member, Roles.Workspace.Member),
assignToWorkspace(workspace, guest, Roles.Workspace.Guest)
])
const resProject1 = await apollo.execute(CreateProjectDocument, {
input: {
name: createRandomPassword(),
workspaceId
}
})
expect(resProject1).to.not.haveGraphQLErrors()
const project1Id = resProject1.data!.projectMutations.create.id
const project1Name = resProject1.data!.projectMutations.create.name
const resProject2 = await apollo.execute(CreateProjectDocument, {
input: {
name: createRandomPassword(),
workspaceId
}
})
expect(resProject2).to.not.haveGraphQLErrors()
const project2Id = resProject2.data!.projectMutations.create.id
const project2Name = resProject2.data!.projectMutations.create.name
await Promise.all([
grantStreamPermissions({
streamId: project1Id,
userId: member.id,
role: Roles.Stream.Contributor
}),
grantStreamPermissions({
streamId: project1Id,
userId: guest.id,
role: Roles.Stream.Reviewer
}),
grantStreamPermissions({
streamId: project2Id,
userId: guest.id,
role: Roles.Stream.Contributor
})
])
const res = await apollo.execute(GetWorkspaceTeamDocument, {
workspaceId
})
expect(res).to.not.haveGraphQLErrors()
const items = res.data?.workspace!.team?.items ?? []
expect(items).to.have.length(3)
expect(items.find((item) => item.role === Roles.Workspace.Admin)).to.deep.eq({
id: testMemberUser.id,
role: Roles.Workspace.Admin,
user: {
name: testMemberUser.name
},
projectRoles: [
{
role: Roles.Stream.Owner,
project: {
id: project1Id,
name: project1Name
}
},
{
role: Roles.Stream.Owner,
project: {
id: project2Id,
name: project2Name
}
}
]
})
expect(items.find((item) => item.role === Roles.Workspace.Member)).to.deep.eq({
id: member.id,
role: Roles.Workspace.Member,
user: {
name: member.name
},
projectRoles: [
{
role: Roles.Stream.Contributor,
project: {
id: project1Id,
name: project1Name
}
},
{
role: Roles.Stream.Reviewer,
project: {
id: project2Id,
name: project2Name
}
}
]
})
expect(items.find((item) => item.role === Roles.Workspace.Guest)).to.deep.eq({
id: guest.id,
role: Roles.Workspace.Guest,
user: {
name: guest.name
},
projectRoles: [
{
role: Roles.Stream.Reviewer,
project: {
id: project1Id,
name: project1Name
}
},
{
role: Roles.Stream.Contributor,
project: {
id: project2Id,
name: project2Name
}
}
]
})
})
})
describe('query workspace.billing', () => {
@@ -524,7 +668,7 @@ describe('Workspaces GQL CRUD', () => {
const res = await apollo.execute(GetActiveUserWorkspacesDocument, {})
expect(res).to.not.haveGraphQLErrors()
// TODO: this test depends on the previous tests
expect(res.data?.activeUser?.workspaces?.items?.length).to.equal(2)
expect(res.data?.activeUser?.workspaces?.items?.length).to.equal(3)
})
})