Skip to content

Commit

Permalink
feat(package): ES2015 refactoring, drop usage of lodash
Browse files Browse the repository at this point in the history
BREAKING CHANGE: minimum version is node 4
  • Loading branch information
sonicoder86 committed Nov 11, 2017
1 parent ae9f788 commit f02bdd4
Show file tree
Hide file tree
Showing 17 changed files with 4,370 additions and 457 deletions.
22 changes: 0 additions & 22 deletions LICENSE

This file was deleted.

107 changes: 107 additions & 0 deletions lib/request.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
'use strict';

const Escher = require('escher-auth');
const Options = require('./requestOption');
const Wrapper = require('./wrapper');
const SuiteRequestError = require('./requestError');
const logger = require('logentries-logformat')('suiterequest');

class SuiteRequest {

static create(accessKeyId, apiSecret, requestOptions) {
return new SuiteRequest(accessKeyId, apiSecret, requestOptions);
}

constructor(accessKeyId, apiSecret, requestOptions) {
const escherConfig = Object.assign({}, SuiteRequest.EscherConstants, {
accessKeyId: accessKeyId,
apiSecret: apiSecret,
credentialScope: requestOptions.credentialScope || SuiteRequest.EscherConstants.credentialScope
});

this._escher = new Escher(escherConfig);
this._options = requestOptions;
}

get(path) {
return this._request('GET', path);
}

post(path, data) {
return this._request('POST', path, data);
}

put(path, data) {
return this._request('PUT', path, data);
}

delete(path) {
return this._request('DELETE', path);
}

_request(method, path, data) {
const options = this._getOptionsFor(method, path);
const payload = data ? this._getPayload(data) : '';
const signedOptions = this._signRequest(options, payload);

logger.log('send', this._getLogParameters(options));
return this._getRequestFor(signedOptions, payload).send();
}

setOptions(requestOptions) {
this._options = requestOptions;
}

getOptions() {
return this._options;
}

_getRequestFor(requestOptions, payload) {
const protocol = (this._options.secure) ? 'https:' : 'http:';
return new Wrapper(requestOptions, protocol, payload);
}

_getOptionsFor(method, path) {
const defaultOptions = this._options.toHash();
const realPath = defaultOptions.prefix + path;

return Object.assign({}, defaultOptions, {
method: method,
url: realPath,
path: realPath
});
}

_signRequest(options, payload) {
const headerNames = options.headers.map(function(header) {
return header[0];
});

return this._escher.signRequest(options, payload, headerNames);
}

_getLogParameters(options) {
const { method, host, url } = options;
return { method, host, url };
}

_getPayload(data) {
if (this._options.getHeader('content-type').indexOf('application/json') === -1) {
return data;
}

return JSON.stringify(data);
}
}

SuiteRequest.EscherConstants = {
algoPrefix: 'EMS',
vendorKey: 'EMS',
credentialScope: 'eu/suite/ems_request',
authHeaderName: 'X-Ems-Auth',
dateHeaderName: 'X-Ems-Date'
};

module.exports = SuiteRequest;
module.exports.Options = Options;
module.exports.Error = SuiteRequestError;
34 changes: 17 additions & 17 deletions request.spec.js → lib/request.spec.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
'use strict';

var SuiteRequest = require('./request');
var request = require('request');
var Escher = require('escher-auth');
const SuiteRequest = require('./request');
const request = require('request');
const Escher = require('escher-auth');

