fix(regions): respect region during project move to workspace (#4985)
This commit is contained in:
@@ -155,7 +155,7 @@ import { getUserFactory, getUsersFactory } from '@/modules/core/repositories/use
|
||||
import { getServerInfoFactory } from '@/modules/core/repositories/server'
|
||||
import { asOperation, commandFactory } from '@/modules/shared/command'
|
||||
import { throwIfRateLimitedFactory } from '@/modules/core/utils/ratelimiter'
|
||||
import { getRegionDb } from '@/modules/multiregion/utils/dbSelector'
|
||||
import { getProjectDbClient, getRegionDb } from '@/modules/multiregion/utils/dbSelector'
|
||||
import {
|
||||
listUserExpiredSsoSessionsFactory,
|
||||
listWorkspaceSsoMembershipsByUserEmailFactory
|
||||
@@ -226,6 +226,7 @@ import {
|
||||
validateProjectInviteBeforeFinalizationFactory
|
||||
} from '@/modules/serverinvites/services/coreFinalization'
|
||||
import { WorkspaceInvitesLimit } from '@/modules/workspaces/domain/constants'
|
||||
import { copyWorkspaceFactory } from '@/modules/workspaces/repositories/projectRegions'
|
||||
|
||||
const eventBus = getEventBus()
|
||||
const getServerInfo = getServerInfoFactory({ db })
|
||||
@@ -1539,6 +1540,8 @@ export = FF_WORKSPACES_MODULE_ENABLED
|
||||
moveToWorkspace: async (_parent, args, context) => {
|
||||
const { projectId, workspaceId } = args
|
||||
|
||||
const projectDb = await getProjectDbClient({ projectId })
|
||||
|
||||
const logger = context.log.child({
|
||||
projectId,
|
||||
streamId: projectId, //legacy
|
||||
@@ -1562,9 +1565,13 @@ export = FF_WORKSPACES_MODULE_ENABLED
|
||||
operationFactory: ({ db, emit }) =>
|
||||
moveProjectToWorkspaceFactory({
|
||||
getProject: getProjectFactory({ db }),
|
||||
updateProject: updateProjectFactory({ db }),
|
||||
updateProject: updateProjectFactory({ db: projectDb }),
|
||||
updateProjectRole: updateStreamRoleAndNotify,
|
||||
getProjectCollaborators: getStreamCollaboratorsFactory({ db }),
|
||||
copyWorkspace: copyWorkspaceFactory({
|
||||
sourceDb: db,
|
||||
targetDb: projectDb
|
||||
}),
|
||||
getWorkspaceRolesAndSeats: getWorkspaceRolesAndSeatsFactory({ db }),
|
||||
updateWorkspaceRole: addOrUpdateWorkspaceRoleFactory({
|
||||
getWorkspaceRoles: getWorkspaceRolesFactory({ db }),
|
||||
|
||||
@@ -7,7 +7,8 @@ import {
|
||||
IntersectProjectCollaboratorsAndWorkspaceCollaborators,
|
||||
QueryAllWorkspaceProjects,
|
||||
AddOrUpdateWorkspaceRole,
|
||||
ValidateWorkspaceMemberProjectRole
|
||||
ValidateWorkspaceMemberProjectRole,
|
||||
CopyWorkspace
|
||||
} from '@/modules/workspaces/domain/operations'
|
||||
import {
|
||||
WorkspaceInvalidProjectError,
|
||||
@@ -99,6 +100,7 @@ export const moveProjectToWorkspaceFactory =
|
||||
updateProject,
|
||||
updateProjectRole,
|
||||
getProjectCollaborators,
|
||||
copyWorkspace,
|
||||
getWorkspaceDomains,
|
||||
getWorkspaceRolesAndSeats,
|
||||
updateWorkspaceRole,
|
||||
@@ -110,6 +112,7 @@ export const moveProjectToWorkspaceFactory =
|
||||
updateProject: UpdateProject
|
||||
updateProjectRole: UpdateStreamRole
|
||||
getProjectCollaborators: GetStreamCollaborators
|
||||
copyWorkspace: CopyWorkspace
|
||||
getWorkspaceDomains: GetWorkspaceDomains
|
||||
getWorkspaceRolesAndSeats: GetWorkspaceRolesAndSeats
|
||||
updateWorkspaceRole: AddOrUpdateWorkspaceRole
|
||||
@@ -139,6 +142,9 @@ export const moveProjectToWorkspaceFactory =
|
||||
])
|
||||
if (!workspace) throw new WorkspaceNotFoundError()
|
||||
|
||||
// Ensure workspace record exists in source region
|
||||
await copyWorkspace({ workspaceId: workspace.id })
|
||||
|
||||
for (const projectMembers of chunk(projectTeam, 5)) {
|
||||
await Promise.all(
|
||||
projectMembers.map(async ({ id: userId, streamRole: currentProjectRole }) => {
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
MoveProjectToWorkspaceDocument,
|
||||
ProjectUpdateRoleInput,
|
||||
ProjectVisibility,
|
||||
UpdateProjectDocument,
|
||||
UpdateProjectRoleDocument,
|
||||
UpdateWorkspaceProjectRoleDocument
|
||||
} from '@/test/graphql/generated/graphql'
|
||||
@@ -40,6 +41,7 @@ import {
|
||||
} from '@/test/graphqlHelper'
|
||||
import { beforeEachContext } from '@/test/hooks'
|
||||
import { mockAdminOverride } from '@/test/mocks/global'
|
||||
import { isMultiRegionTestMode } from '@/test/speckle-helpers/regions'
|
||||
import {
|
||||
addToStream,
|
||||
BasicTestStream,
|
||||
@@ -860,7 +862,8 @@ describe('Workspace project GQL CRUD', () => {
|
||||
id: '',
|
||||
ownerId: '',
|
||||
name: 'Test Project',
|
||||
visibility: ProjectRecordVisibility.Private
|
||||
visibility: ProjectRecordVisibility.Private,
|
||||
regionKey: isMultiRegionTestMode() ? 'region1' : undefined
|
||||
}
|
||||
|
||||
const targetWorkspace: BasicTestWorkspace = {
|
||||
@@ -982,6 +985,27 @@ describe('Workspace project GQL CRUD', () => {
|
||||
expect(resB).to.not.haveGraphQLErrors()
|
||||
expect(adminWorkspaceRole?.role).to.equal(Roles.Workspace.Admin)
|
||||
})
|
||||
|
||||
it('should respect project region during move mutations @multiregion', async () => {
|
||||
const resA = await apollo.execute(MoveProjectToWorkspaceDocument, {
|
||||
projectId: testProject.id,
|
||||
workspaceId: targetWorkspace.id
|
||||
})
|
||||
const resB = await apollo.execute(UpdateProjectDocument, {
|
||||
input: {
|
||||
id: testProject.id,
|
||||
name: 'Foo'
|
||||
}
|
||||
})
|
||||
const resC = await apollo.execute(GetProjectDocument, {
|
||||
id: testProject.id
|
||||
})
|
||||
|
||||
expect(resA).to.not.haveGraphQLErrors()
|
||||
expect(resB).to.not.haveGraphQLErrors()
|
||||
expect(resC).to.not.haveGraphQLErrors()
|
||||
expect(resC.data?.project?.workspaceId).to.equal(targetWorkspace.id)
|
||||
})
|
||||
})
|
||||
|
||||
// moved over Alessandro's tests from core to here, since they are all related to workspaces
|
||||
|
||||
@@ -245,6 +245,7 @@ describe('Project management services', () => {
|
||||
getProjectCollaborators: async () => {
|
||||
expect.fail()
|
||||
},
|
||||
copyWorkspace: async () => '',
|
||||
getWorkspaceRolesAndSeats: async () => {
|
||||
expect.fail()
|
||||
},
|
||||
@@ -290,6 +291,7 @@ describe('Project management services', () => {
|
||||
getProjectCollaborators: async () => {
|
||||
expect.fail()
|
||||
},
|
||||
copyWorkspace: async () => '',
|
||||
getWorkspaceRolesAndSeats: async () => {
|
||||
expect.fail()
|
||||
},
|
||||
@@ -344,6 +346,7 @@ describe('Project management services', () => {
|
||||
} as unknown as ProjectTeamMember
|
||||
]
|
||||
},
|
||||
copyWorkspace: async () => '',
|
||||
getWorkspaceRolesAndSeats: async () => {
|
||||
return {
|
||||
[userId]: {
|
||||
@@ -413,6 +416,7 @@ describe('Project management services', () => {
|
||||
} as unknown as ProjectTeamMember
|
||||
]
|
||||
},
|
||||
copyWorkspace: async () => '',
|
||||
getWorkspaceRolesAndSeats: async () => {
|
||||
return {}
|
||||
},
|
||||
@@ -486,6 +490,7 @@ describe('Project management services', () => {
|
||||
} as unknown as ProjectTeamMember
|
||||
]
|
||||
},
|
||||
copyWorkspace: async () => '',
|
||||
getWorkspaceRolesAndSeats: async () => {
|
||||
return workspaceRole && workspaceSeatType
|
||||
? {
|
||||
|
||||
Reference in New Issue
Block a user