diff --git a/backend/packages/Upgrade/src/api/services/FeatureFlagService.ts b/backend/packages/Upgrade/src/api/services/FeatureFlagService.ts index 1a62db43fd..6c8963d8bd 100644 --- a/backend/packages/Upgrade/src/api/services/FeatureFlagService.ts +++ b/backend/packages/Upgrade/src/api/services/FeatureFlagService.ts @@ -727,7 +727,13 @@ export class FeatureFlagService { const createdFlags = []; - for (const featureFlag of validFiles) { + for (const featureFlagWithEnabledSettings of validFiles) { + const featureFlag = { + ...featureFlagWithEnabledSettings, + status: FEATURE_FLAG_STATUS.DISABLED, + filterMode: FILTER_MODE.EXCLUDE_ALL, + }; + const createdFlag = await this.dataSource.transaction(async (transactionalEntityManager) => { const newFlag = await this.addFeatureFlagInDB( this.featureFlagValidatorToFlag(featureFlag), @@ -751,6 +757,7 @@ export class FeatureFlagService { return { ...segmentInclusionList, + enabled: false, flagId: newFlag.id, segment: { ...segmentInclusionList.segment, userIds, subSegmentIds, groups }, }; diff --git a/backend/packages/Upgrade/test/unit/services/FeatureFlagService.test.ts b/backend/packages/Upgrade/test/unit/services/FeatureFlagService.test.ts index 13aa2b674f..41aabc8566 100644 --- a/backend/packages/Upgrade/test/unit/services/FeatureFlagService.test.ts +++ b/backend/packages/Upgrade/test/unit/services/FeatureFlagService.test.ts @@ -13,6 +13,7 @@ import { Container } from '../../../src/typeorm-typedi-extensions'; import { FLAG_SEARCH_KEY, FLAG_SORT_KEY, + FF_COMPATIBILITY_TYPE, } from '../../../src/api/controllers/validators/FeatureFlagsPaginatedParamsValidator'; import { FEATURE_FLAG_LIST_FILTER_MODE, @@ -61,6 +62,17 @@ describe('Feature Flag Service Testing', () => { const mockFlag3 = new FeatureFlagValidation(); + const mockFlag4 = new FeatureFlag(); + mockFlag4.name = 'name'; + mockFlag4.key = 'key4'; + mockFlag4.description = 'description'; + mockFlag4.context = ['context1']; + mockFlag4.status = FEATURE_FLAG_STATUS.ENABLED; + mockFlag4.filterMode = FILTER_MODE.INCLUDE_ALL; + mockFlag4.tags = []; + mockFlag4.featureFlagSegmentInclusion = []; + mockFlag4.featureFlagSegmentExclusion = []; + const mockSegment = { name: 'name', id: uuid(), @@ -151,18 +163,20 @@ describe('Feature Flag Service Testing', () => { useValue: { upsertSegmentInPipeline: jest.fn().mockResolvedValue(mockList), deleteSegment: jest.fn().mockResolvedValue(mockList), + getSegmentByIds: jest.fn().mockResolvedValue([mockSegment]), }, }, { provide: getRepositoryToken(FeatureFlagRepository), useValue: { find: jest.fn().mockResolvedValue(mockFlagArr), + findBy: jest.fn().mockResolvedValue(mockFlagArr), findOne: jest.fn().mockResolvedValue(mockFlag1), findWithNames: jest.fn().mockResolvedValue(mockFlagArr), findOneById: jest.fn().mockResolvedValue(mockFlag1), count: jest.fn().mockResolvedValue(mockFlagArr.length), findPaginated: jest.fn().mockResolvedValue(mockFlagArr), - insertFeatureFlag: jest.fn().mockResolvedValue(mockFlag1), + insertFeatureFlag: jest.fn().mockResolvedValue([mockFlag1]), deleteById: jest.fn().mockResolvedValue(mockFlag1.id), updateState: jest.fn().mockImplementation((id, status) => { return status; @@ -424,4 +438,49 @@ describe('Feature Flag Service Testing', () => { expect(result).toBeTruthy(); }); + + it('should import a feature flag from a valid file', async () => { + const result = await service.importFeatureFlags( + [{ fileName: 'import.json', fileContent: JSON.stringify(mockFlag4) }], + mockUser1, + logger + ); + + expect(result).toEqual([ + { + fileName: 'import.json', + error: null, + }, + ]); + }); + + it('should not import a feature flag with a duplicate key', async () => { + const result = await service.importFeatureFlags( + [{ fileName: 'import.json', fileContent: JSON.stringify(mockFlag1) }], + mockUser1, + logger + ); + + expect(result).toEqual([ + { + fileName: 'import.json', + error: FF_COMPATIBILITY_TYPE.INCOMPATIBLE, + }, + ]); + }); + + it('should not import a feature flag with incomplete definition', async () => { + const result = await service.importFeatureFlags( + [{ fileName: 'import.json', fileContent: JSON.stringify(mockFlag3) }], + mockUser1, + logger + ); + + expect(result).toEqual([ + { + fileName: 'import.json', + error: FF_COMPATIBILITY_TYPE.INCOMPATIBLE, + }, + ]); + }); });