diff --git a/src/lib/features/export-import-toggles/export-import-service.ts b/src/lib/features/export-import-toggles/export-import-service.ts index e43b261b87..33e73f3217 100644 --- a/src/lib/features/export-import-toggles/export-import-service.ts +++ b/src/lib/features/export-import-toggles/export-import-service.ts @@ -370,29 +370,26 @@ export default class ExportImportService { private async createOrUpdateToggles(dto: ImportTogglesSchema, user: User) { const existingFeatures = await this.getExistingProjectFeatures(dto); const username = extractUsernameFromUser(user); - await Promise.all( - dto.data.features.map((feature) => { - if (existingFeatures.includes(feature.name)) { - const { archivedAt, createdAt, ...rest } = feature; - return this.featureToggleService.updateFeatureToggle( - dto.project, - rest as FeatureToggleDTO, - username, - feature.name, - ); - } - return this.featureToggleService - .validateName(feature.name) - .then(() => { - const { archivedAt, createdAt, ...rest } = feature; - return this.featureToggleService.createFeatureToggle( - dto.project, - rest as FeatureToggleDTO, - extractUsernameFromUser(user), - ); - }); - }), - ); + + for (const feature of dto.data.features) { + if (existingFeatures.includes(feature.name)) { + const { archivedAt, createdAt, ...rest } = feature; + await this.featureToggleService.updateFeatureToggle( + dto.project, + rest as FeatureToggleDTO, + username, + feature.name, + ); + } else { + await this.featureToggleService.validateName(feature.name); + const { archivedAt, createdAt, ...rest } = feature; + await this.featureToggleService.createFeatureToggle( + dto.project, + rest as FeatureToggleDTO, + username, + ); + } + } } private async verifyContextFields(dto: ImportTogglesSchema) { diff --git a/src/lib/features/export-import-toggles/export-import.e2e.test.ts b/src/lib/features/export-import-toggles/export-import.e2e.test.ts index 5e94c0d786..0613af453a 100644 --- a/src/lib/features/export-import-toggles/export-import.e2e.test.ts +++ b/src/lib/features/export-import-toggles/export-import.e2e.test.ts @@ -104,7 +104,10 @@ const createVariants = async (feature: string, variants: IVariant[]) => { ); }; -const createProjects = async (projects: string[] = [DEFAULT_PROJECT]) => { +const createProjects = async ( + projects: string[] = [DEFAULT_PROJECT], + featureLimit = 2, +) => { await db.stores.environmentStore.create({ name: DEFAULT_ENV, type: 'production', @@ -115,6 +118,7 @@ const createProjects = async (projects: string[] = [DEFAULT_PROJECT]) => { description: '', id: project, mode: 'open' as const, + featureLimit, }); await app.linkProjectToEnvironment(project, DEFAULT_ENV); } @@ -725,6 +729,13 @@ test('import multiple features with same tag', async () => { }); }); +test('import too many feature exceeding limit', async () => { + const featureLimit = 1; + await createProjects([DEFAULT_PROJECT], featureLimit); + + await app.importToggles(importWithMultipleFeatures, 403); +}); + test('can update toggles on subsequent import', async () => { await createProjects(); await app.importToggles(defaultImportPayload); @@ -828,7 +839,7 @@ test('reject import with duplicate features', async () => { ); expect(body.details[0].description).toBe( - 'Feature first_feature already exists', + 'A toggle with that name already exists', ); });