test/unit/clinical6.js
import test from 'ava';
import nock from 'nock';
import {
client,
clinical6,
ConsentGrant,
Device,
Location,
Site,
SiteMember,
} 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';
client.device = undefined;
t.context.nock = nock(client.apiBaseUrl)
.delete(/\/v3\/trials\/sites\/([0-9]*)$/)
.reply(200, '')
.get('/v3/trials/sites')
.reply(200, {
data: [
{
id: '10',
type: 'trials__sites',
attributes: {
site_id: '362932',
name: 'Frankie Hermann',
email: 'lisa@kulas.info',
phone_number: null,
fax_number: null
},
relationships: {
contact: {
data: null
},
location: {
data: {
id: '94',
type: 'locations'
}
},
agreement_templates: {
data: [
{
id: '29',
type: 'agreement__templates'
}
]
}
}
},
{
id: '11',
type: 'trials__sites',
attributes: {
site_id: '362854',
name: 'Frankie Hermann',
email: 'lisa@kulas.info',
phone_number: null,
fax_number: null
},
relationships: {
contact: {
data: null
},
location: {
data: {
id: '95',
type: 'locations'
}
},
agreement_templates: {
data: [
{
id: '30',
type: 'agreement__templates'
}
]
}
}
},
{
id: '12',
type: 'trials__sites',
attributes: {
site_id: '742129',
name: 'Frankie Hermann',
email: 'lisa@kulas.info',
phone_number: null,
fax_number: null
},
relationships: {
contact: {
data: null
},
location: {
data: {
id: '96',
type: 'locations'
}
},
agreement_templates: {
data: [
{
id: '31',
type: 'agreement__templates'
}
]
}
}
}
],
included: [
{
id: '29',
type: 'agreement__templates',
attributes: {
template_name: 'dummy_818 29',
description: 'Sample agreement template',
expiration: 20,
message: null,
redirect_url: 'http://kriswunsch.io/josie',
approval_required: true,
approver_first_name: 'John',
approver_last_name: 'Doe',
approver_email: 'john@example.com',
created_at: '2017-09-18T18:20:54Z',
updated_at: '2017-09-18T18:20:54Z',
permanent_link: 'dummy81829',
approver_title: 'Mr.',
reminder_frequency: 'WEEKLY_UNTIL_SIGNED'
}
},
{
id: '30',
type: 'agreement__templates',
attributes: {
template_name: 'dummy_819 30',
description: 'Sample agreement template',
expiration: 20,
message: null,
redirect_url: 'http://kriswunsch.io/josie',
approval_required: true,
approver_first_name: 'John',
approver_last_name: 'Doe',
approver_email: 'john@example.com',
created_at: '2017-09-18T18:20:54Z',
updated_at: '2017-09-18T18:20:54Z',
permanent_link: 'dummy81930',
approver_title: 'Mr.',
reminder_frequency: 'WEEKLY_UNTIL_SIGNED'
}
},
{
id: '31',
type: 'agreement__templates',
attributes: {
template_name: 'dummy_820 31',
description: 'Sample agreement template',
expiration: 20,
message: null,
redirect_url: 'http://kriswunsch.io/josie',
approval_required: true,
approver_first_name: 'John',
approver_last_name: 'Doe',
approver_email: 'john@example.com',
created_at: '2017-09-18T18:20:55Z',
updated_at: '2017-09-18T18:20:55Z',
permanent_link: 'dummy82031',
approver_title: 'Mr.',
reminder_frequency: 'WEEKLY_UNTIL_SIGNED'
}
}
]
})
.get(/\/v3\/trials\/sites\/([0-9]*)$/)
.reply(200, {
data: {
id: '15',
type: 'trials__sites',
attributes: {
site_id: '922176',
name: 'Frankie Hermann',
email: 'lisa@kulas.info',
phone_number: null,
fax_number: null
},
relationships: {
contact: {
data: null
},
location: {
data: {
id: '98',
type: 'locations'
}
},
agreement_templates: {
data: []
}
}
}
})
.get(/\/v3\/trials\/sites\/([0-9]*)\/trials\/site_members$/)
.reply(200, {
data: [
{
id: '21',
type: 'trials__site_members',
attributes: {
member_type: 'pi',
created_at: '2018-02-07T17:48:12Z',
updated_at: '2018-02-07T17:48:12Z'
},
relationships: {
site: {
data: {
id: '24',
type: 'trials__sites'
}
},
mobile_user: {
data: {
id: '47',
type: 'mobile_users'
}
}
}
},
{
id: '22',
type: 'trials__site_members',
attributes: {
member_type: 'pi',
created_at: '2018-02-07T17:48:12Z',
updated_at: '2018-02-07T17:48:12Z'
},
relationships: {
site: {
data: {
id: '24',
type: 'trials__sites'
}
},
mobile_user: {
data: {
id: '48',
type: 'mobile_users'
}
}
}
},
{
id: '23',
type: 'trials__site_members',
attributes: {
member_type: 'pi',
created_at: '2018-02-07T17:48:12Z',
updated_at: '2018-02-07T17:48:12Z'
},
relationships: {
site: {
data: {
id: '24',
type: 'trials__sites'
}
},
mobile_user: {
data: {
id: '49',
type: 'mobile_users'
}
}
}
},
{
id: '24',
type: 'trials__site_members',
attributes: {
member_type: 'patient',
created_at: '2018-02-07T17:48:12Z',
updated_at: '2018-02-07T17:48:12Z'
},
relationships: {
site: {
data: {
id: '24',
type: 'trials__sites'
}
},
mobile_user: {
data: {
id: '50',
type: 'mobile_users'
}
}
}
},
{
id: '25',
type: 'trials__site_members',
attributes: {
member_type: 'patient',
created_at: '2018-02-07T17:48:12Z',
updated_at: '2018-02-07T17:48:12Z'
},
relationships: {
site: {
data: {
id: '24',
type: 'trials__sites'
}
},
mobile_user: {
data: {
id: '51',
type: 'mobile_users'
}
}
}
},
{
id: '26',
type: 'trials__site_members',
attributes: {
member_type: 'patient',
created_at: '2018-02-07T17:48:12Z',
updated_at: '2018-02-07T17:48:12Z'
},
relationships: {
site: {
data: {
id: '24',
type: 'trials__sites'
}
},
mobile_user: {
data: {
id: '52',
type: 'mobile_users'
}
}
}
},
{
id: '27',
type: 'trials__site_members',
attributes: {
member_type: 'patient',
created_at: '2018-02-07T17:48:12Z',
updated_at: '2018-02-07T17:48:12Z'
},
relationships: {
site: {
data: {
id: '24',
type: 'trials__sites'
}
},
mobile_user: {
data: {
id: '53',
type: 'mobile_users'
}
}
}
},
{
id: '28',
type: 'trials__site_members',
attributes: {
member_type: 'patient',
created_at: '2018-02-07T17:48:12Z',
updated_at: '2018-02-07T17:48:12Z'
},
relationships: {
site: {
data: {
id: '24',
type: 'trials__sites'
}
},
mobile_user: {
data: {
id: '54',
type: 'mobile_users'
}
}
}
}
],
included: [
{
id: '47',
type: 'mobile_users',
attributes: {
uuid: 'd140c877-5414-46ca-b96f-60fd74461e83',
account_name: 'dummy_47',
email: 'user61@fake.com',
created_at: '2018-02-07T17:48:12Z',
updated_at: '2018-02-07T17:48:12Z',
verified_at: null,
invitation_sent_at: null,
invitation_accepted_at: null,
disabled: false,
disabled_at: null
},
relationships: {
devices: {
data: []
},
user_role: {
data: null
},
profile: {
data: {
id: '61',
type: 'profiles'
}
},
language: {
data: {
id: '1',
type: 'languages'
}
},
patient: {
data: {
id: '21',
type: 'trials__site_members'
}
}
}
},
{
id: '61',
type: 'profiles',
attributes: {
created_at: '2018-02-07T17:48:12Z',
updated_at: '2018-02-07T17:48:12Z',
first_name: 'Stephany',
middle_initial: null,
last_name: 'Lubowitz',
prefix: null,
suffix: null,
gender: 'male',
ethnicity: '',
occupation: null,
avatar: {
url: '/uploads/test/profile/avatar/61/1.png',
small: {
url: '/uploads/test/profile/avatar/61/small_1.png'
},
main: {
url: '/uploads/test/profile/avatar/61/main_1.png'
},
thumb: {
url: '/uploads/test/profile/avatar/61/thumb_1.png'
}
},
username: null,
dob: null,
timezone: 'UTC',
phone: null,
email: 'user61@fake.com',
age: 33,
},
relationships: {
profileable: {
data: {
id: '47',
type: 'mobile_users'
}
}
}
},
{
id: '48',
type: 'mobile_users',
attributes: {
uuid: '08e956a6-929c-48ce-b913-0386bd5f0220',
account_name: 'dummy_48',
email: 'user62@fake.com',
created_at: '2018-02-07T17:48:12Z',
updated_at: '2018-02-07T17:48:12Z',
verified_at: null,
invitation_sent_at: null,
invitation_accepted_at: null,
disabled: false,
disabled_at: null
},
relationships: {
devices: {
data: []
},
user_role: {
data: null
},
profile: {
data: {
id: '62',
type: 'profiles'
}
},
language: {
data: {
id: '1',
type: 'languages'
}
},
patient: {
data: {
id: '22',
type: 'trials__site_members'
}
}
}
},
{
id: '62',
type: 'profiles',
attributes: {
created_at: '2018-02-07T17:48:12Z',
updated_at: '2018-02-07T17:48:12Z',
first_name: 'Rosalyn',
middle_initial: null,
last_name: 'Conn',
prefix: null,
suffix: null,
gender: 'male',
ethnicity: '',
occupation: null,
avatar: {
url: '/uploads/test/profile/avatar/62/1.png',
small: {
url: '/uploads/test/profile/avatar/62/small_1.png'
},
main: {
url: '/uploads/test/profile/avatar/62/main_1.png'
},
thumb: {
url: '/uploads/test/profile/avatar/62/thumb_1.png'
}
},
username: null,
dob: null,
timezone: 'UTC',
phone: null,
email: 'user62@fake.com',
age: 33,
},
relationships: {
profileable: {
data: {
id: '48',
type: 'mobile_users'
}
}
}
},
{
id: '49',
type: 'mobile_users',
attributes: {
uuid: 'ce178761-cb55-4d59-9f8a-7d797c71290f',
account_name: 'dummy_49',
email: 'user63@fake.com',
created_at: '2018-02-07T17:48:12Z',
updated_at: '2018-02-07T17:48:12Z',
verified_at: null,
invitation_sent_at: null,
invitation_accepted_at: null,
disabled: false,
disabled_at: null
},
relationships: {
devices: {
data: []
},
user_role: {
data: null
},
profile: {
data: {
id: '63',
type: 'profiles'
}
},
language: {
data: {
id: '1',
type: 'languages'
}
},
patient: {
data: {
id: '23',
type: 'trials__site_members'
}
}
}
},
{
id: '63',
type: 'profiles',
attributes: {
created_at: '2018-02-07T17:48:12Z',
updated_at: '2018-02-07T17:48:12Z',
first_name: 'Triston',
middle_initial: null,
last_name: 'Gorczany',
prefix: null,
suffix: null,
gender: 'male',
ethnicity: '',
occupation: null,
avatar: {
url: '/uploads/test/profile/avatar/63/1.png',
small: {
url: '/uploads/test/profile/avatar/63/small_1.png'
},
main: {
url: '/uploads/test/profile/avatar/63/main_1.png'
},
thumb: {
url: '/uploads/test/profile/avatar/63/thumb_1.png'
}
},
username: null,
dob: null,
timezone: 'UTC',
phone: null,
email: 'user63@fake.com',
age: 33,
},
relationships: {
profileable: {
data: {
id: '49',
type: 'mobile_users'
}
}
}
},
{
id: '50',
type: 'mobile_users',
attributes: {
uuid: '901741a7-2b6d-4f9c-9d00-d470b86d2f66',
account_name: 'dummy_50',
email: 'user64@fake.com',
created_at: '2018-02-07T17:48:12Z',
updated_at: '2018-02-07T17:48:12Z',
verified_at: null,
invitation_sent_at: null,
invitation_accepted_at: null,
disabled: false,
disabled_at: null
},
relationships: {
devices: {
data: []
},
user_role: {
data: null
},
profile: {
data: {
id: '64',
type: 'profiles'
}
},
language: {
data: {
id: '1',
type: 'languages'
}
},
patient: {
data: {
id: '24',
type: 'trials__site_members'
}
}
}
},
{
id: '64',
type: 'profiles',
attributes: {
created_at: '2018-02-07T17:48:12Z',
updated_at: '2018-02-07T17:48:12Z',
first_name: 'Gregg',
middle_initial: null,
last_name: 'Rodriguez',
prefix: null,
suffix: null,
gender: 'male',
ethnicity: '',
occupation: null,
avatar: {
url: '/uploads/test/profile/avatar/64/1.png',
small: {
url: '/uploads/test/profile/avatar/64/small_1.png'
},
main: {
url: '/uploads/test/profile/avatar/64/main_1.png'
},
thumb: {
url: '/uploads/test/profile/avatar/64/thumb_1.png'
}
},
username: null,
dob: null,
timezone: 'UTC',
phone: null,
email: 'user64@fake.com',
age: 33,
},
relationships: {
profileable: {
data: {
id: '50',
type: 'mobile_users'
}
}
}
},
{
id: '51',
type: 'mobile_users',
attributes: {
uuid: 'ec259c81-a4a4-466c-be64-adfc7eb71e03',
account_name: 'dummy_51',
email: 'user65@fake.com',
created_at: '2018-02-07T17:48:12Z',
updated_at: '2018-02-07T17:48:12Z',
verified_at: null,
invitation_sent_at: null,
invitation_accepted_at: null,
disabled: false,
disabled_at: null
},
relationships: {
devices: {
data: []
},
user_role: {
data: null
},
profile: {
data: {
id: '65',
type: 'profiles'
}
},
language: {
data: {
id: '1',
type: 'languages'
}
},
patient: {
data: {
id: '25',
type: 'trials__site_members'
}
}
}
},
{
id: '65',
type: 'profiles',
attributes: {
created_at: '2018-02-07T17:48:12Z',
updated_at: '2018-02-07T17:48:12Z',
first_name: 'Alfonso',
middle_initial: null,
last_name: 'Rippin',
prefix: null,
suffix: null,
gender: 'male',
ethnicity: '',
occupation: null,
avatar: {
url: '/uploads/test/profile/avatar/65/1.png',
small: {
url: '/uploads/test/profile/avatar/65/small_1.png'
},
main: {
url: '/uploads/test/profile/avatar/65/main_1.png'
},
thumb: {
url: '/uploads/test/profile/avatar/65/thumb_1.png'
}
},
username: null,
dob: null,
timezone: 'UTC',
phone: null,
email: 'user65@fake.com',
age: 33,
},
relationships: {
profileable: {
data: {
id: '51',
type: 'mobile_users'
}
}
}
},
{
id: '52',
type: 'mobile_users',
attributes: {
uuid: 'a4b0974a-6e1b-432d-8087-6121b925dffb',
account_name: 'dummy_52',
email: 'user66@fake.com',
created_at: '2018-02-07T17:48:12Z',
updated_at: '2018-02-07T17:48:12Z',
verified_at: null,
invitation_sent_at: null,
invitation_accepted_at: null,
disabled: false,
disabled_at: null
},
relationships: {
devices: {
data: []
},
user_role: {
data: null
},
profile: {
data: {
id: '66',
type: 'profiles'
}
},
language: {
data: {
id: '1',
type: 'languages'
}
},
patient: {
data: {
id: '26',
type: 'trials__site_members'
}
}
}
},
{
id: '66',
type: 'profiles',
attributes: {
created_at: '2018-02-07T17:48:12Z',
updated_at: '2018-02-07T17:48:12Z',
first_name: 'Robbie',
middle_initial: null,
last_name: 'Schinner',
prefix: null,
suffix: null,
gender: 'male',
ethnicity: '',
occupation: null,
avatar: {
url: '/uploads/test/profile/avatar/66/1.png',
small: {
url: '/uploads/test/profile/avatar/66/small_1.png'
},
main: {
url: '/uploads/test/profile/avatar/66/main_1.png'
},
thumb: {
url: '/uploads/test/profile/avatar/66/thumb_1.png'
}
},
username: null,
dob: null,
timezone: 'UTC',
phone: null,
email: 'user66@fake.com',
age: 33,
},
relationships: {
profileable: {
data: {
id: '52',
type: 'mobile_users'
}
}
}
},
{
id: '53',
type: 'mobile_users',
attributes: {
uuid: '49c35ac6-4483-4ff4-b7e7-43aa3b7500c6',
account_name: 'dummy_53',
email: 'user67@fake.com',
created_at: '2018-02-07T17:48:12Z',
updated_at: '2018-02-07T17:48:12Z',
verified_at: null,
invitation_sent_at: null,
invitation_accepted_at: null,
disabled: false,
disabled_at: null
},
relationships: {
devices: {
data: []
},
user_role: {
data: null
},
profile: {
data: {
id: '67',
type: 'profiles'
}
},
language: {
data: {
id: '1',
type: 'languages'
}
},
patient: {
data: {
id: '27',
type: 'trials__site_members'
}
}
}
},
{
id: '67',
type: 'profiles',
attributes: {
created_at: '2018-02-07T17:48:12Z',
updated_at: '2018-02-07T17:48:12Z',
first_name: 'Justyn',
middle_initial: null,
last_name: 'Jaskolski',
prefix: null,
suffix: null,
gender: 'male',
ethnicity: '',
occupation: null,
avatar: {
url: '/uploads/test/profile/avatar/67/1.png',
small: {
url: '/uploads/test/profile/avatar/67/small_1.png'
},
main: {
url: '/uploads/test/profile/avatar/67/main_1.png'
},
thumb: {
url: '/uploads/test/profile/avatar/67/thumb_1.png'
}
},
username: null,
dob: null,
timezone: 'UTC',
phone: null,
email: 'user67@fake.com',
age: 33,
},
relationships: {
profileable: {
data: {
id: '53',
type: 'mobile_users'
}
}
}
},
{
id: '54',
type: 'mobile_users',
attributes: {
uuid: 'f7eeac76-0057-444e-9bc8-feaf29018dc3',
account_name: 'dummy_54',
email: 'user68@fake.com',
created_at: '2018-02-07T17:48:12Z',
updated_at: '2018-02-07T17:48:12Z',
verified_at: null,
invitation_sent_at: null,
invitation_accepted_at: null,
disabled: false,
disabled_at: null
},
relationships: {
devices: {
data: []
},
user_role: {
data: null
},
profile: {
data: {
id: '68',
type: 'profiles'
}
},
language: {
data: {
id: '1',
type: 'languages'
}
},
patient: {
data: {
id: '28',
type: 'trials__site_members'
}
}
}
},
{
id: '68',
type: 'profiles',
attributes: {
created_at: '2018-02-07T17:48:12Z',
updated_at: '2018-02-07T17:48:12Z',
first_name: 'Verlie',
middle_initial: null,
last_name: 'Treutel',
prefix: null,
suffix: null,
gender: 'male',
ethnicity: '',
occupation: null,
avatar: {
url: '/uploads/test/profile/avatar/68/1.png',
small: {
url: '/uploads/test/profile/avatar/68/small_1.png'
},
main: {
url: '/uploads/test/profile/avatar/68/main_1.png'
},
thumb: {
url: '/uploads/test/profile/avatar/68/thumb_1.png'
}
},
username: null,
dob: null,
timezone: 'UTC',
phone: null,
email: 'user68@fake.com',
age: 33,
},
relationships: {
profileable: {
data: {
id: '54',
type: 'mobile_users'
}
}
}
}
]
})
.get(/\/v3\/trials\/sites\/([0-9]*)\/trials\/site_members\/([0-9]*)$/)
.reply(200, {
data: {
id: '20',
type: 'trials__site_members',
attributes: {
member_type: 'pi',
created_at: '2018-02-07T17:48:11Z',
updated_at: '2018-02-07T17:48:11Z'
},
relationships: {
site: {
data: {
id: '22',
type: 'trials__sites'
}
},
mobile_user: {
data: {
id: '46',
type: 'mobile_users'
}
}
}
},
included: [
{
id: '46',
type: 'mobile_users',
attributes: {
uuid: '21660223-8d6f-4a5e-ba1a-581656e65b4e',
account_name: 'dummy_46',
email: 'user58@fake.com',
created_at: '2018-02-07T17:48:11Z',
updated_at: '2018-02-07T17:48:11Z',
verified_at: null,
invitation_sent_at: null,
invitation_accepted_at: null,
disabled: false,
disabled_at: null
},
relationships: {
devices: {
data: []
},
user_role: {
data: null
},
profile: {
data: {
id: '58',
type: 'profiles'
}
},
language: {
data: {
id: '1',
type: 'languages'
}
},
patient: {
data: {
id: '20',
type: 'trials__site_members'
}
}
}
},
{
id: '58',
type: 'profiles',
attributes: {
created_at: '2018-02-07T17:48:11Z',
updated_at: '2018-02-07T17:48:11Z',
first_name: 'Ellis',
middle_initial: null,
last_name: 'Rempel',
prefix: null,
suffix: null,
gender: 'male',
ethnicity: '',
occupation: null,
avatar: {
url: '/uploads/test/profile/avatar/58/1.png',
small: {
url: '/uploads/test/profile/avatar/58/small_1.png'
},
main: {
url: '/uploads/test/profile/avatar/58/main_1.png'
},
thumb: {
url: '/uploads/test/profile/avatar/58/thumb_1.png'
}
},
username: null,
dob: null,
timezone: 'UTC',
phone: null,
email: 'user58@fake.com',
age: 33,
},
relationships: {
profileable: {
data: {
id: '46',
type: 'mobile_users'
}
}
}
}
]
})
.patch(/\/v3\/devices\/(\d*)$/)
.reply(200, {
data: {
id: '1',
type: 'devices',
attributes: {
udid: 'this-is-a-udid-string',
technology: 'ios',
access_token: 'valid_token',
push_id: '7a02jf0s8dhf8a',
created_at: '2017-05-19T17:21:26.311Z',
updated_at: '2017-05-19T17:21:26.311Z',
app_version: '0.0.5'
}
}
})
.post(`/v3/devices`)
.reply(201, {
data: {
id: '105',
type: 'devices',
attributes: {
udid: null,
technology: null,
access_token: 'valid_token',
push_id: null,
created_at: '2017-06-09T22:00:50Z',
updated_at: '2017-06-09T22:00:50Z',
app_version: null
}
}
})
.post(`/v3/mobile_users/registrations`)
.reply(200, {
data: {
id: '136',
type: 'mobile_users',
attributes: {
uuid: '454dbea4-c561-4f6f-8e6e-d095e58a4773',
account_name: 'cthdohmk',
email: null,
encryption_key: null,
created_at: '2017-06-09T23:07:45Z',
updated_at: '2017-06-09T23:07:45Z',
verified_at: null,
invitation_sent_at: null,
invitation_accepted_at: null
},
relationships: {
devices: {
data: [
{
id: '3',
type: 'devices'
}
]
}
}
},
included: [
{
id: '3',
type: 'devices',
attributes: {
udid: 'mztas1qvch5ic2xg3nx2',
technology: 'ios',
access_token: 'mztas1qvch5ic2xg3nx2',
push_id: 'edh0et0xtllk4a063eb00rmeu82ok82oosjeviyxutzbqal7lq5hmyudf1vbukp7',
created_at: '2017-06-09T23:07:45Z',
updated_at: '2017-06-09T23:07:45Z',
app_version: null
}
}
]
});
t.context.storage = client.storageUtility;
client.site = new Site({});
t.context.siteJsonApi = {
data: {
id: 18,
type: 'trials__sites',
attributes: {
site_id: '413326',
name: 'Ms. Elenor Hodkiewicz',
email: 'roger.medhurst@schoen.info',
phone_number: null,
fax_number: null
},
relationships: {
contact: {
data: null
},
location: {
data: {
id: 117,
type: 'locations'
}
},
agreement_templates: {
data: []
}
}
}
};
t.context.site = new Site(t.context.siteJsonApi);
});
// test.afterEach(() => nock.cleanAll());
// Clinical6 constructor
/**
* @test {Clinical6}
*/
test('[unit] Clinical6 constructor should set certain properties', async (t) => {
await t.truthy(clinical6.apiBaseUrl);
await t.truthy(clinical6.Client);
await t.truthy(clinical6.storage);
await t.truthy(clinical6.authToken);
await t.truthy(clinical6.config);
await t.truthy(clinical6.device);
await t.truthy(clinical6.mobileApplicationKey);
await t.truthy(clinical6.user);
});
// Clinical6.delete method
/**
* @test {Clinical6.delete}
*/
test('[unit] Clinical6.delete should throw errors for invalid parameters', async (t) => {
const title = `Clinical6.delete error`;
await t.throwsAsync(clinical6.delete(), `${title}: obj is not defined`);
await t.throwsAsync(clinical6.delete({}), `${title}: obj does not have type`);
await t.throwsAsync(clinical6.delete({ id: 5 }), `${title}: obj does not have type`);
client.authToken = 'valid_authToken';
await t.throwsAsync(clinical6.delete({ type: 'trials' }), `JsonApiService.delete error: trial does not have id`);
});
/**
* @test {Clinical6.delete}
*/
test('[unit] Clinical6.delete should receive a valid response for a delete request', async (t) => {
const { site } = t.context;
site.id = 5;
const response = await clinical6.delete(site);
t.falsy(response);
});
/**
* @test {Clinical6.delete}
*/
test.serial('[unit] Clinical6.delete should remove the element from local storage', async (t) => {
const { site, storage } = t.context;
site.id = 5;
await storage.set('sites', site.toJSON(), { id: site.id });
await clinical6.delete(site);
t.is(storage.has('sites', { id: site.id }), false);
});
// Clinical6.get method
/**
* @test {Clinical6.get}
*/
test.serial('[unit] Clinical6.get should throw an error when there is no authToken', async (t) => {
client.authToken = undefined;
const title = `SiteService.get error`;
await t.throwsAsync(clinical6.get(Site), `${title}: requires authToken`);
});
/**
* @test {Clinical6.get}
*/
test('[unit] Clinical6.get should receive a valid response for a get request without an id', async (t) => {
const response = await clinical6.get(Site);
t.truthy(response);
t.is(Object.keys(response).length, 3);
t.is(response[0].id, 10);
t.is(response[0].type, 'trials__sites');
t.is(response[0].siteId, '362932');
t.is(response[0].name, 'Frankie Hermann');
t.is(response[0].email, 'lisa@kulas.info');
t.falsy(response[0].phoneNumber);
t.falsy(response[0].faxNumber);
t.is(response[1].id, 11);
t.is(response[1].type, 'trials__sites');
t.is(response[1].siteId, '362854');
t.is(response[1].name, 'Frankie Hermann');
t.is(response[1].email, 'lisa@kulas.info');
t.falsy(response[1].phoneNumber);
t.falsy(response[1].faxNumber);
t.is(response[2].id, 12);
t.is(response[2].type, 'trials__sites');
t.is(response[2].siteId, '742129');
t.is(response[2].name, 'Frankie Hermann');
t.is(response[2].email, 'lisa@kulas.info');
t.falsy(response[2].phoneNumber);
t.falsy(response[2].faxNumber);
});
/**
* @test {Clinical6.get}
*/
test('[unit] Clinical6.get should receive a valid response for a get request with an id', async (t) => {
const response = await clinical6.get(new Site({ id: 15 }));
t.truthy(response);
t.is(response.id, 15);
t.is(response.type, 'trials__sites');
t.is(response.siteId, '922176');
t.is(response.name, 'Frankie Hermann');
t.is(response.email, 'lisa@kulas.info');
t.falsy(response.phoneNumber);
t.falsy(response.faxNumber);
});
// Clinical6.getChildren method
/**
* @test {Clinical6.getChildren}
*/
test.serial('[unit] Clinical6.getChildren should throw an error when there is no authToken or invalid params', async (t) => {
client.authToken = undefined;
const title = `SiteService.getChildren error`;
const site = new Site({ id: 23 });
await t.throwsAsync(clinical6.getChildren(site, { type: 'trials__site_members' }), `${title}: requires authToken`);
client.authToken = 'valid_authToken';
await t.throwsAsync(clinical6.getChildren(site), `${title}: child does not have type`);
});
/**
* @test {Clinical6.getChildren}
*/
test(`[unit] Clinical6.getChildren should receive a valid request and response for a get request without an id`, async (t) => {
const site = new Site({ id: 23 });
const response = await clinical6.getChildren(site, { type: 'trials__site_members' });
// const request = t.context.server.requests[0];
// t.is(request.method, 'GET');
// t.is(request.url, `${client.apiBaseUrl}/v3/trials/sites/23/trials/site_members`);
// 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(Object.keys(response).length, 8);
t.truthy(response[0] instanceof SiteMember);
t.is(response[0].id, 21);
t.is(response[0].type, 'trials__site_members');
t.is(response[0].memberType, 'pi');
t.is(response[0].createdAt, '2018-02-07T17:48:12Z');
t.is(response[0].updatedAt, '2018-02-07T17:48:12Z');
t.truthy(response[0].mobileUser);
t.is(response[0].mobileUser.id, 47);
t.is(response[0].mobileUser.accountName, 'dummy_47');
t.is(response[0].mobileUser.createdAt, '2018-02-07T17:48:12Z');
t.is(response[0].mobileUser.email, 'user61@fake.com');
t.is(response[0].mobileUser.updatedAt, '2018-02-07T17:48:12Z');
t.is(response[0].mobileUser.uuid, 'd140c877-5414-46ca-b96f-60fd74461e83');
t.truthy(response[1] instanceof SiteMember);
t.is(response[1].id, 22);
t.is(response[1].type, 'trials__site_members');
t.is(response[1].memberType, 'pi');
t.is(response[1].createdAt, '2018-02-07T17:48:12Z');
t.is(response[1].updatedAt, '2018-02-07T17:48:12Z');
t.truthy(response[2] instanceof SiteMember);
t.is(response[2].id, 23);
t.is(response[2].type, 'trials__site_members');
t.is(response[2].memberType, 'pi');
t.is(response[2].createdAt, '2018-02-07T17:48:12Z');
t.is(response[2].updatedAt, '2018-02-07T17:48:12Z');
});
/**
* @test {Clinical6.getChildren}
*/
test('[unit] Clinical6.getChildren should receive a valid response for a get request with an id', async (t) => {
const site = new Site({ id: 23 });
const response = await clinical6.getChildren(site, { id: 20, type: 'trials__site_members' });
// const request = t.context.server.requests[0];
// t.is(request.method, 'GET');
// t.is(request.url, `${client.apiBaseUrl}/v3/trials/sites/23/trials/site_members/20`);
// 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.truthy(response instanceof SiteMember);
t.is(response.id, 20);
t.is(response.type, 'trials__site_members');
t.is(response.memberType, 'pi');
t.is(response.createdAt, '2018-02-07T17:48:11Z');
t.is(response.updatedAt, '2018-02-07T17:48:11Z');
t.truthy(response.mobileUser);
t.is(response.mobileUser.id, 46);
t.is(response.mobileUser.accountName, 'dummy_46');
t.is(response.mobileUser.createdAt, '2018-02-07T17:48:11Z');
t.is(response.mobileUser.email, 'user58@fake.com');
t.is(response.mobileUser.updatedAt, '2018-02-07T17:48:11Z');
t.is(response.mobileUser.uuid, '21660223-8d6f-4a5e-ba1a-581656e65b4e');
t.is(response.site.id, 22);
t.is(response.site.type, 'trials__sites');
});
// Clinical6.getProfile method
/**
* @test {Clinical6.getProfile}
*/
test.serial('[unit] Clinical6.getProfile should throw an error when there is no authToken', async (t) => {
client.authToken = undefined;
const title = `UserService.getProfile error`;
await t.throwsAsync(clinical6.getProfile(), `${title}: requires authToken and user does not have id`);
});
// Clinical6.insert method
/**
* @test {Clinical6.insert}
*/
test.serial('[unit] Clinical6.insert should throw an error when there is no authToken', async (t) => {
client.authToken = undefined;
const title = `SiteService.insert error`;
await t.throwsAsync(clinical6.insert(new Site()), `${title}: requires authToken`);
});
/**
* @test {Clinical6.insert}
*/
test('[unit] Clinical6.insert should successfully insert a site with a site object', async (t) => {
const requestJsonApi = {
data: {
type: 'trials__sites',
attributes: {
email: 'roger.medhurst@schoen.info',
name: 'Ms. Elenor Hodkiewicz'
}
}
};
let requestBody = {};
const server = nock(client.apiBaseUrl)
.post('/v3/trials/sites', (body) => {
requestBody = body;
return requestJsonApi;
})
.reply(201, {
data: {
id: '12',
type: 'trials__sites',
attributes: {
site_id: '652286',
name: 'Ms. Elenor Hodkiewicz',
email: 'roger.medhurst@schoen.info',
phone_number: null,
fax_number: null
},
relationships: {
contact: {
data: null
},
location: {
data: null
},
agreement_templates: {
data: []
}
}
}
});
const site = new Site(requestJsonApi);
const response = await clinical6.insert(site);
t.deepEqual(requestBody, requestJsonApi);
server.done();
t.is(response.id, 12);
t.is(response.type, 'trials__sites');
t.is(response.siteId, '652286');
t.is(response.name, 'Ms. Elenor Hodkiewicz');
t.is(response.email, 'roger.medhurst@schoen.info');
t.falsy(response.phoneNumber);
t.falsy(response.faxNumber);
});
/**
* @test {Clinical6.insert}
*/
test('[unit] Clinical6.insert should throw an error with an invalid token', async (t) => {
const requestJsonApi = {
data: {
type: 'trials__sites',
attributes: {
email: 'roger.medhurst@schoen.info'
}
}
};
let requestBody = {};
const server = nock(client.apiBaseUrl)
.post('/v3/trials/sites', (body) => {
requestBody = body;
return requestJsonApi;
})
.reply(422, {
errors: [
{
source: {
pointer: '/data/attributes/name'
},
detail: 'can\'t be blank'
}
]
});
const site = new Site(requestJsonApi);
const response = await clinical6.insert(site).catch(err => err);
t.deepEqual(requestBody, requestJsonApi);
server.done();
// const request = t.context.server.requests[0];
// t.is(request.method, 'POST');
// t.is(request.url, `${client.apiBaseUrl}/v3/trials/sites`);
// 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.message, `"/data/attributes/name": can't be blank`);
});
// Clinical6.fetch
/**
* @test {Clinical6.fetch}
*/
test('[unit] Clinical6 should have a fetch method', async (t) => {
await t.truthy(clinical6.fetch);
});
/**
* @test {Clinical6.fetch}
*/
test('[unit] Clinical6 should throw an error on fetch when data is not present in put call', async (t) => {
const expectedError = 'Clinical6 fetch error: invalid PUT/POST request, no data given';
await t.throws(() => clinical6.fetch('/this/is/a/random/endpoint', 'put'), expectedError);
});
// Clinical6.log method
/**
* @test {Clinical6.log}
*/
test.serial('[unit] Clinical6.log should throw an error when there is no authToken', (t) => {
client.authToken = undefined;
const expectedError = 'Clinical6 log error: requires authToken';
t.truthy(() => clinical6.log(), expectedError);
});
/**
* @test {Clinical6.log}
*/
test('[unit] Clinical6.log should throw an error when an event is passed in without a level field', (t) => {
const undefinedError = 'Clinical6 log error: logEntry does not have level';
t.truthy(() => clinical6.log({ message: 'log message' }), undefinedError);
});
// Clinical6.register method
/**
* @test {Clinical6.register}
*/
test('[unit] Clinical6.register should throw errors for invalid parameters', async (t) => {
client.device = undefined;
let account;
let password;
// let device = new Device({ id: 23 });
let device;
const title = `UserService.register error`;
await t.throwsAsync(clinical6.register(account, password, device), `${title}: device is not defined`);
const userTitle = `UserService.register error`;
device = new Device({ id: 23, access_token: 'valid_token' });
account = 'hello@gmail.com';
password = undefined;
await t.throwsAsync(clinical6.register(account, password, device), `${userTitle}: attributes must be valid`);
account = 'email@gmail.com';
password = undefined;
await t.throwsAsync(clinical6.register(account, password, device), `${userTitle}: attributes must be valid`);
account = undefined;
password = '1234';
await t.throwsAsync(clinical6.register(account, password, device), `${userTitle}: attributes must be valid`);
});
/**
* @test {Clinical6.register}
*/
test('[unit] Clinical6.register should assign a device', 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 device = new Device({ id: 23, access_token: 'valid_token' });
const response = await clinical6.register(undefined, undefined, device);
t.is(response.id, 136);
});
// Clinical6.requestPasswordReset method
/**
* @test {Clinical6.requestPasswordReset}
*/
test('[unit] Clinical6.requestPasswordReset should throw errors for invalid parameters', async (t) => {
const validError = 'UserService.requestPasswordReset error: attributes must be valid';
await t.throwsAsync(clinical6.requestPasswordReset(), validError);
});
/**
* @test {Clinical6.requestPasswordReset}
*/
test('[unit] Clinical6.requestPasswordReset should successfully requestPasswordReset mobile user with a mobile user object', async (t) => {
const requestJson = {
data: {
type: 'password_resets',
attributes: {
email: 'user116@fake.com'
}
}
};
let request = {};
nock(client.apiBaseUrl).post(`/v3/mobile_users/password`).reply(function (uri, requestBody) {
request = this.req;
request.requestBody = requestBody;
return [201, ''];
});
const response = await clinical6.requestPasswordReset('user116@fake.com');
t.is(request.path, `/v3/mobile_users/password`);
t.is(request.headers.accept, 'application/json');
t.deepEqual(request.requestBody, requestJson);
t.is(request.headers['content-type'], 'application/json');
t.is(request.headers.authorization, 'Token token=valid_token');
t.is(response, undefined);
});
// Clinical6.resetPassword method
/**
* @test {Clinical6.resetPassword}
*/
test('[unit] Clinical6.resetPassword should throw errors for invalid parameters', async (t) => {
const pre = 'UserService.resetPassword error:';
await t.throwsAsync(clinical6.resetPassword(), `${pre} attributes is not defined`);
const attr = {};
const device = new Device({ id: 5 });
await t.throwsAsync(clinical6.resetPassword(attr, device), `${pre} attributes does not have reset_password_token and attributes does not have password`);
attr.reset_password_token = 23;
await t.throwsAsync(clinical6.resetPassword(attr, device), `${pre} attributes does not have password`);
attr.password = 23;
await t.throwsAsync(clinical6.resetPassword(attr, device), `${pre} reset_password_token is not a string and password is not a string`);
attr.reset_password_token = 'asdf';
await t.throwsAsync(clinical6.resetPassword(attr, device), `${pre} password is not a string`);
attr.password = 'asdf';
attr.email = 23;
await t.throwsAsync(clinical6.resetPassword(attr, device), `${pre} email is not a string and email must be a valid email`);
});
// Clinical6.signIn method
/**
* @test {Clinical6.signIn}
*/
test('[unit] Clinical6.signIn should throw errors for invalid parameters', async (t) => {
// const undefinedError = 'UserService.signIn error: attributes is not defined';
const validError = 'UserService.signIn error: attributes must be valid';
// await t.throwsAsync(clinical6.signIn(), undefinedError);
// await t.throwsAsync(clinical6.signIn({}, { id: 5 }), validError);
await t.throwsAsync(clinical6.signIn('hello@gmail.com'), validError);
await t.throwsAsync(clinical6.signIn('hello@gmail.com'), validError);
await t.throwsAsync(clinical6.signIn(undefined, '1234'), validError);
});
/**
* @test {Clinical6.signInGuest}
*/
test.serial('[unit] Clinical6.signInGuest should successfully signInGuest a guest user to a device (example 1)', async (t) => {
let request = {};
nock(client.apiBaseUrl).patch(/\/v3\/devices\/(\d*)$/).reply(function (uri, requestBody) {
request = this.req;
request.requestBody = requestBody;
return [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'
}
}
}];
});
nock(client.apiBaseUrl).post(`/v3/devices`).reply(function (uri, requestBody) {
request = this.req;
request.requestBody = requestBody;
return [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
}
}
}];
});
nock(client.apiBaseUrl).post(`/v3/mobile_users/registrations`).reply(function (uri, requestBody) {
request = this.req;
request.requestBody = requestBody;
return [200, {
data: {
id: '4',
type: 'mobile_users',
attributes: {
uuid: '57543ae1-e2dc-40d3-8d6c-01cd74bcc5a8',
account_name: '88e1zppz',
email: null,
encryption_key: null,
created_at: '2017-05-15T19:08:18.110Z',
updated_at: '2017-05-15T19:08:18.122Z',
verified_at: null,
invitation_sent_at: null,
invitation_accepted_at: null
},
relationships: {
devices: {
data: [
{
id: '3',
type: 'devices'
}
]
}
}
},
included: [
{
id: '3',
type: 'devices',
attributes: {
udid: 'mztas1qvch5ic2xg3nx2',
technology: 'ios',
access_token: null,
push_id: 'edh0et0xtllk4a063eb00rmeu82ok82oosjeviyxutzbqal7lq5hmyudf1vbukp7',
created_at: '2017-06-09T23:07:45Z',
updated_at: '2017-06-09T23:07:45Z',
app_version: null
}
}
]
}];
});
clinical6.device = new Device();
clinical6.authToken = undefined;
clinical6.mobileApplicationKey = '1234';
const response = await clinical6.signInGuest();
t.is(response.id, 136);
t.is(response.type, 'mobile_users');
t.is(response.uuid, '454dbea4-c561-4f6f-8e6e-d095e58a4773');
t.is(response.accountName, 'cthdohmk');
t.is(response.createdAt, '2017-06-09T23:07:45Z');
t.is(response.updatedAt, '2017-06-09T23:07:45Z');
const dresp = response.devices[0];
t.is(dresp.id, 3);
t.is(dresp.type, 'devices');
t.is(dresp.udid, 'mztas1qvch5ic2xg3nx2');
t.is(dresp.technology, 'ios');
t.is(dresp.accessToken, 'mztas1qvch5ic2xg3nx2');
t.is(dresp.pushId, 'edh0et0xtllk4a063eb00rmeu82ok82oosjeviyxutzbqal7lq5hmyudf1vbukp7');
t.is(dresp.createdAt, '2017-06-09T23:07:45Z');
t.is(dresp.updatedAt, '2017-06-09T23:07:45Z');
t.is(client.authToken, 'valid_token');
});
// Clinical6.signIn signOut
/**
* @test {Clinical6.signOut}
*/
test('[unit] Clinical6.signOut should clear the client authToken, device, and storage', async (t) => {
client.storageUtility.set('mobile_users', 4);
client.authToken = '123456789';
client.device = new Device({ push_id: 'REAL_ID' });
await clinical6.signOut();
t.is(client.authToken, undefined);
t.is(client.device.pushId, 'FAKE_ID');
t.is(client.storage, undefined);
});
// Clinical6.update method
/**
* @test {Clinical6.update}
*/
test('[unit] Clinical6.update should throw errors for invalid parameters', async (t) => {
const title = `Clinical6.update error`;
await t.throwsAsync(clinical6.update(), `${title}: obj is not defined`);
});
/**
* @test {Clinical6.update}
*/
test('[unit] Clinical6.update should successfully update a site with a site object', async (t) => {
const { site, siteJsonApi } = t.context;
let requestBody = {};
const server = nock(client.apiBaseUrl)
.patch(/\/v3\/trials\/sites\/([0-9]*)$/, (body) => {
requestBody = body;
return siteJsonApi;
})
.reply(200, {
data: {
id: '18',
type: 'trials__sites',
attributes: {
site_id: '413326',
name: 'Ms. Elenor Hodkiewicz',
email: 'roger.medhurst@schoen.info',
phone_number: null,
fax_number: null
},
relationships: {
contact: {
data: null
},
location: {
data: {
id: '117',
type: 'locations'
}
},
agreement_templates: {
data: []
}
}
}
});
new Location({ id: 117 }).store();
const response = await clinical6.update(site);
t.deepEqual(requestBody, siteJsonApi);
server.done();
// const request = t.context.server.requests[0];
// t.is(request.method, 'PATCH');
// t.is(request.url, `${client.apiBaseUrl}/v3/trials/sites/${site.id}`);
// t.is(request.requestHeaders.Accept, 'application/json');
// t.deepEqual(JSON.parse(request.requestBody), siteJsonApi);
// t.is(request.requestHeaders['Content-Type'], 'application/json;charset=utf-8');
// t.is(request.requestHeaders.Authorization, 'Token token=valid_token');
t.is(response.id, 18);
t.is(response.type, 'trials__sites');
});
/**
* @test {Clinical6.update}
*/
test('[unit] Clinical6.update should successfully update a site with reason for change', async (t) => {
const grant = new ConsentGrant();
grant.id = 92;
grant.consented_at = '2018-11-07T06:00:00.000Z';
const meta = {
reason_for_changes: {
consented_at: 'Option 2'
}
};
const requestPayload = {
data: {
id: 92,
type: 'consent__grants',
attributes: {
consented_at: '2018-11-07T06:00:00.000Z'
}
},
meta
};
let requestBody = {};
const server = nock(client.apiBaseUrl)
.patch(/\/v3\/consent\/grants\/([0-9]*)$/, (body) => {
requestBody = body;
return requestPayload;
})
.reply(200, {
data: {
id: '92',
type: 'consent__grants',
attributes: {
document: {
url: null
},
progress: 'all_signed',
consented_at: '2018-11-07T06:00:00Z',
created_at: '2018-11-12T17:44:08Z',
updated_at: '2018-11-12T18:57:16Z'
},
relationships: {
granted_for: {
data: {
id: '26',
type: 'mobile_users'
}
},
granted_by: {
data: {
id: '10',
type: 'users'
}
},
strategy: {
data: {
id: '7',
type: 'consent__strategies'
}
},
form_version: {
data: {
id: '4',
type: 'consent__form_versions'
}
},
agreement: {
data: null
}
}
},
meta: {
reason_for_changes: {
consented_at: 'Option 2'
}
}
});
const response = await clinical6.update(grant, { cacheMode: 'networkOnly', meta });
t.deepEqual(requestBody, requestPayload);
server.done();
t.is(response.id, 92);
t.is(response.type, 'consent__grants');
});
// Cliinical6.xAuth method
/**
* @test {Cliinical6.xAuth}
*/
test('[unit] Cliinical6.xAuth should throw an error when a JSON value is not provided', (t) => {
const expectedError = 'Clinical6 xAuth error: json is not defined';
t.truthy(() => clinical6.xAuth(), expectedError);
});