Skip to content

Commit c35fd4c

Browse files
authored
Merge branch 'master' into zeeshan/multi-package-unit-tests
2 parents 7da929f + 6999786 commit c35fd4c

File tree

23 files changed

+682
-430
lines changed

23 files changed

+682
-430
lines changed

.eslintrc.js

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

.travis.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ after_success: npm run coveralls
2626

2727
# Integration tests need to run first to reset the PR build status to pending
2828
stages:
29+
- 'Lint'
2930
- 'Integration tests'
3031
- 'Benchmarking tests'
3132
- 'Cross-browser and umd unit tests'
@@ -34,6 +35,9 @@ stages:
3435

3536
jobs:
3637
include:
38+
- stage: 'Lint'
39+
node_js: '12'
40+
script: npm run lint
3741
- &integrationtest
3842
stage: 'Integration tests'
3943
merge_mode: replace

packages/optimizely-sdk/.eslintignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
*.tests.js
2+
*.umdtests.js
3+
test_data.js

packages/optimizely-sdk/.eslintrc.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module.exports = {
2+
env: {
3+
browser: true,
4+
commonjs: true,
5+
node: true,
6+
},
7+
extends: 'eslint:recommended',
8+
globals: {
9+
Atomics: 'readonly',
10+
SharedArrayBuffer: 'readonly',
11+
Promise: 'readonly',
12+
},
13+
parserOptions: {
14+
ecmaVersion: 5,
15+
},
16+
rules: {
17+
'no-prototype-builtins': 'off',
18+
},
19+
};

packages/optimizely-sdk/CHANGELOG.MD

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
77
## [Unreleased]
88
Changes that have landed but are not yet released.
99

