Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(voip): EN-3490: add voip ticket resource #47

Merged
merged 2 commits into from Aug 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6,015 changes: 3,513 additions & 2,502 deletions package-lock.json

Large diffs are not rendered by default.

30 changes: 30 additions & 0 deletions src/examples/get_voip_ticket.test.js
@@ -0,0 +1,30 @@
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import fetchMock from 'fetch-mock';
import Track from '../index';
import { charlie, voipTickets as mockVoipTickets } from '../mocks';

chai.should();
chai.use(chaiAsPromised);

describe('When retrieving a VoIP ticket for a customer', () => {
const api = new Track({ autoRenew: false });

beforeEach(() => charlie.setUpSuccessfulMock(api.client));
beforeEach(() => mockVoipTickets.setUpSuccessfulMock(api.client));
beforeEach(() => fetchMock.catch(503));
afterEach(fetchMock.restore);

it('should get a fresh VoIP ticket', () => {
api.logIn({ username: 'charlie@example.com', password: 'securepassword' });

const voipTicketPromise = api.customer('SYNC').voipTicket()
.fetch()
.then((voipTicket) => {
/* do something with voipTicket */
return voipTicket;
});

return voipTicketPromise;
});
});
1 change: 1 addition & 0 deletions src/mocks/index.js
Expand Up @@ -21,6 +21,7 @@ export { default as tags } from './tags';
export { default as trips } from './trips';
export { default as users } from './users';
export { default as vehicles } from './vehicles';
export { default as voipTickets } from './voipTicket';

export const charlie = {
setUpSuccessfulMock: (client) => {
Expand Down
2 changes: 2 additions & 0 deletions src/mocks/settings.js
Expand Up @@ -7,13 +7,15 @@ const settings = {
const singleResponse = () => new Response(Client.toBlob({
href: '/1/SYNC/settings',
sign_in_type: 'trip',
is_voip_enabled: true,
}));

fetchMock.get(client.resolve('/1/SYNC/settings'), singleResponse);
},
get: () => ({
href: '/1/SYNC/settings',
sign_in_type: 'trip',
is_voip_enabled: true,
}),
};

Expand Down
23 changes: 23 additions & 0 deletions src/mocks/voipTicket.js
@@ -0,0 +1,23 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import fetchMock from 'fetch-mock';
import Client from '../Client';

const voipTickets = {
setUpSuccessfulMock: (client) => {
const sync = voipTickets.getByCode('SYNC');
const singleResponse = () => new Response(Client.toBlob(sync));

fetchMock
.post(client.resolve('/1/SYNC/voip_ticket'), singleResponse);
},
getByCode: code => voipTickets.list.find(a => a.code === code),
list: [{
href: '/1/SYNC/voip_ticket',
code: 'SYNC',
expiration: '2017-06-12T08:00:00-08:00',
ticket: 'ticket',
application_key: 'application key',
}],
};

export default voipTickets;
9 changes: 9 additions & 0 deletions src/resources/Customer.js
Expand Up @@ -30,6 +30,7 @@ import TagsContext from './TagsContext';
import Trip from './Trip';
import Vehicle from './Vehicle';
import VehiclesContext from './VehiclesContext';
import VoipTicket from './VoipTicket';

/**
* Customer resource
Expand Down Expand Up @@ -325,6 +326,14 @@ class Customer extends Resource {
vehicle(id) {
return this.resource(Vehicle, Vehicle.makeHref(this.code, id));
}

/**
* Gets a voip ticket resource
* @returns {VoipTicket} VoipTicket resource
*/
voipTicket() {
return this.resource(VoipTicket, VoipTicket.makeHref(this.code));
}
}

export default Customer;
2 changes: 2 additions & 0 deletions src/resources/Customer.test.js
Expand Up @@ -31,6 +31,7 @@ import Trip from './Trip';
import TagsContext from './TagsContext';
import Vehicle from './Vehicle';
import VehiclesContext from './VehiclesContext';
import VoipTicket from './VoipTicket';
import Assignment from './Assignment';

chai.should();
Expand Down Expand Up @@ -70,6 +71,7 @@ describe('When getting resources related to a customer', () => {
it('should allow a trip to be retrieved', () => customer.trip().should.be.instanceof(Trip));
it('should allow vehicles to be searched', () => customer.vehicles().should.be.instanceof(VehiclesContext));
it('should allow a vehicle to be retrieved', () => customer.vehicle().should.be.instanceof(Vehicle));
it('should allow a voip ticket to be retrieved', () => customer.voipTicket().should.be.instanceof(VoipTicket));
});

