Manual Reference Source Test

test/unit/services.analytics.js

import test from 'ava';
import sinon from 'sinon';
import {
  client,
  analyticsService,
} from '../../src';

test.before('start server', () => {
  client.apiBaseUrl = 'https://somesite.Clinical6.com';
});

test.after('server shut down', () => {});

test.beforeEach((t) => {
  client.authToken = 'valid_token';
  client.config.track.gps = true;

  t.context.server = sinon.fakeServer.create();
  t.context.server.autoRespond = true;
  t.context.server.autoRespond = true;

  t.context.server.respondWith('GET', `${client.apiBaseUrl}/v3/analytics/metrics/*`,
    [200, { 'Content-Type': 'application/json' }, JSON.stringify({
      data: {
        id: '8d45fdc4-71d4-41f8-bab6-5f4206680cbc',
        type: 'analytics__metrics',
        attributes: {
          value: 1,
          unit: 'Users',
          name: 'accepted_users',
          key_name: null
        }
      }
    })]);

  t.context.server.respondWith('POST', `${client.apiBaseUrl}/api/v2/insights/track`,
    [200, { 'Content-Type': 'application/json' }, JSON.stringify({
      status: 'ok',
      message: 'Event tracked!'
    })]);
  t.context.server.respondWith('POST', `${client.apiBaseUrl}/api/devices/update_location`,
    [200, { 'Content-Type': 'application/json' }, JSON.stringify({
      status: 'ok',
      message: 'Location was successfully updated'
    })]);
});

test.afterEach((t) => {
  t.context.server.restore();
});


// AnalyticsService.getMetrics method
/**
 * @test {AnalyticsService.getMetrics}
 */
test('[unit] AnalyticsService.getMetrics should exist', (t) => {
  t.truthy(analyticsService.getMetrics);
});

/**
 * @test {AnalyticsService.getMetrics}
 */
test.serial('[unit] AnalyticsService.getMetrics should throw errors when there is no authToken', (t) => {
  client.authToken = undefined;
  const undefinedError = 'AnalyticsService.getMetrics error: requires authToken';
  t.throws(() => analyticsService.getMetrics({ name: 'accepted_users' }), undefinedError);
});

// /**
//  * @test {AnalyticsService.getMetrics}
//  */
// test('[unit] AnalyticsService.getMetrics should throw errors when there is no name', (t) => {
//   const undefinedError = 'AnalyticsService.getMetrics error: name is not defined';
//   t.throws(() => analyticsService.getMetrics(), undefinedError);
// });

// /**
//  * @test {AnalyticsService.getMetrics}
//  */
// test('[unit] AnalyticsService.getMetrics should make a properly formatted get request', async (t) => {
//   await analyticsService.getMetrics({ name: 'accepted_users' });
//   const request = t.context.server.requests[0];
//   t.is(request.method, 'GET');
//   t.is(request.url, `${client.apiBaseUrl}/v3/analytics/metrics/accepted_users`);
//   t.is(request.requestHeaders.Accept, 'application/json');
//   t.is(request.requestHeaders['Content-Type'], 'application/json;charset=utf-8');
//   t.is(request.requestHeaders.Authorization, 'Token token=valid_token');
// });

/**
 * @test {AnalyticsService.getMetrics}
 */
test('[unit] AnalyticsService.getMetrics should receive a valid response for a get request with name', async (t) => {
  const response = await analyticsService.getMetrics({ name: 'accepted_users' });
  // const request = t.context.server.requests[0];
  // t.is(request.method, 'GET');
  // t.is(request.url, `${client.apiBaseUrl}/v3/analytics/metrics/accepted_users`);
  // t.is(request.requestHeaders.Accept, 'application/json');
  // t.is(request.requestHeaders['Content-Type'], 'application/json;charset=utf-8');
  // t.is(request.requestHeaders.Authorization, 'Token token=valid_token');
  t.truthy(response);
  t.is(response.id, '8d45fdc4-71d4-41f8-bab6-5f4206680cbc');
  t.is(response.type, 'analytics__metrics');
  t.is(response.value, 1);
  t.is(response.unit, 'Users');
  t.is(response.name, 'accepted_users');
});


/**
 * @test {AnalyticsService.postInsights}
 */
test('[unit] AnalyticsService.postInsights should have an postInsights method', (t) => {
  t.truthy(analyticsService.postInsights);
});

/**
 * @test {AnalyticsService.postInsights}
 */
test.serial('[unit] AnalyticsService.postInsights should throw errors for invalid parameters', (t) => {
  t.throws(() => {
    analyticsService.postInsights();
  }, 'Clinical6 postInsights error: action is not defined and section is not defined');

  t.throws(() => {
    analyticsService.postInsights(100);
  }, 'Clinical6 postInsights error: section is not defined');

  t.throws(() => {
    analyticsService.postInsights(100, 'section');
  }, 'Clinical6 postInsights error: action is not a string');

  t.throws(() => {
    analyticsService.postInsights('action');
  }, 'Clinical6 postInsights error: section is not defined');

  t.throws(() => {
    analyticsService.postInsights('action', {});
  }, 'Clinical6 postInsights error: section is not a string');
});

/**
 * @test {AnalyticsService.postInsights}
 */
test.serial('[unit] AnalyticsService.postInsights should call getCurrent if track.gps is set to true', async (t) => {
  navigator.geolocation = {
    getCurrentPosition: (callback) => {
      callback({
        coords: {
          latitude: 0.918198,
          longitude: -67.56789
        }
      });
    },
  };

  const getCurrent = sinon.spy(analyticsService, 'getCurrent');
  const getCurrentPosition = sinon.spy(navigator.geolocation, 'getCurrentPosition');
  const response = await analyticsService.postInsights('actionA', 'section1').catch(e => e);
  // const request = t.context.server.requests[0];
  // t.is(request.method, 'POST');
  // t.is(request.url, `${client.apiBaseUrl}/api/v2/insights/track`);
  // t.is(request.requestHeaders.Accept, 'application/json');
  // t.is(request.requestHeaders['Content-Type'], 'application/json;charset=utf-8');
  // t.deepEqual(JSON.parse(request.requestBody), {
  //   location: {
  //     latitude: 0.918198,
  //     longitude: -67.56789,
  //   },
  //   tracker: {
  //     action: 'actionA',
  //     section: 'section1',
  //   },
  // });
  t.truthy(response);
  t.is(response.status, 'ok');
  t.is(response.message, 'Event tracked!');
  t.truthy(getCurrent.called);
  t.truthy(getCurrentPosition.called);
  getCurrent.restore();
  getCurrentPosition.restore();
});

/**
 * @test {AnalyticsService.postInsights}
 */
test.serial('[unit] AnalyticsService.postInsights should construct a valid POST method', async (t) => {
  client.config.track.gps = false;
  const response = await analyticsService.postInsights('actionA', 'section1');
  // const request = t.context.server.requests[0];
  // t.is(request.method, 'POST');
  // t.is(request.url, `${client.apiBaseUrl}/api/v2/insights/track`);
  // t.is(request.requestHeaders.Accept, 'application/json');
  // t.is(request.requestHeaders['Content-Type'], 'application/json;charset=utf-8');
  // t.deepEqual(JSON.parse(request.requestBody), {
  //   location: {},
  //   tracker: {
  //     action: 'actionA',
  //     section: 'section1',
  //   },
  // });

  t.is(response.status, 'ok');
  t.is(response.message, 'Event tracked!');
});