Skip to content

Commit

Permalink
Fix globalAnalyticsKey not working
Browse files Browse the repository at this point in the history
  • Loading branch information
zikaari committed Jan 19, 2024
1 parent 2f8ad5a commit 7748a5b
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 12 deletions.
1 change: 1 addition & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ exports.min = function(options) {

function defaults(options) {
options || (options = {});
options.globalAnalyticsKey || (options.globalAnalyticsKey = 'analytics');
options.apiKey || (options.apiKey = 'YOUR_API_KEY');
options.host || (options.host = 'cdn.segment.com');
options.ajsPath || (options.ajsPath = '/analytics.js/v1/\" + key + \"/analytics.min.js');
Expand Down
11 changes: 8 additions & 3 deletions template/snippet.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
(function() {
// define the key where the global analytics object will be accessible
// customers can safely set this to be something else if need be
var globalAnalyticsKey = "<%= settings.globalAnalyticsKey %>"

// Create a queue, but don't obliterate an existing one!
var analytics = window.analytics = window.analytics || [];
var analytics = window[globalAnalyticsKey] = window[globalAnalyticsKey] || [];

// If the real analytics.js is already on the page return.
if (analytics.initialize) return;
Expand Down Expand Up @@ -49,10 +53,10 @@
// stored as the first argument, so we can replay the data.
analytics.factory = function(e) {
return function() {
if (window.analytics.initialized) {
if (window[globalAnalyticsKey].initialized) {
// Sometimes users assigned analytics to a variable before analytics is done loading, resulting in a stale reference.
// If so, proxy any calls to the 'real' analytics instance.
return window.analytics[e].apply(window.analytics, arguments);
return window[globalAnalyticsKey][e].apply(window[globalAnalyticsKey], arguments);
}
var args = Array.prototype.slice.call(arguments);

Expand Down Expand Up @@ -90,6 +94,7 @@
var t = document.createElement("script");
t.type = "text/javascript";
t.async = true;
t.setAttribute("data-global-segment-analytics-key", globalAnalyticsKey)
t.src = "https://<%= settings.host %><%= settings.ajsPath %>";

// Insert our script next to the first script element.
Expand Down
65 changes: 56 additions & 9 deletions test/snippet.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,12 @@ describe('snippet', function() {
t: '',
r: document.referrer
};

before(function() {
snippet = Function(render.max({
// https://app.segment.com/segment-libraries/sources/snippet/settings/keys
apiKey: 'zCueSsEKipbrRgqbJarlTG8UJsAZWpkm'
}));
});

beforeEach(function() {
var setup = function(options) {
snippet = Function(render.max(Object.assign({}, {
// https://app.segment.com/segment-libraries/sources/snippet/settings/keys
apiKey: 'zCueSsEKipbrRgqbJarlTG8UJsAZWpkm',
}, options)));
sandbox = sinon.sandbox.create();
origConsole = window.console;
origError = window.console.error;
Expand All @@ -42,7 +39,7 @@ describe('snippet', function() {
sandbox.spy(window.console, 'error');
window.analytics = undefined;
snippet();
});
};

afterEach(function() {
sandbox.restore();
Expand All @@ -51,27 +48,45 @@ describe('snippet', function() {
});

it('should define a global queue', function() {
setup()
assert(window.analytics instanceof Array);
});

it('works with different globalAnalyticsKey', function () {
setup({
globalAnalyticsKey: 'segment_analytics'
})

assert(window.analytics === undefined)
assert(window.segment_analytics instanceof Array)
assert(typeof window.segment_analytics.track === 'function')
assert(typeof window.segment_analytics.identify === 'function')
// check that the custom global key is exposed to the main runtime through a data attribute
assert(document.querySelector('script[data-global-segment-analytics-key]').dataset.globalSegmentAnalyticsKey === 'segment_analytics')
})

it('should load the script once', function() {
setup()
var scripts = document.scripts;
var length = scripts.length;
Function(snippet)();
assert(length === scripts.length);
});

it('should set SNIPPET_VERSION to module version', function() {
setup()
assert(require('../package.json').version === window.analytics.SNIPPET_VERSION);
});

it('should warn using console.error when the snippet is included > 1', function() {
setup()
snippet();
var args = window.console.error.args;
assert.equal('Segment snippet included twice.', args[0][0]);
});

it('should ignore the snippet when the real analytics is already included', function() {
setup()
var ajs = { initialize: function() {} };
window.analytics = ajs;
snippet();
Expand All @@ -81,20 +96,23 @@ describe('snippet', function() {
});

it('should not call .page() again when included > 1', function() {
setup()
window.analytics = { invoked: true, page: sandbox.spy() };
snippet();
var args = window.analytics.page.args;
assert.equal(0, args.length);
});

it('should not error when window.console is unavailable', function() {
setup()
window.analytics.included = true;
window.console = null;
snippet();
});

describe('.page', function() {
it('should call .page by default', function() {
setup()
assert.strictEqual(window.analytics[0][0], 'page');
});
});
Expand All @@ -103,6 +121,7 @@ describe('snippet', function() {
['track', 'screen', 'alias', 'group', 'page', 'identify'].forEach(
function(method) {
it(method + ' should have a buffered page context', function() {
setup()
window.analytics[method]('foo');
var lastCall = window.analytics[window.analytics.length - 1];
assert.deepStrictEqual(lastCall, [method, 'foo', bufferedPageContext]);
Expand All @@ -113,112 +132,138 @@ describe('snippet', function() {

describe('.methods', function() {
it('should define analytics.js methods', function() {
setup()
assert(window.analytics.methods instanceof Array);
});

it('.identify', function() {
setup()
assert(arrayContains(window.analytics.methods, 'identify'));
});

it('.track', function() {
setup()
assert(arrayContains(window.analytics.methods, 'track'));
});

it('.trackLink', function() {
setup()
assert(arrayContains(window.analytics.methods, 'trackLink'));
});

it('.trackForm', function() {
setup()
assert(arrayContains(window.analytics.methods, 'trackForm'));
});

it('.trackClick', function() {
setup()
assert(arrayContains(window.analytics.methods, 'trackClick'));
});

it('.trackSubmit', function() {
setup()
assert(arrayContains(window.analytics.methods, 'trackSubmit'));
});

it('.page', function() {
setup()
assert(arrayContains(window.analytics.methods, 'page'));
});

it('.pageview', function() {
setup()
assert(arrayContains(window.analytics.methods, 'pageview'));
});

it('.alias', function() {
setup()
assert(arrayContains(window.analytics.methods, 'alias'));
});

it('.ready', function() {
setup()
assert(arrayContains(window.analytics.methods, 'ready'));
});

it('.group', function() {
setup()
assert(arrayContains(window.analytics.methods, 'group'));
});

it('.on', function() {
setup()
assert(arrayContains(window.analytics.methods, 'on'));
});

it('.once', function() {
setup()
assert(arrayContains(window.analytics.methods, 'once'));
});

it('.off', function() {
setup()
assert(arrayContains(window.analytics.methods, 'off'));
});

it('.addSourceMiddleware', function() {
setup()
assert(arrayContains(window.analytics.methods, 'addSourceMiddleware'));
});

it('.addIntegrationMiddleware', function() {
setup()
assert(arrayContains(window.analytics.methods, 'addIntegrationMiddleware'));
});

it('.setAnonymousId', function() {
setup()
assert(arrayContains(window.analytics.methods, 'setAnonymousId'));
});

it('.addDestinationMiddleware', function() {
setup()
assert(arrayContains(window.analytics.methods, 'addDestinationMiddleware'));
});

it('.screen', function() {
setup()
assert(arrayContains(window.analytics.methods, 'screen'));
});

it('.register', function() {
setup()
assert(arrayContains(window.analytics.methods, 'register'));
});
});

describe('.factory', function() {
it('should define a factory', function() {
setup()
assert.strictEqual(typeof window.analytics.factory, 'function');
});

it('should return a queue stub', function() {
setup()
assert.strictEqual(typeof window.analytics.factory('test'), 'function');
});

it('should push arguments onto the stub', function() {
setup()
var stub = window.analytics.factory('test');
stub(1, 2, 3);
var args = window.analytics[window.analytics.length - 1];
assert.deepEqual(args, ['test', 1, 2, 3]);
});

it('should return the analytics object', function() {
setup()
var stub = window.analytics.factory();
assert(window.analytics === stub());
});

it('should generate a stub for each method', function() {
setup()
for (var i = 0; i < window.analytics.methods.length; i++) {
var method = window.analytics.methods[i];
assert.strictEqual(typeof window.analytics[method], 'function');
Expand All @@ -228,10 +273,12 @@ describe('snippet', function() {

describe('.load', function() {
it('should define a load method', function() {
setup()
assert.strictEqual(typeof window.analytics.load, 'function');
});

it('should load analytics.js from the server', function(done) {
setup()
var id = setInterval(function() {
if (typeof window.analytics === 'object') {
clearInterval(id);
Expand Down

0 comments on commit 7748a5b

Please sign in to comment.