Skip to content

Commit

Permalink
Merge pull request #54 from bhushankumarl/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
Bhushankumar L authored Sep 22, 2018
2 parents f927a5f + 1694d89 commit da53aec
Show file tree
Hide file tree
Showing 11 changed files with 193 additions and 30 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ node_js:
- "6"
- "7"
- "8"
- "9"
sudo: false
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
0.0.20
- Handle for non content type responses
- Bug fix for GetMyPriceForASIN and similar other products API
- Add example, test case for GetMyPriceForASIN
- Add test case for failure/error responses
- Add support for RequestReport API
- Add example for GetMyFeesEstimate in Products
- Add force check for the XML string

0.0.19
- Correct lint and increase test case timeout
- Added Status Code in Error Response.
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# amazon-mws (Amazon Marketplace Web Service)
[![Version](https://img.shields.io/npm/v/amazon-mws.svg)](https://www.npmjs.org/package/amazon-mws)
[![Build Status](https://travis-ci.org/bhushankumarl/amazon-mws.svg?branch=master)](https://travis-ci.org/bhushankumarl/amazon-mws)

This API supported Amazon Marketplace Web Service(MWS)'s standard REST-style API that accepts/returns JSON requests and Here is the [API reference] (http://docs.developer.amazonservices.com/en_IN/dev_guide/DG_IfNew.html)
Expand Down
33 changes: 33 additions & 0 deletions examples/javaScript/products/getMyFeesEstimate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use strict';

var accessKey = process.env.AWS_ACCESS_KEY_ID || 'YOUR_KEY';
var accessSecret = process.env.AWS_SECRET_ACCESS_KEY || 'YOUR_SECRET';

var amazonMws = require('../../../lib/amazon-mws')(accessKey, accessSecret);

var productRequest = function () {
amazonMws.products.searchFor({
'Version': '2011-10-01',
'Action': 'GetMyFeesEstimate',
'SellerId': 'SELLER_ID',
'MWSAuthToken': 'MWS_AUTH_TOKEN',
'FeesEstimateRequestList.FeesEstimateRequest.1.MarketplaceId': 'MARKET_PLACE_ID',
'FeesEstimateRequestList.FeesEstimateRequest.1.IdType': 'ASIN',
'FeesEstimateRequestList.FeesEstimateRequest.1.IdValue': 'ASIN',
'FeesEstimateRequestList.FeesEstimateRequest.1.IsAmazonFulfilled': 'true',
'FeesEstimateRequestList.FeesEstimateRequest.1.Identifier': 'Hello',
'FeesEstimateRequestList.FeesEstimateRequest.1.PriceToEstimateFees.ListingPrice.CurrencyCode': 'USD',
'FeesEstimateRequestList.FeesEstimateRequest.1.PriceToEstimateFees.ListingPrice.Amount': '30.00',
'FeesEstimateRequestList.FeesEstimateRequest.1.PriceToEstimateFees.Shipping.CurrencyCode': 'USD',
'FeesEstimateRequestList.FeesEstimateRequest.1.PriceToEstimateFees.Shipping.Amount': '3.99',
'FeesEstimateRequestList.FeesEstimateRequest.1.PriceToEstimateFees.Points.PointsNumber': '0'
}, function (error, response) {
if (error) {
console.log('error products', error);
return;
}
console.log('response ', response);
});
};

productRequest();
25 changes: 25 additions & 0 deletions examples/javaScript/products/getMyPriceForASIN.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use strict';

var accessKey = process.env.AWS_ACCESS_KEY_ID || 'YOUR_KEY';
var accessSecret = process.env.AWS_SECRET_ACCESS_KEY || 'YOUR_SECRET';

var amazonMws = require('../../../lib/amazon-mws')(accessKey, accessSecret);

var productRequest = function () {
amazonMws.products.searchFor({
'Version': '2011-10-01',
'Action': 'GetMyPriceForASIN',
'SellerId': 'SELLER_ID',
'MWSAuthToken': 'MWS_AUTH_TOKEN',
'MarketplaceId': 'MARKET_PLACE_ID',
'ASINList.ASIN.1': 'ASINList_ASIN_1'
}, function (error, response) {
if (error) {
console.log('error products', error);
return;
}
console.log('response ', response);
});
};

productRequest();
2 changes: 2 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ declare class Products extends BaseAmazonMWS {

declare class Reports extends BaseAmazonMWS {

submit(params: any): Promise<any>;

}

declare class Sellers extends BaseAmazonMWS {
Expand Down
72 changes: 44 additions & 28 deletions lib/AmazonMwsResource.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ var Error = require('./Error');

var hasOwn = {}.hasOwnProperty;

var RESPONSE_CONTENT_TYPE = ['text/xml', 'text/xml;charset=utf-8', 'application/xml'];
var RESPONSE_CONTENT_TYPE_XML = ['text/xml', 'text/xml;charset=utf-8', 'application/xml'];
// Provide extension mechanism for AmazonMws Resource Sub-Classes
AmazonMwsResource.extend = utils.protoExtend;

Expand Down Expand Up @@ -168,20 +168,31 @@ AmazonMwsResource.prototype = {

function processResponseType(res, responseString, callback) {
//debug('res %o ', res);
//debug('res.headers %o ', res.headers);
if (RESPONSE_CONTENT_TYPE.indexOf(res.headers['content-type'].toLowerCase()) > -1) {
var xmlParser = new xml2js.Parser({
mergeAttrs: true,
explicitArray: false,
emptyTag: {}
});
if (!res.headers['content-type']) {
debug('Content type has not set, so considered it as XML response');
xmlParser.parseString(responseString, function (err, response) {
//debug('response after parsing JSON %o ', response);
return callback(null, response);
});
} else if (RESPONSE_CONTENT_TYPE_XML.indexOf(res.headers['content-type'].toLowerCase()) > -1) {
debug('It is XML Response');
var parser = new xml2js.Parser({
explicitArray: false,
ignoreAttrs: true
xmlParser.parseString(responseString, function (err, response) {
// debug('response after parsing JSON %o ', response);
return callback(null, response);
});

parser.parseString(responseString, function (err, response) {
//debug('response after parsing JSON %o ', response);
} else if (_.includes(responseString, '?xml')) {
debug('It is XML Response be find out from responseString');
xmlParser.parseString(responseString, function (err, response) {
// debug('response after parsing JSON %o ', response);
return callback(null, response);
});
} else {
debug('It is NON-XML Response');
debug('It is NON-XML Response, so considered it as CSV file');
var TAB_DELIMITER = '\t';
var COMMA_DELIMITER = ',';
parseCSVFile(res, responseString, TAB_DELIMITER, function (error, response) {
Expand All @@ -200,29 +211,34 @@ AmazonMwsResource.prototype = {
var dbgResponseBuffer = [];
var headers = res.headers;
var statusCode = res.statusCode;
var contentType = '';
if (headers['content-type']) {
contentType = headers['content-type'].toLowerCase();
}
try {
statusCode = parseInt(statusCode, 10);
} catch (Exception) {
debug('Failed to parse statusCode as statusCode not provided in the response. ', statusCode);
}
var charset = '';
var content_type = '';
var responseString = '';
if (headers['content-type'].indexOf('charset') > -1 && headers['content-type'].split(';')[0] && headers['content-type'].split(';')[1]) {
content_type = headers['content-type'].split(';')[0].toLowerCase();
if (headers['content-type'].split(';')[1].match(/^((\b[^\s=]+)=(([^=]|\\=)+))*$/)[3]) {
charset = headers['content-type'].split(';')[1].match(/^((\b[^\s=]+)=(([^=]|\\=)+))*$/)[3];

/**
* Separate the charset & content type
*/
if (contentType.indexOf('charset') > -1 && contentType.split(';')[0] && contentType.split(';')[1]) {
if (contentType.split(';')[1] && contentType.split(';')[1].match(/^((\b[^\s=]+)=(([^=]|\\=)+))*$/)[3]) {
charset = contentType.split(';')[1].match(/^((\b[^\s=]+)=(([^=]|\\=)+))*$/)[3];
}
} else {
content_type = headers['content-type'].toLowerCase();
contentType = contentType.split(';')[0].toLowerCase();
}

var ResponseHeaders = {
'x-mws-quota-max': res.headers['x-mws-quota-max'] || 'unknown',
'x-mws-quota-remaining': res.headers['x-mws-quota-remaining'] || 'unknown',
'x-mws-quota-resetson': res.headers['x-mws-quota-resetson'] || 'unknown',
'x-mws-timestamp': res.headers['x-mws-timestamp'],
'content-type': content_type || 'unknown',
'content-type': contentType || 'unknown',
'content-charset': charset || 'unknown',
'content-length': res.headers['content-length'] || 'unknown',
'content-md5': res.headers['content-md5'] || 'unknown',
Expand Down Expand Up @@ -269,21 +285,21 @@ AmazonMwsResource.prototype = {
}

debug('responseString ', responseString);
debug('content_type ', content_type);
debug('contentType ', contentType);
debug('statusCode ', statusCode);

if (!content_type) {
return callback.call(self, new Error.AmazonMwsAPIError({
message: 'Content Type is not provided in response received from the AmazonMws API',
StatusCode: statusCode || 'unknown'
}), null);
}

try {
var errorResponse = {};
if (statusCode > 499 && !responseString) {
errorResponse.message = res.statusMessage || 'unknown';
errorResponse.Headers = ResponseHeaders;
errorResponse.StatusCode = statusCode || 'unknown';
return callback.call(self, errorResponse, null);
}
processResponseType(res, responseString, function (error, response) {
if (response.ErrorResponse) {
debug('It is ErrorResponse');
var errorResponse = response.ErrorResponse.Error;
errorResponse = response.ErrorResponse.Error;
errorResponse.Headers = ResponseHeaders;
errorResponse.StatusCode = statusCode || 'unknown';
errorResponse.RequestId = response.ErrorResponse.RequestID || response.ErrorResponse.RequestId || 'unknown';
Expand All @@ -301,7 +317,7 @@ AmazonMwsResource.prototype = {
}

var ResponseMetadata = {};
if (RESPONSE_CONTENT_TYPE.indexOf(content_type) > -1) {
if (RESPONSE_CONTENT_TYPE_XML.indexOf(contentType) > -1) {
/**
* It should execute for only XML response
*/
Expand Down
4 changes: 3 additions & 1 deletion lib/resources/Reports.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ module.exports = AmazonMwsResource.extend({
path: 'Reports',
search: amazonMwsMethod({
method: 'GET'
}),
submit: amazonMwsMethod({
method: 'POST'
})

});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "amazon-mws",
"version": "0.0.19",
"version": "0.0.20",
"description": "Amazon MWS API wrapper",
"keywords": [
"Amazon MWS",
Expand Down
1 change: 1 addition & 0 deletions test/mocha.opts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
### mocha.opts
###

--exclude ./test/specs/fulfillmentInboundShipment.spec.js
--bail
--silly
--full-trace
Expand Down
73 changes: 73 additions & 0 deletions test/specs/products.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,77 @@ describe('Products', function () {
expect(response).to.have.property('Headers').to.have.property('x-mws-quota-resetson');
expect(response).to.have.property('Headers').to.have.property('x-mws-timestamp');
});

it('It should get my price for ASIN using getMyPriceForASIN Action', async function () {
var options = {
'Version': '2011-10-01',
'Action': 'GetMyPriceForASIN',
'SellerId': config.SellerId,
'MWSAuthToken': config.MWSAuthToken,
'MarketplaceId': config.MarketplaceId,
'ASINList.ASIN.1': config.ASIN
};
expect(options.SellerId).to.be.a('string');
expect(options.MWSAuthToken).to.be.a('string');
expect(options.MarketplaceId).to.be.a('string');
expect(options['ASINList.ASIN.1']).to.be.a('string');

var response = await amazonMws.products.searchFor(options);

expect(response).to.be.a('object');
expect(response).to.have.property('ASIN').to.be.a('string');
expect(response).to.have.property('status').to.be.a('string');
expect(response).to.have.property('Product').to.be.a('object');
expect(response).to.have.property('ResponseMetadata').to.be.a('object');
expect(response).to.have.property('ResponseMetadata').to.have.property('RequestId');
expect(response).to.have.property('Headers').to.be.a('object');
expect(response).to.have.property('Headers').to.have.property('x-mws-quota-max');
expect(response).to.have.property('Headers').to.have.property('x-mws-quota-remaining');
expect(response).to.have.property('Headers').to.have.property('x-mws-quota-resetson');
expect(response).to.have.property('Headers').to.have.property('x-mws-timestamp');
});

it('It should NOT get my price for INVALID ASIN using getMyPriceForASIN Action', async function () {
var options = {
'Version': '2011-10-01',
'Action': 'GetMyPriceForASIN',
'SellerId': config.SellerId,
'MWSAuthToken': config.MWSAuthToken,
'MarketplaceId': config.MarketplaceId,
'ASINList.ASIN.1': undefined
};
expect(options.SellerId).to.be.a('string');
expect(options.MWSAuthToken).to.be.a('string');
expect(options.MarketplaceId).to.be.a('string');

try {
var response = await amazonMws.products.searchFor(options);

expect(response).to.be.a('object');
expect(response).to.have.property('ASIN').to.be.a('string');
expect(response).to.have.property('status').to.be.a('string');
expect(response).to.have.property('Product').to.be.a('object');
expect(response).to.have.property('ResponseMetadata').to.be.a('object');
expect(response).to.have.property('ResponseMetadata').to.have.property('RequestId');
expect(response).to.have.property('Headers').to.be.a('object');
expect(response).to.have.property('Headers').to.have.property('x-mws-quota-max');
expect(response).to.have.property('Headers').to.have.property('x-mws-quota-remaining');
expect(response).to.have.property('Headers').to.have.property('x-mws-quota-resetson');
expect(response).to.have.property('Headers').to.have.property('x-mws-timestamp');
} catch (exception) {
console.log('exception ', exception);
expect(exception).to.be.a('object');
expect(exception).to.have.property('Type').to.be.a('string');
expect(exception).to.have.property('Message').to.be.a('string');
expect(exception).to.have.property('Detail').to.be.a('object');
expect(exception).to.have.property('StatusCode').to.be.a('number');
expect(exception).to.have.property('RequestId').to.be.a('string');
expect(exception).to.have.property('Headers').to.be.a('object');
expect(exception).to.have.property('Headers').to.have.property('x-mws-quota-max');
expect(exception).to.have.property('Headers').to.have.property('x-mws-quota-remaining');
expect(exception).to.have.property('Headers').to.have.property('x-mws-quota-resetson');
expect(exception).to.have.property('Headers').to.have.property('x-mws-timestamp');
}

});
});

0 comments on commit da53aec

Please sign in to comment.