diff --git a/frontend/src/component/project/Project/Project.tsx b/frontend/src/component/project/Project/Project.tsx index aba5ce3aa0..1233fbd389 100644 --- a/frontend/src/component/project/Project/Project.tsx +++ b/frontend/src/component/project/Project/Project.tsx @@ -28,7 +28,7 @@ import ProjectOverview from './ProjectOverview'; import ProjectHealth from './ProjectHealth/ProjectHealth'; import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton'; import { - CREATE_FEATURE, + UPDATE_FEATURE, DELETE_PROJECT, UPDATE_PROJECT, } from 'component/providers/AccessProvider/permissions'; @@ -143,7 +143,7 @@ export const Project = () => { )} show={ setModalOpen(true)} tooltipProps={{ title: 'Import' }} diff --git a/src/lib/export-import-toggles/export-import-permissions.e2e.test.ts b/src/lib/export-import-toggles/export-import-permissions.e2e.test.ts index 107b4f2864..79535a3f7a 100644 --- a/src/lib/export-import-toggles/export-import-permissions.e2e.test.ts +++ b/src/lib/export-import-toggles/export-import-permissions.e2e.test.ts @@ -6,6 +6,7 @@ import dbInit, { ITestDb } from '../../test/e2e/helpers/database-init'; import getLogger from '../../test/fixtures/no-logger'; import { DEFAULT_PROJECT, + IContextFieldStore, IEnvironmentStore, IEventStore, IFeatureToggleStore, @@ -22,6 +23,7 @@ let app: IUnleashTest; let db: ITestDb; let eventStore: IEventStore; let environmentStore: IEnvironmentStore; +let contextFieldStore: IContextFieldStore; let projectStore: IProjectStore; let toggleStore: IFeatureToggleStore; let accessService: AccessService; @@ -242,6 +244,7 @@ beforeAll(async () => { projectStore = db.stores.projectStore; toggleStore = db.stores.featureToggleStore; accessService = app.services.accessService; + contextFieldStore = db.stores.contextFieldStore; const roles = await accessService.getRootRoles(); adminRole = roles.find((role) => role.name === RoleName.ADMIN); @@ -261,6 +264,11 @@ beforeEach(async () => { await toggleStore.deleteAll(); await projectStore.deleteAll(); await environmentStore.deleteAll(); + await contextFieldStore.deleteAll(); + + await contextFieldStore.deleteAll(); + await loginAdminUser(); + await createContextField({ name: 'appName' }); }); afterAll(async () => { diff --git a/src/lib/export-import-toggles/export-import-service.ts b/src/lib/export-import-toggles/export-import-service.ts index da30733eac..dd9e0bc9d1 100644 --- a/src/lib/export-import-toggles/export-import-service.ts +++ b/src/lib/export-import-toggles/export-import-service.ts @@ -576,24 +576,38 @@ export default class ExportImportService { dto: ImportTogglesSchema, user: User, ): Promise { - const [newTagTypes, newContextFields] = await Promise.all([ + const [ + newTagTypes, + newContextFields, + strategiesExistForFeatures, + featureEnvsWithVariants, + existingFeatures, + ] = await Promise.all([ this.getNewTagTypes(dto), this.getNewContextFields(dto), + this.importTogglesStore.strategiesExistForFeatures( + dto.data.features.map((feature) => feature.name), + dto.environment, + ), + dto.data.featureEnvironments?.filter( + (featureEnvironment) => + Array.isArray(featureEnvironment.variants) && + featureEnvironment.variants.length > 0, + ) || Promise.resolve([]), + this.importTogglesStore.getExistingFeatures( + dto.data.features.map((feature) => feature.name), + ), ]); + const permissions = [UPDATE_FEATURE]; if (newTagTypes.length > 0) { permissions.push(UPDATE_TAG_TYPE); } + if (Array.isArray(newContextFields) && newContextFields.length > 0) { permissions.push(CREATE_CONTEXT_FIELD); } - const strategiesExistForFeatures = - await this.importTogglesStore.strategiesExistForFeatures( - dto.data.features.map((feature) => feature.name), - dto.environment, - ); - if (strategiesExistForFeatures) { permissions.push(DELETE_FEATURE_STRATEGY); } @@ -602,22 +616,10 @@ export default class ExportImportService { permissions.push(CREATE_FEATURE_STRATEGY); } - const featureEnvsWithVariants = - dto.data.featureEnvironments?.filter( - (featureEnvironment) => - Array.isArray(featureEnvironment.variants) && - featureEnvironment.variants.length > 0, - ) || []; - if (featureEnvsWithVariants.length > 0) { permissions.push(UPDATE_FEATURE_ENVIRONMENT_VARIANTS); } - const existingFeatures = - await this.importTogglesStore.getExistingFeatures( - dto.data.features.map((feature) => feature.name), - ); - if (existingFeatures.length < dto.data.features.length) { permissions.push(CREATE_FEATURE); } diff --git a/src/lib/export-import-toggles/export-import.e2e.test.ts b/src/lib/export-import-toggles/export-import.e2e.test.ts index d1645ccc9e..b7e533906d 100644 --- a/src/lib/export-import-toggles/export-import.e2e.test.ts +++ b/src/lib/export-import-toggles/export-import.e2e.test.ts @@ -7,6 +7,7 @@ import getLogger from '../../test/fixtures/no-logger'; import { DEFAULT_PROJECT, FeatureToggleDTO, + IContextFieldStore, IEnvironmentStore, IEventStore, IFeatureToggleStore, @@ -28,6 +29,7 @@ let app: IUnleashTest; let db: ITestDb; let eventStore: IEventStore; let environmentStore: IEnvironmentStore; +let contextFieldStore: IContextFieldStore; let projectStore: IProjectStore; let toggleStore: IFeatureToggleStore; @@ -170,6 +172,7 @@ beforeAll(async () => { eventStore = db.stores.eventStore; environmentStore = db.stores.environmentStore; projectStore = db.stores.projectStore; + contextFieldStore = db.stores.contextFieldStore; toggleStore = db.stores.featureToggleStore; }); @@ -178,6 +181,9 @@ beforeEach(async () => { await toggleStore.deleteAll(); await projectStore.deleteAll(); await environmentStore.deleteAll(); + + await contextFieldStore.deleteAll(); + await createContextField({ name: 'appName' }); }); afterAll(async () => {