Manual Reference Source Test

test/unit/services.device.js

import test from 'ava';
import nock from 'nock';
import { client, Device, deviceService } from '../../src';

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

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

test.beforeEach((t) => {
  client.cache = 'never';
  client.authToken = 'valid_token';

  nock(client.apiBaseUrl).delete(/\/v3\/devices\/(\d*)$/).reply(200, { status: 'ok' });

  nock(client.apiBaseUrl).get(`/v3/devices`).reply(200, {
    data: [
      {
        id: '1',
        type: 'devices',
        attributes: {
          udid: 'this-is-a-udid-string',
          technology: 'ios',
          access_token: 'cd68fa04e458d6d1a9d29faec6a329d3',
          push_id: null,
          created_at: '2017-05-19T17:21:26.311Z',
          updated_at: '2017-05-19T17:21:26.311Z',
          app_version: null
        }
      },
      {
        id: '2',
        type: 'devices',
        attributes: {
          udid: 'this-is-a-udid-string',
          technology: 'ios',
          access_token: 'cd68fa04e458d6d1a9d29faec6a329d3',
          push_id: null,
          created_at: '2017-05-19T17:21:26.311Z',
          updated_at: '2017-05-19T17:21:26.311Z',
          app_version: null
        }
      }
    ]
  });

  nock(client.apiBaseUrl).get(`/v3/devices/2`).reply(200, {
    data: {
      id: '2',
      type: 'devices',
      attributes: {
        udid: 'this-is-a-udid-string',
        technology: 'ios',
        access_token: 'cd68fa04e458d6d1a9d29faec6a329d3',
        push_id: '7a02jf0s8dhf8a',
        created_at: '2017-05-19T17:21:26.311Z',
        updated_at: '2017-05-19T17:21:26.311Z',
        app_version: '0.0.5'
      }
    }
  });

  nock(client.apiBaseUrl).patch(/\/v3\/devices\/(\d*)$/).reply(200, {
    data: {
      id: '1',
      type: 'devices',
      attributes: {
        udid: 'this-is-a-udid-string',
        technology: 'ios',
        access_token: 'cd68fa04e458d6d1a9d29faec6a329d3',
        push_id: '7a02jf0s8dhf8a',
        created_at: '2017-05-19T17:21:26.311Z',
        updated_at: '2017-05-19T17:21:26.311Z',
        app_version: '0.0.5'
      }
    }
  });

  t.context.storage = client.storageUtility;
  client.device = new Device({});
  t.context.deviceJsonApi = {
    data: {
      id: 1,
      type: 'devices',
      attributes: {
        udid: 'this-is-a-udid-string',
        technology: 'ios',
        access_token: 'cd68fa04e458d6d1a9d29faec6a329d3',
        push_id: '7a02jf0s8dhf8a',
        created_at: '2017-05-19T17:21:26.311Z',
        updated_at: '2017-05-19T17:21:26.311Z',
        app_version: '0.0.5'
      }
    }
  };
  t.context.device = new Device(t.context.deviceJsonApi);
});

// DeviceService.delete method
/**
 * @test {DeviceService.delete}
 */
test('[unit] DeviceService.delete should exist', (t) => {
  t.truthy(deviceService.delete);
});

/**
 * @test {DeviceService.delete}
 */
test('[unit] DeviceService.delete should return a promise', async (t) => {
  const { device } = t.context;
  t.truthy(await deviceService.delete(device).then);
});

/**
 * @test {DeviceService.delete}
 */
test('[unit] DeviceService.delete should throw errors for invalid parameters', (t) => {
  const undefinedError = 'DeviceService.delete error: device is not defined';
  t.throws(() => deviceService.delete(), undefinedError);
});

// /**
//  * @test {DeviceService.delete}
//  */
// test('[unit] DeviceService.delete should make a properly formatted delete request', async (t) => {
//   const { device } = t.context;
//   await deviceService.delete(device);
//   const request = t.context.server.requests[0];
//   t.is(request.method, 'DELETE');
//   t.is(request.url, `${client.apiBaseUrl}/v3/devices/${device.id}`);
//   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 {DeviceService.delete}
 */
test('[unit] DeviceService.delete should receive a valid response for a delete request', async (t) => {
  const { device } = t.context;
  const response = await deviceService.delete(device);
  // const request = t.context.server.requests[0];
  // t.is(request.requestHeaders.Authorization, 'Token token=valid_token');

  t.truthy(response);
});

/**
 * @test {DeviceService.delete}
 */
test('[unit] DeviceService.delete should remove the element from local storage', async (t) => {
  const { device, storage } = t.context;
  await storage.set('devices', device.toJSON(), { id: device.id });
  await deviceService.delete(device);
  t.is(storage.has('devices', { id: device.id }), false);
});


// DeviceService.get method
/**
 * @test {DeviceService.get}
 */
test('[unit] DeviceService.get should exist', (t) => {
  t.truthy(deviceService.get);
});

/**
 * @test {DeviceService.get}
 */
test.serial('[unit] DeviceService.get should throw an error when there is no authToken', (t) => {
  client.authToken = undefined;
  const expectedError = 'DeviceService.get error: requires authToken';
  t.throws(() => deviceService.get(), expectedError);
});

/**
 * @test {DeviceService.get}
 */
test('[unit] DeviceService.get should return a promise', async (t) => {
  t.truthy(await deviceService.get().then);
});

