diff --git a/src/lib/services/export-import-service.ts b/src/lib/services/export-import-service.ts index f7d363c3b2..02f0c85713 100644 --- a/src/lib/services/export-import-service.ts +++ b/src/lib/services/export-import-service.ts @@ -106,14 +106,26 @@ export default class ExportImportService { this.tagTypeStore.getAll(), ]); this.addSegmentsToStrategies(featureStrategies, strategySegments); - const filteredContextFields = contextFields.filter((field) => - featureStrategies.some( - (strategy) => - strategy.parameters.stickiness === field.name || - strategy.constraints.some( - (constraint) => constraint.contextName === field.name, + const filteredContextFields = contextFields.filter( + (field) => + featureEnvironments.some((featureEnv) => + featureEnv.variants.some( + (variant) => + variant.stickiness === field.name || + variant.overrides.some( + (override) => + override.contextName === field.name, + ), ), - ), + ) || + featureStrategies.some( + (strategy) => + strategy.parameters.stickiness === field.name || + strategy.constraints.some( + (constraint) => + constraint.contextName === field.name, + ), + ), ); const filteredSegments = segments.filter((segment) => featureStrategies.some((strategy) => diff --git a/src/lib/services/scheduler-service.test.ts b/src/lib/services/scheduler-service.test.ts index 1fcf656859..bea869da4a 100644 --- a/src/lib/services/scheduler-service.test.ts +++ b/src/lib/services/scheduler-service.test.ts @@ -63,9 +63,9 @@ test('Can schedule multiple jobs at the different intervals', async () => { const job = jest.fn(); const anotherJob = jest.fn(); - schedulerService.schedule(job, 10); - schedulerService.schedule(anotherJob, 20); - await ms(25); + schedulerService.schedule(job, 100); + schedulerService.schedule(anotherJob, 200); + await ms(250); expect(job).toBeCalledTimes(3); expect(anotherJob).toBeCalledTimes(2); diff --git a/src/test/e2e/api/admin/export-import.e2e.test.ts b/src/test/e2e/api/admin/export-import.e2e.test.ts index 8adc4647d7..c4d63b7c92 100644 --- a/src/test/e2e/api/admin/export-import.e2e.test.ts +++ b/src/test/e2e/api/admin/export-import.e2e.test.ts @@ -4,17 +4,19 @@ import { } from '../../helpers/test-helper'; import dbInit, { ITestDb } from '../../helpers/database-init'; import getLogger from '../../../fixtures/no-logger'; -import { IEventStore } from 'lib/types/stores/event-store'; import { FeatureToggleDTO, IEnvironmentStore, + IEventStore, IFeatureToggleStore, IProjectStore, ISegment, IStrategyConfig, + IVariant, } from 'lib/types'; import { DEFAULT_ENV } from '../../../../lib/util'; import { ContextFieldSchema } from '../../../../lib/openapi'; +import User from '../../../../lib/types/user'; let app: IUnleashTest; let db: ITestDb; @@ -79,6 +81,21 @@ const createContext = async (context: ContextFieldSchema = defaultContext) => { .expect(201); }; +const createVariants = async ( + project: string, + feature: string, + environment: string, + variants: IVariant[], +) => { + await app.services.featureToggleService.saveVariantsOnEnv( + project, + feature, + environment, + variants, + new User({ id: 1 }), + ); +}; + const createProject = async (project: string, environment: string) => { await db.stores.environmentStore.create({ name: environment, @@ -192,24 +209,32 @@ test('exports features', async () => { }); }); -test('should export custom context fields', async () => { +test('should export custom context fields from strategies and variants', async () => { await createProject('default', 'default'); - const context = { - name: 'test-export', + const strategyContext = { + name: 'strategy-context', legalValues: [ - { value: 'estonia' }, - { value: 'norway' }, - { value: 'poland' }, + { value: 'strategy-context-1' }, + { value: 'strategy-context-2' }, + { value: 'strategy-context-3' }, ], }; - await createContext(context); + const strategyStickinessContext = { + name: 'strategy-stickiness', + legalValues: [ + { value: 'strategy-stickiness-1' }, + { value: 'strategy-stickiness-2' }, + ], + }; + await createContext(strategyContext); + await createContext(strategyStickinessContext); const strategy = { name: 'default', - parameters: { rollout: '100', stickiness: 'default' }, + parameters: { rollout: '100', stickiness: 'strategy-stickiness' }, constraints: [ { - contextName: context.name, - values: ['estonia', 'norway'], + contextName: strategyContext.name, + values: ['strategy-context-1', 'strategy-context-2'], operator: 'IN' as const, }, ], @@ -221,6 +246,36 @@ test('should export custom context fields', async () => { }, strategy, ); + const variantStickinessContext = { + name: 'variant-stickiness-context', + legalValues: [ + { value: 'variant-stickiness-context-1' }, + { value: 'variant-stickiness-context-2' }, + ], + }; + const variantOverridesContext = { + name: 'variant-overrides-context', + legalValues: [ + { value: 'variant-overrides-context-1' }, + { value: 'variant-overrides-context-2' }, + ], + }; + await createContext(variantStickinessContext); + await createContext(variantOverridesContext); + await createVariants('default', 'first_feature', 'default', [ + { + name: 'irrelevant', + weight: 1000, + stickiness: 'variant-stickiness-context', + weightType: 'variable', + overrides: [ + { + contextName: 'variant-overrides-context', + values: ['variant-overrides-context-1'], + }, + ], + }, + ]); const { body } = await app.request .post('/api/admin/features-batch/export') @@ -246,7 +301,12 @@ test('should export custom context fields', async () => { featureName: 'first_feature', }, ], - contextFields: [context], + contextFields: [ + strategyContext, + strategyStickinessContext, + variantOverridesContext, + variantStickinessContext, + ], }); });