From a733def9ba82b479efedf395488f2afd5ea9bd18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Parker?= Date: Tue, 26 Apr 2016 15:27:41 +0200 Subject: [PATCH 1/4] chore(line-endings): convert to LF --- mailjet-client.js | 750 +++++++++++++++++++++++----------------------- 1 file changed, 375 insertions(+), 375 deletions(-) diff --git a/mailjet-client.js b/mailjet-client.js index b250e71..1eb9a22 100755 --- a/mailjet-client.js +++ b/mailjet-client.js @@ -1,375 +1,375 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2015 Mailjet - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -const DEBUG_MODE = false; -const RESOURCE = 0; -const ID = 1; -const ACTION = 2; - -const STRICT = false; - -/* - * Imports. - * - * qs is used to format the url from the provided parameters and method - * _path will join a path according to the OS specifications - * https will be used to make a secure http request to the API - * fs will simply be used to read files - */ - -var qs = require ('querystring') - , request = require ('request') - , EventEmitter = require ('events').EventEmitter - , fs = require ('fs') - , _path = require ('path'); - - -/* - * MailjetClient constructor. - * - * @qpi_key (optional) {String} mailjet account api key - * @api_secret (optional) {String} mailjet account api secret - * - * If you don't know what this is about, sign up to Mailjet at: - * https://www.mailjet.com/ - */ -function MailjetClient (api_key, api_secret, testMode) { - this.config = require ('./config'); - this.testMode = testMode || false; - // To be updated according to the npm repo version - this.version = "1.0.3"; - if (api_key && api_secret) - this.connect(api_key, api_secret); -}; - -MailjetClient.prototype.typeJson = function (body) { - var keys = Object.keys(body); - for (var i in keys) { - var key = keys[i]; - body[key] = parseInt(body[key]) || body[key]; - } - return body; -}; - -/* - * [Static] connect. - * - * Return a nez connected instance of the MailjetClient class - * - * @k {String} mailjet qpi key - * @s {String} mailjet api secret - * - */ -MailjetClient.connect = function (k, s) { - return new MailjetClient().connect(k, s); -} - -/* - * connect. - * - * create a auth property from the api key and secret - * - * @api_key {String} - * @api_secret {String} - * - */ -MailjetClient.prototype.connect = function(apiKey, apiSecret) { - this.apiKey = apiKey; - this.apiSecret = apiSecret; - return this; -}; - -/* - * path. - * - * Returns a formatted url from a http method and - * a parameters object literal - * - * @resource {String} - * @sub {String} REST/''/DATA - * @params {Object literal} {name: value} - * - */ -MailjetClient.prototype.path = function(resource, sub, params) { - if (DEBUG_MODE) { - console.log("resource =", resource); - console.log("subPath =", sub); - console.log("filters =", params); - } - var base = _path.join(this.config.version, sub); - if (Object.keys(params).length === 0) - return base + '/' + resource; - - var q = qs.stringify(params); - return base + '/' + resource + '/?' + q; -}; - -/* - * httpRequest. - * - * @method {String} http method (GET/POST...) - * @url {String} url path to be used for the request - * @data {Object literal} additional data espacially for POST/PUT operations - * @callback -optional {Function} called on response from the server, or on error - * - * @return a promise triggering 'success' on response - * and error on error - */ - -MailjetClient.prototype.httpRequest = function(method, url, data, callback) { - var promise = new EventEmitter().on('error', function () {}); - - /** - * json: true converts the output from string to JSON - */ - var options = { - json: url.indexOf('text:plain') === -1, - url: url, - useragent: 'mailjet-api-v3-nodejs/' + this.version, - auth: {user: this.apiKey, pass: this.apiSecret} - } - if ((method === 'post' || method === 'put')) { - options.body = STRICT ? this.typeJson(data) : data; - } - - options['Content-Type'] = url.toLowerCase().indexOf('text:plain') > -1 ? - 'text/plain' : 'application/json'; - - if (DEBUG_MODE) { - console.log ('Final url: ' + url); - console.log ('body: ' + options.body); - } - - if (this.testMode) { - return [options.url, options.body || {}]; - } - - if(method === 'delete'){ - method = 'del'; - } - /* - * request[method] returns either request.post, request.get etc - * - * If a callback is provided, it triggers it, else it trigger an event - * on the promise object - */ - request[method](options, function (err, response, body) { - if (err || (response.statusCode > 210)) { - if (callback) { - callback(err || body, response); - } - else promise.emit('error', err || body, response); - } else { - if (callback) callback(null, response, body); - else promise.emit('success', response, body); - } - }); - - return promise; -}; - -/* - * - * MailjetResource constructor - * - * This class creates a function that can be build through method chaining - * - * @method {String} http method - * @func {String} resource/path to be sent - * @context {MailjetClient[instance]} parent client - */ -function MailjetResource (method, func, context) { - this.base = func; - this.callUrl = func; - - this.resource = func.toLowerCase(); - - this.lastAdded = RESOURCE; - var self = context; - - /* - It can be REST or nothing if we only know the resource - */ - this.subPath = (function () { - if (func.toLowerCase() !== 'send') return 'REST'; - return ''; - })(); - - /** - * - * result. - * - * @params (optional) {Object Littteral} parameters to be sent to the server - * @callback (optional) {Function} called on response or error - */ - var that = this; - this.result = function (params, callback) { - params = params || {}; - if (typeof params === 'function') { - callback = params; - params = {}; - } - - /* - We build the querystring depending on the parameters. if the user explicitly mentionned - a filters property, we pass it to the url - */ - var path = self.path(that.callUrl, that.subPath, (function () { - if (params['filters']) { - var ret = params['filters']; - delete params['filters']; - return ret; - } else if (method === 'get') return params; - else return {}; - })()); - - that.callUrl = that.base; - self.lastAdded = RESOURCE; - return self.httpRequest(method, 'https://' + _path.join(self.config.url, path), params, callback); - } -} - -/** - * - * id. - * - * Add an ID and prevent invalid id chaining - * - * @value {String/Number} append an id to the path - * @return the MailjetResource instance to allow method chaining - * - */ -MailjetResource.prototype.id = function(value) { - if (this.lastAdded === ID && DEBUG_MODE) - console.warn('[WARNING] your request may fail due to invalid id chaining'); - - this.callUrl = _path.join(this.callUrl, value.toString()); - this.lastAdded = ID; - return this; -}; - -/** - * - * action. - * - * Add an Action and prevent invalid action chaining - * - * @value {String} append an action to the path - * @return the MailjetResource instance to allow method chaining - * - */ -MailjetResource.prototype.action = function(name) { - if (this.lastAdded === ACTION && DEBUG_MODE) - console.warn('[WARNING] your request may fail due to invalid action chaining'); - - this.callUrl = _path.join(this.callUrl, name); - this.action = name.toLowerCase(); - - this.lastAdded = ACTION; - - if (this.action.toLowerCase() == 'csvdata') - this.action = 'csvdata/text:plain'; - else if (this.action.toLowerCase() == 'csverror') - this.action = 'csverror/text:csv'; - - var self = this; - this.subPath = (function () { - if (self.resource === 'contactslist' && self.action === 'csvdata/text:plain' || - self.resource === 'batchjob' && self.action === 'csverror/text:csv') - return 'DATA'; - else return self.subPath; - })(); - return self; -}; - -/** - * - * request. - * - * @parmas {Object literal} method parameters - * @callback (optional) {Function} triggered when done - * - * @return {String} the server response - */ - -MailjetResource.prototype.request = function(params, callback) { - return this.result(params, callback); -}; - -/* - * post. - * - * @func {String} required Mailjet API function to be used (can contain a whole action path) - * - * @returns a function that make an httpRequest for each call - */ -MailjetClient.prototype.post = function(func) { - return new MailjetResource('post', func, this); -}; - - -/* - * get. - * - * @func {String} required Mailjet API function to be used (can contain a whole action path) - * - * @returns a function that make an httpRequest for each call - */ -MailjetClient.prototype.get = function(func) { - return new MailjetResource('get', func, this); -}; - -/* - * delete. - * - * @func {String} required Mailjet API function to be used (can contain a whole action path) - * - * @returns a function that make an httpRequest for each call - */ -MailjetClient.prototype.delete = function(func) { - return new MailjetResource('delete', func, this); -}; - -/* - * put. - * - * @func {String} required Mailjet API function to be used (can contain a whole action path) - * - * @returns a function that make an httpRequest for each call - */ -MailjetClient.prototype.put = function(func) { - return new MailjetResource('put', func, this); -}; - -/* - * Exports the Mailjet client. - * - * you can require it like so: - * var mj = require ('./mailjet-client'); - * - * or for the bleeding edge developpers out there: - * import mj from './mailjet-client'; - */ -module.exports = MailjetClient; +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 Mailjet + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +const DEBUG_MODE = false; +const RESOURCE = 0; +const ID = 1; +const ACTION = 2; + +const STRICT = false; + +/* + * Imports. + * + * qs is used to format the url from the provided parameters and method + * _path will join a path according to the OS specifications + * https will be used to make a secure http request to the API + * fs will simply be used to read files + */ + +var qs = require ('querystring') + , request = require ('request') + , EventEmitter = require ('events').EventEmitter + , fs = require ('fs') + , _path = require ('path'); + + +/* + * MailjetClient constructor. + * + * @qpi_key (optional) {String} mailjet account api key + * @api_secret (optional) {String} mailjet account api secret + * + * If you don't know what this is about, sign up to Mailjet at: + * https://www.mailjet.com/ + */ +function MailjetClient (api_key, api_secret, testMode) { + this.config = require ('./config'); + this.testMode = testMode || false; + // To be updated according to the npm repo version + this.version = "1.0.3"; + if (api_key && api_secret) + this.connect(api_key, api_secret); +}; + +MailjetClient.prototype.typeJson = function (body) { + var keys = Object.keys(body); + for (var i in keys) { + var key = keys[i]; + body[key] = parseInt(body[key]) || body[key]; + } + return body; +}; + +/* + * [Static] connect. + * + * Return a nez connected instance of the MailjetClient class + * + * @k {String} mailjet qpi key + * @s {String} mailjet api secret + * + */ +MailjetClient.connect = function (k, s) { + return new MailjetClient().connect(k, s); +} + +/* + * connect. + * + * create a auth property from the api key and secret + * + * @api_key {String} + * @api_secret {String} + * + */ +MailjetClient.prototype.connect = function(apiKey, apiSecret) { + this.apiKey = apiKey; + this.apiSecret = apiSecret; + return this; +}; + +/* + * path. + * + * Returns a formatted url from a http method and + * a parameters object literal + * + * @resource {String} + * @sub {String} REST/''/DATA + * @params {Object literal} {name: value} + * + */ +MailjetClient.prototype.path = function(resource, sub, params) { + if (DEBUG_MODE) { + console.log("resource =", resource); + console.log("subPath =", sub); + console.log("filters =", params); + } + var base = _path.join(this.config.version, sub); + if (Object.keys(params).length === 0) + return base + '/' + resource; + + var q = qs.stringify(params); + return base + '/' + resource + '/?' + q; +}; + +/* + * httpRequest. + * + * @method {String} http method (GET/POST...) + * @url {String} url path to be used for the request + * @data {Object literal} additional data espacially for POST/PUT operations + * @callback -optional {Function} called on response from the server, or on error + * + * @return a promise triggering 'success' on response + * and error on error + */ + +MailjetClient.prototype.httpRequest = function(method, url, data, callback) { + var promise = new EventEmitter().on('error', function () {}); + + /** + * json: true converts the output from string to JSON + */ + var options = { + json: url.indexOf('text:plain') === -1, + url: url, + useragent: 'mailjet-api-v3-nodejs/' + this.version, + auth: {user: this.apiKey, pass: this.apiSecret} + } + if ((method === 'post' || method === 'put')) { + options.body = STRICT ? this.typeJson(data) : data; + } + + options['Content-Type'] = url.toLowerCase().indexOf('text:plain') > -1 ? + 'text/plain' : 'application/json'; + + if (DEBUG_MODE) { + console.log ('Final url: ' + url); + console.log ('body: ' + options.body); + } + + if (this.testMode) { + return [options.url, options.body || {}]; + } + + if(method === 'delete'){ + method = 'del'; + } + /* + * request[method] returns either request.post, request.get etc + * + * If a callback is provided, it triggers it, else it trigger an event + * on the promise object + */ + request[method](options, function (err, response, body) { + if (err || (response.statusCode > 210)) { + if (callback) { + callback(err || body, response); + } + else promise.emit('error', err || body, response); + } else { + if (callback) callback(null, response, body); + else promise.emit('success', response, body); + } + }); + + return promise; +}; + +/* + * + * MailjetResource constructor + * + * This class creates a function that can be build through method chaining + * + * @method {String} http method + * @func {String} resource/path to be sent + * @context {MailjetClient[instance]} parent client + */ +function MailjetResource (method, func, context) { + this.base = func; + this.callUrl = func; + + this.resource = func.toLowerCase(); + + this.lastAdded = RESOURCE; + var self = context; + + /* + It can be REST or nothing if we only know the resource + */ + this.subPath = (function () { + if (func.toLowerCase() !== 'send') return 'REST'; + return ''; + })(); + + /** + * + * result. + * + * @params (optional) {Object Littteral} parameters to be sent to the server + * @callback (optional) {Function} called on response or error + */ + var that = this; + this.result = function (params, callback) { + params = params || {}; + if (typeof params === 'function') { + callback = params; + params = {}; + } + + /* + We build the querystring depending on the parameters. if the user explicitly mentionned + a filters property, we pass it to the url + */ + var path = self.path(that.callUrl, that.subPath, (function () { + if (params['filters']) { + var ret = params['filters']; + delete params['filters']; + return ret; + } else if (method === 'get') return params; + else return {}; + })()); + + that.callUrl = that.base; + self.lastAdded = RESOURCE; + return self.httpRequest(method, 'https://' + _path.join(self.config.url, path), params, callback); + } +} + +/** + * + * id. + * + * Add an ID and prevent invalid id chaining + * + * @value {String/Number} append an id to the path + * @return the MailjetResource instance to allow method chaining + * + */ +MailjetResource.prototype.id = function(value) { + if (this.lastAdded === ID && DEBUG_MODE) + console.warn('[WARNING] your request may fail due to invalid id chaining'); + + this.callUrl = _path.join(this.callUrl, value.toString()); + this.lastAdded = ID; + return this; +}; + +/** + * + * action. + * + * Add an Action and prevent invalid action chaining + * + * @value {String} append an action to the path + * @return the MailjetResource instance to allow method chaining + * + */ +MailjetResource.prototype.action = function(name) { + if (this.lastAdded === ACTION && DEBUG_MODE) + console.warn('[WARNING] your request may fail due to invalid action chaining'); + + this.callUrl = _path.join(this.callUrl, name); + this.action = name.toLowerCase(); + + this.lastAdded = ACTION; + + if (this.action.toLowerCase() == 'csvdata') + this.action = 'csvdata/text:plain'; + else if (this.action.toLowerCase() == 'csverror') + this.action = 'csverror/text:csv'; + + var self = this; + this.subPath = (function () { + if (self.resource === 'contactslist' && self.action === 'csvdata/text:plain' || + self.resource === 'batchjob' && self.action === 'csverror/text:csv') + return 'DATA'; + else return self.subPath; + })(); + return self; +}; + +/** + * + * request. + * + * @parmas {Object literal} method parameters + * @callback (optional) {Function} triggered when done + * + * @return {String} the server response + */ + +MailjetResource.prototype.request = function(params, callback) { + return this.result(params, callback); +}; + +/* + * post. + * + * @func {String} required Mailjet API function to be used (can contain a whole action path) + * + * @returns a function that make an httpRequest for each call + */ +MailjetClient.prototype.post = function(func) { + return new MailjetResource('post', func, this); +}; + + +/* + * get. + * + * @func {String} required Mailjet API function to be used (can contain a whole action path) + * + * @returns a function that make an httpRequest for each call + */ +MailjetClient.prototype.get = function(func) { + return new MailjetResource('get', func, this); +}; + +/* + * delete. + * + * @func {String} required Mailjet API function to be used (can contain a whole action path) + * + * @returns a function that make an httpRequest for each call + */ +MailjetClient.prototype.delete = function(func) { + return new MailjetResource('delete', func, this); +}; + +/* + * put. + * + * @func {String} required Mailjet API function to be used (can contain a whole action path) + * + * @returns a function that make an httpRequest for each call + */ +MailjetClient.prototype.put = function(func) { + return new MailjetResource('put', func, this); +}; + +/* + * Exports the Mailjet client. + * + * you can require it like so: + * var mj = require ('./mailjet-client'); + * + * or for the bleeding edge developpers out there: + * import mj from './mailjet-client'; + */ +module.exports = MailjetClient; From 975d1b640b8b8693cbdcd6fd5988b3b6a6ceda7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Parker?= Date: Tue, 26 Apr 2016 15:41:38 +0200 Subject: [PATCH 2/4] style(standard): format project to follow standard styleguide --- index.js | 4 +- mailjet-client.js | 400 ++++++++++++++++++++++++---------------------- package.json | 3 +- test/test.js | 371 +++++++++++++++++++++--------------------- 4 files changed, 392 insertions(+), 386 deletions(-) diff --git a/index.js b/index.js index 78bf3b2..4fd7824 100644 --- a/index.js +++ b/index.js @@ -1,3 +1,3 @@ -var mailjet = require ('./mailjet-client'); +var mailjet = require('./mailjet-client') -module.exports = mailjet; +module.exports = mailjet diff --git a/mailjet-client.js b/mailjet-client.js index 1eb9a22..4ec417e 100755 --- a/mailjet-client.js +++ b/mailjet-client.js @@ -23,12 +23,12 @@ * */ -const DEBUG_MODE = false; -const RESOURCE = 0; -const ID = 1; -const ACTION = 2; +const DEBUG_MODE = false +const RESOURCE = 0 +const ID = 1 +const ACTION = 2 -const STRICT = false; +const STRICT = false /* * Imports. @@ -39,12 +39,10 @@ const STRICT = false; * fs will simply be used to read files */ -var qs = require ('querystring') - , request = require ('request') - , EventEmitter = require ('events').EventEmitter - , fs = require ('fs') - , _path = require ('path'); - +var qs = require('querystring') +var request = require('request') +var EventEmitter = require('events').EventEmitter +var _path = require('path') /* * MailjetClient constructor. @@ -56,22 +54,23 @@ var qs = require ('querystring') * https://www.mailjet.com/ */ function MailjetClient (api_key, api_secret, testMode) { - this.config = require ('./config'); - this.testMode = testMode || false; - // To be updated according to the npm repo version - this.version = "1.0.3"; - if (api_key && api_secret) - this.connect(api_key, api_secret); -}; + this.config = require('./config') + this.testMode = testMode || false + // To be updated according to the npm repo version + this.version = '1.0.3' + if (api_key && api_secret) { + this.connect(api_key, api_secret) + } +} MailjetClient.prototype.typeJson = function (body) { - var keys = Object.keys(body); - for (var i in keys) { - var key = keys[i]; - body[key] = parseInt(body[key]) || body[key]; - } - return body; -}; + var keys = Object.keys(body) + for (var i in keys) { + var key = keys[i] + body[key] = parseInt(body[key]) || body[key] + } + return body +} /* * [Static] connect. @@ -83,7 +82,7 @@ MailjetClient.prototype.typeJson = function (body) { * */ MailjetClient.connect = function (k, s) { - return new MailjetClient().connect(k, s); + return new MailjetClient().connect(k, s) } /* @@ -95,11 +94,11 @@ MailjetClient.connect = function (k, s) { * @api_secret {String} * */ -MailjetClient.prototype.connect = function(apiKey, apiSecret) { - this.apiKey = apiKey; - this.apiSecret = apiSecret; - return this; -}; +MailjetClient.prototype.connect = function (apiKey, apiSecret) { + this.apiKey = apiKey + this.apiSecret = apiSecret + return this +} /* * path. @@ -112,19 +111,20 @@ MailjetClient.prototype.connect = function(apiKey, apiSecret) { * @params {Object literal} {name: value} * */ -MailjetClient.prototype.path = function(resource, sub, params) { - if (DEBUG_MODE) { - console.log("resource =", resource); - console.log("subPath =", sub); - console.log("filters =", params); - } - var base = _path.join(this.config.version, sub); - if (Object.keys(params).length === 0) - return base + '/' + resource; - - var q = qs.stringify(params); - return base + '/' + resource + '/?' + q; -}; +MailjetClient.prototype.path = function (resource, sub, params) { + if (DEBUG_MODE) { + console.log('resource =', resource) + console.log('subPath =', sub) + console.log('filters =', params) + } + var base = _path.join(this.config.version, sub) + if (Object.keys(params).length === 0) { + return base + '/' + resource + } + + var q = qs.stringify(params) + return base + '/' + resource + '/?' + q +} /* * httpRequest. @@ -138,57 +138,62 @@ MailjetClient.prototype.path = function(resource, sub, params) { * and error on error */ -MailjetClient.prototype.httpRequest = function(method, url, data, callback) { - var promise = new EventEmitter().on('error', function () {}); - - /** - * json: true converts the output from string to JSON - */ - var options = { - json: url.indexOf('text:plain') === -1, - url: url, - useragent: 'mailjet-api-v3-nodejs/' + this.version, - auth: {user: this.apiKey, pass: this.apiSecret} - } - if ((method === 'post' || method === 'put')) { - options.body = STRICT ? this.typeJson(data) : data; - } - - options['Content-Type'] = url.toLowerCase().indexOf('text:plain') > -1 ? - 'text/plain' : 'application/json'; - - if (DEBUG_MODE) { - console.log ('Final url: ' + url); - console.log ('body: ' + options.body); - } - - if (this.testMode) { - return [options.url, options.body || {}]; - } - - if(method === 'delete'){ - method = 'del'; - } - /* - * request[method] returns either request.post, request.get etc - * - * If a callback is provided, it triggers it, else it trigger an event - * on the promise object - */ - request[method](options, function (err, response, body) { - if (err || (response.statusCode > 210)) { - if (callback) { - callback(err || body, response); - } - else promise.emit('error', err || body, response); - } else { - if (callback) callback(null, response, body); - else promise.emit('success', response, body); - } - }); - - return promise; -}; +MailjetClient.prototype.httpRequest = function (method, url, data, callback) { + var promise = new EventEmitter().on('error', function () {}) + + /** + * json: true converts the output from string to JSON + */ + var options = { + json: url.indexOf('text:plain') === -1, + url: url, + useragent: 'mailjet-api-v3-nodejs/' + this.version, + auth: {user: this.apiKey, pass: this.apiSecret} + } + if (method === 'post' || method === 'put') { + options.body = STRICT ? this.typeJson(data) : data + } + + options['Content-Type'] = (url.toLowerCase().indexOf('text:plain') > -1) + ? 'text/plain' + : 'application/json' + + if (DEBUG_MODE) { + console.log('Final url: ' + url) + console.log('body: ' + options.body) + } + + if (this.testMode) { + return [options.url, options.body || {}] + } + + if (method === 'delete') { + method = 'del' + } + /* + * request[method] returns either request.post, request.get etc + * + * If a callback is provided, it triggers it, else it trigger an event + * on the promise object + */ + request[method](options, function (err, response, body) { + if (err || (response.statusCode > 210)) { + if (callback) { + callback(err || body, response) + } else { + promise.emit('error', err || body, response) + } + } else { + if (callback) { + callback(null, response, body) + } else { + promise.emit('success', response, body) + } + } + }) + + return promise +} /* * @@ -201,54 +206,59 @@ MailjetClient.prototype.httpRequest = function(method, url, data, callback) { * @context {MailjetClient[instance]} parent client */ function MailjetResource (method, func, context) { - this.base = func; - this.callUrl = func; - - this.resource = func.toLowerCase(); - - this.lastAdded = RESOURCE; - var self = context; - - /* - It can be REST or nothing if we only know the resource - */ - this.subPath = (function () { - if (func.toLowerCase() !== 'send') return 'REST'; - return ''; - })(); - - /** - * - * result. - * - * @params (optional) {Object Littteral} parameters to be sent to the server - * @callback (optional) {Function} called on response or error - */ - var that = this; - this.result = function (params, callback) { - params = params || {}; - if (typeof params === 'function') { - callback = params; - params = {}; - } - - /* - We build the querystring depending on the parameters. if the user explicitly mentionned - a filters property, we pass it to the url - */ - var path = self.path(that.callUrl, that.subPath, (function () { - if (params['filters']) { - var ret = params['filters']; - delete params['filters']; - return ret; - } else if (method === 'get') return params; - else return {}; - })()); - - that.callUrl = that.base; - self.lastAdded = RESOURCE; - return self.httpRequest(method, 'https://' + _path.join(self.config.url, path), params, callback); - } + this.base = func + this.callUrl = func + + this.resource = func.toLowerCase() + + this.lastAdded = RESOURCE + var self = context + + /* + It can be REST or nothing if we only know the resource + */ + this.subPath = (function () { + if (func.toLowerCase() !== 'send') { + return 'REST' + } + return '' + })() + + /** + * + * result. + * + * @params (optional) {Object Littteral} parameters to be sent to the server + * @callback (optional) {Function} called on response or error + */ + var that = this + this.result = function (params, callback) { + params = params || {} + if (typeof params === 'function') { + callback = params + params = {} + } + + /* + We build the querystring depending on the parameters. if the user explicitly mentionned + a filters property, we pass it to the url + */ + var path = self.path(that.callUrl, that.subPath, (function () { + if (params['filters']) { + var ret = params['filters'] + delete params['filters'] + return ret + } else if (method === 'get') { + return params + } else { + return {} + } + })()) + + that.callUrl = that.base + self.lastAdded = RESOURCE + return self.httpRequest(method, 'https://' + _path.join(self.config.url, path), params, callback) + } } /** @@ -261,14 +271,15 @@ function MailjetResource (method, func, context) { * @return the MailjetResource instance to allow method chaining * */ -MailjetResource.prototype.id = function(value) { - if (this.lastAdded === ID && DEBUG_MODE) - console.warn('[WARNING] your request may fail due to invalid id chaining'); - - this.callUrl = _path.join(this.callUrl, value.toString()); - this.lastAdded = ID; - return this; -}; +MailjetResource.prototype.id = function (value) { + if (this.lastAdded === ID && DEBUG_MODE) { + console.warn('[WARNING] your request may fail due to invalid id chaining') + } + + this.callUrl = _path.join(this.callUrl, value.toString()) + this.lastAdded = ID + return this +} /** * @@ -280,29 +291,33 @@ MailjetResource.prototype.id = function(value) { * @return the MailjetResource instance to allow method chaining * */ -MailjetResource.prototype.action = function(name) { - if (this.lastAdded === ACTION && DEBUG_MODE) - console.warn('[WARNING] your request may fail due to invalid action chaining'); - - this.callUrl = _path.join(this.callUrl, name); - this.action = name.toLowerCase(); - - this.lastAdded = ACTION; - - if (this.action.toLowerCase() == 'csvdata') - this.action = 'csvdata/text:plain'; - else if (this.action.toLowerCase() == 'csverror') - this.action = 'csverror/text:csv'; - - var self = this; - this.subPath = (function () { - if (self.resource === 'contactslist' && self.action === 'csvdata/text:plain' || - self.resource === 'batchjob' && self.action === 'csverror/text:csv') - return 'DATA'; - else return self.subPath; - })(); - return self; -}; +MailjetResource.prototype.action = function (name) { + if (this.lastAdded === ACTION && DEBUG_MODE) { + console.warn('[WARNING] your request may fail due to invalid action chaining') + } + + this.callUrl = _path.join(this.callUrl, name) + this.action = name.toLowerCase() + + this.lastAdded = ACTION + + if (this.action.toLowerCase() === 'csvdata') { + this.action = 'csvdata/text:plain' + } else if (this.action.toLowerCase() === 'csverror') { + this.action = 'csverror/text:csv' + } + + var self = this + this.subPath = (function () { + if (self.resource === 'contactslist' && self.action === 'csvdata/text:plain' || + self.resource === 'batchjob' && self.action === 'csverror/text:csv') { + return 'DATA' + } else { + return self.subPath + } + })() + return self +} /** * @@ -314,9 +329,9 @@ MailjetResource.prototype.action = function(name) { * @return {String} the server response */ -MailjetResource.prototype.request = function(params, callback) { - return this.result(params, callback); -}; +MailjetResource.prototype.request = function (params, callback) { + return this.result(params, callback) +} /* * post. @@ -325,10 +340,9 @@ MailjetResource.prototype.request = function(params, callback) { * * @returns a function that make an httpRequest for each call */ -MailjetClient.prototype.post = function(func) { - return new MailjetResource('post', func, this); -}; - +MailjetClient.prototype.post = function (func) { + return new MailjetResource('post', func, this) +} /* * get. @@ -337,9 +351,9 @@ MailjetClient.prototype.post = function(func) { * * @returns a function that make an httpRequest for each call */ -MailjetClient.prototype.get = function(func) { - return new MailjetResource('get', func, this); -}; +MailjetClient.prototype.get = function (func) { + return new MailjetResource('get', func, this) +} /* * delete. @@ -348,9 +362,9 @@ MailjetClient.prototype.get = function(func) { * * @returns a function that make an httpRequest for each call */ -MailjetClient.prototype.delete = function(func) { - return new MailjetResource('delete', func, this); -}; +MailjetClient.prototype.delete = function (func) { + return new MailjetResource('delete', func, this) +} /* * put. @@ -359,17 +373,17 @@ MailjetClient.prototype.delete = function(func) { * * @returns a function that make an httpRequest for each call */ -MailjetClient.prototype.put = function(func) { - return new MailjetResource('put', func, this); -}; +MailjetClient.prototype.put = function (func) { + return new MailjetResource('put', func, this) +} /* * Exports the Mailjet client. * * you can require it like so: - * var mj = require ('./mailjet-client'); + * var mj = require ('./mailjet-client') * * or for the bleeding edge developpers out there: - * import mj from './mailjet-client'; + * import mj from './mailjet-client' */ -module.exports = MailjetClient; +module.exports = MailjetClient diff --git a/package.json b/package.json index 3d8216a..985ec4a 100644 --- a/package.json +++ b/package.json @@ -7,9 +7,10 @@ "test": "test" }, "dependencies": { + "chai": "^3.2.0", "qs": "^4.0.0", "request": "^2.61.0", - "chai": "^3.2.0" + "standard": "^6.0.8" }, "devDependencies": { "mocha": "^2.4.5" diff --git a/test/test.js b/test/test.js index ff290ef..3f7ff92 100644 --- a/test/test.js +++ b/test/test.js @@ -1,190 +1,181 @@ - -const FILE = 'FILE'; -const EMAIL = 'test@mailjet.com'; -const EMAIL2 = 'test2@mailjet.com'; -const NAME = 'name'; -const SOME_ID = 3; -const SUBJECT = 'subject'; -const TEXT_PART = 'text'; -const VAR = {'Key1': 'Value1', 'Key2': 'Value2'}; -const SIMPLE_RECIPIENTS = [{email: EMAIL}, {email: EMAIL2}]; -const UNIQUE_RECIPIENT = [{email: EMAIL}]; -const RECIPIENTS_NAME = [{email: EMAIL, name: NAME}, {email: EMAIL2, name: NAME}]; -const RECIPIENTS_VARS = [{email: EMAIL, vars: VAR}]; -const API_KEY = process.env.MJ_APIKEY_PUBLIC; -const API_SECRET = process.env.MJ_APIKEY_PRIVATE; - -var Mailjet = require ('../mailjet-client'); -var chai = require ('chai'); -var expect = chai.expect; -var should = chai.should(); -var EventEmitter = require ('events').EventEmitter; -var fs = require ('fs'); - - -describe ('Basic Usage', function () { - - var client = Mailjet.connect(API_KEY, API_SECRET); - - describe ('connection', function () { - it ('creates an instance of the client', function () { - var connectionType1 = new Mailjet(API_KEY, API_SECRET); - var connectionType2 = new Mailjet().connect(API_KEY, API_SECRET); - var connectionType3 = Mailjet.connect(API_KEY, API_SECRET); - - expect('' + connectionType1.apiKey + connectionType1.apiSecret).to.equal('' + API_KEY + API_SECRET); - expect('' + connectionType2.apiKey + connectionType2.apiSecret).to.equal('' + API_KEY + API_SECRET); - expect('' + connectionType3.apiKey + connectionType3.apiSecret).to.equal('' + API_KEY + API_SECRET); - }); - }) - - describe ('method request', function () { - - describe ('get', function () { - - var contact = client.get('contact'); - - it ('calls the contact ressource instance whith no parameters', function (done) { - contact.request() - .on('success', function (response, body) { - body.should.be.a('object'); - expect(response.statusCode).to.equal(200); - done(); - }) - .on('error', function (e) { - // We want it to raise an error if it gets here - expect(e).to.equal(undefined); - done(); - }); - }); - - it ('calls the contact ressource instance whith parameters', function (done) { - var ee = contact.request({Name: 'Guillaume Badi'}) - .on('success', function (response, body) { - body.should.be.a('object'); - expect(response.statusCode).to.be.within(200, 201); - done(); - }) - .on('error', function (e) { - // We want it to raise an error if it gets here - expect(e).to.equal(undefined); - done(); - }); - expect(EventEmitter.prototype.isPrototypeOf(ee)).to.equal(true); - }); - - it ('calls the contact ressource instance with empty parameters', function (done) { - var ee = contact.request({}) - .on('success', function (response, body) { - body.should.be.a('object'); - expect(response.statusCode).to.be.within(200, 201); - done(); - }); - }); - }); - - describe ('post', function () { - - var sender = client.post('sender'); - - it ('calls the sender ressource instance whith no parameters', function (done) { - var ee = sender.request() - .on('error', function (e, response) { - response.statusCode.should.equal(400); - done(); - }); - }); - - it ('calls the sender ressource instance whith invalid parameters', function (done) { - var ee = sender.request({Name: 'Guillaume Badi'}) - .on('error', function (e, response) { - expect(response.statusCode).to.equal(400); - done(); - }); - }); - - it ('calls the sender ressource instance whith valid parameters', function (done) { - var ee = sender.request({email: 'gbadi@mailjet.com'}) - .on('success', function (response, body) { - expect(response.statusCode).to.equal(201); - done(); - }) - .on('error', function (e, response) { - // if it fails because the sender already exist. should be 400 - expect(response.statusCode).to.equal(400); - done(); - }); - }); - - it ('calls the sender resource with empty parameters', function (done) { - var ee = sender.request({}) - .on('error', function (e, response) { - expect(response.statusCode).to.equal(400); - done(); - }); - }); - }); - }); -}); - -describe ('Advanced API Calls', function () { - function Example (fn, payload) { - this.fn = fn; - this.payload = payload; - this.format = function (obj) {return JSON.stringify(obj).match(/\S+/g).join('')}; - this.call = function () { - var res = this.fn.request(this.payload); - var ret = res[0] + ' ' + this.format(res[1]); - return ret; - }; - } - - var client2 = new Mailjet(API_KEY, API_SECRET, true); - - const EXAMPLES_SET = [ - new Example(client2.get('contact')), - new Example(client2.get('contact').id(2)), - new Example(client2.get('contact/2')), - new Example(client2.get('contact').id(3).action('getcontactslist')), - new Example(client2.get('contact'), {countOnly: 1}), - new Example(client2.get('contact'), {limit: 2}), - new Example(client2.get('contact'), {offset: 233}), - new Example(client2.get('contact'), {contatctList: 34}), - new Example(client2.post('contactslist').id(34).action('managecontact'), {email: EMAIL}), - new Example(client2.post('contactslist').id(34).action('csvdata'), FILE), - new Example(client2.get('newsletter'), {filters: {CountOnly: 1}}), - new Example(client2.get('batchjob').action('csverror')), - new Example(client2.post('contact'), {email: EMAIL}), - new Example(client2.post('send'), {'FromName': NAME, 'FromEmail': EMAIL, 'Subject': SUBJECT, 'Text-Part': TEXT_PART, 'Recipients': UNIQUE_RECIPIENT}), - new Example(client2.post('send'), {'FromName': NAME, 'FromEmail': EMAIL, 'Subject': SUBJECT, 'Text-Part': TEXT_PART, 'Recipients': SIMPLE_RECIPIENTS}), - new Example(client2.post('send'), {'FromName': NAME, 'FromEmail': EMAIL, 'Subject': SUBJECT, 'Text-Part': TEXT_PART, 'Recipients': RECIPIENTS_NAME}), - new Example(client2.post('send'), {'FromName': NAME, 'FromEmail': EMAIL, 'Subject': SUBJECT, 'Text-Part': TEXT_PART, 'Recipients': RECIPIENTS_VARS}), - ]; - - const EXPECTED_SET = [ - 'https://api.mailjet.com/v3/REST/contact {}', - 'https://api.mailjet.com/v3/REST/contact/2 {}', - 'https://api.mailjet.com/v3/REST/contact/2 {}', - 'https://api.mailjet.com/v3/REST/contact/3/getcontactslist {}', - 'https://api.mailjet.com/v3/REST/contact/?countOnly=1 {}', - 'https://api.mailjet.com/v3/REST/contact/?limit=2 {}', - 'https://api.mailjet.com/v3/REST/contact/?offset=233 {}', - 'https://api.mailjet.com/v3/REST/contact/?contatctList=34 {}', - 'https://api.mailjet.com/v3/REST/contactslist/34/managecontact {"email":"test@mailjet.com"}', - 'https://api.mailjet.com/v3/DATA/contactslist/34/csvdata "FILE"', - 'https://api.mailjet.com/v3/REST/newsletter/?CountOnly=1 {}', - 'https://api.mailjet.com/v3/DATA/batchjob/csverror {}', - 'https://api.mailjet.com/v3/REST/contact {"email":"test@mailjet.com"}', - 'https://api.mailjet.com/v3/send {"FromName":"name","FromEmail":"test@mailjet.com","Subject":"subject","Text-Part":"text","Recipients":[{"email":"test@mailjet.com"}]}', - 'https://api.mailjet.com/v3/send {"FromName":"name","FromEmail":"test@mailjet.com","Subject":"subject","Text-Part":"text","Recipients":[{"email":"test@mailjet.com"},{"email":"test2@mailjet.com"}]}', - 'https://api.mailjet.com/v3/send {"FromName":"name","FromEmail":"test@mailjet.com","Subject":"subject","Text-Part":"text","Recipients":[{"email":"test@mailjet.com","name":"name"},{"email":"test2@mailjet.com","name":"name"}]}', - 'https://api.mailjet.com/v3/send {"FromName":"name","FromEmail":"test@mailjet.com","Subject":"subject","Text-Part":"text","Recipients":[{"email":"test@mailjet.com","vars":{"Key1":"Value1","Key2":"Value2"}}]}', - ] - - EXPECTED_SET.forEach(function (test, index) { - it ('should output: ' + test, function () { - EXAMPLES_SET[index].call().should.equal(test); - }); - }); - -}); +const FILE = 'FILE' +const EMAIL = 'test@mailjet.com' +const EMAIL2 = 'test2@mailjet.com' +const NAME = 'name' +const SUBJECT = 'subject' +const TEXT_PART = 'text' +const VAR = {'Key1': 'Value1', 'Key2': 'Value2'} +const SIMPLE_RECIPIENTS = [{email: EMAIL}, {email: EMAIL2}] +const UNIQUE_RECIPIENT = [{email: EMAIL}] +const RECIPIENTS_NAME = [{email: EMAIL, name: NAME}, {email: EMAIL2, name: NAME}] +const RECIPIENTS_VARS = [{email: EMAIL, vars: VAR}] +const API_KEY = process.env.MJ_APIKEY_PUBLIC +const API_SECRET = process.env.MJ_APIKEY_PRIVATE + +var Mailjet = require('../mailjet-client') +var chai = require('chai') +var expect = chai.expect +var should = chai.should() // eslint-disable-line no-unused-vars +var EventEmitter = require('events').EventEmitter + +describe('Basic Usage', function () { + var client = Mailjet.connect(API_KEY, API_SECRET) + + describe('connection', function () { + it('creates an instance of the client', function () { + var connectionType1 = new Mailjet(API_KEY, API_SECRET) + var connectionType2 = new Mailjet().connect(API_KEY, API_SECRET) + var connectionType3 = Mailjet.connect(API_KEY, API_SECRET) + + expect('' + connectionType1.apiKey + connectionType1.apiSecret).to.equal('' + API_KEY + API_SECRET) + expect('' + connectionType2.apiKey + connectionType2.apiSecret).to.equal('' + API_KEY + API_SECRET) + expect('' + connectionType3.apiKey + connectionType3.apiSecret).to.equal('' + API_KEY + API_SECRET) + }) + }) + + describe('method request', function () { + describe('get', function () { + var contact = client.get('contact') + + it('calls the contact ressource instance whith no parameters', function (done) { + contact.request() + .on('success', function (response, body) { + body.should.be.a('object') + expect(response.statusCode).to.equal(200) + done() + }) + .on('error', function (e) { + // We want it to raise an error if it gets here + expect(e).to.equal(undefined) + done() + }) + }) + + it('calls the contact ressource instance whith parameters', function (done) { + var ee = contact.request({Name: 'Guillaume Badi'}) + .on('success', function (response, body) { + body.should.be.a('object') + expect(response.statusCode).to.be.within(200, 201) + done() + }) + .on('error', function (e) { + // We want it to raise an error if it gets here + expect(e).to.equal(undefined) + done() + }) + expect(EventEmitter.prototype.isPrototypeOf(ee)).to.equal(true) + }) + + it('calls the contact ressource instance with empty parameters', function (done) { + contact.request({}) + .on('success', function (response, body) { + body.should.be.a('object') + expect(response.statusCode).to.be.within(200, 201) + done() + }) + }) + }) + + describe('post', function () { + var sender = client.post('sender') + + it('calls the sender ressource instance whith no parameters', function (done) { + sender.request() + .on('error', function (e, response) { + response.statusCode.should.equal(400) + done() + }) + }) + + it('calls the sender ressource instance whith invalid parameters', function (done) { + sender.request({Name: 'Guillaume Badi'}) + .on('error', function (e, response) { + expect(response.statusCode).to.equal(400) + done() + }) + }) + + it('calls the sender ressource instance whith valid parameters', function (done) { + sender.request({email: 'gbadi@mailjet.com'}) + .on('success', function (response, body) { + expect(response.statusCode).to.equal(201) + done() + }) + .on('error', function (e, response) { + // if it fails because the sender already exist. should be 400 + expect(response.statusCode).to.equal(400) + done() + }) + }) + + it('calls the sender resource with empty parameters', function (done) { + sender.request({}) + .on('error', function (e, response) { + expect(response.statusCode).to.equal(400) + done() + }) + }) + }) + }) +}) + +describe('Advanced API Calls', function () { + function Example (fn, payload) { + this.fn = fn + this.payload = payload + this.format = function (obj) { return JSON.stringify(obj).match(/\S+/g).join('') } + this.call = function () { + var res = this.fn.request(this.payload) + var ret = res[0] + ' ' + this.format(res[1]) + return ret + } + } + + var client2 = new Mailjet(API_KEY, API_SECRET, true) + + const EXAMPLES_SET = [ + new Example(client2.get('contact')), + new Example(client2.get('contact').id(2)), + new Example(client2.get('contact/2')), + new Example(client2.get('contact').id(3).action('getcontactslist')), + new Example(client2.get('contact'), {countOnly: 1}), + new Example(client2.get('contact'), {limit: 2}), + new Example(client2.get('contact'), {offset: 233}), + new Example(client2.get('contact'), {contatctList: 34}), + new Example(client2.post('contactslist').id(34).action('managecontact'), {email: EMAIL}), + new Example(client2.post('contactslist').id(34).action('csvdata'), FILE), + new Example(client2.get('newsletter'), {filters: {CountOnly: 1}}), + new Example(client2.get('batchjob').action('csverror')), + new Example(client2.post('contact'), {email: EMAIL}), + new Example(client2.post('send'), {'FromName': NAME, 'FromEmail': EMAIL, 'Subject': SUBJECT, 'Text-Part': TEXT_PART, 'Recipients': UNIQUE_RECIPIENT}), + new Example(client2.post('send'), {'FromName': NAME, 'FromEmail': EMAIL, 'Subject': SUBJECT, 'Text-Part': TEXT_PART, 'Recipients': SIMPLE_RECIPIENTS}), + new Example(client2.post('send'), {'FromName': NAME, 'FromEmail': EMAIL, 'Subject': SUBJECT, 'Text-Part': TEXT_PART, 'Recipients': RECIPIENTS_NAME}), + new Example(client2.post('send'), {'FromName': NAME, 'FromEmail': EMAIL, 'Subject': SUBJECT, 'Text-Part': TEXT_PART, 'Recipients': RECIPIENTS_VARS}) + ] + + const EXPECTED_SET = [ + 'https://api.mailjet.com/v3/REST/contact {}', + 'https://api.mailjet.com/v3/REST/contact/2 {}', + 'https://api.mailjet.com/v3/REST/contact/2 {}', + 'https://api.mailjet.com/v3/REST/contact/3/getcontactslist {}', + 'https://api.mailjet.com/v3/REST/contact/?countOnly=1 {}', + 'https://api.mailjet.com/v3/REST/contact/?limit=2 {}', + 'https://api.mailjet.com/v3/REST/contact/?offset=233 {}', + 'https://api.mailjet.com/v3/REST/contact/?contatctList=34 {}', + 'https://api.mailjet.com/v3/REST/contactslist/34/managecontact {"email":"test@mailjet.com"}', + 'https://api.mailjet.com/v3/DATA/contactslist/34/csvdata "FILE"', + 'https://api.mailjet.com/v3/REST/newsletter/?CountOnly=1 {}', + 'https://api.mailjet.com/v3/DATA/batchjob/csverror {}', + 'https://api.mailjet.com/v3/REST/contact {"email":"test@mailjet.com"}', + 'https://api.mailjet.com/v3/send {"FromName":"name","FromEmail":"test@mailjet.com","Subject":"subject","Text-Part":"text","Recipients":[{"email":"test@mailjet.com"}]}', + 'https://api.mailjet.com/v3/send {"FromName":"name","FromEmail":"test@mailjet.com","Subject":"subject","Text-Part":"text","Recipients":[{"email":"test@mailjet.com"},{"email":"test2@mailjet.com"}]}', + 'https://api.mailjet.com/v3/send {"FromName":"name","FromEmail":"test@mailjet.com","Subject":"subject","Text-Part":"text","Recipients":[{"email":"test@mailjet.com","name":"name"},{"email":"test2@mailjet.com","name":"name"}]}', + 'https://api.mailjet.com/v3/send {"FromName":"name","FromEmail":"test@mailjet.com","Subject":"subject","Text-Part":"text","Recipients":[{"email":"test@mailjet.com","vars":{"Key1":"Value1","Key2":"Value2"}}]}' + ] + + EXPECTED_SET.forEach(function (test, index) { + it('should output: ' + test, function () { + EXAMPLES_SET[index].call().should.equal(test) + }) + }) +}) From b62fcb6128804c75b5238f8bf99bd31db00c388f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Parker?= Date: Tue, 26 Apr 2016 15:44:57 +0200 Subject: [PATCH 3/4] feat(promise): use real promise --- mailjet-client.js | 55 ++++++++++++++++++---------------- package.json | 8 ++++- test/test.js | 75 +++++++++++++++++++++++------------------------ 3 files changed, 73 insertions(+), 65 deletions(-) diff --git a/mailjet-client.js b/mailjet-client.js index 4ec417e..f8df6bb 100755 --- a/mailjet-client.js +++ b/mailjet-client.js @@ -39,10 +39,10 @@ const STRICT = false * fs will simply be used to read files */ -var qs = require('querystring') -var request = require('request') -var EventEmitter = require('events').EventEmitter -var _path = require('path') +const qs = require('querystring') +const request = require('request') +const Promise = require('bluebird') +const _path = require('path') /* * MailjetClient constructor. @@ -139,8 +139,6 @@ MailjetClient.prototype.path = function (resource, sub, params) { */ MailjetClient.prototype.httpRequest = function (method, url, data, callback) { - var promise = new EventEmitter().on('error', function () {}) - /** * json: true converts the output from string to JSON */ @@ -170,29 +168,34 @@ MailjetClient.prototype.httpRequest = function (method, url, data, callback) { if (method === 'delete') { method = 'del' } - /* - * request[method] returns either request.post, request.get etc - * - * If a callback is provided, it triggers it, else it trigger an event - * on the promise object - */ - request[method](options, function (err, response, body) { - if (err || (response.statusCode > 210)) { - if (callback) { - callback(err || body, response) - } else { - promise.emit('error', err || body, response) - } - } else { - if (callback) { - callback(null, response, body) + + return new Promise((resolve, reject) => { + /* + * request[method] returns either request.post, request.get etc + * + * If a callback is provided, it triggers it, else it trigger an event + * on the promise object + */ + request[method](options, function (err, response, body) { + if (err || (response.statusCode > 210)) { + if (typeof callback === 'function') { + callback(err || body, response) + } + reject({ + error: err || body, + response: response + }) } else { - promise.emit('success', response, body) + if (typeof callback === 'function') { + callback(null, response, body) + } + resolve({ + response: response, + body: body + }) } - } + }) }) - - return promise } /* diff --git a/package.json b/package.json index 985ec4a..9bc106c 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,13 @@ { "name": "node-mailjet", - "version": "1.1.0", + "version": "2.0.0", "description": "Mailjet NodeJS API client", "main": "index.js", "directories": { "test": "test" }, "dependencies": { + "bluebird": "^3.3.5", "chai": "^3.2.0", "qs": "^4.0.0", "request": "^2.61.0", @@ -29,6 +30,11 @@ "mailjet" ], "author": "Guillaume Badi (https://github.com/GuillaumeBadi)", + "contributors": [ + "Arnaud Breton (https://github.com/arnaudbreton)", + "Nicholas Smith (https://github.com/safani)", + "Jérémie Parker (https://github.com/p-j)" + ], "license": "MIT", "bugs": { "url": "https://github.com/mailjet/mailjet-apiv3-nodejs/issues" diff --git a/test/test.js b/test/test.js index 3f7ff92..0d0356b 100644 --- a/test/test.js +++ b/test/test.js @@ -16,7 +16,10 @@ var Mailjet = require('../mailjet-client') var chai = require('chai') var expect = chai.expect var should = chai.should() // eslint-disable-line no-unused-vars -var EventEmitter = require('events').EventEmitter +var Promise = require('bluebird') +if (typeof API_KEY === 'undefined' || typeof API_SECRET === 'undefined') { + throw new Error(`Mailjet API_KEY and API_SECRET are required, respectively "${API_KEY}" and "${API_SECRET}" given`) +} describe('Basic Usage', function () { var client = Mailjet.connect(API_KEY, API_SECRET) @@ -39,40 +42,39 @@ describe('Basic Usage', function () { it('calls the contact ressource instance whith no parameters', function (done) { contact.request() - .on('success', function (response, body) { - body.should.be.a('object') - expect(response.statusCode).to.equal(200) + .then(function (result) { + result.body.should.be.a('object') + expect(result.response.statusCode).to.equal(200) done() }) - .on('error', function (e) { + .catch(function (reason) { // We want it to raise an error if it gets here - expect(e).to.equal(undefined) + expect(reason).to.equal(undefined) done() }) }) it('calls the contact ressource instance whith parameters', function (done) { - var ee = contact.request({Name: 'Guillaume Badi'}) - .on('success', function (response, body) { - body.should.be.a('object') - expect(response.statusCode).to.be.within(200, 201) + var promise = contact.request({Name: 'Guillaume Badi'}) + .then(function (result) { + result.body.should.be.a('object') + expect(result.response.statusCode).to.be.within(200, 201) done() }) - .on('error', function (e) { + .catch(function (reason) { // We want it to raise an error if it gets here - expect(e).to.equal(undefined) + expect(reason).to.equal(undefined) done() }) - expect(EventEmitter.prototype.isPrototypeOf(ee)).to.equal(true) + expect(Promise.prototype.isPrototypeOf(promise)).to.equal(true) }) it('calls the contact ressource instance with empty parameters', function (done) { - contact.request({}) - .on('success', function (response, body) { - body.should.be.a('object') - expect(response.statusCode).to.be.within(200, 201) - done() - }) + contact.request({}).then(function (result) { + result.body.should.be.a('object') + expect(result.response.statusCode).to.be.within(200, 201) + done() + }) }) }) @@ -80,40 +82,37 @@ describe('Basic Usage', function () { var sender = client.post('sender') it('calls the sender ressource instance whith no parameters', function (done) { - sender.request() - .on('error', function (e, response) { - response.statusCode.should.equal(400) - done() - }) + sender.request().catch(function (reason) { + reason.response.statusCode.should.equal(400) + done() + }) }) it('calls the sender ressource instance whith invalid parameters', function (done) { - sender.request({Name: 'Guillaume Badi'}) - .on('error', function (e, response) { - expect(response.statusCode).to.equal(400) - done() - }) + sender.request({Name: 'Guillaume Badi'}).catch(function (reason) { + expect(reason.response.statusCode).to.equal(400) + done() + }) }) it('calls the sender ressource instance whith valid parameters', function (done) { sender.request({email: 'gbadi@mailjet.com'}) - .on('success', function (response, body) { - expect(response.statusCode).to.equal(201) + .then(function (result) { + expect(result.response.statusCode).to.equal(201) done() }) - .on('error', function (e, response) { + .catch(function (reason) { // if it fails because the sender already exist. should be 400 - expect(response.statusCode).to.equal(400) + expect(reason.response.statusCode).to.equal(400) done() }) }) it('calls the sender resource with empty parameters', function (done) { - sender.request({}) - .on('error', function (e, response) { - expect(response.statusCode).to.equal(400) - done() - }) + sender.request({}).catch(function (reason) { + expect(reason.response.statusCode).to.equal(400) + done() + }) }) }) }) From c4cacebafdfcb47080f038c15d725e72d15b8936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Parker?= Date: Tue, 26 Apr 2016 16:44:19 +0200 Subject: [PATCH 4/4] doc(readme): update readme with promise examples --- README.md | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index b802ee5..cd3bb59 100644 --- a/README.md +++ b/README.md @@ -94,13 +94,17 @@ user.request(function (error, response, body) { ### Make the same request with a Promise -the request method actually returns a [EventEmitter][eventemitter] triggering `success` and `error` - ``` javascript user.request() - .on('error', function (error, response) {}) - .on('success', function (response, body) {}); + .then(function (result) { + // do something with the result + // result structure is {response: {...}, body: {...}} + }) + .catch(function (reason) { + // handle the rejection reason + // reason structure is {error: {...}, response: {...}} + }) ``` @@ -109,8 +113,8 @@ user.request() ``` javascript sender.request({ Email: 'mr@mailjet.com' }) - .on('success', handleData) - .on('error', handleError); + .then(handleData) + .catch(handleError); ``` @@ -166,8 +170,8 @@ var emailData = { sendEmail .request(emailData) - .on('success', handlePostResponse) - .on('error', handleError); + .then(handlePostResponse) + .catch(handleError); ``` @@ -188,13 +192,13 @@ emailData2['Text-part'] = 'This is another Email'; sendEmail .request(emailData) - .on('success', handleData) - .on('error', handleError); + .then(handleData) + .catch(handleError); sendEmail .request(emailData2) - .on('success', handleData) - .on('error', handleError); + .then(handleData) + .catch(handleError); ``` ## Have Fun ! @@ -209,7 +213,7 @@ function handleError (err) { function newContact (email) { mailjet.post('contact') .request({Email: email}) - .on('error', handleError); + .catch(handleError); } function testEmail (text) { @@ -222,7 +226,7 @@ function testEmail (text) { mailjet.post('send') .request(email) - .on('error', handleError); + .catch(handleError); } testEmail('Hello World!');