Skip to content

Commit aac1303

Browse files
Update splitchanges and use properties validator
1 parent 949ac9c commit aac1303

7 files changed

Lines changed: 274 additions & 341 deletions

File tree

client/__tests__/track.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ describe('track', () => {
145145

146146
test('should be 400 if properties is invalid', async () => {
147147
const expected = [
148-
'properties must be a plain object.'
148+
'Input must be a plain object.'
149149
];
150150
const response = await request(app)
151151
.get('/client/track?key=my-key&event-type=my-event&traffic-type=my-traffic&value=1&properties=lalala')
@@ -158,7 +158,7 @@ describe('track', () => {
158158
'key too long, key must be 250 characters or less.',
159159
'you passed "@!test", event-type must adhere to the regular expression /^[a-zA-Z0-9][-_.:a-zA-Z0-9]{0,79}$/g. This means an event_type must be alphanumeric, cannot be more than 80 characters long, and can only include a dash, underscore, period, or colon as separators of alphanumeric characters.',
160160
'you passed an empty traffic-type, traffic-type must be a non-empty string.',
161-
'properties must be a plain object.',
161+
'Input must be a plain object.',
162162
'value must be null or number.'
163163
];
164164
const key = getLongKey();

client/client.router.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ const propertiesValidator = require('../utils/inputValidation/properties');
1212
const keysValidator = require('../utils/inputValidation/keys');
1313
const clientController = require('./client.controller');
1414
const { parseValidators } = require('../utils/utils');
15-
const validateEvaluationOptions = require('../utils/inputValidation/evaluationOptions');
1615

1716
/**
1817
* treatmentValidation performs input validation for treatment call.
@@ -25,7 +24,7 @@ const treatmentValidation = (req, res, next) => {
2524
const bucketingKeyValidation = req.query['bucketing-key'] !== undefined ? keyValidator(req.query['bucketing-key'], 'bucketing-key') : null;
2625
const featureFlagNameValidation = splitValidator(req.query['split-name']);
2726
const attributesValidation = attributesValidator(req.query.attributes);
28-
const optionsValidation = validateEvaluationOptions(req.query.options);
27+
const optionsValidation = propertiesValidator(req.query.options);
2928

3029
const error = parseValidators([matchingKeyValidation, bucketingKeyValidation, featureFlagNameValidation, attributesValidation, optionsValidation]);
3130
if (error.length) {
@@ -59,7 +58,7 @@ const treatmentsValidation = (req, res, next) => {
5958
const bucketingKeyValidation = req.query['bucketing-key'] !== undefined ? keyValidator(req.query['bucketing-key'], 'bucketing-key') : null;
6059
const featureFlagsNameValidation = splitsValidator(req.query['split-names']);
6160
const attributesValidation = attributesValidator(req.query.attributes);
62-
const optionsValidation = validateEvaluationOptions(req.query.options);
61+
const optionsValidation = propertiesValidator(req.query.options);
6362

6463
const error = parseValidators([matchingKeyValidation, bucketingKeyValidation, featureFlagsNameValidation, attributesValidation, optionsValidation]);
6564
if (error.length) {
@@ -93,7 +92,7 @@ const flagSetsValidation = (req, res, next) => {
9392
const bucketingKeyValidation = req.query['bucketing-key'] !== undefined ? keyValidator(req.query['bucketing-key'], 'bucketing-key') : null;
9493
const flagSetNameValidation = flagSetsValidator(req.query['flag-sets']);
9594
const attributesValidation = attributesValidator(req.query.attributes);
96-
const optionsValidation = validateEvaluationOptions(req.query.options);
95+
const optionsValidation = propertiesValidator(req.query.options);
9796

9897
const error = parseValidators([matchingKeyValidation, bucketingKeyValidation, flagSetNameValidation, attributesValidation, optionsValidation]);
9998
if (error.length) {
@@ -158,7 +157,7 @@ const trackValidation = (req, res, next) => {
158157
const allTreatmentValidation = (req, res, next) => {
159158
const keysValidation = keysValidator(req.query.keys);
160159
const attributesValidation = attributesValidator(req.query.attributes);
161-
const optionsValidation = validateEvaluationOptions(req.query.options);
160+
const optionsValidation = propertiesValidator(req.query.options);
162161

163162
const error = parseValidators([keysValidation, attributesValidation, optionsValidation]);
164163
if (error.length) {

utils/inputValidation/__tests__/evaluationOptions.test.js

Lines changed: 0 additions & 57 deletions
This file was deleted.

utils/inputValidation/__tests__/properties.test.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ const propertiesValidator = require('../properties');
22

33
describe('properties validator', () => {
44
test('should return error on invalid properties', done => {
5-
const expected = 'properties must be a plain object.';
5+
const expected = 'Input must be a plain object.';
66

77
const result = propertiesValidator('test');
88

@@ -13,7 +13,7 @@ describe('properties validator', () => {
1313
});
1414

1515
test('should return error on invalid properties 2', done => {
16-
const expected = 'properties must be a plain object.';
16+
const expected = 'Input must be a plain object.';
1717

1818
const result = propertiesValidator('[]');
1919

@@ -24,7 +24,7 @@ describe('properties validator', () => {
2424
});
2525

2626
test('should return error on invalid properties 3', done => {
27-
const expected = 'properties must be a plain object.';
27+
const expected = 'Input must be a plain object.';
2828

2929
const result = propertiesValidator('true');
3030

utils/inputValidation/evaluationOptions.js

Lines changed: 0 additions & 34 deletions
This file was deleted.
Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,40 @@
1+
const { isObject, isString } = require('../lang');
12
const errorWrapper = require('./wrapper/error');
23
const okWrapper = require('./wrapper/ok');
3-
const lang = require('../lang');
44

5-
const validateProperties = (maybeProperties) => {
5+
const allowedTypes = ['boolean', 'string', 'number'];
6+
7+
function validatePropertiesObject(obj) {
8+
if (!isObject(obj)) return false;
9+
return Object.values(obj).every(v => allowedTypes.includes(typeof v));
10+
}
11+
12+
const validateOptionsOrProperties = (maybeInput) => {
613
// eslint-disable-next-line eqeqeq
7-
if (maybeProperties == undefined) return okWrapper(null);
14+
if (maybeInput == undefined) return okWrapper(null);
815

16+
let input;
917
try {
10-
const properties = JSON.parse(maybeProperties);
11-
return (lang.isObject(properties)) ? okWrapper(properties) : errorWrapper('properties must be a plain object.');
18+
input = isString(maybeInput) ? JSON.parse(maybeInput) : maybeInput;
19+
if (!isObject(input)) {
20+
return errorWrapper('Input must be a plain object.');
21+
}
22+
23+
if (input.properties !== undefined) {
24+
if (!validatePropertiesObject(input.properties)) {
25+
return errorWrapper('options.properties must only contain boolean, string, or number values.');
26+
}
27+
return okWrapper(input);
28+
}
29+
30+
if (validatePropertiesObject(input)) {
31+
return okWrapper(input);
32+
}
33+
34+
return errorWrapper('Input must be a plain object.');
1235
} catch (e) {
13-
return errorWrapper('properties must be a plain object.');
36+
return errorWrapper('Input must be a plain object.');
1437
}
1538
};
1639

17-
module.exports = validateProperties;
40+
module.exports = validateOptionsOrProperties;

0 commit comments

Comments
 (0)