10+
## [3.4.0-beta] - December 18th, 2019
11+
### Bug fixes
12+
- Fixed incorrect payload for decision notification triggered by calling getVariation on a feature test in a mutex group([#375](https://github.com/optimizely/javascript-sdk/pull/375))
13+
14+
### New Features
15+
16+
- Added a new API to get a project configuration static data.
17+
- Call `getOptimizelyConfig()` to get a snapshot copy of project configuration static data.
18+
- It returns an `OptimizelyConfig` instance which includes a datafile revision number, all experiments, and feature flags mapped by their key values.
19+
- For details, refer to a documention page: https://docs.developers.optimizely.com/full-stack/docs/optimizelyconfig-javascript-node
20+
1021
## [3.3.2] - November 14th, 2019
1122
### Bug fixes
1223
- Fixed error message that was being logged when a user was bucketed into empty space in an experiment or a mutual exclusion group. This is not an error. With the fix, the message indicates that the user was not included in any experiment ([#366](https://github.com/optimizely/javascript-sdk/pull/366)).

packages/optimizely-sdk/lib/core/custom_attribute_condition_evaluator/index.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ var LOG_LEVEL = enums.LOG_LEVEL;
2222
var LOG_MESSAGES = enums.LOG_MESSAGES;
2323
var MODULE_NAME = 'CUSTOM_ATTRIBUTE_CONDITION_EVALUATOR';
2424

25-
var CUSTOM_ATTRIBUTE_CONDITION_TYPE = 'custom_attribute';
26-
2725
var EXACT_MATCH_TYPE = 'exact';
2826
var EXISTS_MATCH_TYPE = 'exists';
2927
var GREATER_THAN_MATCH_TYPE = 'gt';

packages/optimizely-sdk/lib/core/decision_service/index.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,24 +67,24 @@ DecisionService.prototype.getVariation = function(configObj, experimentKey, user
6767
// by default, the bucketing ID should be the user ID
6868
var bucketingId = this._getBucketingId(userId, attributes);
6969

70-
if (!this.__checkIfExperimentIsActive(configObj, experimentKey, userId)) {
70+
if (!this.__checkIfExperimentIsActive(configObj, experimentKey)) {
7171
return null;
7272
}
7373
var experiment = configObj.experimentKeyMap[experimentKey];
7474
var forcedVariationKey = this.getForcedVariation(configObj, experimentKey, userId);
75-
if (!!forcedVariationKey) {
75+
if (forcedVariationKey) {
7676
return forcedVariationKey;
7777
}
7878

7979
var variation = this.__getWhitelistedVariation(experiment, userId);
80-
if (!!variation) {
80+
if (variation) {
8181
return variation.key;
8282
}
8383

8484
// check for sticky bucketing
8585
var experimentBucketMap = this.__resolveExperimentBucketMap(userId, attributes);
8686
variation = this.__getStoredVariation(configObj, experiment, userId, experimentBucketMap);
87-
if (!!variation) {
87+
if (variation) {
8888
this.logger.log(LOG_LEVEL.INFO, sprintf(LOG_MESSAGES.RETURNING_STORED_VARIATION, MODULE_NAME, variation.key, experimentKey, userId));
8989
return variation.key;
9090
}
@@ -127,7 +127,7 @@ DecisionService.prototype.__resolveExperimentBucketMap = function(userId, attrib
127127
* @param {string} userId ID of user
128128
* @return {boolean} True if experiment is running
129129
*/
130-
DecisionService.prototype.__checkIfExperimentIsActive = function(configObj, experimentKey, userId) {
130+
DecisionService.prototype.__checkIfExperimentIsActive = function(configObj, experimentKey) {
131131
if (!projectConfig.isActive(configObj, experimentKey)) {
132132
var experimentNotRunningLogMessage = sprintf(LOG_MESSAGES.EXPERIMENT_NOT_RUNNING, MODULE_NAME, experimentKey);
133133
this.logger.log(LOG_LEVEL.INFO, experimentNotRunningLogMessage);

packages/optimizely-sdk/lib/core/decision_service/index.tests.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -404,12 +404,12 @@ describe('lib/core/decision_service', function() {
404404

405405
describe('__checkIfExperimentIsActive', function () {
406406
it('should return true if experiment is running', function () {
407-
assert.isTrue(decisionServiceInstance.__checkIfExperimentIsActive(configObj, 'testExperiment', 'testUser'));
407+
assert.isTrue(decisionServiceInstance.__checkIfExperimentIsActive(configObj, 'testExperiment'));
408408
sinon.assert.notCalled(mockLogger.log);
409409
});
410410

411411
it('should return false when experiment is not running', function () {
412-
assert.isFalse(decisionServiceInstance.__checkIfExperimentIsActive(configObj, 'testExperimentNotRunning', 'testUser'));
412+
assert.isFalse(decisionServiceInstance.__checkIfExperimentIsActive(configObj, 'testExperimentNotRunning'));
413413
sinon.assert.calledOnce(mockLogger.log);
414414
var logMessage = mockLogger.log.args[0][1];
415415
assert.strictEqual(logMessage, sprintf(LOG_MESSAGES.EXPERIMENT_NOT_RUNNING, 'DECISION_SERVICE', 'testExperimentNotRunning'));

packages/optimizely-sdk/lib/core/optimizely_config/index.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ function getExperimentsMap(configObj) {
5555
// Merges feature key and type from feature variables to variation variables.
5656
function getMergedVariablesMap(configObj, variation, experimentId, featureVariablesMap) {
5757
var featureId = configObj.experimentFeatureMap[experimentId];
58-
variablesObject = {};
58+
var variablesObject = {};
5959
if (featureId) {
60-
experimentFeatureVariables = featureVariablesMap[featureId];
60+
var experimentFeatureVariables = featureVariablesMap[featureId];
6161
// Temporary variation variables map to get values to merge.
6262
var tempVariablesIdMap = variation.variables.reduce(function(variablesMap, variable) {
6363
variablesMap[variable.id] = {
@@ -67,16 +67,16 @@ function getMergedVariablesMap(configObj, variation, experimentId, featureVariab
6767
return variablesMap;
6868
}, {});
6969
variablesObject = experimentFeatureVariables.reduce(function(variablesMap, featureVariable) {
70-
variationVariable = tempVariablesIdMap[featureVariable.id];
71-
variableValue = variation.featureEnabled && variationVariable ? variationVariable.value : featureVariable.defaultValue;
70+
var variationVariable = tempVariablesIdMap[featureVariable.id];
71+
var variableValue = variation.featureEnabled && variationVariable ? variationVariable.value : featureVariable.defaultValue;
7272
variablesMap[featureVariable.key] = {
7373
id: featureVariable.id,
7474
key: featureVariable.key,
7575
type: featureVariable.type,
7676
value: variableValue,
7777
};
7878
return variablesMap;
79-
}, {})
79+
}, {});
8080
}
8181
return variablesObject;
8282
}
@@ -98,7 +98,7 @@ function getFeaturesMap(configObj, allExperiments) {
9898
key: variable.key,
9999
type: variable.type,
100100
value: variable.defaultValue,
101-
}
101+
};
102102
return variables;
103103
}, {}),
104104
};
@@ -111,9 +111,9 @@ module.exports = {
111111
// Fetch all feature variables from feature flags to merge them with variation variables
112112
var experimentsMap = getExperimentsMap(configObj);
113113
return {
114-
experimentsMap,
114+
experimentsMap: experimentsMap,
115115
featuresMap: getFeaturesMap(configObj, experimentsMap),
116116
revision: configObj.revision,
117-
}
117+
};
118118
},
119119
};

packages/optimizely-sdk/lib/core/project_config/index.js

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,16 +98,15 @@ module.exports = {
9898
fns.forEach(feature.experimentIds || [], function(experimentId) {
9999
// Add this experiment in experiment-feature map.
100100
if (projectConfig.experimentFeatureMap[experimentId]) {
101-
projectConfig.experimentFeatureMap[experimentId].push(feature.id);
101+
projectConfig.experimentFeatureMap[experimentId].push(feature.id);
102102
} else {
103103
projectConfig.experimentFeatureMap[experimentId] = [feature.id];
104104
}
105-
105+
106106
var experimentInFeature = projectConfig.experimentIdMap[experimentId];
107-
if (experimentInFeature.groupId) {
107+
// Experiments in feature can only belong to one mutex group.
108+
if (experimentInFeature.groupId && !feature.groupId) {
108109
feature.groupId = experimentInFeature.groupId;
109-
// Experiments in feature can only belong to one mutex group.
110-
return false;
111110
}
112111
});
113112
});
@@ -272,7 +271,7 @@ module.exports = {
272271
getExperimentFromKey: function(projectConfig, experimentKey) {
273272
if (projectConfig.experimentKeyMap.hasOwnProperty(experimentKey)) {
274273
var experiment = projectConfig.experimentKeyMap[experimentKey];
275-
if (!!experiment) {
274+
if (experiment) {
276275
return experiment;
277276
}
278277
}
@@ -305,7 +304,7 @@ module.exports = {
305304
getExperimentFromId: function(projectConfig, experimentId, logger) {
306305
if (projectConfig.experimentIdMap.hasOwnProperty(experimentId)) {
307306
var experiment = projectConfig.experimentIdMap[experimentId];
308-
if (!!experiment) {
307+
if (experiment) {
309308
return experiment;
310309
}
311310
}
@@ -326,7 +325,7 @@ module.exports = {
326325
getFeatureFromKey: function(projectConfig, featureKey, logger) {
327326
if (projectConfig.featureKeyMap.hasOwnProperty(featureKey)) {
328327
var feature = projectConfig.featureKeyMap[featureKey];
329-
if (!!feature) {
328+
if (feature) {
330329
return feature;
331330
}
332331
}

packages/optimizely-sdk/lib/core/project_config/index.tests.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,28 @@ describe('lib/core/project_config', function() {
559559
assert.deepEqual(result, ['and', ['or', '3468206642', '3988293898'], ['or', '3988293899', '3468206646', '3468206647', '3468206644', '3468206643']]);
560560
});
561561
});
562+
563+
describe('#isFeatureExperiment', function() {
564+
it('returns true for a feature test', function() {
565+
var config = projectConfig.createProjectConfig(testDatafile.getTestProjectConfigWithFeatures());
566+
var result = projectConfig.isFeatureExperiment(config, '594098'); // id of 'testing_my_feature'
567+
assert.isTrue(result);
568+
});
569+
570+
it('returns false for an A/B test', function() {
571+
var config = projectConfig.createProjectConfig(testDatafile.getTestProjectConfig());
572+
var result = projectConfig.isFeatureExperiment(config, '111127'); // id of 'testExperiment'
573+
assert.isFalse(result);
574+
});
575+
576+
it('returns true for a feature test in a mutex group', function() {
577+
var config = projectConfig.createProjectConfig(testDatafile.getMutexFeatureTestsConfig());
578+
var result = projectConfig.isFeatureExperiment(config, '17128410791'); // id of 'f_test1'
579+
assert.isTrue(result);
580+
result = projectConfig.isFeatureExperiment(config, '17139931304'); // id of 'f_test2'
581+
assert.isTrue(result);
582+
});
583+
});
562584
});
563585

564586
describe('#tryCreatingProjectConfig', function() {

packages/optimizely-sdk/lib/index.browser.tests.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ describe('javascript-sdk', function() {
148148
optlyInstance.onReady().catch(function() {});
149149

150150
assert.instanceOf(optlyInstance, Optimizely);
151-
assert.equal(optlyInstance.clientVersion, '3.3.2');
151+
assert.equal(optlyInstance.clientVersion, '3.4.0-beta');
152152
});
153153

154154
it('should set the JavaScript client engine and version', function() {

packages/optimizely-sdk/lib/index.node.tests.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ describe('optimizelyFactory', function() {
9292
optlyInstance.onReady().catch(function() {});
9393

9494
assert.instanceOf(optlyInstance, Optimizely);
95-
assert.equal(optlyInstance.clientVersion, '3.3.2');
95+
assert.equal(optlyInstance.clientVersion, '3.4.0-beta');
9696
});
9797

9898
describe('event processor configuration', function() {

packages/optimizely-sdk/lib/index.react_native.tests.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ describe('javascript-sdk/react-native', function() {
9191
optlyInstance.onReady().catch(function() {});
9292

9393
assert.instanceOf(optlyInstance, Optimizely);
94-
assert.equal(optlyInstance.clientVersion, '3.3.2');
94+
assert.equal(optlyInstance.clientVersion, '3.4.0-beta');
9595
});
9696

9797
it('should set the JavaScript client engine and version', function() {

packages/optimizely-sdk/lib/optimizely/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,7 @@ Optimizely.prototype.isFeatureEnabled = function(featureKey, userId, attributes)
562562
var variation = decision.variation;
563563
var sourceInfo = {};
564564

565-
if (!!variation) {
565+
if (variation) {
566566
featureEnabled = variation.featureEnabled;
567567
if (decision.decisionSource === DECISION_SOURCES.FEATURE_TEST) {
568568
sourceInfo = {

packages/optimizely-sdk/lib/plugins/error_handler/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ module.exports = {
2222
* Handle given exception
2323
* @param {Object} exception An exception object
2424
*/
25-
handleError: function(exception) {
25+
handleError: function() {
2626
// no-op
2727
}
2828
};

packages/optimizely-sdk/lib/plugins/event_dispatcher/index.browser.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@ module.exports = {
2929
dispatchEvent: function(eventObj, callback) {
3030
var url = eventObj.url;
3131
var params = eventObj.params;
32+
var req;
3233
if (eventObj.httpVerb === POST_METHOD) {
33-
var req = new XMLHttpRequest();
34+
req = new XMLHttpRequest();
3435
req.open(POST_METHOD, url, true);
3536
req.setRequestHeader('Content-Type', 'application/json');
3637
req.onreadystatechange = function() {
@@ -50,7 +51,7 @@ module.exports = {
5051
url += '&' + toQueryString(params);
5152
}
5253

53-
var req = new XMLHttpRequest();
54+
req = new XMLHttpRequest();
5455
req.open(GET_METHOD, url, true);
5556
req.onreadystatechange = function() {
5657
if (req.readyState === READYSTATE_COMPLETE && callback && typeof callback === 'function') {

packages/optimizely-sdk/lib/plugins/event_dispatcher/index.node.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,6 @@ module.exports = {
3434
}
3535

3636
var parsedUrl = url.parse(eventObj.url);
37-
var path = parsedUrl.path;
38-
if (parsedUrl.query) {
39-
path += '?' + parsedUrl.query;
40-
}
4137

4238
var dataString = JSON.stringify(eventObj.params);
4339

0 commit comments

Comments
 (0)