describe('When accessing a realTimeContext', () => {
Expand Down
2 changes: 2 additions & 0 deletions src/resources/Settings.test.js
Expand Up @@ -21,6 +21,7 @@ describe('When instantiating settings based on an object', () => {
const settings = new Settings(client, {
href: '/1/SYNC/settings',
sign_in_type: 'trip',
is_voip_enabled: true,
});

it('should set the href', () => settings.href.should.equal('/1/SYNC/settings'));
Expand All @@ -33,6 +34,7 @@ describe('When fetching settings based on customer', () => {
fetchMock.get(client.resolve('/1/SYNC/settings'), Client.toBlob({
href: '/1/SYNC/settings',
sign_in_type: 'trip',
is_voip_enabled: true,
}));

const promise = new Settings(client, Settings.makeHref('SYNC')).fetch();
Expand Down
46 changes: 46 additions & 0 deletions src/resources/VoipTicket.js
@@ -0,0 +1,46 @@
import Resource from './Resource';

/**
* VoipTicket resource
*/
class VoipTicket extends Resource {
/**
* Creates a new VoipTicket object
*
* Will populate itself with the values given to it after the client parameter
* @param {Client} client Instance of pre-configured client
* @param {Array} rest Remaining arguments to use in assigning values to this instance
*/
constructor(client, ...rest) {
super(client);

const newProperties = Object.assign({}, ...rest);
const hydrated = !Object.keys(newProperties).every(k => k === 'href' || k === 'code');

Object.assign(this, newProperties, { hydrated });
}

/**
* Makes a href for a given customer code
* @param {string} customerCode Customer code
* @returns {string} URI to instance of voip ticket
*/
static makeHref(customerCode) {
return {
href: `/1/${customerCode}/voip_ticket`,
code: customerCode,
};
}

/**
* Generates a new voip ticket via the client
* @returns {Promise} If successful, a hydrated instance of a fresh voip ticket
*/
fetch() {
return this.client.post(this.href)
.then(response => response.json())
.then(voipTicket => new VoipTicket(this.client, this, voipTicket));
}
}

export default VoipTicket;
49 changes: 49 additions & 0 deletions src/resources/VoipTicket.test.js
@@ -0,0 +1,49 @@
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import fetchMock from 'fetch-mock';
import Client from '../Client';
import VoipTicket from './VoipTicket';
import { voipTickets as mockVoipTickets } from '../mocks';

chai.should();
chai.use(chaiAsPromised);

describe('When instantiating a VoIP ticket based on a customer', () => {
const client = new Client();
const voipTicket = new VoipTicket(client, VoipTicket.makeHref('SYNC'));

it('should set the href', () => voipTicket.href.should.equal('/1/SYNC/voip_ticket'));
it('should not be hydrated', () => voipTicket.hydrated.should.equal(false));
});

describe('When instantiating a VoIP ticket based on an object', () => {
const client = new Client();
const voipTicket = new VoipTicket(client, {
href: '/1/SYNC/voip_ticket',
expiration: '2017-06-12T08:00:00-08:00',
ticket: 'ticket',
application_key: 'application key',
});

it('should set the href', () => voipTicket.href.should.equal('/1/SYNC/voip_ticket'));
it('should be hydrated', () => voipTicket.hydrated.should.equal(true));
});

describe('When fetching a VoIP ticket based on a customer', () => {
const client = new Client();
beforeEach(() => mockVoipTickets.setUpSuccessfulMock(client));
beforeEach(() => fetchMock.catch(503));
afterEach(fetchMock.restore);

let promise;
beforeEach(() => {
promise = new VoipTicket(client, VoipTicket.makeHref('SYNC')).fetch();
});

it('should resolve the promise', () => promise.should.be.fulfilled);
it('should set the expiration', () => promise.then(v => v.expiration).should.eventually.equal('2017-06-12T08:00:00-08:00'));
it('should set the ticket', () => promise.then(v => v.ticket).should.eventually.equal('ticket'));
it('should set the application key', () => promise.then(v => v.application_key).should.eventually.equal('application key'));
it('should set the href', () => promise.then(v => v.href).should.eventually.equal('/1/SYNC/voip_ticket'));
it('should be hydrated', () => promise.then(v => v.hydrated).should.eventually.equal(true));
});