dispatch-node-sdk
Advanced tools
Comparing version 0.0.32 to 0.0.33
@@ -663,2 +663,102 @@ 'use strict'; | ||
} | ||
/** | ||
* This function creates a customer, job, and an optional appointment, which together make | ||
* the action of "create and optionally schedule a job" | ||
* | ||
* IF `customerData` has an `id` property, then it will be assumed that the customer already | ||
* exists and the customer creation step will be skipped. | ||
* | ||
* IF there is an error, the returned promise will be REJECTED with a MultiActionError. This | ||
* error type has a `data` property, which in this case will be an object with `job`, `customer`, | ||
* and `appointment` properties, denoting the error that happened in each step, if applicable. | ||
* | ||
* IF it succeeds, the returned promise will be RESOLVED with an object containing properties for | ||
* `job`, `customer`, and `appointment`, which will be the returned values from the API as a | ||
* result of creating each respective entity. | ||
* | ||
* @param {Object} jobInfo Job data | ||
* @param {Object} customerInfo Customer data | ||
* @param {Object} appointmentInfo (optional) Appointment data | ||
* @return {Promise<Object>} [description] | ||
*/ | ||
}, { | ||
key: 'createAndScheduleJob', | ||
value: function createAndScheduleJob(jobInfo, customerInfo) { | ||
var _this8 = this; | ||
var appointmentInfo = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2]; | ||
var returnData = { | ||
job: null, | ||
customer: null, | ||
appointment: null | ||
}; | ||
var errorData = { | ||
job: null, | ||
customer: null, | ||
appointment: null | ||
}; | ||
var createCustomer = function createCustomer() { | ||
if (customerInfo.id) { | ||
jobInfo.customer_id = customerInfo.id; | ||
return Promise.resolve(); | ||
} | ||
return new Promise(function (resolve, reject) { | ||
_this8.entities.customers.create(customerInfo).then(function (customer) { | ||
returnData.customer = customer; | ||
jobInfo.customer_id = customer.id; | ||
resolve(); | ||
}).catch(function (err) { | ||
errorData.customer = err; | ||
reject(err); | ||
}); | ||
}); | ||
}; | ||
var createJob = function createJob() { | ||
return new Promise(function (resolve, reject) { | ||
_this8.entities.jobs.create(jobInfo).then(function (job) { | ||
returnData.job = job; | ||
if (appointmentInfo) { | ||
appointmentInfo.job_id = job.id; | ||
} | ||
resolve(); | ||
}).catch(function (err) { | ||
errorData.job = err; | ||
reject(err); | ||
}); | ||
}); | ||
}; | ||
var createAppointment = function createAppointment() { | ||
if (!appointmentInfo) { | ||
return Promise.resolve(); | ||
} | ||
return new Promise(function (resolve, reject) { | ||
_this8.entities.appointments.create(appointmentInfo).then(function (appointment) { | ||
returnData.appointment = appointment; | ||
resolve(); | ||
}).catch(function (err) { | ||
errorData.appointment = err; | ||
reject(err); | ||
}); | ||
}); | ||
}; | ||
return new Promise(function (resolve, reject) { | ||
createCustomer().then(function () { | ||
return createJob(); | ||
}).then(function () { | ||
return createAppointment(); | ||
}).then(function () { | ||
resolve(returnData); | ||
}).catch(function () { | ||
reject(new _errors.MultiActionError('Job creation failed', errorData)); | ||
}); | ||
}); | ||
} | ||
}]); | ||
@@ -665,0 +765,0 @@ |
@@ -64,2 +64,13 @@ 'use strict'; | ||
makeError(APIError); | ||
makeError(APIError); | ||
var MultiActionError = exports.MultiActionError = function MultiActionError(message, data) { | ||
_classCallCheck(this, MultiActionError); | ||
this.name = 'MultiActionError'; | ||
this.message = message; | ||
this.data = data; | ||
this.stack = new Error().stack; | ||
}; | ||
makeError(MultiActionError); |
@@ -11,3 +11,3 @@ import _ from 'underscore'; | ||
import Collection from './entities/Collection'; | ||
import { UnauthorizedError } from './errors'; | ||
import { UnauthorizedError, MultiActionError } from './errors'; | ||
import FormData from 'form-data'; | ||
@@ -487,2 +487,100 @@ import { dataURItoBlob } from './fileHelpers'; | ||
} | ||
/** | ||
* This function creates a customer, job, and an optional appointment, which together make | ||
* the action of "create and optionally schedule a job" | ||
* | ||
* IF `customerData` has an `id` property, then it will be assumed that the customer already | ||
* exists and the customer creation step will be skipped. | ||
* | ||
* IF there is an error, the returned promise will be REJECTED with a MultiActionError. This | ||
* error type has a `data` property, which in this case will be an object with `job`, `customer`, | ||
* and `appointment` properties, denoting the error that happened in each step, if applicable. | ||
* | ||
* IF it succeeds, the returned promise will be RESOLVED with an object containing properties for | ||
* `job`, `customer`, and `appointment`, which will be the returned values from the API as a | ||
* result of creating each respective entity. | ||
* | ||
* @param {Object} jobInfo Job data | ||
* @param {Object} customerInfo Customer data | ||
* @param {Object} appointmentInfo (optional) Appointment data | ||
* @return {Promise<Object>} [description] | ||
*/ | ||
createAndScheduleJob(jobInfo, customerInfo, appointmentInfo = null) { | ||
const returnData = { | ||
job: null, | ||
customer: null, | ||
appointment: null, | ||
}; | ||
const errorData = { | ||
job: null, | ||
customer: null, | ||
appointment: null, | ||
}; | ||
const createCustomer = () => { | ||
if (customerInfo.id) { | ||
jobInfo.customer_id = customerInfo.id; | ||
return Promise.resolve(); | ||
} | ||
return new Promise((resolve, reject) => { | ||
this.entities.customers.create(customerInfo) | ||
.then(customer => { | ||
returnData.customer = customer; | ||
jobInfo.customer_id = customer.id; | ||
resolve(); | ||
}).catch(err => { | ||
errorData.customer = err; | ||
reject(err); | ||
}); | ||
}); | ||
}; | ||
const createJob = () => { | ||
return new Promise((resolve, reject) => { | ||
this.entities.jobs.create(jobInfo) | ||
.then(job => { | ||
returnData.job = job; | ||
if (appointmentInfo) { | ||
appointmentInfo.job_id = job.id; | ||
} | ||
resolve(); | ||
}) | ||
.catch(err => { | ||
errorData.job = err; | ||
reject(err); | ||
}); | ||
}); | ||
}; | ||
const createAppointment = () => { | ||
if (!appointmentInfo) { | ||
return Promise.resolve(); | ||
} | ||
return new Promise((resolve, reject) => { | ||
this.entities.appointments.create(appointmentInfo) | ||
.then(appointment => { | ||
returnData.appointment = appointment; | ||
resolve(); | ||
}) | ||
.catch(err => { | ||
errorData.appointment = err; | ||
reject(err); | ||
}); | ||
}); | ||
}; | ||
return new Promise((resolve, reject) => { | ||
createCustomer() | ||
.then(() => createJob()) | ||
.then(() => createAppointment()) | ||
.then(() => { | ||
resolve(returnData); | ||
}) | ||
.catch(() => { | ||
reject(new MultiActionError('Job creation failed', errorData)); | ||
}); | ||
}); | ||
} | ||
} |
import nock from 'nock'; | ||
import Dispatch from './dispatch'; | ||
import expect from 'expect'; | ||
import { UnauthorizedError } from './errors'; | ||
import expect, { spyOn, restoreSpies } from 'expect'; | ||
import { UnauthorizedError, MultiActionError, UnprocessableEntityError } from './errors'; | ||
@@ -330,2 +330,175 @@ const testClientID = '12345'; | ||
}); | ||
describe('createAndScheduleJob', () => { | ||
let client; | ||
beforeEach(() => { | ||
client = new Dispatch(testClientID, testClientSecret); | ||
client.setBearerToken(testBearerToken, testRefreshToken); | ||
}); | ||
afterEach(() => { | ||
restoreSpies(); | ||
}); | ||
describe('error handling', () => { | ||
it('should fail and store the customer error correctly if the customer creation fails', done => { | ||
spyOn(client.entities.customers, 'create').andReturn(Promise.reject(new UnprocessableEntityError({}))); | ||
client.createAndScheduleJob({}, { | ||
full_name: 'Testy McGee', | ||
}).then(() => { | ||
done(new Error('Should not have worked man')); | ||
}).catch(err => { | ||
expect(err instanceof MultiActionError).toEqual(true); | ||
expect(err.data.customer instanceof UnprocessableEntityError).toEqual(true); | ||
expect(err.data.job).toEqual(null); | ||
expect(err.data.appointment).toEqual(null); | ||
done(); | ||
}); | ||
}); | ||
it('should fail and store the job error correctly if the job creation fails', done => { | ||
spyOn(client.entities.customers, 'create').andReturn(Promise.resolve({ | ||
id: 123, | ||
full_name: 'Testy Mcgee', | ||
})); | ||
spyOn(client.entities.jobs, 'create').andReturn(Promise.reject(new UnauthorizedError())); | ||
client.createAndScheduleJob({ | ||
title: 'Test Job', | ||
}, { | ||
full_name: 'Testy McGee', | ||
}).then(() => { | ||
done(new Error('Should not have worked man')); | ||
}).catch(err => { | ||
expect(err instanceof MultiActionError).toEqual(true); | ||
expect(err.data.customer).toEqual(null); | ||
expect(err.data.job instanceof UnauthorizedError).toEqual(true); | ||
expect(err.data.appointment).toEqual(null); | ||
done(); | ||
}); | ||
}); | ||
it('should fail and store the appointment error correctly if the appointment creation fails', done => { | ||
spyOn(client.entities.customers, 'create').andReturn(Promise.resolve({ | ||
id: 123, | ||
full_name: 'Testy Mcgee', | ||
})); | ||
spyOn(client.entities.jobs, 'create').andReturn(Promise.resolve({ | ||
id: 456, | ||
title: 'Test Job', | ||
})); | ||
spyOn(client.entities.appointments, 'create').andReturn(Promise.reject(new UnauthorizedError())); | ||
client.createAndScheduleJob({ | ||
title: 'Test Job', | ||
}, { | ||
full_name: 'Testy McGee', | ||
}, { | ||
time: '12345', | ||
}).then(() => { | ||
done(new Error('Should not have worked man')); | ||
}).catch(err => { | ||
expect(err instanceof MultiActionError).toEqual(true); | ||
expect(err.data.customer).toEqual(null); | ||
expect(err.data.appointment instanceof UnauthorizedError).toEqual(true); | ||
expect(err.data.job).toEqual(null); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('success', () => { | ||
it('should make post requests with all correct data with appointment', done => { | ||
spyOn(client.entities.customers, 'create').andReturn(Promise.resolve({ | ||
id: 123, | ||
full_name: 'Testy Mcgee', | ||
})); | ||
spyOn(client.entities.jobs, 'create').andReturn(Promise.resolve({ | ||
id: 456, | ||
title: 'Test Job', | ||
customer_id: 123, | ||
})); | ||
spyOn(client.entities.appointments, 'create').andReturn(Promise.resolve({ | ||
id: 789, | ||
job_id: 456, | ||
time: '12345', | ||
})); | ||
client.createAndScheduleJob({ | ||
title: 'Test Job', | ||
}, { | ||
full_name: 'Testy McGee', | ||
}, { | ||
time: '12345', | ||
}).then((response) => { | ||
expect(response).toEqual({ | ||
job: { | ||
id: 456, | ||
title: 'Test Job', | ||
customer_id: 123, | ||
}, | ||
customer: { | ||
id: 123, | ||
full_name: 'Testy Mcgee', | ||
}, | ||
appointment: { | ||
job_id: 456, | ||
id: 789, | ||
time: '12345', | ||
}, | ||
}); | ||
// Make sure it set the right IDs | ||
expect(client.entities.customers.create).toHaveBeenCalledWith({ | ||
full_name: 'Testy McGee', | ||
}); | ||
expect(client.entities.jobs.create).toHaveBeenCalledWith({ | ||
customer_id: 123, | ||
title: 'Test Job', | ||
}); | ||
expect(client.entities.appointments.create).toHaveBeenCalledWith({ | ||
job_id: 456, | ||
time: '12345', | ||
}); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('should make post requests with all correct data with existing customer', done => { | ||
spyOn(client.entities.customers, 'create').andCallThrough(); | ||
spyOn(client.entities.jobs, 'create').andReturn(Promise.resolve({ | ||
id: 456, | ||
title: 'Test Job', | ||
customer_id: 123, | ||
})); | ||
client.createAndScheduleJob({ | ||
title: 'Test Job', | ||
}, { | ||
id: 123, | ||
}).then((response) => { | ||
expect(response).toEqual({ | ||
job: { | ||
id: 456, | ||
title: 'Test Job', | ||
customer_id: 123, | ||
}, | ||
customer: null, | ||
appointment: null, | ||
}); | ||
expect(client.entities.customers.create).toNotHaveBeenCalled(); | ||
expect(client.entities.jobs.create).toHaveBeenCalledWith({ | ||
customer_id: 123, | ||
title: 'Test Job', | ||
}); | ||
// Not creating appointment is tested here as well. | ||
done(); | ||
}).catch(done); | ||
}); | ||
}); | ||
}); | ||
}); |
@@ -58,1 +58,12 @@ function makeError(klass) { | ||
export class MultiActionError { | ||
constructor(message, data) { | ||
this.name = 'MultiActionError'; | ||
this.message = message; | ||
this.data = data; | ||
this.stack = (new Error()).stack; | ||
} | ||
} | ||
makeError(MultiActionError); | ||
{ | ||
"name": "dispatch-node-sdk", | ||
"version": "0.0.32", | ||
"version": "0.0.33", | ||
"description": "High- and low-level libraries for interacting with the Dispatch API", | ||
@@ -5,0 +5,0 @@ "main": "dist/lib/index.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
163806
4201
2