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
|
||||
? {
|
||||
|
||||
@@ -6082,6 +6082,13 @@ export type BatchDeleteProjectsMutationVariables = Exact<{
|
||||
|
||||
export type BatchDeleteProjectsMutation = { __typename?: 'Mutation', projectMutations: { __typename?: 'ProjectMutations', batchDelete: boolean } };
|
||||
|
||||
export type UpdateProjectMutationVariables = Exact<{
|
||||
input: ProjectUpdateInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type UpdateProjectMutation = { __typename?: 'Mutation', projectMutations: { __typename?: 'ProjectMutations', update: { __typename?: 'Project', id: string, name: string, description?: string | null, visibility: ProjectVisibility, allowPublicComments: boolean, role?: string | null, createdAt: string, updatedAt: string } } };
|
||||
|
||||
export type UpdateProjectRoleMutationVariables = Exact<{
|
||||
input: ProjectUpdateRoleInput;
|
||||
}>;
|
||||
@@ -6635,6 +6642,7 @@ export const GetProjectObjectDocument = {"kind":"Document","definitions":[{"kind
|
||||
export const GetProjectDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetProject"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"project"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"BasicProjectFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"BasicProjectFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"allowPublicComments"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]} as unknown as DocumentNode<GetProjectQuery, GetProjectQueryVariables>;
|
||||
export const CreateProjectDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateProject"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ProjectCreateInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"projectMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"create"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"BasicProjectFields"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"BasicProjectFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"allowPublicComments"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]} as unknown as DocumentNode<CreateProjectMutation, CreateProjectMutationVariables>;
|
||||
export const BatchDeleteProjectsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"BatchDeleteProjects"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"projectMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"batchDelete"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}}]}]}}]}}]} as unknown as DocumentNode<BatchDeleteProjectsMutation, BatchDeleteProjectsMutationVariables>;
|
||||
export const UpdateProjectDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateProject"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ProjectUpdateInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"projectMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"update"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"update"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"BasicProjectFields"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"BasicProjectFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"allowPublicComments"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]} as unknown as DocumentNode<UpdateProjectMutation, UpdateProjectMutationVariables>;
|
||||
export const UpdateProjectRoleDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateProjectRole"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ProjectUpdateRoleInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"projectMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateRole"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"BasicProjectFields"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"BasicProjectFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"allowPublicComments"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]} as unknown as DocumentNode<UpdateProjectRoleMutation, UpdateProjectRoleMutationVariables>;
|
||||
export const GetProjectCollaboratorsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetProjectCollaborators"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"project"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}}]}}]}}]} as unknown as DocumentNode<GetProjectCollaboratorsQuery, GetProjectCollaboratorsQueryVariables>;
|
||||
export const GetProjectVersionsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetProjectVersions"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"project"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"versions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"referencedObject"}}]}}]}}]}}]}}]} as unknown as DocumentNode<GetProjectVersionsQuery, GetProjectVersionsQueryVariables>;
|
||||
|
||||
@@ -86,6 +86,18 @@ export const batchDeleteProjectsMutation = gql`
|
||||
}
|
||||
`
|
||||
|
||||
export const updateProjectMutation = gql`
|
||||
mutation UpdateProject($input: ProjectUpdateInput!) {
|
||||
projectMutations {
|
||||
update(update: $input) {
|
||||
...BasicProjectFields
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
${basicProjectFieldsFragment}
|
||||
`
|
||||
|
||||
export const updateProjectRoleMutation = gql`
|
||||
mutation UpdateProjectRole($input: ProjectUpdateRoleInput!) {
|
||||
projectMutations {
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import { db } from '@/db/knex'
|
||||
import { StreamAcl } from '@/modules/core/dbSchema'
|
||||
import { RegionalProjectCreationError } from '@/modules/core/errors/projects'
|
||||
import { StreamNotFoundError } from '@/modules/core/errors/stream'
|
||||
import { mapDbToGqlProjectVisibility } from '@/modules/core/helpers/project'
|
||||
import { StreamAclRecord, StreamRecord } from '@/modules/core/helpers/types'
|
||||
import { createBranchFactory } from '@/modules/core/repositories/branches'
|
||||
import { getProjectFactory } from '@/modules/core/repositories/projects'
|
||||
import { getServerInfoFactory } from '@/modules/core/repositories/server'
|
||||
import {
|
||||
createStreamFactory,
|
||||
@@ -32,6 +35,7 @@ import { deleteOldAndInsertNewVerificationFactory } from '@/modules/emails/repos
|
||||
import { renderEmail } from '@/modules/emails/services/emailRendering'
|
||||
import { sendEmail } from '@/modules/emails/services/sending'
|
||||
import { requestNewEmailVerificationFactory } from '@/modules/emails/services/verification/request'
|
||||
import { getRegionDb } from '@/modules/multiregion/utils/dbSelector'
|
||||
import {
|
||||
deleteInvitesByTargetFactory,
|
||||
deleteServerOnlyInvitesFactory,
|
||||
@@ -53,6 +57,7 @@ import {
|
||||
} from '@/modules/serverinvites/services/processing'
|
||||
import { inviteUsersToProjectFactory } from '@/modules/serverinvites/services/projectInviteManagement'
|
||||
import { authorizeResolver } from '@/modules/shared'
|
||||
import { isTestEnv } from '@/modules/shared/helpers/envHelper'
|
||||
import { Nullable } from '@/modules/shared/helpers/typeHelper'
|
||||
import { getEventBus } from '@/modules/shared/services/eventBus'
|
||||
import { getDefaultRegionFactory } from '@/modules/workspaces/repositories/regions'
|
||||
@@ -60,7 +65,8 @@ import { createWorkspaceProjectFactory } from '@/modules/workspaces/services/pro
|
||||
import { BasicTestUser } from '@/test/authHelper'
|
||||
import { ProjectVisibility } from '@/test/graphql/generated/graphql'
|
||||
import { faker } from '@faker-js/faker'
|
||||
import { ensureError, Roles, StreamRoles } from '@speckle/shared'
|
||||
import { retry } from '@lifeomic/attempt'
|
||||
import { ensureError, Roles, StreamRoles, TIME_MS } from '@speckle/shared'
|
||||
import { omit } from 'lodash'
|
||||
|
||||
const getServerInfo = getServerInfoFactory({ db })
|
||||
@@ -215,11 +221,45 @@ export async function createTestStream(
|
||||
})
|
||||
id = newProject.id
|
||||
} else {
|
||||
id = await createStream({
|
||||
...omit(streamObj, ['id', 'ownerId', 'visibility']),
|
||||
isPublic: visibility === ProjectVisibility.Public,
|
||||
ownerId: owner.id
|
||||
})
|
||||
// Create personal project
|
||||
if (streamObj.regionKey) {
|
||||
const regionDb = await getRegionDb({ regionKey: streamObj.regionKey })
|
||||
const project = await createStreamFactory({ db: regionDb })({
|
||||
...omit(streamObj, ['id', 'ownerId', 'visibility']),
|
||||
isPublic: visibility === ProjectVisibility.Public
|
||||
})
|
||||
try {
|
||||
await retry(
|
||||
async () => {
|
||||
const replicatedProject = await getProjectFactory({
|
||||
db
|
||||
})({ projectId: project.id })
|
||||
if (!replicatedProject) throw new StreamNotFoundError()
|
||||
},
|
||||
{ maxAttempts: 10, delay: isTestEnv() ? TIME_MS.second : undefined }
|
||||
)
|
||||
} catch (err) {
|
||||
if (err instanceof StreamNotFoundError) {
|
||||
throw new RegionalProjectCreationError(undefined, {
|
||||
info: { projectId: project.id, regionKey: streamObj.regionKey }
|
||||
})
|
||||
}
|
||||
// else throw as is
|
||||
throw err
|
||||
}
|
||||
await grantStreamPermissionsFactory({ db })({
|
||||
streamId: project.id,
|
||||
userId: owner.id,
|
||||
role: Roles.Stream.Owner
|
||||
})
|
||||
id = project.id
|
||||
} else {
|
||||
id = await createStream({
|
||||
...omit(streamObj, ['id', 'ownerId', 'visibility']),
|
||||
isPublic: visibility === ProjectVisibility.Public,
|
||||
ownerId: owner.id
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
streamObj.id = id
|
||||
|
||||
Reference in New Issue
Block a user