UNPKG

unleash-server

Version:

Unleash is an enterprise ready feature toggles service. It provides different strategies for handling feature toggles.

224 lines • 9.35 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const feature_toggle_service_1 = __importDefault(require("../../../lib/services/feature-toggle-service")); const test_config_1 = require("../../config/test-config"); const database_init_1 = __importDefault(require("../helpers/database-init")); const constants_1 = require("../../../lib/util/constants"); const segment_service_1 = require("../../../lib/services/segment-service"); const access_service_1 = require("../../../lib/services/access-service"); const group_service_1 = require("../../../lib/services/group-service"); const environment_service_1 = __importDefault(require("../../../lib/services/environment-service")); let stores; let db; let service; let segmentService; let environmentService; let unleashConfig; const mockConstraints = () => { return Array.from({ length: 5 }).map(() => ({ values: ['x', 'y', 'z'], operator: 'IN', contextName: 'a', })); }; beforeAll(async () => { const config = (0, test_config_1.createTestConfig)(); db = await (0, database_init_1.default)('feature_toggle_service_v2_service_serial', config.getLogger); unleashConfig = config; stores = db.stores; segmentService = new segment_service_1.SegmentService(stores, config); const groupService = new group_service_1.GroupService(stores, config); const accessService = new access_service_1.AccessService(stores, config, groupService); service = new feature_toggle_service_1.default(stores, config, segmentService, accessService); }); afterAll(async () => { await db.destroy(); }); test('Should create feature toggle strategy configuration', async () => { const projectId = 'default'; const username = 'feature-toggle'; const config = { name: 'default', constraints: [], parameters: {}, }; await service.createFeatureToggle('default', { name: 'Demo', }, 'test'); const createdConfig = await service.createStrategy(config, { projectId, featureName: 'Demo', environment: constants_1.DEFAULT_ENV }, username); expect(createdConfig.name).toEqual('default'); expect(createdConfig.id).toBeDefined(); }); test('Should be able to update existing strategy configuration', async () => { const projectId = 'default'; const username = 'existing-strategy'; const featureName = 'update-existing-strategy'; const config = { name: 'default', constraints: [], parameters: {}, }; await service.createFeatureToggle(projectId, { name: featureName, }, 'test'); const createdConfig = await service.createStrategy(config, { projectId, featureName, environment: constants_1.DEFAULT_ENV }, username); expect(createdConfig.name).toEqual('default'); const updatedConfig = await service.updateStrategy(createdConfig.id, { parameters: { b2b: 'true' } }, { projectId, featureName, environment: constants_1.DEFAULT_ENV }, username); expect(createdConfig.id).toEqual(updatedConfig.id); expect(updatedConfig.parameters).toEqual({ b2b: 'true' }); }); test('Should be able to get strategy by id', async () => { const featureName = 'get-strategy-by-id'; const projectId = 'default'; const userName = 'strategy'; const config = { name: 'default', constraints: [], parameters: {}, }; await service.createFeatureToggle(projectId, { name: featureName, }, userName); const createdConfig = await service.createStrategy(config, { projectId, featureName, environment: constants_1.DEFAULT_ENV }, userName); const fetchedConfig = await service.getStrategy(createdConfig.id); expect(fetchedConfig).toEqual(createdConfig); }); test('should ignore name in the body when updating feature toggle', async () => { const featureName = 'body-name-update'; const projectId = 'default'; const userName = 'strategy'; const secondFeatureName = 'body-name-update2'; await service.createFeatureToggle(projectId, { name: featureName, description: 'First toggle', }, userName); await service.createFeatureToggle(projectId, { name: secondFeatureName, description: 'Second toggle', }, userName); const update = { name: secondFeatureName, description: "I'm changed", }; await service.updateFeatureToggle(projectId, update, userName, featureName); const featureOne = await service.getFeature({ featureName }); const featureTwo = await service.getFeature({ featureName: secondFeatureName, }); expect(featureOne.description).toBe(`I'm changed`); expect(featureTwo.description).toBe('Second toggle'); }); test('should not get empty rows as features', async () => { const projectId = 'default'; const userName = 'strategy'; await service.createFeatureToggle(projectId, { name: 'linked-with-segment', description: 'First toggle', }, userName); await service.createFeatureToggle(projectId, { name: 'not-linked-with-segment', description: 'Second toggle', }, userName); const user = { email: 'test@example.com' }; const postData = { name: 'Unlinked segment', constraints: mockConstraints(), }; await segmentService.create(postData, user); const features = await service.getClientFeatures(); const namelessFeature = features.find((p) => !p.name); expect(features.length).toBe(7); expect(namelessFeature).toBeUndefined(); }); test('adding and removing an environment preserves variants when variants per env is off', async () => { const featureName = 'something-that-has-variants'; const prodEnv = 'mock-prod-env'; await stores.environmentStore.create({ name: prodEnv, type: 'production', }); await service.createFeatureToggle('default', { name: featureName, description: 'Second toggle', variants: [ { name: 'variant1', weight: 100, weightType: 'fix', stickiness: 'default', }, ], }, 'random_user'); //force the variantEnvironments flag off so that we can test legacy behavior environmentService = new environment_service_1.default(stores, { ...unleashConfig, flagResolver: { // eslint-disable-next-line @typescript-eslint/no-unused-vars isEnabled: (toggleName) => false, }, }); await environmentService.addEnvironmentToProject(prodEnv, 'default'); await environmentService.removeEnvironmentFromProject(prodEnv, 'default'); await environmentService.addEnvironmentToProject(prodEnv, 'default'); const toggle = await service.getFeature({ featureName, projectId: null, environmentVariants: false, }); expect(toggle.variants).toHaveLength(1); }); test('cloning a feature toggle copies variant environments correctly', async () => { const newToggleName = 'Molly'; const clonedToggleName = 'Dolly'; const targetEnv = 'gene-lab'; await service.createFeatureToggle('default', { name: newToggleName, }, 'test'); await stores.environmentStore.create({ name: 'gene-lab', type: 'production', }); await stores.featureEnvironmentStore.connectFeatureToEnvironmentsForProject(newToggleName, 'default'); await stores.featureEnvironmentStore.addVariantsToFeatureEnvironment(newToggleName, targetEnv, [ { name: 'variant1', weight: 100, weightType: 'fix', stickiness: 'default', }, ]); await service.cloneFeatureToggle(newToggleName, 'default', clonedToggleName, true, 'test-user'); const clonedToggle = await stores.featureStrategiesStore.getFeatureToggleWithVariantEnvs(clonedToggleName); const defaultEnv = clonedToggle.environments.find((x) => x.name === 'default'); const newEnv = clonedToggle.environments.find((x) => x.name === targetEnv); expect(defaultEnv.variants).toHaveLength(0); expect(newEnv.variants).toHaveLength(1); }); test('Cloning a feature toggle also clones segments correctly', async () => { const featureName = 'ToggleWithSegments'; const clonedFeatureName = 'AWholeNewFeatureToggle'; let segment = await segmentService.create({ name: 'SomeSegment', constraints: mockConstraints(), }, { email: 'test@example.com', }); await service.createFeatureToggle('default', { name: featureName, }, 'test-user'); const config = { name: 'default', constraints: [], parameters: {}, segments: [segment.id], }; await service.createStrategy(config, { projectId: 'default', featureName, environment: constants_1.DEFAULT_ENV }, 'test-user'); await service.cloneFeatureToggle(featureName, 'default', clonedFeatureName, true, 'test-user'); let feature = await service.getFeature({ featureName: clonedFeatureName }); expect(feature.environments.find((x) => x.name === 'default').strategies[0] .segments).toHaveLength(1); }); //# sourceMappingURL=feature-toggle-service-v2.e2e.test.js.map