diff --git a/LICENSE.md b/LICENSE.md index 00e9fbbf..2e2b867d 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,9 +1,21 @@ The MIT License (MIT) -Copyright (c) 2015 +Copyright (c) 2015 Lauren Elizabeth Tan -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md index 53d2b6f2..9aec613c 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![npm version](https://badge.fury.io/js/ember-metrics.svg)](http://badge.fury.io/js/ember-metrics) [![Build Status](https://travis-ci.org/poteto/ember-metrics.svg)](https://travis-ci.org/poteto/ember-metrics) [![Ember Observer Score](http://emberobserver.com/badges/ember-metrics.svg)](http://emberobserver.com/addons/ember-metrics) -This addon adds a simple `metrics` service and customized `LinkComponent` to your app that makes it simple to send data to multiple analytics services without having to implement a new API each time. +This addon adds a simple `metrics` service to your app that makes it simple to send data to multiple analytics services without having to implement a new API each time. Using this addon, you can easily use bundled adapters for various analytics services, and one API to track events, page views, and more. When you decide to add another analytics service to your stack, all you need to do is add it to your configuration, and that's it! @@ -55,18 +55,21 @@ module.exports = function(environment) { metricsAdapters: [ { name: 'GoogleAnalytics', + environments: ['development', 'production'] config: { id: 'UA-XXXX-Y' } }, { name: 'Mixpanel', + environments: ['production'] config: { token: '0f76c037-4d76-4fce-8a0f-a9a8f89d1453' } }, { name: 'LocalAdapter', + environments: ['all'] // default config: { foo: 'bar' } @@ -83,10 +86,12 @@ The `metricsAdapters` option in `ENV` accepts an array of objects containing set ```js /** * @param {String} name Adapter name + * @param {Array} environments Environments that the adapter should be activated in * @param {Object} config Configuration options for the service */ { name: 'Analytics', + environments: ['all'], config: {} } ``` @@ -104,6 +109,13 @@ export default BaseAdapter.extend({ }); ``` +To only activate adapters in specific environments, you can add an array of environment names to the config, as the `environments` key. Valid environments are: + +- `development` +- `test,` +- `production` +- `all` (default, will be activated in all environments) + ## Usage In order to use the addon, you must first [configure](#configuration) it, then inject it into any Object registered in the container that you wish to track. For example, you can call a `trackPage` event across all your analytics services whenever you transition into a route, like so: @@ -124,9 +136,9 @@ const Router = Ember.Router.extend({ _trackPage() { Ember.run.scheduleOnce('afterRender', this, () => { - const page = document.location.href; - const title = Ember.getWithDefault(this, 'routeName', 'unknown'); - + const page = document.location.pathname; + const title = this.getWithDefault('currentRouteName', 'unknown'); + Ember.get(this, 'metrics').trackPage({ page, title }); }); } @@ -175,29 +187,6 @@ There are 4 main methods implemented by the service, with the same argument sign For services that implement it, this method notifies the analytics service that an anonymous user now has a unique identifier. -#### `link-to` API - -To use the augmented `link-to`, just use the same helper, but add some extra `metrics` attributes: - -```hbs -{{#link-to 'index' metricsAdapterName="GoogleAnalytics" metricsCategory="Home Button" metricsAction="click" metricsLabel="Top Nav"}} - Home -{{/link-to}} -``` - -This is the equivalent of sending: - -```js -ga('send', { - 'hitType': 'event', - 'eventCategory': 'Home Button', - 'eventAction': 'click', - 'eventLabel': 'Top Nav' -}); -``` - -To add an attribute, just prefix it with `metrics` and enter it in camelcase. - ### Lazy Initialization If your app implements dynamic API keys for various analytics integration, you can defer the initialization of the adapters. Instead of configuring `ember-metrics` through `config/environment`, you can call the following from any Object registered in the container: @@ -214,6 +203,7 @@ export default Ember.Route.extend({ metrics.activateAdapters([ { name: 'GoogleAnalytics', + environments: ['all'], config: { id } @@ -257,6 +247,7 @@ module.exports = function(environment) { metricsAdapters: [ { name: 'MyAdapter', + environments: ['all'], config: { secret: '29fJs90qnfEa', options: { @@ -276,6 +267,7 @@ For unit tests, you will need to specify the adapters in use under `needs`, like ```js moduleFor('route:foo', 'Unit | Route | foo', { needs: [ + 'service:metrics', 'ember-metrics@metrics-adapter:google-analytics', // bundled adapter 'ember-metrics@metrics-adapter:mixpanel', // bundled adapter 'metrics-adapter:local-dummy-adapter' // local adapter diff --git a/addon/ext/link.js b/addon/ext/link.js deleted file mode 100644 index 405fe210..00000000 --- a/addon/ext/link.js +++ /dev/null @@ -1,51 +0,0 @@ -import Ember from 'ember'; - -const { - inject, - isPresent, - get, - getWithDefault, - String: { camelize } -} = Ember; -const LinkComponent = Ember.LinkComponent || Ember.LinkView; - -export default LinkComponent.reopen({ - metrics: inject.service(), - - click() { - const attrs = Object.keys(getWithDefault(this, 'attrs', this)); - const metricsProperties = this._deserializeEvent(attrs); - const hasMetricsKeys = isPresent(Object.keys(metricsProperties)); - - if (hasMetricsKeys) { - this._trackEvent(metricsProperties); - } - - this._super(...arguments); - }, - - _deserializeEvent(attrs) { - let metricsProperties = {}; - - attrs.forEach((attr) => { - if (attr.indexOf('metrics') !== -1) { - const camelizedAttr = camelize(attr.replace('metrics', '')); - metricsProperties[camelizedAttr] = get(this, attr); - } - }); - - return metricsProperties; - }, - - _trackEvent(metricsProperties) { - const metrics = get(this, 'metrics'); - const { adapterName } = metricsProperties; - delete metricsProperties.adapterName; - - if (adapterName) { - metrics.trackEvent(adapterName, metricsProperties); - } else { - metrics.trackEvent(metricsProperties); - } - } -}); diff --git a/addon/initializers/metrics-link.js b/addon/initializers/metrics-link.js deleted file mode 100644 index 08e20f02..00000000 --- a/addon/initializers/metrics-link.js +++ /dev/null @@ -1,18 +0,0 @@ -import Ember from 'ember'; -import LinkComponent from 'ember-metrics/ext/link'; - -const { isBlank } = Ember; - -export function initialize() { - if (isBlank(Ember.LinkComponent)) { - Ember.LinkView = Ember.LinkComponent; - return; - } - - Ember.LinkComponent = LinkComponent; -} - -export default { - name: 'metrics-link', - initialize -}; diff --git a/addon/metrics-adapters/mixpanel.js b/addon/metrics-adapters/mixpanel.js index 3d78a0d9..afb52936 100644 --- a/addon/metrics-adapters/mixpanel.js +++ b/addon/metrics-adapters/mixpanel.js @@ -27,8 +27,8 @@ export default BaseAdapter.extend({ if (canUseDOM) { /* jshint ignore:start */ - (function(f,b){if(!b.__SV){var a,e,i,g;window.mixpanel=b;b._i=[];b.init=function(a,e,d){function f(b,h){var a=h.split(".");2==a.length&&(b=b[a[0]],h=a[1]);b[h]=function(){b.push([h].concat(Array.prototype.slice.call(arguments,0)))}}var c=b;"undefined"!==typeof d?c=b[d]=[]:d="mixpanel";c.people=c.people||[];c.toString=function(b){var a="mixpanel";"mixpanel"!==d&&(a+="."+d);b||(a+=" (stub)");return a};c.people.toString=function(){return c.toString(1)+".people (stub)"};i="disable track track_pageview track_links track_forms register register_once alias unregister identify name_tag set_config people.set people.set_once people.increment people.append people.union people.track_charge people.clear_charges people.delete_user".split(" "); - for(g=0;g { - const { name } = adapterOption; - const adapter = cachedAdapters[name] ? cachedAdapters[name] : this._activateAdapter(adapterOption); + adapterOptions + .filter((adapterOption) => this._filterEnvironments(adapterOption, appEnvironment)) + .forEach((adapterOption) => { + const { name } = adapterOption; + const adapter = cachedAdapters[name] ? cachedAdapters[name] : this._activateAdapter(adapterOption); - set(activatedAdapters, name, adapter); - }); + set(activatedAdapters, name, adapter); + }); return set(this, '_adapters', activatedAdapters); }, @@ -100,6 +113,8 @@ export default Service.extend({ * @return {Void} */ invoke(methodName, ...args) { + if (!get(this, 'enabled')) { return; } + const cachedAdapters = get(this, '_adapters'); const allAdapterNames = keys(cachedAdapters); const [selectedAdapterNames, options] = args.length > 1 ? [[args[0]], args[1]] : [allAdapterNames, args[0]]; @@ -161,5 +176,24 @@ export default Service.extend({ const localAdapter = container.lookupFactory(`metrics-adapter:${dasherizedAdapterName}`); return localAdapter ? localAdapter : availableAdapter; + }, + + /** + * Predicate that Filters out adapters that should not be activated in the + * current application environment. Defaults to all environments if the option + * is `all` or undefined. + * + * @method _filterEnvironments + * @param {Object} adapterOption + * @param {String} appEnvironment + * @private + * @return {Boolean} should an adapter be activated + */ + _filterEnvironments(adapterOption, appEnvironment) { + let { environments } = adapterOption; + environments = environments || ['all']; + const wrappedEnvironments = emberArray(environments); + + return wrappedEnvironments.contains('all') || wrappedEnvironments.contains(appEnvironment); } }); diff --git a/app/ext/link.js b/app/ext/link.js deleted file mode 100644 index abb61db5..00000000 --- a/app/ext/link.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from 'ember-metrics/ext/link'; diff --git a/app/initializers/metrics-link.js b/app/initializers/metrics-link.js deleted file mode 100644 index 0f6e2515..00000000 --- a/app/initializers/metrics-link.js +++ /dev/null @@ -1 +0,0 @@ -export { default, initialize } from 'ember-metrics/initializers/metrics-link'; diff --git a/app/initializers/metrics.js b/app/initializers/metrics.js index d20b0d29..8f609a01 100644 --- a/app/initializers/metrics.js +++ b/app/initializers/metrics.js @@ -2,9 +2,11 @@ import config from '../config/environment'; export function initialize(_container, application ) { const { metricsAdapters = {} } = config; + const { environment = 'development' } = config; + const options = { metricsAdapters, environment }; - application.register('config:metrics', metricsAdapters, { instantiate: false }); - application.inject('service:metrics', 'metricsAdapters', 'config:metrics'); + application.register('config:metrics', options, { instantiate: false }); + application.inject('service:metrics', 'options', 'config:metrics'); } export default { diff --git a/package.json b/package.json index 6db68c74..5a314c38 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ember-metrics", - "version": "0.3.1", + "version": "0.4.0", "description": "Send data to multiple analytics integrations without re-implementing new API", "directories": { "doc": "doc", diff --git a/tests/acceptance/augmented-link-test.js b/tests/acceptance/augmented-link-test.js deleted file mode 100644 index b3522f69..00000000 --- a/tests/acceptance/augmented-link-test.js +++ /dev/null @@ -1,49 +0,0 @@ -import Ember from 'ember'; -import { module, test } from 'qunit'; -import startApp from '../../tests/helpers/start-app'; -import sinon from 'sinon'; - -let application, sandbox, service; - -module('Acceptance | augmented link', { - beforeEach() { - sandbox = sinon.sandbox.create(); - application = startApp(); - service = application.__container__.lookup('service:metrics'); - }, - - afterEach() { - sandbox.restore(); - Ember.run(application, 'destroy'); - } -}); - -test('clicking a link with named adapter and metrics properties triggers the metrics service', function(assert) { - const spy = sandbox.spy(service, 'trackEvent'); - visit('/foo'); - - andThen(() => click(find('#only-google-analytics'))); - andThen(() => { - assert.ok(spy.calledOnce, 'it calls `trackEvent` on the metrics service'); - assert.ok(spy.calledWith('GoogleAnalytics', { - action: 'click', - category: 'Home Button', - label: 'Top Nav' - }), 'it calls with the right arguments'); - }); -}); - -test('clicking a link with metrics properties triggers the metrics service', function(assert) { - const spy = sandbox.spy(service, 'trackEvent'); - visit('/foo'); - - andThen(() => click(find('#all-integrations'))); - andThen(() => { - assert.ok(spy.calledOnce, 'it calls `trackEvent` on the metrics service'); - assert.ok(spy.calledWith({ - action: 'click', - category: 'Home Button', - label: 'Top Nav' - }), 'it calls with the right arguments'); - }); -}); diff --git a/tests/dummy/app/templates/components/index.hbs b/tests/dummy/app/templates/components/index.hbs deleted file mode 100644 index 3657d62c..00000000 --- a/tests/dummy/app/templates/components/index.hbs +++ /dev/null @@ -1 +0,0 @@ -

I'm the index page!

\ No newline at end of file diff --git a/tests/dummy/app/templates/foo.hbs b/tests/dummy/app/templates/foo.hbs deleted file mode 100644 index 09631354..00000000 --- a/tests/dummy/app/templates/foo.hbs +++ /dev/null @@ -1,7 +0,0 @@ -{{#link-to 'index' id="only-google-analytics" metricsAdapterName="GoogleAnalytics" metricsCategory="Home Button" metricsAction="click" metricsLabel="Top Nav"}} - Home -{{/link-to}} - -{{#link-to 'index' id="all-integrations" metricsCategory="Home Button" metricsAction="click" metricsLabel="Top Nav"}} - Home -{{/link-to}} \ No newline at end of file diff --git a/tests/dummy/config/environment.js b/tests/dummy/config/environment.js index 028a4fc5..22dfc5e0 100644 --- a/tests/dummy/config/environment.js +++ b/tests/dummy/config/environment.js @@ -21,18 +21,22 @@ module.exports = function(environment) { metricsAdapters: [ { name: 'GoogleAnalytics', + environments: ['all'], config: { id: 'UA-XXXX-Y' } }, { + // if `environments` is undefined, it defaults to all name: 'Mixpanel', + // environments: ['all'], config: { token: '0f76c037-4d76-4fce-8a0f-a9a8f89d1453' } }, { name: 'LocalDummyAdapter', + environments: ['all'], config: { foo: 'bar' } diff --git a/tests/index.html b/tests/index.html index 8fea6fe7..0d9c8caa 100644 --- a/tests/index.html +++ b/tests/index.html @@ -24,7 +24,7 @@ - + {{content-for 'body-footer'}} diff --git a/tests/unit/initializers/metrics-link-test.js b/tests/unit/initializers/metrics-link-test.js deleted file mode 100644 index 6b9620f7..00000000 --- a/tests/unit/initializers/metrics-link-test.js +++ /dev/null @@ -1,23 +0,0 @@ -import Ember from 'ember'; -import { initialize } from '../../../initializers/metrics-link'; -import { module, test } from 'qunit'; - -var registry, application; - -module('Unit | Initializer | metrics link', { - beforeEach: function() { - Ember.run(function() { - application = Ember.Application.create(); - registry = application.registry; - application.deferReadiness(); - }); - } -}); - -// Replace this with your real tests. -test('it works', function(assert) { - initialize(registry, application); - - // you would normally confirm the results of the initializer here - assert.ok(true); -}); diff --git a/tests/unit/services/metrics-test.js b/tests/unit/services/metrics-test.js index 423bea3d..1a17c73d 100644 --- a/tests/unit/services/metrics-test.js +++ b/tests/unit/services/metrics-test.js @@ -2,8 +2,9 @@ import Ember from 'ember'; import { moduleFor, test } from 'ember-qunit'; import sinon from 'sinon'; -const { get, set } = Ember; -let sandbox, metricsAdapters; +const { get, set, K } = Ember; +const environment = 'test'; +let sandbox, metricsAdapters, options; moduleFor('service:metrics', 'Unit | Service | metrics', { needs: [ @@ -17,23 +18,33 @@ moduleFor('service:metrics', 'Unit | Service | metrics', { metricsAdapters = [ { name: 'GoogleAnalytics', + environments: ['all'], config: { id: 'UA-XXXX-Y' } }, { name: 'Mixpanel', + environments: ['all'], config: { token: '0f76c037-4d76-4fce-8a0f-a9a8f89d1453' } }, { name: 'LocalDummyAdapter', + environments: ['all'], config: { foo: 'bar' } } ]; + + options = { + metricsAdapters, + environment + }; + + window.ga = window.ga || K; }, afterEach() { @@ -42,36 +53,39 @@ moduleFor('service:metrics', 'Unit | Service | metrics', { }); test('it activates local adapters', function(assert) { - const service = this.subject({ metricsAdapters }); + const service = this.subject({ options }); assert.ok(get(service, '_adapters.LocalDummyAdapter'), 'it activated the LocalDummyAdapter'); assert.equal(get(service, '_adapters.LocalDummyAdapter.config.foo'), 'bar', 'it passes config options to the LocalDummyAdapter'); }); test('#activateAdapters activates an array of adapters', function(assert) { - const service = this.subject({ metricsAdapters }); + const service = this.subject({ options }); assert.ok(get(service, '_adapters.GoogleAnalytics'), 'it activated the GoogleAnalytics adapter'); assert.equal(get(service, '_adapters.GoogleAnalytics.config.id'), 'UA-XXXX-Y', 'it passes config options to the GoogleAnalytics adapter'); }); test('#activateAdapters is idempotent', function(assert) { - const service = this.subject({ metricsAdapters }); + const service = this.subject({ options }); service.activateAdapters([ { name: 'GoogleAnalytics', + environments: ['all'], config: { id: 'I like pie' } }, { name: 'Mixpanel', + environments: ['all'], config: { id: 'I like pie' } }, { name: 'LocalDummyAdapter', + environments: ['all'], config: { id: 'I like pie' } @@ -83,46 +97,46 @@ test('#activateAdapters is idempotent', function(assert) { }); test('#invoke invokes the named method on activated adapters', function(assert) { - const service = this.subject({ metricsAdapters }); + const service = this.subject({ options }); const MixpanelStub = sandbox.stub(window.mixpanel, 'identify'); const GoogleAnalyticsStub = sandbox.stub(window, 'ga'); const GoogleAnalyticsSpy = sandbox.spy(get(service, '_adapters.GoogleAnalytics'), 'identify'); const MixpanelSpy = sandbox.spy(get(service, '_adapters.Mixpanel'), 'identify'); - const options = { + const opts = { userId: '1e810c197e', name: 'Bill Limbergh', email: 'bill@initech.com' }; - service.invoke('identify', options); + service.invoke('identify', opts); assert.ok(GoogleAnalyticsSpy.calledOnce, 'it invokes the identify method on the adapter'); - assert.ok(GoogleAnalyticsSpy.calledWith(options), 'it invokes with the correct arguments'); + assert.ok(GoogleAnalyticsSpy.calledWith(opts), 'it invokes with the correct arguments'); assert.ok(GoogleAnalyticsStub.calledOnce, 'it invoked the GoogleAnalytics method'); assert.ok(MixpanelSpy.calledOnce, 'it invokes the identify method on the adapter'); - assert.ok(MixpanelSpy.calledWith(options), 'it invokes with the correct arguments'); + assert.ok(MixpanelSpy.calledWith(opts), 'it invokes with the correct arguments'); assert.ok(MixpanelStub.calledOnce, 'it invoked the Mixpanel method'); }); test('#invoke invokes the named method on a single activated adapter', function(assert) { - const service = this.subject({ metricsAdapters }); + const service = this.subject({ options }); const GoogleAnalyticsStub = sandbox.stub(window, 'ga'); const GoogleAnalyticsSpy = sandbox.spy(get(service, '_adapters.GoogleAnalytics'), 'trackEvent'); const MixpanelSpy = sandbox.spy(get(service, '_adapters.Mixpanel'), 'trackEvent'); - const options = { + const opts = { userId: '1e810c197e', name: 'Bill Limbergh', email: 'bill@initech.com' }; - service.invoke('trackEvent', 'GoogleAnalytics', options); + service.invoke('trackEvent', 'GoogleAnalytics', opts); assert.ok(GoogleAnalyticsSpy.calledOnce, 'it invokes the track method on the adapter'); - assert.ok(GoogleAnalyticsSpy.calledWith(options), 'it invokes with the correct arguments'); + assert.ok(GoogleAnalyticsSpy.calledWith(opts), 'it invokes with the correct arguments'); assert.ok(GoogleAnalyticsStub.calledOnce, 'it invoked the Google Analytics method'); assert.equal(MixpanelSpy.callCount, 0, 'it does not invoke other adapters'); }); test('#invoke invokes the named method on a single activated adapter with no arguments', function(assert) { - const service = this.subject({ metricsAdapters }); + const service = this.subject({ options }); const GoogleAnalyticsStub = sandbox.stub(window, 'ga'); const GoogleAnalyticsSpy = sandbox.spy(get(service, '_adapters.GoogleAnalytics'), 'trackPage'); service.invoke('trackPage', 'GoogleAnalytics'); @@ -131,8 +145,8 @@ test('#invoke invokes the named method on a single activated adapter with no arg assert.ok(GoogleAnalyticsStub.calledOnce, 'it invoked the Google Analytics method'); }); -test('#invoke includes `context` properties', function(assert){ - const service = this.subject({ metricsAdapters }); +test('#invoke includes `context` properties', function(assert) { + const service = this.subject({ options }); const GoogleAnalyticsSpy = sandbox.spy(get(service, '_adapters.GoogleAnalytics'), 'trackPage'); set(service, 'context.userName', 'Jimbo'); @@ -141,8 +155,8 @@ 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 }); +test('#invoke does not leak options between calls', function(assert) { + const service = this.subject({ options }); const GoogleAnalyticsSpy = sandbox.spy(get(service, '_adapters.GoogleAnalytics'), 'trackPage'); set(service, 'context.userName', 'Jimbo'); @@ -152,8 +166,18 @@ test('#invoke does not leak options between calls', function(assert){ assert.ok(GoogleAnalyticsSpy.calledWith({ userName: 'Jimbo', page: 'page/1', title: 'page one', callTwo: true }), 'it does not include options from previous call'); }); +test('it can be disabled', function(assert) { + const service = this.subject({ options }); + const GoogleAnalyticsSpy = sandbox.spy(get(service, '_adapters.GoogleAnalytics'), 'trackPage'); + + set(service, 'enabled', false); + service.invoke('trackPage', 'GoogleAnalytics', { page: 'page/1', title: 'page one' }); + + assert.notOk(GoogleAnalyticsSpy.called, 'it does not call adapters'); +}); + test('it implements standard contracts', function(assert) { - const service = this.subject({ metricsAdapters }); + const service = this.subject({ options }); sandbox.stub(window.mixpanel); sandbox.stub(window, 'ga'); const spy = sandbox.spy(service, 'invoke'); @@ -167,3 +191,29 @@ test('it implements standard contracts', function(assert) { assert.equal(spy.callCount, 4, 'it implements standard contracts'); }); + +test('it does not activate adapters that are not in the current app environment', function(assert) { + const service = this.subject({ + options: { + metricsAdapters: [ + { + name: 'GoogleAnalytics', + config: { + id: 'UA-XXXX-Y' + } + }, + { + name: 'LocalDummyAdapter', + environments: ['production'], + config: { + foo: 'bar' + } + } + ] + }, + environment + }); + + assert.ok(get(service, '_adapters.GoogleAnalytics'), 'it activated the GoogleAnalytics adapter'); + assert.notOk(get(service, '_adapters.LocalDummyAdapter'), 'it did not activate the LocalDummyAdapter'); +});