Skip to content

Commit a73cbf5

Browse files
author
Daniel Jih
committed
add tests for amplitude instance handling
1 parent aa03c35 commit a73cbf5

File tree

4 files changed

+203
-15
lines changed

4 files changed

+203
-15
lines changed

amplitude.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,9 @@ var DEFAULT_OPTIONS = require('./options');
499499
* @public
500500
* @example var amplitude = new Amplitude();
501501
*/
502-
var AmplitudeClient = function Amplitude() {
502+
var AmplitudeClient = function Amplitude(instanceName) {
503+
this._instanceName = (utils.isEmptyString(instanceName) ? Constants.DEFAULT_INSTANCE : instanceName).toLowerCase();
504+
this._storageSuffix = this._instanceName === Constants.DEFAULT_INSTANCE ? '' : '_' + this._instanceName;
503505
this._unsentEvents = [];
504506
this._unsentIdentifys = [];
505507
this._ua = new UAParser(navigator.userAgent).getResult();
@@ -547,7 +549,9 @@ AmplitudeClient.prototype.init = function init(apiKey, opt_userId, opt_config, o
547549
});
548550
this.options.domain = this.cookieStorage.options().domain;
549551

550-
_upgradeCookeData(this);
552+
if (this._instanceName === Constants.DEFAULT_INSTANCE) {
553+
_upgradeCookeData(this);
554+
}
551555
_loadCookieData(this);
552556

553557
// load deviceId and userId from input, or try to fetch existing value from cookie
@@ -780,7 +784,7 @@ AmplitudeClient.prototype._sendEventsIfReady = function _sendEventsIfReady(callb
780784
* @private
781785
*/
782786
AmplitudeClient.prototype._getFromStorage = function _getFromStorage(storage, key) {
783-
return storage.getItem(key);
787+
return storage.getItem(key + this._storageSuffix);
784788
};
785789

786790
/**
@@ -789,7 +793,7 @@ AmplitudeClient.prototype._getFromStorage = function _getFromStorage(storage, ke
789793
* @private
790794
*/
791795
AmplitudeClient.prototype._setInStorage = function _setInStorage(storage, key, value) {
792-
storage.setItem(key, value);
796+
storage.setItem(key + this._storageSuffix, value);
793797
};
794798

795799
/**
@@ -852,7 +856,7 @@ var _upgradeCookeData = function _upgradeCookeData(scope) {
852856
* @private
853857
*/
854858
var _loadCookieData = function _loadCookieData(scope) {
855-
var cookieData = scope.cookieStorage.get(scope.options.cookieName);
859+
var cookieData = scope.cookieStorage.get(scope.options.cookieName + scope._storageSuffix);
856860
if (type(cookieData) === 'object') {
857861
if (cookieData.deviceId) {
858862
scope.options.deviceId = cookieData.deviceId;
@@ -886,7 +890,7 @@ var _loadCookieData = function _loadCookieData(scope) {
886890
* @private
887891
*/
888892
var _saveCookieData = function _saveCookieData(scope) {
889-
scope.cookieStorage.set(scope.options.cookieName, {
893+
scope.cookieStorage.set(scope.options.cookieName + scope._storageSuffix, {
890894
deviceId: scope.options.deviceId,
891895
userId: scope.options.userId,
892896
optOut: scope.options.optOut,

amplitude.min.js

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/amplitude-client.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ var DEFAULT_OPTIONS = require('./options');
2121
* @public
2222
* @example var amplitude = new Amplitude();
2323
*/
24-
var AmplitudeClient = function Amplitude() {
24+
var AmplitudeClient = function Amplitude(instanceName) {
25+
this._instanceName = (utils.isEmptyString(instanceName) ? Constants.DEFAULT_INSTANCE : instanceName).toLowerCase();
26+
this._storageSuffix = this._instanceName === Constants.DEFAULT_INSTANCE ? '' : '_' + this._instanceName;
2527
this._unsentEvents = [];
2628
this._unsentIdentifys = [];
2729
this._ua = new UAParser(navigator.userAgent).getResult();
@@ -69,7 +71,9 @@ AmplitudeClient.prototype.init = function init(apiKey, opt_userId, opt_config, o
6971
});
7072
this.options.domain = this.cookieStorage.options().domain;
7173

72-
_upgradeCookeData(this);
74+
if (this._instanceName === Constants.DEFAULT_INSTANCE) {
75+
_upgradeCookeData(this);
76+
}
7377
_loadCookieData(this);
7478

7579
// load deviceId and userId from input, or try to fetch existing value from cookie
@@ -302,7 +306,7 @@ AmplitudeClient.prototype._sendEventsIfReady = function _sendEventsIfReady(callb
302306
* @private
303307
*/
304308
AmplitudeClient.prototype._getFromStorage = function _getFromStorage(storage, key) {
305-
return storage.getItem(key);
309+
return storage.getItem(key + this._storageSuffix);
306310
};
307311

308312
/**
@@ -311,7 +315,7 @@ AmplitudeClient.prototype._getFromStorage = function _getFromStorage(storage, ke
311315
* @private
312316
*/
313317
AmplitudeClient.prototype._setInStorage = function _setInStorage(storage, key, value) {
314-
storage.setItem(key, value);
318+
storage.setItem(key + this._storageSuffix, value);
315319
};
316320

317321
/**
@@ -374,7 +378,7 @@ var _upgradeCookeData = function _upgradeCookeData(scope) {
374378
* @private
375379
*/
376380
var _loadCookieData = function _loadCookieData(scope) {
377-
var cookieData = scope.cookieStorage.get(scope.options.cookieName);
381+
var cookieData = scope.cookieStorage.get(scope.options.cookieName + scope._storageSuffix);
378382
if (type(cookieData) === 'object') {
379383
if (cookieData.deviceId) {
380384
scope.options.deviceId = cookieData.deviceId;
@@ -408,7 +412,7 @@ var _loadCookieData = function _loadCookieData(scope) {
408412
* @private
409413
*/
410414
var _saveCookieData = function _saveCookieData(scope) {
411-
scope.cookieStorage.set(scope.options.cookieName, {
415+
scope.cookieStorage.set(scope.options.cookieName + scope._storageSuffix, {
412416
deviceId: scope.options.deviceId,
413417
userId: scope.options.userId,
414418
optOut: scope.options.optOut,

test/amplitude.js

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,189 @@ describe('Amplitude', function() {
3434
localStorage.clear();
3535
sessionStorage.clear();
3636
cookie.remove(amplitude.getInstance().options.cookieName);
37+
cookie.remove(amplitude.getInstance().options.cookieName + keySuffix);
38+
cookie.remove(amplitude.getInstance().options.cookieName + '_app1');
39+
cookie.remove(amplitude.getInstance().options.cookieName + '_app2');
3740
cookie.reset();
3841
}
3942

43+
describe('getInstance', function() {
44+
beforeEach(function() {
45+
reset();
46+
});
47+
48+
afterEach(function() {
49+
reset();
50+
});
51+
52+
it('should map no instance to default instance', function() {
53+
amplitude.init(apiKey);
54+
assert.equal(amplitude.getInstance().options.apiKey, apiKey);
55+
assert.equal(amplitude.options, amplitude.getInstance().options);
56+
assert.equal(amplitude.getInstance('$default_instance').options.apiKey, apiKey);
57+
assert.equal(amplitude.getInstance(), amplitude.getInstance('$default_instance'));
58+
assert.equal(amplitude.options.deviceId, amplitude.getInstance().options.deviceId);
59+
60+
// test for case insensitivity
61+
assert.equal(amplitude.getInstance(), amplitude.getInstance('$DEFAULT_INSTANCE'));
62+
assert.equal(amplitude.getInstance(), amplitude.getInstance('$DEFAULT_instance'));
63+
});
64+
65+
it('should create two separate instances', function() {
66+
var app1 = amplitude.getInstance('app1');
67+
app1.init('1');
68+
var app2 = amplitude.getInstance('app2');
69+
app2.init('2');
70+
71+
assert.notEqual(app1, app2);
72+
assert.equal(app1.options.apiKey, '1');
73+
assert.equal(app2.options.apiKey, '2');
74+
75+
assert.equal(app1, amplitude.getInstance('app1'));
76+
assert.equal(app1, amplitude.getInstance('APP1'));
77+
assert.equal(app1, amplitude.getInstance('aPp1'));
78+
assert.equal(app2, amplitude.getInstance('app2'));
79+
assert.equal(app2, amplitude.getInstance('APP2'));
80+
assert.equal(app2, amplitude.getInstance('aPp2'));
81+
82+
assert.equal(amplitude.getInstance('APP3')._instanceName, 'app3');
83+
});
84+
85+
it('should return the same instance for same key', function() {
86+
var app = amplitude.getInstance('app');
87+
app.init('1');
88+
assert.equal(app, amplitude.getInstance('app'));
89+
assert.equal(amplitude.getInstance('app').options.apiKey, '1');
90+
});
91+
92+
it('instances should have separate event queues and settings', function() {
93+
amplitude.init(apiKey, null, {batchEvents: true, eventUploadThreshold: 2});
94+
var app1 = amplitude.getInstance('app1');
95+
app1.init('1');
96+
var app2 = amplitude.getInstance('app2');
97+
app2.init('2');
98+
99+
assert.notEqual(amplitude.options.deviceId, app1.options.deviceId);
100+
assert.notEqual(amplitude.options.deviceId, app2.options.deviceId);
101+
assert.notEqual(app1.options.deviceId, app2.options.deviceId);
102+
103+
amplitude.logEvent('amplitude event');
104+
amplitude.logEvent('amplitude event2');
105+
var identify = new Identify().set('key', 'value');
106+
app1.identify(identify);
107+
app2.logEvent('app2 event');
108+
109+
assert.lengthOf(amplitude.getInstance()._unsentEvents, 2);
110+
assert.lengthOf(amplitude.getInstance()._unsentIdentifys, 0);
111+
112+
assert.lengthOf(app1._unsentEvents, 0);
113+
assert.lengthOf(app1._unsentIdentifys, 1);
114+
assert.lengthOf(app2._unsentEvents, 1);
115+
assert.lengthOf(app2._unsentIdentifys, 0);
116+
117+
assert.deepEqual(amplitude.getInstance()._unsentEvents[0].event_type, 'amplitude event');
118+
assert.deepEqual(amplitude.getInstance()._unsentEvents[1].event_type, 'amplitude event2');
119+
assert.deepEqual(amplitude.getInstance()._unsentIdentifys, []);
120+
assert.deepEqual(app1._unsentEvents, []);
121+
assert.deepEqual(app1._unsentIdentifys[0].user_properties, {'$set':{'key':'value'}});
122+
assert.deepEqual(app2._unsentEvents[0].event_type, 'app2 event');
123+
assert.deepEqual(app2._unsentIdentifys, []);
124+
125+
assert.equal(amplitude.getInstance()._eventId, 2);
126+
assert.equal(amplitude.getInstance()._identifyId, 0);
127+
assert.equal(amplitude.getInstance()._sequenceNumber, 2);
128+
assert.equal(app1._eventId, 0);
129+
assert.equal(app1._identifyId, 1);
130+
assert.equal(app1._sequenceNumber, 1);
131+
assert.equal(app2._eventId, 1);
132+
assert.equal(app2._identifyId, 0);
133+
assert.equal(app2._sequenceNumber, 1);
134+
135+
// verify separate localstorages
136+
assert.deepEqual(
137+
JSON.parse(localStorage.getItem('amplitude_unsent'))[0].event_type, 'amplitude event'
138+
);
139+
assert.deepEqual(
140+
JSON.parse(localStorage.getItem('amplitude_unsent'))[1].event_type, 'amplitude event2'
141+
);
142+
assert.equal(localStorage.getItem('amplitude_unsent_identify'), JSON.stringify([]));
143+
assert.equal(localStorage.getItem('amplitude_unsent_app1'), JSON.stringify([]));
144+
assert.deepEqual(
145+
JSON.parse(localStorage.getItem('amplitude_unsent_identify_app1'))[0].user_properties, {'$set':{'key':'value'}}
146+
);
147+
assert.equal(
148+
JSON.parse(localStorage.getItem('amplitude_unsent_app2'))[0].event_type, 'app2 event'
149+
);
150+
assert.equal(localStorage.getItem('amplitude_unsent_identify_app2'), JSON.stringify([]));
151+
152+
// verify separate apiKeys in server requests
153+
assert.lengthOf(server.requests, 3);
154+
assert.equal(JSON.parse(querystring.parse(server.requests[1].requestBody).client), 1);
155+
assert.equal(JSON.parse(querystring.parse(server.requests[2].requestBody).client), 2);
156+
157+
// verify separate cookie data
158+
var cookieData = cookie.get(amplitude.options.cookieName);
159+
assert.equal(cookieData.deviceId, amplitude.options.deviceId);
160+
161+
var cookieData1 = cookie.get(app1.options.cookieName + '_app1');
162+
assert.equal(cookieData1.deviceId, app1.options.deviceId);
163+
164+
var cookieData2 = cookie.get(app2.options.cookieName + '_app2');
165+
assert.equal(cookieData2.deviceId, app2.options.deviceId);
166+
});
167+
168+
it('new instances should not load historical cookie data', function() {
169+
var now = new Date().getTime();
170+
171+
var cookieData = {
172+
deviceId: 'test_device_id',
173+
userId: 'test_user_id',
174+
optOut: true,
175+
sessionId: now-500,
176+
lastEventTime: now-500,
177+
eventId: 50,
178+
identifyId: 60,
179+
sequenceNumber: 70
180+
}
181+
cookie.set(amplitude.options.cookieName, cookieData);
182+
183+
// default instance loads from existing cookie
184+
var app = amplitude.getInstance();
185+
app.init(apiKey);
186+
assert.equal(app.options.deviceId, 'test_device_id');
187+
assert.equal(app.options.userId, 'test_user_id');
188+
assert.isTrue(app.options.optOut);
189+
assert.equal(app._sessionId, now-500);
190+
assert.isTrue(app._lastEventTime >= now);
191+
assert.equal(app._eventId, 50);
192+
assert.equal(app._identifyId, 60);
193+
assert.equal(app._sequenceNumber, 70);
194+
195+
var app1 = amplitude.getInstance('app1');
196+
app1.init('1');
197+
assert.notEqual(app1.options.deviceId, 'test_device_id');
198+
assert.isNull(app1.options.userId);
199+
assert.isFalse(app1.options.optOut);
200+
console.log(app1._sessionId);
201+
assert.isTrue(app1._sessionId >= now);
202+
assert.isTrue(app1._lastEventTime >= now);
203+
assert.equal(app1._eventId, 0);
204+
assert.equal(app1._identifyId, 0);
205+
assert.equal(app1._sequenceNumber, 0);
206+
207+
var app2 = amplitude.getInstance('app2');
208+
app2.init('2');
209+
assert.notEqual(app2.options.deviceId, 'test_device_id');
210+
assert.isNull(app2.options.userId);
211+
assert.isFalse(app2.options.optOut);
212+
assert.isTrue(app2._sessionId >= now);
213+
assert.isTrue(app2._lastEventTime >= now);
214+
assert.equal(app2._eventId, 0);
215+
assert.equal(app2._identifyId, 0);
216+
assert.equal(app2._sequenceNumber, 0);
217+
});
218+
});
219+
40220
describe('init', function() {
41221
beforeEach(function() {
42222
reset();

0 commit comments

Comments
 (0)