-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactoring code to follow Zapier CLI best practices.
- Loading branch information
1 parent
ca410ff
commit 0e7f8b6
Showing
5 changed files
with
239 additions
and
299 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/** | ||
* Retrieves the ID of a case goods lot from the API. | ||
* | ||
* @param {Object} z - The Zapier core object. | ||
* @param {Object} bundle - The Zapier bundle object. | ||
* @return {Promise} - A promise that resolves to an array with the lot ID object. | ||
* @throws {Error} - Throws an error for invalid JSON response or unexpected status codes. | ||
*/ | ||
const getCaseGoodsLotId = async (z, bundle) => { | ||
const headers = { | ||
'Content-Type': 'application/json', | ||
'Accept': 'application/json', | ||
'Authorization': `Access-Token ${bundle.authData.accessToken}`, | ||
}; | ||
|
||
const url = `https://sutter.innovint.us/api/v1/wineries/${bundle.inputData.wineryId}/lots`; | ||
const responseData = await z.request(url, 'GET', | ||
{limit: 1, q: bundle.inputData.caseGoodsName}, headers); | ||
|
||
if (responseData) { | ||
if (responseData.status === 200) { | ||
// Check if the responseData.data is undefined (invalid JSON response) | ||
if (!responseData.data) { | ||
throw new Error('Invalid JSON response'); | ||
} | ||
|
||
// Handle a successful response (HTTP 200) | ||
const lotData = responseData.data.results[0]?.data; | ||
if (lotData && lotData.id) { | ||
return [{id: lotData.id}]; // Return an array with the lot ID object | ||
} else { | ||
throw new Error( | ||
'No lot found with the provided name, or the data structure is unexpected.'); | ||
} | ||
} else if (responseData.status === 400) { | ||
// Handle a Bad Request (HTTP 400) response | ||
if (responseData.data && responseData.data.errors && | ||
responseData.data.errors.length > 0) { | ||
const firstError = responseData.data.errors[0]; | ||
const errorMessage = firstError.details || 'Bad Request'; | ||
throw new Error(errorMessage); | ||
} else { | ||
throw new Error('Bad Request: The request parameters are invalid.'); | ||
} | ||
} else if (responseData.status === 500) { | ||
// Handle a Server Error (HTTP 500) response | ||
if (responseData.data && responseData.data.errors && | ||
responseData.data.errors.length > 0) { | ||
const firstError = responseData.data.errors[0]; | ||
const errorMessage = firstError.details || 'Internal Server Error'; | ||
throw new Error(errorMessage); | ||
} else { | ||
throw new Error( | ||
'Internal Server Error: An internal server error occurred.'); | ||
} | ||
} else { | ||
// Handle other response status codes if needed | ||
throw new Error(`Request failed with status ${responseData.status}`); | ||
} | ||
} else { | ||
// Handle unexpected response data (null or undefined) | ||
throw new Error('Unexpected response data from the API.'); | ||
} | ||
}; | ||
|
||
module.exports = { | ||
key: 'getCaseGoodsLotId', | ||
noun: 'Lot ID', | ||
display: { | ||
label: 'Get Lot By Case Goods Name', | ||
description: 'Gets a lot ID based on the provided case goods name.', | ||
}, | ||
operation: { | ||
perform: getCaseGoodsLotId, | ||
inputFields: [ | ||
{key: 'wineryId', required: true, type: 'string'}, | ||
{key: 'caseGoodsName', required: true, type: 'string'}, | ||
], | ||
sample: {id: 'lot_Z1LPW8OQMY23L6QM3KXJD45Y'}, | ||
}, | ||
}; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
const zapier = require('zapier-platform-core'); | ||
const nock = require('nock'); | ||
const should = require('should'); | ||
const App = require('../../../index'); // Adjust this path as necessary | ||
/** | ||
* Creates a testing instance for the specified Zapier app. | ||
* | ||
* @param {Object} App - The Zapier app object. | ||
* @returns {Object} - The testing instance for the app. | ||
*/ | ||
const appTester = zapier.createAppTester(App); | ||
const {bundle} = require('../../_bundle'); | ||
|
||
describe('getCaseGoodsLotId', function() { | ||
afterEach(() => { | ||
nock.cleanAll(); | ||
}); | ||
|
||
it('should handle HTTP errors', async () => { | ||
nock(bundle.baseUrl) | ||
.get(`/api/v1/wineries/${bundle.inputData.wineryId}/lots`) | ||
.query(true) | ||
.reply(400, {}); | ||
|
||
try { | ||
await appTester(App.searches.getCaseGoodsLotId.operation.perform, bundle); | ||
should.fail('No error', 'Error', 'No error was thrown', 'should.fail'); | ||
} catch (error) { | ||
const errorObject = JSON.parse(error.message); | ||
should(errorObject.status).be.equal(400); | ||
} | ||
}); | ||
|
||
it('should fetch the correct Lot ID', async () => { | ||
const lotIdResponse = { | ||
results: [{data: {id: 'lot_Z1LPW8OQMY23L6QM3KXJD45Y'}}], // Mock response structure | ||
}; | ||
|
||
nock(bundle.baseUrl) | ||
.get(`/api/v1/wineries/${bundle.inputData.wineryId}/lots`) | ||
.query(true) | ||
.reply(200, lotIdResponse); | ||
|
||
const result = await appTester( | ||
App.searches.getCaseGoodsLotId.operation.perform, bundle); | ||
should(result[0]).have.property('id', 'lot_Z1LPW8OQMY23L6QM3KXJD45Y'); // Check the first element of the array | ||
}); | ||
|
||
it('should throw an error if no lot is found', async () => { | ||
nock(bundle.baseUrl) | ||
.get(`/api/v1/wineries/${bundle.inputData.wineryId}/lots`) | ||
.query(true) | ||
.reply(200, | ||
{results: [], pagination: {count: 0, next: null, previous: null}}); | ||
|
||
try { | ||
await appTester(App.searches.getCaseGoodsLotId.operation.perform, bundle); | ||
should.fail('No error', 'Error', 'No error was thrown', 'should.fail'); | ||
} catch (error) { | ||
error.message.should.containEql( | ||
'No lot found with the provided name, or the data structure is unexpected.'); | ||
} | ||
}); | ||
|
||
it('should handle HTTP 400 Bad Request errors', async () => { | ||
nock(bundle.baseUrl) | ||
.get(`/api/v1/wineries/${bundle.inputData.wineryId}/lots`) | ||
.query(true) | ||
.reply(400, { | ||
errors: [{details: 'Invalid input data'}], | ||
}); | ||
|
||
try { | ||
await appTester(App.searches.getCaseGoodsLotId.operation.perform, bundle); | ||
should.fail('No error', 'Error', 'No error was thrown', 'should.fail'); | ||
} catch (error) { | ||
try { | ||
const errorContent = JSON.parse(error.message).content; | ||
const errorObject = JSON.parse(errorContent); | ||
should.exist(errorObject); // Ensure errorObject is not null or undefined | ||
should(errorObject.errors[0].details).be.equal('Invalid input data'); | ||
} catch (parseError) { | ||
should.fail('Error parsing JSON response', 'Error', parseError.message, | ||
'should.fail'); | ||
} | ||
} | ||
}); | ||
|
||
it('should handle HTTP 500 Internal Server Error', async () => { | ||
nock(bundle.baseUrl) | ||
.get(`/api/v1/wineries/${bundle.inputData.wineryId}/lots`) | ||
.query(true) | ||
.reply(500, { | ||
errors: [{details: 'Internal server error'}], | ||
}); | ||
|
||
try { | ||
await appTester(App.searches.getCaseGoodsLotId.operation.perform, bundle); | ||
should.fail('No error', 'Error', 'No error was thrown', 'should.fail'); | ||
} catch (error) { | ||
try { | ||
const errorContent = JSON.parse(error.message).content; | ||
const errorObject = JSON.parse(errorContent); | ||
should.exist(errorObject); // Ensure errorObject is not null or undefined | ||
should(errorObject.errors[0].details).be.equal('Internal server error'); | ||
} catch (parseError) { | ||
should.fail('Error parsing JSON response', 'Error', parseError.message, | ||
'should.fail'); | ||
} | ||
} | ||
}); | ||
|
||
it('should handle invalid JSON responses', async () => { | ||
nock(bundle.baseUrl) | ||
.get(`/api/v1/wineries/${bundle.inputData.wineryId}/lots`) | ||
.query(true) | ||
.reply(200, 'This is not JSON'); | ||
|
||
try { | ||
await appTester(App.searches.getCaseGoodsLotId.operation.perform, bundle); | ||
should.fail('No error', 'Error', 'Expected an invalid JSON error', | ||
'should.fail'); | ||
} catch (error) { | ||
should(error.message).containEql('Invalid JSON response'); | ||
} | ||
}); | ||
|
||
it('should handle invalid input data', async function() { | ||
// Modify the bundle to simulate invalid input | ||
const invalidBundle = { | ||
...bundle, | ||
inputData: { | ||
wineryId: 'invalid-id', | ||
caseGoodsName: 'InvalidName', | ||
}, | ||
}; | ||
|
||
try { | ||
await appTester(App.searches.getCaseGoodsLotId.operation.perform, | ||
invalidBundle); | ||
should.fail('No error', 'Error', 'Expected an invalid input error', | ||
'should.fail'); | ||
} catch (error) { | ||
should(error.message).containEql('Innovint server error!'); | ||
} | ||
}); | ||
}); |
Oops, something went wrong.