mirror of
https://github.com/Unleash/unleash.git
synced 2025-08-04 13:48:56 +02:00
feat: add tests for number validator
This commit is contained in:
parent
371ad6c009
commit
6c8a228d01
@ -14,6 +14,7 @@ import { IUnleashServices } from '../../types/services';
|
||||
import ContextService from '../../services/context-service';
|
||||
import { Logger } from '../../logger';
|
||||
import { IAuthRequest } from '../unleash-types';
|
||||
import { IConstraint } from 'lib/types/model';
|
||||
|
||||
class ContextController extends Controller {
|
||||
private logger: Logger;
|
||||
|
@ -337,6 +337,13 @@ export default class ProjectFeaturesController extends Controller {
|
||||
res.status(200).json(updatedStrategy);
|
||||
}
|
||||
|
||||
async validateConstraint(req: Request, res: Response): Promise<void> {
|
||||
const constraint: IConstraint = { ...req.body };
|
||||
|
||||
await this.featureService.validateConstraint(constraint);
|
||||
res.status(204).send();
|
||||
}
|
||||
|
||||
async getStrategy(
|
||||
req: IAuthRequest<StrategyIdParams, any, any, any>,
|
||||
res: Response,
|
||||
|
25
src/lib/schema/constraint-value-types.test.ts
Normal file
25
src/lib/schema/constraint-value-types.test.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { constraintNumberTypeSchema } from './constraint-value-types';
|
||||
|
||||
test('should require number', async () => {
|
||||
try {
|
||||
await constraintNumberTypeSchema.validateAsync('test');
|
||||
} catch (error) {
|
||||
expect(error.details[0].message).toEqual('"value" must be a number');
|
||||
}
|
||||
});
|
||||
|
||||
test('should allow strings that can be parsed to a number', async () => {
|
||||
await constraintNumberTypeSchema.validateAsync('5');
|
||||
});
|
||||
|
||||
test('should allow floating point numbers', async () => {
|
||||
await constraintNumberTypeSchema.validateAsync(5.72);
|
||||
});
|
||||
|
||||
test('should allow numbers', async () => {
|
||||
await constraintNumberTypeSchema.validateAsync(5);
|
||||
});
|
||||
|
||||
test('should allow negative numbers', async () => {
|
||||
await constraintNumberTypeSchema.validateAsync(-5);
|
||||
});
|
3
src/lib/schema/constraint-value-types.ts
Normal file
3
src/lib/schema/constraint-value-types.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import joi from 'joi';
|
||||
|
||||
export const constraintNumberTypeSchema = joi.number();
|
@ -39,6 +39,7 @@ import {
|
||||
FeatureToggleDTO,
|
||||
FeatureToggleLegacy,
|
||||
FeatureToggleWithEnvironment,
|
||||
IConstraint,
|
||||
IEnvironmentDetail,
|
||||
IFeatureEnvironmentInfo,
|
||||
IFeatureOverview,
|
||||
@ -50,7 +51,13 @@ import {
|
||||
} from '../types/model';
|
||||
import { IFeatureEnvironmentStore } from '../types/stores/feature-environment-store';
|
||||
import { IFeatureToggleClientStore } from '../types/stores/feature-toggle-client-store';
|
||||
import { DEFAULT_ENV } from '../util/constants';
|
||||
import {
|
||||
DATE_OPERATORS,
|
||||
DEFAULT_ENV,
|
||||
NUM_OPERATORS,
|
||||
SEMVER_OPERATORS,
|
||||
STRING_OPERATORS,
|
||||
} from '../util/constants';
|
||||
import { applyPatch, deepClone, Operation } from 'fast-json-patch';
|
||||
import { OperationDeniedError } from '../error/operation-denied-error';
|
||||
|
||||
@ -63,6 +70,10 @@ interface IFeatureStrategyContext extends IFeatureContext {
|
||||
environment: string;
|
||||
}
|
||||
|
||||
const oneOf = (values: string[], match: string) => {
|
||||
return values.some((value) => value === match);
|
||||
};
|
||||
|
||||
class FeatureToggleService {
|
||||
private logger: Logger;
|
||||
|
||||
@ -140,6 +151,25 @@ class FeatureToggleService {
|
||||
}
|
||||
}
|
||||
|
||||
validateConstraint(constraint: IConstraint): void {
|
||||
const { operator } = constraint;
|
||||
if (oneOf(NUM_OPERATORS, operator)) {
|
||||
// Validate number value
|
||||
}
|
||||
|
||||
if (oneOf(STRING_OPERATORS, operator)) {
|
||||
// validate string values array
|
||||
}
|
||||
|
||||
if (oneOf(SEMVER_OPERATORS, operator)) {
|
||||
// validate semver
|
||||
}
|
||||
|
||||
if (oneOf(DATE_OPERATORS, operator)) {
|
||||
// validate dates
|
||||
}
|
||||
}
|
||||
|
||||
async patchFeature(
|
||||
project: string,
|
||||
featureName: string,
|
||||
|
@ -6,7 +6,10 @@ import { IUser } from './user';
|
||||
export interface IConstraint {
|
||||
contextName: string;
|
||||
operator: string;
|
||||
values: string[];
|
||||
values?: string[];
|
||||
value?: string;
|
||||
inverted?: boolean;
|
||||
caseInsensitive?: boolean;
|
||||
}
|
||||
export enum WeightType {
|
||||
VARIABLE = 'variable',
|
||||
|
@ -5,3 +5,50 @@ export const ENVIRONMENT_PERMISSION_TYPE = 'environment';
|
||||
export const PROJECT_PERMISSION_TYPE = 'project';
|
||||
|
||||
export const CUSTOM_ROLE_TYPE = 'custom';
|
||||
|
||||
/* CONTEXT FIELD OPERATORS */
|
||||
|
||||
export const NOT_IN = 'NOT_IN';
|
||||
export const IN = 'IN';
|
||||
export const STR_ENDS_WITH = 'STR_ENDS_WITH';
|
||||
export const STR_STARTS_WITH = 'STR_STARTS_WITH';
|
||||
export const STR_CONTAINS = 'STR_CONTAINS';
|
||||
export const NUM_EQ = 'NUM_EQ';
|
||||
export const NUM_GT = 'NUM_GT';
|
||||
export const NUM_GTE = 'NUM_GTE';
|
||||
export const NUM_LT = 'NUM_LT';
|
||||
export const NUM_LTE = 'NUM_LTE';
|
||||
export const DATE_AFTER = 'DATE_AFTER';
|
||||
export const DATE_BEFORE = 'DATE_BEFORE';
|
||||
export const SEMVER_EQ = 'SEMVER_EQ';
|
||||
export const SEMVER_GT = 'SEMVER_GT';
|
||||
export const SEMVER_LT = 'SEMVER_LT';
|
||||
|
||||
export const ALL_OPERATORS = [
|
||||
NOT_IN,
|
||||
IN,
|
||||
STR_ENDS_WITH,
|
||||
STR_STARTS_WITH,
|
||||
STR_CONTAINS,
|
||||
NUM_EQ,
|
||||
NUM_GT,
|
||||
NUM_GTE,
|
||||
NUM_LT,
|
||||
NUM_LTE,
|
||||
DATE_AFTER,
|
||||
DATE_BEFORE,
|
||||
SEMVER_EQ,
|
||||
SEMVER_GT,
|
||||
SEMVER_LT,
|
||||
];
|
||||
|
||||
export const STRING_OPERATORS = [
|
||||
STR_ENDS_WITH,
|
||||
STR_STARTS_WITH,
|
||||
STR_CONTAINS,
|
||||
IN,
|
||||
NOT_IN,
|
||||
];
|
||||
export const NUM_OPERATORS = [NUM_EQ, NUM_GT, NUM_GTE, NUM_LT, NUM_LTE];
|
||||
export const DATE_OPERATORS = [DATE_AFTER, DATE_BEFORE];
|
||||
export const SEMVER_OPERATORS = [SEMVER_EQ, SEMVER_GT, SEMVER_LT];
|
||||
|
5
src/lib/util/validators/constraint-types.ts
Normal file
5
src/lib/util/validators/constraint-types.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { constraintNumberTypeSchema } from 'lib/schema/constraint-value-types';
|
||||
|
||||
export const validateNumber = async (value: unknown): Promise<void> => {
|
||||
await constraintNumberTypeSchema.validateAsync(value);
|
||||
};
|
@ -12,7 +12,7 @@ process.nextTick(async () => {
|
||||
password: 'passord',
|
||||
host: 'localhost',
|
||||
port: 5432,
|
||||
database: 'unleash',
|
||||
database: 'contextfields',
|
||||
ssl: false,
|
||||
},
|
||||
server: {
|
||||
|
Loading…
Reference in New Issue
Block a user