// /**
//  * @test {DeviceService.get}
//  */
// test('[unit] DeviceService.get should make a properly formatted get request', async (t) => {
//   await deviceService.get();
//   const request = t.context.server.requests[0];
//   t.is(request.method, 'GET');
//   t.is(request.url, `${client.apiBaseUrl}/v3/devices`);
//   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 {DeviceService.get}
 */
test('[unit] DeviceService.get should receive a valid response for a get request without an id', async (t) => {
  const response = await deviceService.get();
  t.truthy(response);
  t.is(Object.keys(response).length, 2);
});

/**
 * @test {DeviceService.get}
 */
test('[unit] DeviceService.get should receive a valid response for a get request with an id', async (t) => {
  const response = await deviceService.get({ id: 2 });
  t.truthy(response);
  t.is(response.id, 2);
  t.is(response.type, 'devices');
  t.is(response.udid, 'this-is-a-udid-string');
  t.is(response.technology, 'ios');
  t.is(response.accessToken, 'cd68fa04e458d6d1a9d29faec6a329d3');
  t.is(response.pushId, '7a02jf0s8dhf8a');
  t.is(response.createdAt, '2017-05-19T17:21:26.311Z');
  t.is(response.updatedAt, '2017-05-19T17:21:26.311Z');
  t.is(response.appVersion, '0.0.5');
});


// DeviceService.insert method
/**
 * @test {DeviceService.insert}
 */
test('[unit] DeviceService.insert should successfully insert user device with a device object', async (t) => {
  nock(client.apiBaseUrl).post(`/v3/devices`).reply(201, {
    data: {
      id: '105',
      type: 'devices',
      attributes: {
        udid: null,
        technology: null,
        access_token: 'd3fdd6be7a20d9c75ef3b1ac6c8df175',
        push_id: null,
        created_at: '2017-06-09T22:00:50Z',
        updated_at: '2017-06-09T22:00:50Z',
        app_version: null
      }
    }
  });

  // const requestJsonApi = {
  //   data: {
  //     type: 'devices',
  //     attributes: {
  //       push_id: 'FAKE_ID',
  //       mobile_application_key: '0355b2fb1c8fa7210bec203abb32b916'
  //     }
  //   }
  // };

  client.mobileApplicationKey = '0355b2fb1c8fa7210bec203abb32b916';
  const response = await deviceService.insert();

  // const request = t.context.server.requests[0];
  // t.is(request.method, 'POST');
  // t.is(request.url, `${client.apiBaseUrl}/v3/devices`);
  // t.is(request.requestHeaders.Accept, 'application/json');
  // t.is(request.requestBody, JSON.stringify(requestJsonApi));
  // t.is(request.requestHeaders['Content-Type'], 'application/json;charset=utf-8');
  // t.is(request.requestHeaders.Authorization, 'Token token=valid_token');
  t.is(response.id, 105);
  t.is(response.type, 'devices');
  t.is(response.accessToken, 'd3fdd6be7a20d9c75ef3b1ac6c8df175');
});

/**
 * @test {DeviceService.insert}
 */
test('[unit] DeviceService.insert should throw an error with an invalid token', async (t) => {
  deviceService.cacheMode = 'networkOnly';
  nock(client.apiBaseUrl).post(`/v3/devices`).reply(422, {
    errors: [
      {
        source: {
          pointer: '/data/attributes/mobile_application_key'
        },
        detail: 'can\'t be blank'
      }
    ]
  });

  // const requestJsonApi = {
  //   data: {
  //     type: 'devices',
  //     attributes: {
  //       push_id: 'FAKE_ID',
  //       mobile_application_key: 'invalid'
  //     }
  //   }
  // };

  client.mobileApplicationKey = 'invalid';
  let response;
  await deviceService.insert().catch(res => (response = res));

  // const request = t.context.server.requests[0];
  // t.is(request.method, 'POST');
  // t.is(request.url, `${client.apiBaseUrl}/v3/devices`);
  // t.is(request.requestHeaders.Accept, 'application/json');
  // t.is(request.requestBody, JSON.stringify(requestJsonApi));
  // t.is(request.requestHeaders['Content-Type'], 'application/json;charset=utf-8');
  // t.is(request.requestHeaders.Authorization, 'Token token=valid_token');
  t.truthy(response);
});


// DeviceService.update method
/**
 * @test {DeviceService.update}
 */
test('[unit] DeviceService.update should throw errors for invalid parameters', (t) => {
  const undefinedError = 'DeviceService.update error: device is not defined';
  t.throws(() => deviceService.update(), undefinedError);
});

/**
 * @test {DeviceService.update}
 */
test('[unit] DeviceService.update should successfully update user device with a device object', async (t) => {
  // const { deviceJsonApi } = t.context;
  const { device } = t.context;
  const response = await deviceService.update(device);

  // const request = t.context.server.requests[0];
  // t.is(request.method, 'PATCH');
  // t.is(request.url, `${client.apiBaseUrl}/v3/devices/${device.id}`);
  // t.is(request.requestHeaders.Accept, 'application/json');
  // t.is(request.requestBody, JSON.stringify(deviceJsonApi));
  // t.is(request.requestHeaders['Content-Type'], 'application/json;charset=utf-8');
  // t.is(request.requestHeaders.Authorization, 'Token token=valid_token');
  t.is(response.id, 1);
  t.is(response.type, 'devices');
});