Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 2 additions & 45 deletions client/__tests__/treatmentsByFlagSets.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const request = require('supertest');
const app = require('../../app');
const { expectError, expectErrorContaining, expectOkMultipleResults, getLongKey } = require('../../utils/testWrapper');
const { NULL_FLAG_SETS, EMPTY_FLAG_SETS } = require('../../utils/constants');
const { expectedGreenResults, expectedPurpleResults, expectedPinkResults } = require('../../utils/mocks');

jest.mock('node-fetch', () => {
return jest.fn().mockImplementation((url) => {
Expand Down Expand Up @@ -215,7 +216,7 @@ describe('get-treatments-by-sets', () => {

test('should be 400 if attributes is an invalid json (POST)', async (done) => {
const response = await request(app)
.post('/client/get-treatments-by-sets?key=test&set-name=my-experiment')
.post('/client/get-treatments-by-sets?key=test&flag-sets=my-experiment')
.set('Content-Type', 'application/json')
// eslint-disable-next-line no-useless-escape
.send('\|\\\"/regex/i') // Syntax error parsing the JSON.
Expand All @@ -225,50 +226,6 @@ describe('get-treatments-by-sets', () => {
done();
});

const expectedGreenResults = {
'test_green': {
treatment: 'on',
},
'test_color': {
treatment: 'on',
},
'test_green_config': {
treatment: 'on',
config: undefined,
},
};
const expectedPurpleResults = {
'test_purple': {
treatment: 'on',
},
'test_color': {
treatment: 'on',
},
'test_purple_config': {
treatment: 'on',
config: undefined,
},
};
const expectedPinkResults = {
'test_purple': {
treatment: 'on',
},
'test_green': {
treatment: 'on',
},
'test_color': {
treatment: 'on',
},
'test_purple_config': {
treatment: 'on',
config: undefined,
},
'test_green_config': {
treatment: 'on',
config: undefined,
},
};

test('should be 200 if is valid attributes (GET)', async (done) => {
const response = await request(app)
.get('/client/get-treatments-by-sets?key=key_green&flag-sets=set_green&attributes={"test":"test"}')
Expand Down
61 changes: 9 additions & 52 deletions client/__tests__/treatmentsWithConfigByFlagSets.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const request = require('supertest');
const app = require('../../app');
const { expectError, expectErrorContaining, expectOkMultipleResults, getLongKey } = require('../../utils/testWrapper');
const { NULL_FLAG_SETS, EMPTY_FLAG_SETS } = require('../../utils/constants');
const { expectedGreenResultsWithConfig, expectedPurpleResultsWithConfig, expectedPinkResultsWithConfig } = require('../../utils/mocks');

jest.mock('node-fetch', () => {
return jest.fn().mockImplementation((url) => {
Expand Down Expand Up @@ -204,63 +205,19 @@ describe('get-treatments-with-config-by-sets', () => {
done();
});

const expectedGreenResults = {
'test_green': {
treatment: 'on',
},
'test_color': {
treatment: 'on',
},
'test_green_config': {
treatment: 'on',
config: '{"color":"green"}',
},
};
const expectedPurpleResults = {
'test_purple': {
treatment: 'on',
},
'test_color': {
treatment: 'on',
},
'test_purple_config': {
treatment: 'on',
config: '{"color":"purple"}',
},
};
const expectedPinkResults = {
'test_purple': {
treatment: 'on',
},
'test_green': {
treatment: 'on',
},
'test_color': {
treatment: 'on',
},
'test_purple_config': {
treatment: 'on',
config: '{"color":"purple"}',
},
'test_green_config': {
treatment: 'on',
config: '{"color":"green"}',
},
};

test('should be 200 if is valid attributes (GET)', async (done) => {
const response = await request(app)
.get('/client/get-treatments-with-config-by-sets?key=key_green&flag-sets=set_green&attributes={"test":"test"}')
.set('Authorization', 'key_green');
expectOkMultipleResults(response, 200, expectedGreenResults, 3);
expectOkMultipleResults(response, 200, expectedGreenResultsWithConfig, 3);
done();
});

test('should be 200 when attributes is null (GET)', async (done) => {
const response = await request(app)
.get('/client/get-treatments-with-config-by-sets?key=key_green&flag-sets=set_green')
.set('Authorization', 'key_green');
expectOkMultipleResults(response, 200, expectedGreenResults, 3);
expectOkMultipleResults(response, 200, expectedGreenResultsWithConfig, 3);
done();
});

Expand All @@ -269,7 +226,7 @@ describe('get-treatments-with-config-by-sets', () => {
.post('/client/get-treatments-with-config-by-sets?key=key_green&flag-sets=set_green')
.send({attributes: { test:'test' }})
.set('Authorization', 'key_green');
expectOkMultipleResults(response, 200, expectedGreenResults, 3);
expectOkMultipleResults(response, 200, expectedGreenResultsWithConfig, 3);
done();
});

Expand All @@ -278,7 +235,7 @@ describe('get-treatments-with-config-by-sets', () => {
.get('/client/get-treatments-with-config-by-sets?key=key_green&flag-sets=set_green&attributes={"test":"test"}')
.send(JSON.stringify({attributes: { test:'test' }}))
.set('Authorization', 'key_green');
expectOkMultipleResults(response, 200, expectedGreenResults, 3);
expectOkMultipleResults(response, 200, expectedGreenResultsWithConfig, 3);
done();
});

Expand All @@ -289,31 +246,31 @@ describe('get-treatments-with-config-by-sets', () => {
attributes: null,
})
.set('Authorization', 'key_green');
expectOkMultipleResults(response, 200, expectedGreenResults, 3);
expectOkMultipleResults(response, 200, expectedGreenResultsWithConfig, 3);
done();
});

test('should be 200 with multiple evaluation but evualuate configured flag sets', async (done) => {
const response = await request(app)
.get('/client/get-treatments-with-config-by-sets?key=key_green&flag-sets=set_green,set_purple,nonexistant-experiment')
.set('Authorization', 'key_green');
expectOkMultipleResults(response, 200, expectedGreenResults, 3);
expectOkMultipleResults(response, 200, expectedGreenResultsWithConfig, 3);
done();
});

test('should be 200 with multiple evaluation but evualuate configured flag sets', async (done) => {
const response = await request(app)
.get('/client/get-treatments-with-config-by-sets?key=key_purple&flag-sets=set_green,set_purple,nonexistant-experiment')
.set('Authorization', 'key_purple');
expectOkMultipleResults(response, 200, expectedPurpleResults, 3);
expectOkMultipleResults(response, 200, expectedPurpleResultsWithConfig, 3);
done();
});

test('should be 200 with multiple evaluation but evualuate configured flag sets', async (done) => {
const response = await request(app)
.get('/client/get-treatments-with-config-by-sets?key=key_purple&flag-sets=set_green,set_purple,nonexistant-experiment')
.set('Authorization', 'key_pink');
expectOkMultipleResults(response, 200, expectedPinkResults, 5);
expectOkMultipleResults(response, 200, expectedPinkResultsWithConfig, 5);
done();
});
});
4 changes: 2 additions & 2 deletions client/client.router.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const express = require('express');
const router = express.Router();
const keyValidator = require('../utils/inputValidation/key');
const splitValidator = require('../utils/inputValidation/split');
const flagSetValidator = require('../utils/inputValidation/flagSet');
const flagSetsValidator = require('../utils/inputValidation/flagSets');
const splitsValidator = require('../utils/inputValidation/splits');
const attributesValidator = require('../utils/inputValidation/attributes');
const trafficTypeValidator = require('../utils/inputValidation/trafficType');
Expand Down Expand Up @@ -86,7 +86,7 @@ const treatmentsValidation = (req, res, next) => {
const flagSetsValidation = (req, res, next) => {
const matchingKeyValidation = keyValidator(req.query.key, 'key');
const bucketingKeyValidation = req.query['bucketing-key'] !== undefined ? keyValidator(req.query['bucketing-key'], 'bucketing-key') : null;
const flagSetNameValidation = flagSetValidator(req.query['flag-sets']);
const flagSetNameValidation = flagSetsValidator(req.query['flag-sets']);
const attributesValidation = attributesValidator(req.query.attributes);

const error = parseValidators([matchingKeyValidation, bucketingKeyValidation, flagSetNameValidation, attributesValidation]);
Expand Down
3 changes: 3 additions & 0 deletions utils/constants.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
const TRIMMABLE_SPACES_REGEX = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/;

const EMPTY_FLAG_SETS = 'you passed an empty flag-sets, flag-sets must be a non-empty array.';
const NULL_FLAG_SETS = 'you passed a null or undefined flag-sets, flag-sets must be a non-empty array.';

module.exports = {
TRIMMABLE_SPACES_REGEX,
EMPTY_FLAG_SETS,
NULL_FLAG_SETS,
};
9 changes: 4 additions & 5 deletions utils/inputValidation/flagSet.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
const { NULL_FLAG_SETS, EMPTY_FLAG_SETS } = require('../constants');
const errorWrapper = require('./wrapper/error');
const okWrapper = require('./wrapper/ok');
const TRIMMABLE_SPACES_REGEX = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/;
const { NULL_FLAG_SET, EMPTY_FLAG_SET, TRIMMABLE_SPACES_REGEX } = require('../constants');

const validateFlagSet = (maybeFlagSet) => {
// eslint-disable-next-line
if (maybeFlagSet == undefined) return errorWrapper(NULL_FLAG_SETS);
if (maybeFlagSet == undefined) return errorWrapper(NULL_FLAG_SET);

if (TRIMMABLE_SPACES_REGEX.test(maybeFlagSet)) {
console.log(`flag-sets "${maybeFlagSet}" has extra whitespace, trimming.`);
maybeFlagSet = maybeFlagSet.trim();
}
if (maybeFlagSet.length === 0) return errorWrapper(EMPTY_FLAG_SETS);
if (maybeFlagSet.length === 0) return errorWrapper(EMPTY_FLAG_SET);

return okWrapper(maybeFlagSet.split(','));
return okWrapper(maybeFlagSet);
};

module.exports = validateFlagSet;
28 changes: 28 additions & 0 deletions utils/inputValidation/flagSets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const errorWrapper = require('./wrapper/error');
const okWrapper = require('./wrapper/ok');
const lang = require('../lang');
const validateFlagSet = require('./flagSet');
const { EMPTY_FLAG_SETS, NULL_FLAG_SETS } = require('../constants');

const validateFlagSets = (maybeFlagSets) => {
// eslint-disable-next-line eqeqeq
if (maybeFlagSets == undefined) return errorWrapper(NULL_FLAG_SETS);

maybeFlagSets = maybeFlagSets.split(',');

if (maybeFlagSets.length > 0) {
let validatedArray = [];
Comment thread
mmelograno marked this conversation as resolved.
// Remove invalid values
maybeFlagSets.forEach(maybeFlagSet => {
const flagSetValidation = validateFlagSet(maybeFlagSet);
if (flagSetValidation.valid) validatedArray.push(flagSetValidation.value);
});

// Strip off duplicated values if we have valid flag sets then return
if (validatedArray.length) return okWrapper(lang.uniq(validatedArray));
}

return errorWrapper(EMPTY_FLAG_SETS);
};

module.exports = validateFlagSets;
2 changes: 1 addition & 1 deletion utils/inputValidation/split.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const errorWrapper = require('./wrapper/error');
const okWrapper = require('./wrapper/ok');
const TRIMMABLE_SPACES_REGEX = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/;
const { TRIMMABLE_SPACES_REGEX } = require('../constants');

const validateSplit = (maybeSplit) => {
// eslint-disable-next-line eqeqeq
Expand Down
68 changes: 67 additions & 1 deletion utils/mocks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,70 @@ const integrations = [{
type: 'GOOGLE_ANALYTICS_TO_SPLIT',
}];

module.exports = { core, scheduler, urls, startup, storage, sync, integrations, apiKeyMocksMap };
const expectedGreenResults = {
'test_green': {
treatment: 'on',
},
'test_color': {
treatment: 'on',
},
'test_green_config': {
treatment: 'on',
},
};
const expectedPurpleResults = {
'test_purple': {
treatment: 'on',
},
'test_color': {
treatment: 'on',
},
'test_purple_config': {
treatment: 'on',
},
};
const expectedPinkResults = {
...expectedGreenResults,
...expectedPurpleResults,
};

const expectedGreenResultsWithConfig = {
'test_green': {
treatment: 'on',
},
'test_color': {
treatment: 'on',
},
'test_green_config': {
treatment: 'on',
config: '{"color":"green"}',
},
};

const expectedPurpleResultsWithConfig = {
'test_purple': {
treatment: 'on',
},
'test_color': {
treatment: 'on',
},
'test_purple_config': {
treatment: 'on',
config: '{"color":"purple"}',
},
};

const expectedPinkResultsWithConfig = {
...expectedGreenResultsWithConfig,
...expectedPurpleResultsWithConfig,
};

module.exports = {
core, scheduler, urls, startup, storage, sync, integrations, apiKeyMocksMap,
expectedGreenResults,
expectedPurpleResults,
expectedPinkResults,
expectedGreenResultsWithConfig,
expectedPurpleResultsWithConfig,
expectedPinkResultsWithConfig,
};