describe('SuiteRequest', function() {
var serviceConfig = {
const serviceConfig = {
host: 'localhost',
port: 1234,
prefix: '/api',
Expand All @@ -14,21 +14,21 @@ describe('SuiteRequest', function() {
credentialScope: 'eu/dummy/ems_request'
};

var createDummyResponse = function() {
const createDummyResponse = function() {
return {
headers: {},
body: 'response body dummy'
};
};

var requestOptions;
let requestOptions;

beforeEach(function() {
requestOptions = new SuiteRequest.Options(serviceConfig.host, serviceConfig);
});

it('should sign headers of GET request', function() {
var suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions);
const suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions);

this.sandbox.stub(request, 'get', function(options, callback) {
expect(options.headers['x-ems-auth'])
Expand All @@ -40,7 +40,7 @@ describe('SuiteRequest', function() {
});

it('should sign headers of POST request', function() {
var suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions);
const suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions);

this.sandbox.stub(request, 'post', function(options, callback) {
expect(options.headers['x-ems-auth'])
Expand All @@ -52,7 +52,7 @@ describe('SuiteRequest', function() {
});

it('should sign headers of DELETE request', function() {
var suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions);
const suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions);

this.sandbox.stub(request, 'delete', function(options, callback) {
expect(options.headers['x-ems-auth'])
Expand All @@ -64,7 +64,7 @@ describe('SuiteRequest', function() {
});

it('should sign headers with non string values', function() {
var suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions);
const suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions);
requestOptions.setHeader(['x-customer-id', 15]);

this.sandbox.stub(request, 'post', function(options, callback) {
Expand All @@ -77,7 +77,7 @@ describe('SuiteRequest', function() {
});

it('should encode payload when content type is json', function() {
var suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions);
const suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions);
this.sandbox.stub(request, 'post', function(options, callback) {
try {
expect(options.body).to.eql('{"name":"Almanach"}');
Expand All @@ -91,7 +91,7 @@ describe('SuiteRequest', function() {
});

it('should encode payload when content type is utf8 json', function() {
var suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions);
const suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions);
requestOptions.setHeader(['content-type', 'application/json;charset=utf-8']);

this.sandbox.stub(request, 'post', function(options, callback) {
Expand All @@ -107,7 +107,7 @@ describe('SuiteRequest', function() {
});

it('should skip encoding of payload when content type is not json', function() {
var suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions);
const suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions);
requestOptions.setHeader(['content-type', 'text/csv']);

this.sandbox.stub(request, 'post', function(options, callback) {
Expand All @@ -124,7 +124,7 @@ describe('SuiteRequest', function() {

it('signs extra headers too', function() {
requestOptions.setHeader(['extra-header', 'header-value']);
var suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions);
const suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions);

this.sandbox.stub(request, 'get', function(options, callback) {
expect(options.headers['x-ems-auth'])
Expand All @@ -136,8 +136,8 @@ describe('SuiteRequest', function() {
});

it('should sign the payload of POST request', function() {
let suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions);
let payload = { name: 'Test' };
const suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions);
const payload = { name: 'Test' };
this.sandbox.spy(Escher.prototype, 'signRequest');

this.sandbox.stub(request, 'post', function(options, callback) {
Expand All @@ -147,7 +147,7 @@ describe('SuiteRequest', function() {
suiteRequest.post('/path', payload);

expect(Escher.prototype.signRequest.callCount).to.eql(1);
let firstCall = Escher.prototype.signRequest.getCall(0);
const firstCall = Escher.prototype.signRequest.getCall(0);
expect(firstCall.args[1]).to.eql(JSON.stringify(payload));
});
});
20 changes: 20 additions & 0 deletions lib/requestError.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use strict';

class SuiteRequestError extends Error {
constructor(message, code, response) {
super(message);

this.code = code;
this.name = 'SuiteRequestError';

if (response) {
this.data = response.data || response;
} else {
this.data = {
replyText: message
};
}
}
}

module.exports = SuiteRequestError;
10 changes: 5 additions & 5 deletions requestError.spec.js → lib/requestError.spec.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
'use strict';

var SuiteRequestError = require('./requestError');
const SuiteRequestError = require('./requestError');

describe('SuiteRequestError', function() {
it('should extend base Error class', function() {
var error = new SuiteRequestError();
const error = new SuiteRequestError();

expect(error).to.be.an.instanceOf(Error);
});

it('should store constructor parameters', function() {
var error = new SuiteRequestError('Invalid request', 400, {
const error = new SuiteRequestError('Invalid request', 400, {
data: {
replyText: 'Too long',
detailedMessage: 'Line too long'
Expand All @@ -26,7 +26,7 @@ describe('SuiteRequestError', function() {
});

it('should store response as is when no data attribute present', function() {
var error = new SuiteRequestError('Invalid request', 400, {
const error = new SuiteRequestError('Invalid request', 400, {
replyText: 'Too long',
detailedMessage: 'Line too long'
});
Expand All @@ -40,7 +40,7 @@ describe('SuiteRequestError', function() {
});

it('should always contain data on error', function() {
var error = new SuiteRequestError('Unauthorized');
const error = new SuiteRequestError('Unauthorized');

expect(error.data).to.eql({ replyText: 'Unauthorized' });
});
Expand Down

0 comments on commit f02bdd4

Please sign in to comment.