UNPKG

unleash-server

Version:

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

185 lines • 7 kB
import { createFakeFeatureToggleService } from '../createFeatureToggleService.js'; import getLogger from '../../../../test/fixtures/no-logger.js'; import { REGEX } from '../../../util/constants.js'; import { describe, test, expect } from 'vitest'; import { DEFAULT_ENV } from '../../../server-impl.js'; const alwaysOnFlagResolver = { isEnabled() { return true; }, }; const createService = () => createFakeFeatureToggleService({ getLogger, flagResolver: alwaysOnFlagResolver, resourceLimits: {}, }); describe('Constraint validation via create strategy', () => { test('should reject invalid regex', async () => { const { featureToggleService, featureToggleStore } = createService(); await featureToggleStore.create('default', { name: 'feature', createdByUserId: 1, }); await expect(featureToggleService.createStrategy({ name: 'default', featureName: 'feature', constraints: [ { contextName: 'someField', operator: REGEX, value: '(unclosed', values: [], }, ], }, { projectId: 'default', featureName: 'feature' }, {})).rejects.toThrow('not a valid regex string'); }); test('should accept valid regex', async () => { const { featureToggleService, featureToggleStore } = createService(); await featureToggleStore.create('default', { name: 'feature', createdByUserId: 1, }); const result = await featureToggleService.unprotectedCreateStrategy({ name: 'default', featureName: 'feature', constraints: [ { contextName: 'someField', operator: REGEX, value: '^[a-z]+$', values: [], }, ], }, { projectId: 'default', featureName: 'feature' }, {}); expect(result.constraints?.[0].operator).toBe(REGEX); }); test('should validate regex value against legal values', async () => { const { featureToggleService, featureToggleStore, contextFieldStore } = createService(); await featureToggleStore.create('default', { name: 'feature', createdByUserId: 1, }); await contextFieldStore.create({ name: 'customField', description: 'A custom field', sortOrder: 0, stickiness: false, legalValues: [ { value: '^valid-pattern$' }, { value: '^another-pattern$' }, ], }); await expect(featureToggleService.createStrategy({ name: 'default', featureName: 'feature', constraints: [ { contextName: 'customField', operator: REGEX, value: '^valid-pattern$', values: [], }, ], }, { projectId: 'default', featureName: 'feature' }, {})).resolves.toBeDefined(); await expect(featureToggleService.createStrategy({ name: 'default', featureName: 'feature', constraints: [ { contextName: 'customField', operator: REGEX, value: '^not-a-legal-value$', values: [], }, ], }, { projectId: 'default', featureName: 'feature' }, {})).rejects.toThrow('is not specified as a legal value'); }); test('REGEX operator checks value (singular), not values, for legal value validation', async () => { const { featureToggleService, featureToggleStore, contextFieldStore } = createService(); await featureToggleStore.create('default', { name: 'feature', createdByUserId: 1, }); await contextFieldStore.create({ name: 'regexField', description: 'Field with legal values', sortOrder: 0, stickiness: false, legalValues: [{ value: '^allowed$' }], }); await expect(featureToggleService.createStrategy({ name: 'default', featureName: 'feature', constraints: [ { contextName: 'regexField', operator: REGEX, value: '^allowed$', values: ['not-in-legal-values'], }, ], }, { projectId: 'default', featureName: 'feature' }, {})).resolves.toBeDefined(); }); }); describe('Constraint validation via update strategy', () => { test('should reject invalid regex', async () => { const { featureToggleService, featureStrategiesStore } = createService(); await featureStrategiesStore.createFeature({ name: 'feature', createdByUserId: 1, }); const strategy = await featureStrategiesStore.createStrategyFeatureEnv({ parameters: {}, strategyName: 'default', featureName: 'feature', constraints: [], projectId: 'default', environment: DEFAULT_ENV, }); await expect(featureToggleService.updateStrategy(strategy.id, { constraints: [ { contextName: 'someField', operator: REGEX, value: '(unclosed', values: [], }, ], }, { projectId: 'default', featureName: 'feature', environment: DEFAULT_ENV, }, {})).rejects.toThrow('not a valid regex string'); }); test('should accept valid regex', async () => { const { featureToggleService, featureStrategiesStore } = createService(); await featureStrategiesStore.createFeature({ name: 'feature', createdByUserId: 1, }); const strategy = await featureStrategiesStore.createStrategyFeatureEnv({ parameters: {}, strategyName: 'default', featureName: 'feature', constraints: [], projectId: 'default', environment: DEFAULT_ENV, }); const result = await featureToggleService.unprotectedUpdateStrategy(strategy.id, { constraints: [ { contextName: 'someField', operator: REGEX, value: '^[a-z]+$', values: [], }, ], }, { projectId: 'default', featureName: 'feature', environment: DEFAULT_ENV, }, {}); expect(result.constraints?.[0].operator).toBe(REGEX); }); }); //# sourceMappingURL=feature-toggle-service.constraint-validation.test.js.map