diff --git a/frontend/src/component/feature/FeatureView/FeatureSettings/FeatureSettingsProject/FeatureSettingsProjectConfirm/FeatureSettingsProjectConfirm.tsx b/frontend/src/component/feature/FeatureView/FeatureSettings/FeatureSettingsProject/FeatureSettingsProjectConfirm/FeatureSettingsProjectConfirm.tsx index 54920f4db0..1fe31df175 100644 --- a/frontend/src/component/feature/FeatureView/FeatureSettings/FeatureSettingsProject/FeatureSettingsProjectConfirm/FeatureSettingsProjectConfirm.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureSettings/FeatureSettingsProject/FeatureSettingsProjectConfirm/FeatureSettingsProjectConfirm.tsx @@ -8,6 +8,7 @@ import { Alert, List, ListItem, styled } from '@mui/material'; import { Link } from 'react-router-dom'; import { IChangeRequest } from 'component/changeRequest/changeRequest.types'; import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; +import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled'; const StyledContainer = styled('div')(({ theme }) => ({ display: 'grid', @@ -42,6 +43,10 @@ const FeatureSettingsProjectConfirm = ({ const currentProjectId = useRequiredPathParam('projectId'); const { project } = useProject(projectId); + const { isChangeRequestConfiguredInAnyEnv } = + useChangeRequestsEnabled(projectId); + const targetProjectHasChangeRequestsEnabled = + isChangeRequestConfiguredInAnyEnv(); const hasSameEnvironments: boolean = useMemo(() => { return arraysHaveSameItems( feature.environments.map(env => env.name), @@ -55,7 +60,11 @@ const FeatureSettingsProjectConfirm = ({ return ( - Incompatible project environments + Cannot proceed with the move -

- In order to move a feature toggle between two - projects, both projects must have the exact same - environments enabled. -

+ + + In order to move a feature toggle between + two projects, both projects must have the + exact same environments enabled. +

+ } + />

- In addition the feature toggle must not - have any pending change requests. This - feature toggle is currently referenced - in the following change requests: + The feature toggle must not have any + pending change requests. This feature + toggle is currently referenced in the + following change requests:

{changeRequests?.map(changeRequest => { @@ -122,6 +137,21 @@ const FeatureSettingsProjectConfirm = ({ } /> + + You're not allowed to move the feature to + project{' '} + + {projectId} + + . This project has change requests enabled. +

+ } + />
} diff --git a/src/lib/services/feature-toggle-service.ts b/src/lib/services/feature-toggle-service.ts index 079ed21313..14b6c4bfc6 100644 --- a/src/lib/services/feature-toggle-service.ts +++ b/src/lib/services/feature-toggle-service.ts @@ -1350,6 +1350,15 @@ class FeatureToggleService { newProject: string, createdBy: string, ): Promise { + const changeRequestEnabled = + await this.changeRequestAccessReadModel.isChangeRequestsEnabledForProject( + newProject, + ); + if (changeRequestEnabled) { + throw new NoAccessError( + `Changing project not allowed. Project ${newProject} has change requests enabled.`, + ); + } const feature = await this.featureToggleStore.get(featureName); const oldProject = feature.project; feature.project = newProject; diff --git a/src/test/e2e/services/feature-toggle-service-v2.e2e.test.ts b/src/test/e2e/services/feature-toggle-service-v2.e2e.test.ts index 51236152ef..ab492887ed 100644 --- a/src/test/e2e/services/feature-toggle-service-v2.e2e.test.ts +++ b/src/test/e2e/services/feature-toggle-service-v2.e2e.test.ts @@ -354,6 +354,20 @@ test('cloning a feature toggle not allowed for change requests enabled', async ( ); }); +test('changing to a project with change requests enabled should not be allowed', async () => { + await db.rawDatabase('change_request_settings').insert({ + project: 'default', + environment: 'default', + }); + await expect( + service.changeProject('newToggleName', 'default', 'user'), + ).rejects.toEqual( + new NoAccessError( + `Changing project not allowed. Project default has change requests enabled.`, + ), + ); +}); + test('Cloning a feature toggle also clones segments correctly', async () => { const featureName = 'ToggleWithSegments'; const clonedFeatureName = 'AWholeNewFeatureToggle';