optimizely-server-sdk
Version:
Node SDK for Optimizely X Full Stack
895 lines (820 loc) • 30.4 kB
JavaScript
/**
* Copyright 2016-2017, Optimizely
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var eventBuilder = require('./index.js');
var packageJSON = require('../../../package.json');
var projectConfig = require('../project_config');
var testData = require('../../../tests/test_data');
var chai = require('chai');
var assert = chai.assert;
var sinon = require('sinon');
var uuid = require('uuid');
describe('lib/core/event_builder', function() {
describe('APIs', function() {
var configObj;
var clock;
beforeEach(function() {
configObj = projectConfig.createProjectConfig(testData.getTestProjectConfig());
clock = sinon.useFakeTimers(new Date().getTime());
sinon.stub(uuid, 'v4').returns('a68cf1ad-0393-4e18-af87-efe8f01a7c9c');
});
afterEach(function() {
clock.restore();
uuid.v4.restore();
});
describe('getImpressionEvent', function() {
it('should create proper params for getImpressionEvent without attributes', function() {
var expectedParams = {
url: 'https://logx.optimizely.com/v1/events',
httpVerb: 'POST',
params: {
'account_id': '12001',
'project_id': '111001',
'visitors': [{
'attributes': [],
'visitor_id': 'testUser',
'snapshots': [{
'decisions': [{
'variation_id': '111128',
'experiment_id': '111127',
'campaign_id': '4'
}],
'events': [{
'timestamp': Math.round(new Date().getTime()),
'entity_id': '4',
'uuid': 'a68cf1ad-0393-4e18-af87-efe8f01a7c9c',
'key': 'campaign_activated'
}]
}]
}],
'revision': '42',
'client_name': 'node-sdk',
'client_version': packageJSON.version,
'anonymize_ip': false,
}
};
var eventOptions = {
clientEngine: 'node-sdk',
clientVersion: packageJSON.version,
configObj: configObj,
experimentId: '111127',
variationId: '111128',
userId: 'testUser',
};
var actualParams = eventBuilder.getImpressionEvent(eventOptions);
assert.deepEqual(actualParams, expectedParams);
});
it('should create proper params for getImpressionEvent with attributes as a string value', function() {
var expectedParams = {
url: 'https://logx.optimizely.com/v1/events',
httpVerb: 'POST',
params: {
'account_id': '12001',
'project_id': '111001',
'visitors': [{
'attributes': [{
'entity_id': '111094',
'type': 'custom',
'value': 'firefox',
'key': 'browser_type'
}],
'visitor_id': 'testUser',
'snapshots': [{
'decisions': [{
'variation_id': '111128',
'experiment_id': '111127',
'campaign_id': '4'
}],
'events': [{
'timestamp': Math.round(new Date().getTime()),
'entity_id': '4',
'uuid': 'a68cf1ad-0393-4e18-af87-efe8f01a7c9c',
'key': 'campaign_activated'
}]
}]
}],
'revision': '42',
'client_name': 'node-sdk',
'client_version': packageJSON.version,
'anonymize_ip': false,
}
};
var eventOptions = {
attributes: {browser_type: 'firefox'},
clientEngine: 'node-sdk',
clientVersion: packageJSON.version,
configObj: configObj,
experimentId: '111127',
variationId: '111128',
userId: 'testUser',
};
var actualParams = eventBuilder.getImpressionEvent(eventOptions);
assert.deepEqual(actualParams, expectedParams);
});
it('should create proper params for getImpressionEvent with attributes as a false value', function() {
var expectedParams = {
url: 'https://logx.optimizely.com/v1/events',
httpVerb: 'POST',
params: {
'account_id': '12001',
'project_id': '111001',
'visitors': [{
'attributes': [{
'entity_id': '111094',
'type': 'custom',
'value': false,
'key': 'browser_type'
}],
'visitor_id': 'testUser',
'snapshots': [{
'decisions': [{
'variation_id': '111128',
'experiment_id': '111127',
'campaign_id': '4'
}],
'events': [{
'timestamp': Math.round(new Date().getTime()),
'entity_id': '4',
'uuid': 'a68cf1ad-0393-4e18-af87-efe8f01a7c9c',
'key': 'campaign_activated'
}]
}]
}],
'revision': '42',
'client_name': 'node-sdk',
'client_version': packageJSON.version,
'anonymize_ip': false,
}
};
var eventOptions = {
attributes: {browser_type: false},
clientEngine: 'node-sdk',
clientVersion: packageJSON.version,
configObj: configObj,
experimentId: '111127',
variationId: '111128',
userId: 'testUser',
};
var actualParams = eventBuilder.getImpressionEvent(eventOptions);
assert.deepEqual(actualParams, expectedParams);
});
it('should create proper params for getImpressionEvent with attributes as a zero value', function() {
var expectedParams = {
url: 'https://logx.optimizely.com/v1/events',
httpVerb: 'POST',
params: {
'account_id': '12001',
'project_id': '111001',
'visitors': [{
'attributes': [{
'entity_id': '111094',
'type': 'custom',
'value': 0,
'key': 'browser_type'
}],
'visitor_id': 'testUser',
'snapshots': [{
'decisions': [{
'variation_id': '111128',
'experiment_id': '111127',
'campaign_id': '4'
}],
'events': [{
'timestamp': Math.round(new Date().getTime()),
'entity_id': '4',
'uuid': 'a68cf1ad-0393-4e18-af87-efe8f01a7c9c',
'key': 'campaign_activated'
}]
}]
}],
'revision': '42',
'client_name': 'node-sdk',
'client_version': packageJSON.version,
'anonymize_ip': false,
}
};
var eventOptions = {
attributes: {browser_type: 0},
clientEngine: 'node-sdk',
clientVersion: packageJSON.version,
configObj: configObj,
experimentId: '111127',
variationId: '111128',
userId: 'testUser',
};
var actualParams = eventBuilder.getImpressionEvent(eventOptions);
assert.deepEqual(actualParams, expectedParams);
});
it('should not fill in userFeatures for getImpressionEvent when attribute is not in the datafile', function() {
var expectedParams = {
url: 'https://logx.optimizely.com/v1/events',
httpVerb: 'POST',
params: {
'account_id': '12001',
'project_id': '111001',
'visitors': [{
'attributes': [],
'visitor_id': 'testUser',
'snapshots': [{
'decisions': [{
'variation_id': '111128',
'experiment_id': '111127',
'campaign_id': '4'
}],
'events': [{
'timestamp': Math.round(new Date().getTime()),
'entity_id': '4',
'uuid': 'a68cf1ad-0393-4e18-af87-efe8f01a7c9c',
'key': 'campaign_activated'
}]
}]
}],
'revision': '42',
'client_name': 'node-sdk',
'client_version': packageJSON.version,
'anonymize_ip': false,
}
};
var eventOptions = {
attributes: {invalid_attribute: 'sorry_not_sorry'},
clientEngine: 'node-sdk',
clientVersion: packageJSON.version,
configObj: configObj,
experimentId: '111127',
variationId: '111128',
userId: 'testUser',
};
var actualParams = eventBuilder.getImpressionEvent(eventOptions);
assert.deepEqual(actualParams, expectedParams);
});
});
describe('getConversionEvent', function() {
var mockLogger;
beforeEach(function() {
mockLogger = {
log: sinon.stub(),
};
});
it('should create proper params for getConversionEvent without attributes or event value', function() {
var expectedParams = {
url: 'https://logx.optimizely.com/v1/events',
httpVerb: 'POST',
params: {
'account_id': '12001',
'project_id': '111001',
'visitors': [{
'visitor_id': 'testUser',
'attributes': [],
'snapshots': [{
'decisions': [{
'variation_id': '111128',
'experiment_id': '111127',
'campaign_id': '4'
}],
'events': [{
'timestamp': Math.round(new Date().getTime()),
'entity_id': '111095',
'uuid': 'a68cf1ad-0393-4e18-af87-efe8f01a7c9c',
'key': 'testEvent'
}]
}]
}],
'revision': '42',
'client_name': 'node-sdk',
'client_version': packageJSON.version,
'anonymize_ip': false,
}
};
var eventOptions = {
clientEngine: 'node-sdk',
clientVersion: packageJSON.version,
configObj: configObj,
eventKey: 'testEvent',
logger: mockLogger,
userId: 'testUser',
experimentsToVariationMap: { '111127': '111128' },
};
var actualParams = eventBuilder.getConversionEvent(eventOptions);
assert.deepEqual(actualParams, expectedParams);
});
it('should create proper params for getConversionEvent with attributes', function() {
var expectedParams = {
url: 'https://logx.optimizely.com/v1/events',
httpVerb: 'POST',
params: {
'account_id': '12001',
'project_id': '111001',
'visitors': [{
'visitor_id': 'testUser',
'attributes': [{
'entity_id': '111094',
'type': 'custom',
'value': 'firefox',
'key': 'browser_type'
}],
'snapshots': [{
'decisions': [{
'variation_id': '111128',
'experiment_id': '111127',
'campaign_id': '4'
}],
'events': [{
'timestamp': Math.round(new Date().getTime()),
'entity_id': '111095',
'uuid': 'a68cf1ad-0393-4e18-af87-efe8f01a7c9c',
'key': 'testEvent'
}]
}]
}],
'revision': '42',
'client_name': 'node-sdk',
'client_version': packageJSON.version,
'anonymize_ip': false,
}
};
var eventOptions = {
attributes: {browser_type: 'firefox'},
clientEngine: 'node-sdk',
clientVersion: packageJSON.version,
configObj: configObj,
eventKey: 'testEvent',
experimentsToVariationMap: { '111127': '111128' },
logger: mockLogger,
userId: 'testUser',
};
var actualParams = eventBuilder.getConversionEvent(eventOptions);
assert.deepEqual(actualParams, expectedParams);
});
it('should create proper params for getConversionEvent with event value', function() {
var expectedParams = {
url: 'https://logx.optimizely.com/v1/events',
httpVerb: 'POST',
params: {
'client_version': packageJSON.version,
'project_id': '111001',
'visitors': [{
'attributes': [],
'visitor_id': 'testUser',
'snapshots': [{
'decisions': [{
'variation_id': '111128',
'experiment_id': '111127',
'campaign_id': '4'
}],
'events': [{
'uuid': 'a68cf1ad-0393-4e18-af87-efe8f01a7c9c',
'tags': {
'revenue': 4200
},
'timestamp': Math.round(new Date().getTime()),
'revenue': 4200,
'key': 'testEvent',
'entity_id': '111095'
}]
}]
}],
'account_id': '12001',
'client_name': 'node-sdk',
'revision': '42',
'anonymize_ip': false,
}
};
var eventOptions = {
clientEngine: 'node-sdk',
clientVersion: packageJSON.version,
configObj: configObj,
eventKey: 'testEvent',
eventTags: {
revenue: 4200,
},
experimentsToVariationMap: { '111127': '111128' },
logger: mockLogger,
userId: 'testUser',
};
var actualParams = eventBuilder.getConversionEvent(eventOptions);
assert.deepEqual(actualParams, expectedParams);
});
it('should create proper params for getConversionEvent with attributes and event value', function() {
var expectedParams = {
url: 'https://logx.optimizely.com/v1/events',
httpVerb: 'POST',
params: {
'client_version': packageJSON.version,
'project_id': '111001',
'visitors': [{
'attributes': [{
'entity_id': '111094',
'type': 'custom',
'value': 'firefox',
'key': 'browser_type'
}],
'visitor_id': 'testUser',
'snapshots': [{
'decisions': [{
'variation_id': '111128',
'experiment_id': '111127',
'campaign_id': '4'
}],
'events': [{
'uuid': 'a68cf1ad-0393-4e18-af87-efe8f01a7c9c',
'tags': {
'revenue': 4200
},
'timestamp': Math.round(new Date().getTime()),
'revenue': 4200,
'key': 'testEvent',
'entity_id': '111095'
}]
}]
}],
'account_id': '12001',
'client_name': 'node-sdk',
'revision': '42',
'anonymize_ip': false,
}
};
var eventOptions = {
attributes: {browser_type: 'firefox'},
clientEngine: 'node-sdk',
clientVersion: packageJSON.version,
configObj: configObj,
eventKey: 'testEvent',
eventTags: {
revenue: 4200
},
experimentsToVariationMap: { '111127': '111128' },
logger: mockLogger,
userId: 'testUser',
};
var actualParams = eventBuilder.getConversionEvent(eventOptions);
assert.deepEqual(actualParams, expectedParams);
});
it('should not fill in userFeatures for getConversion when attribute is not in the datafile', function() {
var expectedParams = {
url: 'https://logx.optimizely.com/v1/events',
httpVerb: 'POST',
params: {
'client_version': packageJSON.version,
'project_id': '111001',
'visitors': [{
'attributes': [],
'visitor_id': 'testUser',
'snapshots': [{
'decisions': [{
'variation_id': '111128',
'experiment_id': '111127',
'campaign_id': '4'
}],
'events': [{
'uuid': 'a68cf1ad-0393-4e18-af87-efe8f01a7c9c',
'timestamp': Math.round(new Date().getTime()),
'key': 'testEvent',
'entity_id': '111095'
}]
}]
}],
'account_id': '12001',
'client_name': 'node-sdk',
'revision': '42',
'anonymize_ip': false,
}
};
var eventOptions = {
attributes: {invalid_attribute: 'sorry_not_sorry'},
clientEngine: 'node-sdk',
clientVersion: packageJSON.version,
configObj: configObj,
eventKey: 'testEvent',
experimentsToVariationMap: { '111127': '111128' },
logger: mockLogger,
userId: 'testUser',
};
var actualParams = eventBuilder.getConversionEvent(eventOptions);
assert.deepEqual(actualParams, expectedParams);
});
describe('and event tags are passed it', function() {
it('should create proper params for getConversionEvent with event tags', function() {
var expectedParams = {
url: 'https://logx.optimizely.com/v1/events',
httpVerb: 'POST',
params: {
'client_version': packageJSON.version,
'project_id': '111001',
'visitors': [{
'attributes': [],
'visitor_id': 'testUser',
'snapshots': [{
'decisions': [{
'variation_id': '111128',
'experiment_id': '111127',
'campaign_id': '4'
}],
'events': [{
'uuid': 'a68cf1ad-0393-4e18-af87-efe8f01a7c9c',
'tags': {
'non-revenue': 'cool',
},
'timestamp': Math.round(new Date().getTime()),
'key': 'testEvent',
'entity_id': '111095'
}]
}]
}],
'account_id': '12001',
'client_name': 'node-sdk',
'revision': '42',
'anonymize_ip': false,
}
};
var eventOptions = {
clientEngine: 'node-sdk',
clientVersion: packageJSON.version,
configObj: configObj,
eventKey: 'testEvent',
eventTags: {
'non-revenue': 'cool',
},
experimentsToVariationMap: { '111127': '111128' },
logger: mockLogger,
userId: 'testUser',
};
var actualParams = eventBuilder.getConversionEvent(eventOptions);
assert.deepEqual(actualParams, expectedParams);
});
describe('and the event tags contain an entry for "revenue"', function() {
it('should include the revenue value in the event object', function() {
var expectedParams = {
url: 'https://logx.optimizely.com/v1/events',
httpVerb: 'POST',
params: {
'client_version': packageJSON.version,
'project_id': '111001',
'visitors': [{
'attributes': [],
'visitor_id': 'testUser',
'snapshots': [{
'decisions': [{
'variation_id': '111128',
'experiment_id': '111127',
'campaign_id': '4'
}],
'events': [{
'uuid': 'a68cf1ad-0393-4e18-af87-efe8f01a7c9c',
'tags': {
'non-revenue': 'cool',
'revenue': 4200
},
'timestamp': Math.round(new Date().getTime()),
'revenue': 4200,
'key': 'testEvent',
'entity_id': '111095'
}]
}]
}],
'account_id': '12001',
'client_name': 'node-sdk',
'revision': '42',
'anonymize_ip': false,
}
};
var eventOptions = {
clientEngine: 'node-sdk',
clientVersion: packageJSON.version,
configObj: configObj,
eventKey: 'testEvent',
eventTags: {
'revenue': 4200,
'non-revenue': 'cool',
},
experimentsToVariationMap: { '111127': '111128' },
logger: mockLogger,
userId: 'testUser',
};
var actualParams = eventBuilder.getConversionEvent(eventOptions);
assert.deepEqual(actualParams, expectedParams);
});
describe('and the revenue value is invalid', function() {
it('should not include the revenue value in the event object', function() {
var expectedParams = {
url: 'https://logx.optimizely.com/v1/events',
httpVerb: 'POST',
params: {
'client_version': packageJSON.version,
'project_id': '111001',
'visitors': [{
'attributes': [],
'visitor_id': 'testUser',
'snapshots': [{
'decisions': [{
'variation_id': '111128',
'experiment_id': '111127',
'campaign_id': '4'
}],
'events': [{
'uuid': 'a68cf1ad-0393-4e18-af87-efe8f01a7c9c',
'tags': {
'non-revenue': 'cool',
'revenue': 'invalid revenue'
},
'timestamp': Math.round(new Date().getTime()),
'key': 'testEvent',
'entity_id': '111095'
}]
}]
}],
'account_id': '12001',
'client_name': 'node-sdk',
'revision': '42',
'anonymize_ip': false,
}
};
var eventOptions = {
clientEngine: 'node-sdk',
clientVersion: packageJSON.version,
configObj: configObj,
eventKey: 'testEvent',
eventTags: {
'revenue': 'invalid revenue',
'non-revenue': 'cool',
},
experimentsToVariationMap: { '111127': '111128' },
logger: mockLogger,
userId: 'testUser',
};
var actualParams = eventBuilder.getConversionEvent(eventOptions);
assert.deepEqual(actualParams, expectedParams);
});
});
});
describe('and the event tags contain an entry for "value"', function() {
it('should include the event value in the event object', function() {
var expectedParams = {
url: 'https://logx.optimizely.com/v1/events',
httpVerb: 'POST',
params: {
'client_version': packageJSON.version,
'project_id': '111001',
'visitors': [{
'attributes': [],
'visitor_id': 'testUser',
'snapshots': [{
'decisions': [{
'variation_id': '111128',
'experiment_id': '111127',
'campaign_id': '4'
}],
'events': [{
'uuid': 'a68cf1ad-0393-4e18-af87-efe8f01a7c9c',
'tags': {
'non-revenue': 'cool',
'value': '13.37'
},
'timestamp': Math.round(new Date().getTime()),
'value': 13.37,
'key': 'testEvent',
'entity_id': '111095'
}]
}]
}],
'account_id': '12001',
'client_name': 'node-sdk',
'revision': '42',
'anonymize_ip': false,
}
};
var eventOptions = {
clientEngine: 'node-sdk',
clientVersion: packageJSON.version,
configObj: configObj,
eventKey: 'testEvent',
eventTags: {
'value': '13.37',
'non-revenue': 'cool',
},
experimentsToVariationMap: { '111127': '111128' },
logger: mockLogger,
userId: 'testUser',
};
var actualParams = eventBuilder.getConversionEvent(eventOptions);
assert.deepEqual(actualParams, expectedParams);
});
describe('and the event value is invalid', function() {
it('should not include the event value in the event object', function() {
var expectedParams = {
url: 'https://logx.optimizely.com/v1/events',
httpVerb: 'POST',
params: {
'client_version': packageJSON.version,
'project_id': '111001',
'visitors': [{
'attributes': [],
'visitor_id': 'testUser',
'snapshots': [{
'decisions': [{
'variation_id': '111128',
'experiment_id': '111127',
'campaign_id': '4'
}],
'events': [{
'uuid': 'a68cf1ad-0393-4e18-af87-efe8f01a7c9c',
'tags': {
'non-revenue': 'cool',
'value': 'invalid value'
},
'timestamp': Math.round(new Date().getTime()),
'key': 'testEvent',
'entity_id': '111095'
}]
}]
}],
'account_id': '12001',
'client_name': 'node-sdk',
'revision': '42',
'anonymize_ip': false,
}
};
var eventOptions = {
clientEngine: 'node-sdk',
clientVersion: packageJSON.version,
configObj: configObj,
eventKey: 'testEvent',
eventTags: {
'value': 'invalid value',
'non-revenue': 'cool',
},
experimentsToVariationMap: { '111127': '111128' },
logger: mockLogger,
userId: 'testUser',
};
var actualParams = eventBuilder.getConversionEvent(eventOptions);
assert.deepEqual(actualParams, expectedParams);
});
});
});
});
describe('createEventWithBucketingId', function () {
var mockLogger;
beforeEach(function () {
mockLogger = {
log: sinon.stub(),
};
});
it('should send proper bucketingID with user attributes', function () {
var expectedParams = {
url: 'https://logx.optimizely.com/v1/events',
httpVerb: 'POST',
params: {
'account_id': '12001',
'project_id': '111001',
'visitors': [{
'visitor_id': 'testUser',
'attributes': [],
'snapshots': [{
'decisions': [{
'variation_id': '111128',
'experiment_id': '111127',
'campaign_id': '4'
}],
'events': [{
'timestamp': Math.round(new Date().getTime()),
'entity_id': '111095',
'uuid': 'a68cf1ad-0393-4e18-af87-efe8f01a7c9c',
'key': 'testEvent'
}]
}]
}],
'revision': '42',
'client_name': 'node-sdk',
'client_version': packageJSON.version,
'anonymize_ip': false,
}
};
var eventOptions = {
clientEngine: 'node-sdk',
clientVersion: packageJSON.version,
configObj: configObj,
eventKey: 'testEvent',
experimentsToVariationMap: {'111127': '111128'},
logger: mockLogger,
userId: 'testUser',
attributes: {'Optimizely Bucketing ID': 'variation'},
};
var actualParams = eventBuilder.getConversionEvent(eventOptions);
assert.deepEqual(actualParams, expectedParams);
});
});
});
});
});