Skip to content

Commit c09b87d

Browse files
committed
Addressing feedback and adding tests
1 parent a5032f2 commit c09b87d

File tree

6 files changed

+138
-19
lines changed

6 files changed

+138
-19
lines changed

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/****************************************************************************
2-
* Copyright 2017, Optimizely, Inc. and contributors *
2+
* Copyright 2017-2018, Optimizely, Inc. and contributors *
33
* *
44
* Licensed under the Apache License, Version 2.0 (the "License"); *
55
* you may not use this file except in compliance with the License. *
@@ -26,7 +26,6 @@ var MODULE_NAME = 'DECISION_SERVICE';
2626
var ERROR_MESSAGES = enums.ERROR_MESSAGES;
2727
var LOG_LEVEL = enums.LOG_LEVEL;
2828
var LOG_MESSAGES = enums.LOG_MESSAGES;
29-
var RESERVED_ATTRIBUTE_KEY_BUCKETING_ID = '$opt_bucketing_id';
3029
var DECISION_SOURCES = enums.DECISION_SOURCES;
3130

3231

@@ -67,8 +66,8 @@ DecisionService.prototype.getVariation = function(experimentKey, userId, attribu
6766

6867
// If the bucketing ID key is defined in attributes, than use that in place of the userID for the murmur hash key
6968
if (!fns.isEmpty(attributes)) {
70-
if (attributes.hasOwnProperty(RESERVED_ATTRIBUTE_KEY_BUCKETING_ID)) {
71-
bucketingId = attributes[RESERVED_ATTRIBUTE_KEY_BUCKETING_ID];
69+
if (attributes.hasOwnProperty(enums.RESERVED_ATTRIBUTES.BUCKETING_ID)) {
70+
bucketingId = attributes[enums.RESERVED_ATTRIBUTES.BUCKETING_ID];
7271
this.logger.log(LOG_LEVEL.DEBUG, sprintf('Setting the bucketing ID to %s.', bucketingId))
7372
}
7473
}

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

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,10 @@ var eventTagUtils = require('../../utils/event_tag_utils');
1919
var projectConfig = require('../project_config');
2020

2121
var ACTIVATE_EVENT_KEY = 'campaign_activated';
22-
var BOT_FILTERING_FEATURE_KEY = '$opt_bot_filtering';
2322
var CUSTOM_ATTRIBUTE_FEATURE_TYPE = 'custom';
2423
var ENDPOINT = 'https://logx.optimizely.com/v1/events';
2524
var HTTP_VERB = 'POST';
2625

27-
2826
/**
2927
* Get params which are used same in both conversion and impression events
3028
* @param {Object} options.attributes Object representing user attributes and values which need to be recorded
@@ -68,20 +66,13 @@ function getCommonEventParams(options) {
6866
type: CUSTOM_ATTRIBUTE_FEATURE_TYPE,
6967
value: attributes[attributeKey],
7068
});
71-
} else if (enums.RESERVED_ATTRIBUTES.hasOwnProperty(attributeKey)) {
72-
commonParams.visitors[0].attributes.push({
73-
entity_id: attributeKey,
74-
key: attributeKey,
75-
type: CUSTOM_ATTRIBUTE_FEATURE_TYPE,
76-
value: attributes[attributeKey],
77-
});
7869
}
7970
});
8071

8172
if (typeof botFiltering === 'boolean') {
8273
commonParams.visitors[0].attributes.push({
83-
entity_id: BOT_FILTERING_FEATURE_KEY,
84-
key: BOT_FILTERING_FEATURE_KEY,
74+
entity_id: enums.RESERVED_ATTRIBUTES.BOT_FILTERING,
75+
key: enums.RESERVED_ATTRIBUTES.BOT_FILTERING,
8576
type: CUSTOM_ATTRIBUTE_FEATURE_TYPE,
8677
value: botFiltering,
8778
});

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

Lines changed: 123 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2016-2017, Optimizely
2+
* Copyright 2016-2018, Optimizely
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -285,6 +285,63 @@ describe('lib/core/event_builder', function() {
285285

286286
assert.deepEqual(actualParams, expectedParams);
287287
});
288+
289+
it('should fill in userFeatures for user agent and bot filtering', function() {
290+
var v4ConfigObj = projectConfig.createProjectConfig(testData.getTestProjectConfigWithFeatures());
291+
var expectedParams = {
292+
url: 'https://logx.optimizely.com/v1/events',
293+
httpVerb: 'POST',
294+
params: {
295+
'account_id': '572018',
296+
'project_id': '594001',
297+
'visitors': [{
298+
'attributes': [{
299+
'entity_id': '$opt_user_agent',
300+
'key': '$opt_user_agent',
301+
'type': 'custom',
302+
'value': 'Chrome'
303+
}, {
304+
'entity_id': '$opt_bot_filtering',
305+
'key': '$opt_bot_filtering',
306+
'type': 'custom',
307+
'value': true
308+
}],
309+
'visitor_id': 'testUser',
310+
'snapshots': [{
311+
'decisions': [{
312+
'variation_id': '595008',
313+
'experiment_id': '595010',
314+
'campaign_id': '595005'
315+
}],
316+
'events': [{
317+
'timestamp': Math.round(new Date().getTime()),
318+
'entity_id': '595005',
319+
'uuid': 'a68cf1ad-0393-4e18-af87-efe8f01a7c9c',
320+
'key': 'campaign_activated'
321+
}]
322+
}]
323+
}],
324+
'revision': '35',
325+
'client_name': 'node-sdk',
326+
'client_version': packageJSON.version,
327+
'anonymize_ip': true,
328+
}
329+
};
330+
331+
var eventOptions = {
332+
attributes: {'$opt_user_agent': 'Chrome'},
333+
clientEngine: 'node-sdk',
334+
clientVersion: packageJSON.version,
335+
configObj: v4ConfigObj,
336+
experimentId: '595010',
337+
variationId: '595008',
338+
userId: 'testUser',
339+
};
340+
341+
var actualParams = eventBuilder.getImpressionEvent(eventOptions);
342+
343+
assert.deepEqual(actualParams, expectedParams);
344+
});
288345
});
289346

290347
describe('getConversionEvent', function() {
@@ -553,6 +610,64 @@ describe('lib/core/event_builder', function() {
553610
assert.deepEqual(actualParams, expectedParams);
554611
});
555612

613+
it('should fill in userFeatures for user agent and bot filtering', function() {
614+
var v4ConfigObj = projectConfig.createProjectConfig(testData.getTestProjectConfigWithFeatures());
615+
var expectedParams = {
616+
url: 'https://logx.optimizely.com/v1/events',
617+
httpVerb: 'POST',
618+
params: {
619+
'account_id': '572018',
620+
'project_id': '594001',
621+
'visitors': [{
622+
'attributes': [{
623+
'entity_id': '$opt_user_agent',
624+
'key': '$opt_user_agent',
625+
'type': 'custom',
626+
'value': 'Chrome'
627+
}, {
628+
'entity_id': '$opt_bot_filtering',
629+
'key': '$opt_bot_filtering',
630+
'type': 'custom',
631+
'value': true
632+
}],
633+
'visitor_id': 'testUser',
634+
'snapshots': [{
635+
'decisions': [{
636+
'variation_id': '595008',
637+
'experiment_id': '595010',
638+
'campaign_id': '595005'
639+
}],
640+
'events': [{
641+
'timestamp': Math.round(new Date().getTime()),
642+
'entity_id': '594089',
643+
'uuid': 'a68cf1ad-0393-4e18-af87-efe8f01a7c9c',
644+
'key': 'item_bought'
645+
}]
646+
}]
647+
}],
648+
'revision': '35',
649+
'client_name': 'node-sdk',
650+
'client_version': packageJSON.version,
651+
'anonymize_ip': true,
652+
}
653+
};
654+
655+
var eventOptions = {
656+
attributes: {'$opt_user_agent': 'Chrome'},
657+
clientEngine: 'node-sdk',
658+
clientVersion: packageJSON.version,
659+
configObj: v4ConfigObj,
660+
eventKey: 'item_bought',
661+
logger: mockLogger,
662+
experimentsToVariationMap: { '595010': '595008' },
663+
userId: 'testUser',
664+
};
665+
666+
var actualParams = eventBuilder.getConversionEvent(eventOptions);
667+
668+
assert.deepEqual(actualParams, expectedParams);
669+
});
670+
556671
describe('and event tags are passed it', function() {
557672
it('should create proper params for getConversionEvent with event tags', function() {
558673
var expectedParams = {
@@ -851,7 +966,12 @@ describe('lib/core/event_builder', function() {
851966
'project_id': '111001',
852967
'visitors': [{
853968
'visitor_id': 'testUser',
854-
'attributes': [],
969+
'attributes': [{
970+
'entity_id': '$opt_bucketing_id',
971+
'key': '$opt_bucketing_id',
972+
'type': 'custom',
973+
'value': 'variation',
974+
}],
855975
'snapshots': [{
856976
'decisions': [{
857977
'variation_id': '111128',
@@ -881,7 +1001,7 @@ describe('lib/core/event_builder', function() {
8811001
experimentsToVariationMap: {'111127': '111128'},
8821002
logger: mockLogger,
8831003
userId: 'testUser',
884-
attributes: {'Optimizely Bucketing ID': 'variation'},
1004+
attributes: {'$opt_bucketing_id': 'variation'},
8851005
};
8861006

8871007
var actualParams = eventBuilder.getConversionEvent(eventOptions);

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ module.exports = {
138138
var attribute = projectConfig.attributeKeyMap[attributeKey];
139139
if (attribute) {
140140
return attribute.id;
141+
} else if (enums.RESERVED_USER_ATTRIBUTES.indexOf(attributeKey) !== -1) {
142+
return attributeKey;
141143
}
142144
return null;
143145
},

packages/optimizely-sdk/lib/tests/test_data.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2016-2017, Optimizely
2+
* Copyright 2016-2018, Optimizely
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,16 @@ exports.RESERVED_EVENT_KEYWORDS = {
129129
};
130130

131131
exports.RESERVED_ATTRIBUTES = {
132+
BOT_FILTERING: '$opt_bot_filtering',
133+
BUCKETING_ID: '$opt_bucketing_id',
132134
USER_AGENT: '$opt_user_agent',
133135
};
134136

137+
exports.RESERVED_USER_ATTRIBUTES = [
138+
exports.RESERVED_ATTRIBUTES.BUCKETING_ID,
139+
exports.RESERVED_ATTRIBUTES.USER_AGENT
140+
];
141+
135142
exports.JAVASCRIPT_CLIENT_ENGINE = 'javascript-sdk';
136143
exports.NODE_CLIENT_ENGINE = 'node-sdk';
137144
exports.NODE_CLIENT_VERSION = '2.0.1';

0 commit comments

Comments
 (0)