1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-02-09 00:18:00 +01:00

feat: validate strategies (#1429)

* feat: validate strategies

* fix: optional coalescing on constraints

* fix: update test
This commit is contained in:
Fredrik Strand Oseberg 2022-03-10 14:43:53 +01:00 committed by GitHub
parent 3de044ff97
commit 55469801cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 1 deletions

View File

@ -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> { async validateConstraint(constraint: IConstraint): Promise<void> {
const { operator } = constraint; const { operator } = constraint;
await constraintSchema.validateAsync(constraint); await constraintSchema.validateAsync(constraint);
@ -272,6 +280,11 @@ class FeatureToggleService {
): Promise<IStrategyConfig> { ): Promise<IStrategyConfig> {
const { featureName, projectId, environment } = context; const { featureName, projectId, environment } = context;
await this.validateFeatureContext(context); await this.validateFeatureContext(context);
if (strategyConfig.constraints?.length > 0) {
await this.validateConstraints(strategyConfig.constraints);
}
try { try {
const newFeatureStrategy = const newFeatureStrategy =
await this.featureStrategiesStore.createStrategyFeatureEnv({ await this.featureStrategiesStore.createStrategyFeatureEnv({
@ -334,6 +347,10 @@ class FeatureToggleService {
updates, updates,
); );
if (updates.constraints?.length > 0) {
await this.validateConstraints(updates.constraints);
}
// Store event! // Store event!
const tags = await this.tagStore.getAllTagsForFeature(featureName); const tags = await this.tagStore.getAllTagsForFeature(featureName);
const data = this.featureStrategyToPublic(strategy); const data = this.featureStrategyToPublic(strategy);

View File

@ -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 */ /* Legal values tests */
test('should fail validation if value does not exist in single legal value', () => { test('should fail validation if value does not exist in single legal value', () => {
const legalValues = ['100', '200', '300']; const legalValues = ['100', '200', '300'];

View File

@ -16,9 +16,11 @@ export const validateString = async (value: unknown): Promise<void> => {
}; };
export const validateSemver = (value: unknown): void => { export const validateSemver = (value: unknown): void => {
const cleanValue = semver.clean(value) === value;
const result = semver.valid(value); const result = semver.valid(value);
if (result) return; if (result && cleanValue) return;
throw new BadDataError( throw new BadDataError(
`the provided value is not a valid semver format. The value provided was: ${value}`, `the provided value is not a valid semver format. The value provided was: ${value}`,
); );