diff --git a/addon/services/metrics.js b/addon/services/metrics.js index bd4abd8b..e271e518 100644 --- a/addon/services/metrics.js +++ b/addon/services/metrics.js @@ -7,6 +7,7 @@ const { get, set, merge, + copy, A: emberArray, String: { dasherize } } = Ember; @@ -102,7 +103,8 @@ export default Service.extend({ const cachedAdapters = get(this, '_adapters'); const allAdapterNames = keys(cachedAdapters); const [selectedAdapterNames, options] = args.length > 1 ? [[args[0]], args[1]] : [allAdapterNames, args[0]]; - const mergedOptions = merge(get(this, 'context'), options); + const context = copy(get(this, 'context')); + const mergedOptions = merge(context, options); selectedAdapterNames .map((adapterName) => get(cachedAdapters, adapterName)) diff --git a/package.json b/package.json index 5da28f00..6db68c74 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ember-metrics", - "version": "0.3.0", + "version": "0.3.1", "description": "Send data to multiple analytics integrations without re-implementing new API", "directories": { "doc": "doc", diff --git a/tests/unit/services/metrics-test.js b/tests/unit/services/metrics-test.js index 809edbea..423bea3d 100644 --- a/tests/unit/services/metrics-test.js +++ b/tests/unit/services/metrics-test.js @@ -141,6 +141,17 @@ test('#invoke includes `context` properties', function(assert){ assert.ok(GoogleAnalyticsSpy.calledWith({ userName: 'Jimbo', page: 'page/1', title: 'page one' }), 'it includes context properties'); }); +test('#invoke does not leak options between calls', function(assert){ + const service = this.subject({ metricsAdapters }); + const GoogleAnalyticsSpy = sandbox.spy(get(service, '_adapters.GoogleAnalytics'), 'trackPage'); + + set(service, 'context.userName', 'Jimbo'); + service.invoke('trackPage', 'GoogleAnalytics', { page: 'page/1', title: 'page one', callOne: true }); + service.invoke('trackPage', 'GoogleAnalytics', { page: 'page/1', title: 'page one', callTwo: true }); + + assert.ok(GoogleAnalyticsSpy.calledWith({ userName: 'Jimbo', page: 'page/1', title: 'page one', callTwo: true }), 'it does not include options from previous call'); +}); + test('it implements standard contracts', function(assert) { const service = this.subject({ metricsAdapters }); sandbox.stub(window.mixpanel);