mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	feat: validate strategies (#1429)
* feat: validate strategies * fix: optional coalescing on constraints * fix: update test
This commit is contained in:
		
							parent
							
								
									3de044ff97
								
							
						
					
					
						commit
						55469801cf
					
				@ -165,6 +165,14 @@ class FeatureToggleService {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async validateConstraints(constraints: IConstraint[]): Promise<void> {
 | 
			
		||||
        const validations = constraints.map((constraint) => {
 | 
			
		||||
            return this.validateConstraint(constraint);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        await Promise.all(validations);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async validateConstraint(constraint: IConstraint): Promise<void> {
 | 
			
		||||
        const { operator } = constraint;
 | 
			
		||||
        await constraintSchema.validateAsync(constraint);
 | 
			
		||||
@ -272,6 +280,11 @@ class FeatureToggleService {
 | 
			
		||||
    ): Promise<IStrategyConfig> {
 | 
			
		||||
        const { featureName, projectId, environment } = context;
 | 
			
		||||
        await this.validateFeatureContext(context);
 | 
			
		||||
 | 
			
		||||
        if (strategyConfig.constraints?.length > 0) {
 | 
			
		||||
            await this.validateConstraints(strategyConfig.constraints);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            const newFeatureStrategy =
 | 
			
		||||
                await this.featureStrategiesStore.createStrategyFeatureEnv({
 | 
			
		||||
@ -334,6 +347,10 @@ class FeatureToggleService {
 | 
			
		||||
                updates,
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            if (updates.constraints?.length > 0) {
 | 
			
		||||
                await this.validateConstraints(updates.constraints);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Store event!
 | 
			
		||||
            const tags = await this.tagStore.getAllTagsForFeature(featureName);
 | 
			
		||||
            const data = this.featureStrategyToPublic(strategy);
 | 
			
		||||
 | 
			
		||||
@ -39,6 +39,19 @@ test('semver validation should fail partial semver', () => {
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
test('semver validation should fail with leading v', () => {
 | 
			
		||||
    const leadingV = 'v1.2.0';
 | 
			
		||||
    expect.assertions(1);
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
        validateSemver(leadingV);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
        expect(e.message).toBe(
 | 
			
		||||
            `the provided value is not a valid semver format. The value provided was: ${leadingV}`,
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
/* Legal values tests */
 | 
			
		||||
test('should fail validation if value does not exist in single legal value', () => {
 | 
			
		||||
    const legalValues = ['100', '200', '300'];
 | 
			
		||||
 | 
			
		||||
@ -16,9 +16,11 @@ export const validateString = async (value: unknown): Promise<void> => {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const validateSemver = (value: unknown): void => {
 | 
			
		||||
    const cleanValue = semver.clean(value) === value;
 | 
			
		||||
 | 
			
		||||
    const result = semver.valid(value);
 | 
			
		||||
 | 
			
		||||
    if (result) return;
 | 
			
		||||
    if (result && cleanValue) return;
 | 
			
		||||
    throw new BadDataError(
 | 
			
		||||
        `the provided value is not a valid semver format. The value provided was: ${value}`,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user