diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..77712c4 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,2 @@ +**/node_modules +**/test diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..f976464 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,20 @@ +{ + "extends": "formidable/configurations/es5", + "env": { + "node": true + }, + rules: { + "max-len": [0, 120, 4], + "quotes": ["error", "single"], + "indent": [0, "tab"], + "space-before-function-paren": 0, + strict: 0, + curly: 0, + "max-params": 0, + "valid-jsdoc": 0, + "max-statements": 0, + "consistent-return": 0, + "no-magic-numbers": 0, + "consistent-this": ["error", "_this"] + } +} diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index 3678478..0000000 --- a/.jshintrc +++ /dev/null @@ -1,40 +0,0 @@ -{ - "node": true, // Enable globals available when code is running inside of the NodeJS runtime environment. - "browser": true, // Standard browser globals e.g. `window`, `document`. - "esnext": true, // Allow ES.next specific features such as `const` and `let`. - "bitwise": false, // Prohibit bitwise operators (&, |, ^, etc.). - "camelcase": false, // Permit only camelcase for `var` and `object indexes`. - "curly": false, // Require {} for every new block or scope. - "eqeqeq": true, // Require triple equals i.e. `===`. - "immed": true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );` - "latedef": true, // Prohibit variable use before definition. - "newcap": true, // Require capitalization of all constructor functions e.g. `new F()`. - "noarg": true, // Prohibit use of `arguments.caller` and `arguments.callee`. - "quotmark": "single", // Define quotes to string values. - "regexp": true, // Prohibit `.` and `[^...]` in regular expressions. - "undef": true, // Require all non-global variables be declared before they are used. - "unused": false, // Warn unused variables. - "strict": true, // Require `use strict` pragma in every file. - "trailing": true, // Prohibit trailing whitespaces. - "smarttabs": false, // Suppresses warnings about mixed tabs and spaces - "globals": { // Globals variables. - "Promise" : true - }, - "predef": [ // Extra globals. - "define", - "require", - "exports", - "module", - "describe", - "before", - "beforeEach", - "after", - "afterEach", - "it", - "inject", - "expect" - ], - "indent": 4, // Specify indentation spacing - "devel": true, // Allow development statements e.g. `console.log();`. - "noempty": true // Prohibit use of empty blocks. -} \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..35af9c0 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,19 @@ +language: node_js + +node_js: + - "6" + +notifications: + slack: pmpkin:QReL3WOed24nwQcVtqvlQyYW + +script: +- | + if [ "$TEST_TYPE" = test ]; then + npm test + else + npm run $TEST_TYPE + fi +env: + matrix: + - TEST_TYPE=eslint + - TEST_TYPE=test diff --git a/README.md b/README.md index 0064719..53fc371 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ # softlayer-node [Softlayer API](http://sldn.softlayer.com/reference/softlayerapi) wrapper for node. The module provides a simple fluent interface to construct API calls. +[![Build Status](https://travis-ci.org/pmpkin/softlayer-node.svg)](https://travis-ci.org/pmpkin/softlayer-node) +[![npm version](https://badge.fury.io/js/softlayer-node.svg)](https://badge.fury.io/js/softlayer-node) + ## Installation The most simple way is to install the npm package: ``` @@ -50,7 +53,6 @@ This method sets the credentials ```javascript client.auth(apiUser, apiKey); ``` - ##### mask() Using this method you can add an object mask to the request. You can pass an array of mask elements, or simply string arguments to the method. ```javascript @@ -73,8 +75,8 @@ client.headers({ 'Content-Type': 'application/json' }); ``` -##### get() -With get() the request is submitted. This method returns a Promise. If you prefer node callbacks, you can pass a callback to the method. +##### get(), put(), post(), delete() +Calling one of these methods, the request is submitted. This method returns a Promise. If you prefer node callbacks, you can pass a callback to the method. ```javascript //Using Promises: client.get() @@ -85,11 +87,9 @@ client.get() }); //Using node callback: client.get(function(err,res) { - + }); ``` -##### post(), put(), delete() -These methods are not yet implemented. ##### Chaining it all together ```javascript var SoftLayer = require('softlayer-node'); @@ -107,19 +107,21 @@ client ``` ## Tests -To run the tests open a command line and tpye +To run the tests open a command line and type ``` -npm test +npm run test ``` -or +## eslint +To run eslint open a command line and type ``` -gulp test +npm run eslint ``` -You will need to have gulp and mocha installed to run the tests. **Important:** The tests make real http requests (only GET) to an account, which has to be configured in a file called credentials.json in the test folder. + +You will need to have gulp and mocha installed to run the tests. **Important:** The tests make real http requests (currently only GET) to a SoftLayer account, which has to be configured in a file called credentials.json in the test folder. This file must have the following content: ``` json { - "accountId": "[account id]", + "accountId": "[accountId]", "apiUser": "[api user]", "apiKey": "[api key]" } diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index ca03b06..0000000 --- a/gulpfile.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Created by michael.wibmer on 04.02.2015. - */ -var gulp = require('gulp'); -var jshint = require('gulp-jshint'); -var mocha = require('gulp-mocha'); - -gulp.task('test', function () { - return gulp.src('./test/**-test.js', {read: false}) - .pipe(mocha({reporter: 'spec'})); -}); - -gulp.task('lint', function() { - return gulp.src('./lib/*.js') - .pipe(jshint()) - .pipe(jshint.reporter('default')); -}); - -// Watch Files For Changes -gulp.task('dev', ['lint'], function() { - gulp.watch(['lib/*.js', 'test/*.js'], ['test']); -}); \ No newline at end of file diff --git a/lib/http-requests.js b/lib/http-requests.js index 6c0356e..ef2f6f0 100644 --- a/lib/http-requests.js +++ b/lib/http-requests.js @@ -1,52 +1,43 @@ 'use strict'; -var https = require('https'); +var request = require('request'); // Private constants -var _baseUrl = 'api.softlayer.com'; -var _basePath = '/rest/v3/'; +var _baseUrl = 'https://api.softlayer.com/rest/v3/'; var _servicePrefix = 'SoftLayer_'; // Private methods -function _isNumberSet(value) { - return value!==undefined && value!==null; -} - -/** - * Sends a GET request to the given softlayer rest endpoint. - * @param credentials object containing apiUser and apiKey - * @param pathElements an array of path elements to construct the REST url - * @param mask object mask - * @param offset pagination offset - * @param limit pagination result limit - * @param callback - */ -exports.get = function(credentials, pathElements, mask, filter, offset, limit, headers, callback) { - - if (!credentials) return callback(new Error('No credentials provided.'), {}); - if (!pathElements || pathElements.length < 1) return callback(new Error('No path provided.'), {}); - +var _isNumberSet = function(value) { + return value !== undefined && value !== null; +}; +var _buildPath = function(pathElements, mask, filter, offset, limit) { //build path - pathElements[0] = pathElements[0].indexOf(_servicePrefix < 0) ? (_servicePrefix + pathElements[0]) : pathElements[0]; - var path = _basePath + pathElements.join('/'); - + if (pathElements[0].indexOf(_servicePrefix < 0)) { + pathElements[0] = _servicePrefix + pathElements[0]; + } + var path = _baseUrl + pathElements.join('/'); //add object mask if available if (mask && mask.length > 0) { - path += '?objectMask=' + mask.join(';'); + path += path.indexOf('?') > -1 ? '&' : '?'; + path += 'objectMask=' + mask.join(';'); } //add object filter if available if (filter) { - path += '&objectFilter=' + JSON.stringify(filter); + path += path.indexOf('?') > -1 ? '&' : '?'; + path += 'objectFilter=' + JSON.stringify(filter); } //add pagination if available if (_isNumberSet(offset) && _isNumberSet(limit)) { - if (limit === 0) return callback({statusCode: 500, error: 'Limit must not be zero.'}, {}); - path += (path.indexOf('?') > -1 ? '&' : '?'); + path += path.indexOf('?') > -1 ? '&' : '?'; path += 'resultLimit=' + offset + ',' + limit; } + return path; +}; + +var _buildHeaders = function(credentials, headers) { //Basic authentication var auth = 'Basic ' + new Buffer(credentials.apiUser + ':' + credentials.apiKey).toString('base64'); @@ -54,51 +45,131 @@ exports.get = function(credentials, pathElements, mask, filter, offset, limit, h 'Content-Type': 'application/json', 'Accept': 'application/json' }; - headers['Authorization'] = auth; - - var request_options = { - host: _baseUrl, - path: path, - port: 443, - method: 'GET', - rejectUnauthorized: false, - headers: headers - }; - - // Set up the request - var req = https.request(request_options, function(res) { - res.setEncoding('utf8'); - - var data = ''; - res.on('data', function(chunk) { - data += chunk; - }); - - res.on('end', function() { - if (res.statusCode >= 400 && res.statusCode < 600 || res.statusCode < 10) { - var error; - if (data) { - error = JSON.parse(data); - error.statusCode = res.statusCode; - } else { - error = { - statusCode: res.statusCode - }; - } - callback(error, {}); + headers.Authorization = auth; + return headers; +}; + +var _handleResponse = function(callback) { + return function(err, res, body) { + if (res.statusCode >= 400 && res.statusCode < 600 || res.statusCode < 10) { + + if (body && res.headers['content-type'] === 'application/json') { + var error = JSON.parse(body); + error.statusCode = res.statusCode; + return callback(error, {}); + } + if (err) { + err.statusCode = res.statusCode; } else { - if (headers['Content-Type'] === 'application/json') { - callback(null, JSON.parse(data)); - } else { - callback(null, data); - } + err = { + statusCode: res.statusCode + }; } - }); - }); + return callback(err, {}); + } else if (err) { + return callback(err, {}); + } + + if (res.headers['content-type'] === 'application/json') { + return callback(null, JSON.parse(body)); + } + + return callback(null, body); + }; +}; + +/** + * Sends a GET request to the given softlayer rest endpoint. + * @param credentials object containing apiUser and apiKey + * @param pathElements an array of path elements to construct the REST url + * @param mask object mask + * @param offset pagination offset + * @param limit pagination result limit + * @param headers custom headers for the request + * @param callback callback funtion + * @return undefined + */ +exports.get = function(credentials, pathElements, mask, filter, offset, limit, headers, callback) { - req.on('error', function(error) { - callback(error, {}); - }); + if (!credentials) return callback(new Error('No credentials provided.'), {}); + if (!pathElements || pathElements.length < 1) return callback(new Error('No path provided.'), {}); + if (limit === 0) return callback({ statusCode: 500, error: 'Limit must not be zero.' }, { }); - req.end(); -}; \ No newline at end of file + var requestOptions = { + url: _buildPath(pathElements, mask, filter, offset, limit), + headers: _buildHeaders(credentials, headers) + }; + request.get(requestOptions, _handleResponse(callback)); +}; + +/** + * Sends a PUT request to the given softlayer rest endpoint. + * @param {Object} credentials containing apiUser and apiKey + * @param pathElements an array of path elements to construct the REST url + * @param headers custom headers for the request + * @param parameters parameters for the the request body + * @param callback + */ +exports.put = function(credentials, pathElements, headers, parameters, callback) { + + if (!credentials) return callback(new Error('No credentials provided.'), {}); + if (!pathElements || pathElements.length < 1) return callback(new Error('No path provided.'), {}); + + var requestOptions = { + url: _buildPath(pathElements), + headers: _buildHeaders(credentials, headers), + json: { + parameters: parameters.constructor === Array ? parameters : [parameters] + } + }; + + request.put(requestOptions, _handleResponse(callback)); +}; + +/** + * Sends a POST request to the given softlayer rest endpoint. + * @param {Object} credentials containing apiUser and apiKey + * @param pathElements an array of path elements to construct the REST url + * @param headers custom headers for the request + * @param parameters parameters for the the request body + * @param callback + */ +exports.post = function(credentials, pathElements, headers, parameters, callback) { + + if (!credentials) return callback(new Error('No credentials provided.'), {}); + if (!pathElements || pathElements.length < 1) return callback(new Error('No path provided.'), {}); + + var requestOptions = { + url: _buildPath(pathElements), + headers: _buildHeaders(credentials, headers), + json: { + parameters: parameters.constructor === Array ? parameters : [parameters] + } + }; + + request.post(requestOptions, _handleResponse(callback)); +}; + + +/** + * Sends a DELETE request to the given softlayer rest endpoint. + * @param credentials object containing apiUser and apiKey + * @param pathElements an array of path elements to construct the REST url + * @param headers custom headers for the request + * @param parameters parameters for the the request body + * @param callback + */ +exports.delete = function(credentials, pathElements, headers, parameters, callback) { + + if (!credentials) return callback(new Error('No credentials provided.'), {}); + if (!pathElements || pathElements.length < 1) return callback(new Error('No path provided.'), {}); + + var requestOptions = { + url: _buildPath(pathElements), + headers: _buildHeaders(credentials, headers), + json: { + parameters: parameters.constructor === Array ? parameters : [parameters] + } + }; + request.delete(requestOptions, _handleResponse(callback)); +}; diff --git a/lib/services.js b/lib/services.js index 8880cd6..883f5c8 100644 --- a/lib/services.js +++ b/lib/services.js @@ -849,4 +849,4 @@ module.exports = function(SoftLayer) { SoftLayer.prototype.virtualStorageRepository = function () { return this.path('Virtual_Storage_Repository'); }; -}; \ No newline at end of file +}; diff --git a/lib/softlayer.js b/lib/softlayer.js index 55a2da9..957b96f 100644 --- a/lib/softlayer.js +++ b/lib/softlayer.js @@ -31,7 +31,7 @@ var SoftLayer = function SoftLayer(apiUser, apiKey) { module.exports = SoftLayer; //private methods -function _getDefaults() { +var _getDefaults = function() { return { pathElements: [], mask: [], @@ -42,7 +42,7 @@ function _getDefaults() { 'Content-Type': 'application/json' } }; -} +}; /** * Appends the arguments of this function to the path of the prepared service request. @@ -96,15 +96,28 @@ SoftLayer.prototype.mask = function (mask) { * Adds the given object filter to the prepared service request. * You can pass a json object to this method * @params filter json object to add to the path - * @retirn {SoftLayer} + * @return {SoftLayer} */ SoftLayer.prototype.filter = function (filter) { if (!this.service) this.service = _getDefaults(); - if(filter) { + if (filter) { this.service.filter = filter; } return this; -} +}; + +/** + * Adds the given parameters to the prepared service request. + * @params parameters Object to be passed to the request body. + * @return {SoftLayer} + */ + +SoftLayer.prototype.parameters = function(parameters) { + if (!this.service) this.service = _getDefaults(); + this.service.parameters = parameters; + return this; +}; + /** * Adds offset and limit to the prepared service request. @@ -150,7 +163,61 @@ SoftLayer.prototype.auth = function (apiUser, apiKey) { SoftLayer.prototype.get = function (callback) { var _this = this; return new Promise(function (resolve, reject) { - HttpRequests.get(_this.credentials, _this.service.pathElements, _this.service.mask, _this.service.filter, _this.service.offset, _this.service.limit,_this.service.headers, function (error, result) { + HttpRequests.get(_this.credentials, _this.service.pathElements, _this.service.mask, _this.service.filter, _this.service.offset, _this.service.limit, _this.service.headers, function (error, result) { + _this.reset(); + if (error) { + return reject(error); + } + return resolve(result); + }); + }).nodeify(callback); +}; + +/** + * PUT the prepared service request. + * @param callback optional node style callback + * @returns {bluebird} a bluebird promise + */ +SoftLayer.prototype.put = function (callback) { + var _this = this; + return new Promise(function (resolve, reject) { + HttpRequests.put(_this.credentials, _this.service.pathElements, _this.service.headers, _this.service.parameters, function (error, result) { + _this.reset(); + if (error) { + return reject(error); + } + return resolve(result); + }); + }).nodeify(callback); +}; + +/** + * POST the prepared service request. + * @param callback optional node style callback + * @returns {bluebird} a bluebird promise + */ +SoftLayer.prototype.post = function (callback) { + var _this = this; + return new Promise(function (resolve, reject) { + HttpRequests.post(_this.credentials, _this.service.pathElements, _this.service.headers, _this.service.parameters, function (error, result) { + _this.reset(); + if (error) { + return reject(error); + } + return resolve(result); + }); + }).nodeify(callback); +}; + +/** + * DELETE the prepared service request. + * @param callback optional node style callback + * @returns {bluebird} a bluebird promise + */ +SoftLayer.prototype.delete = function (callback) { + var _this = this; + return new Promise(function (resolve, reject) { + HttpRequests.delete(_this.credentials, _this.service.pathElements, _this.service.headers, _this.service.parameters, function (error, result) { _this.reset(); if (error) { return reject(error); @@ -161,4 +228,4 @@ SoftLayer.prototype.get = function (callback) { }; -services(SoftLayer); \ No newline at end of file +services(SoftLayer); diff --git a/package.json b/package.json index 75226a6..58cbfcd 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,11 @@ { "name": "softlayer-node", - "version": "0.1.0", + "version": "0.2.0", "description": "Softlayer API Wrapper for node", "main": "./lib/softlayer.js", "scripts": { - "test": "gulp test" + "test": "./node_modules/.bin/mocha ./test/**/*-test.js --reporter spec || exit 0", + "eslint": "./node_modules/.bin/eslint . || exit 0" }, "repository": { "type": "git", @@ -21,13 +22,15 @@ }, "homepage": "https://github.com/pmpkin/softlayer-node", "dependencies": { - "bluebird": "^2.9.13" + "bluebird": "^2.9.13", + "request": "^2.75.0" }, "devDependencies": { - "chai": "^2.1.1", - "gulp": "^3.8.11", - "gulp-jshint": "^1.9.2", - "gulp-mocha": "^2.0.0", - "mocha": "^2.2.1" + "chai": "^3.5.0", + "eslint": "^3.5.0", + "eslint-config-formidable": "^1.0.1", + "eslint-plugin-filenames": "^1.1.0", + "eslint-plugin-import": "^1.16.0", + "mocha": "^3.0.2" } } diff --git a/test/http-request-test.js b/test/http-request-test.js index 3a57ebf..666f5e8 100644 --- a/test/http-request-test.js +++ b/test/http-request-test.js @@ -1,13 +1,9 @@ /** * Created by michael.wibmer on 11.03.2015. */ -var fs = require('fs'); -var path = require('path'); var expect = require('chai').expect; var HttpRequests = require('../lib/http-requests'); - -var credentials = JSON.parse(fs.readFileSync(path.normalize(__dirname + '/credentials.json', 'utf8'))); - +var credentials = require('./test-utils').loadCredentials(); describe('HttpRequests', function () { @@ -20,24 +16,26 @@ describe('HttpRequests', function () { }); describe('get()', function() { + it('should fail because of missing credentials', function(done) { - HttpRequests.get(undefined, null, null,null,null, null, function(err) { + HttpRequests.get(undefined, null, null, null, null, null, null, function(err) { expect(err).to.be.ok; done(); }); }); it('should fail because of missing path', function(done) { - HttpRequests.get({apiUser: 'user', apiKey: 'key'}, null, null,null,null, null, function(err) { + HttpRequests.get({apiUser: 'user', apiKey: 'key'}, null, null,null,null, null, null, function(err) { expect(err).to.be.ok; done(); }); }); + it('should fail with status 401 because of incorrect user credentials', function(done) { var path=['Account']; - HttpRequests.get({apiUser: 'user', apiKey: 'key'}, path, null,null,null, null, function(err) { + HttpRequests.get({apiUser: 'user', apiKey: 'key'}, path, null, null, null, null, null, function(err) { expect(err).to.be.ok; expect(err.statusCode).to.equal(401); @@ -45,9 +43,11 @@ describe('HttpRequests', function () { }); }); + + it('should fail with status 404 because of invalid path', function(done) { var path=['ThisIsInvalid']; - HttpRequests.get(credentials, path, null,null,null, null, function(err) { + HttpRequests.get(credentials, path, null, null, null, null, null, function(err) { expect(err).to.be.ok; expect(err.statusCode).to.equal(404); done(); @@ -57,17 +57,18 @@ describe('HttpRequests', function () { it('should fail with status 500 because of invalid mask', function(done) { var path=['Account']; var mask=['(/;'] - HttpRequests.get(credentials, path, mask, null,null, null, function(err) { + HttpRequests.get(credentials, path, mask, null, null, null, null, function(err) { expect(err).to.be.ok; expect(err.statusCode).to.equal(500); done(); }); }); + it('should fail with status 500 because of using pagination with invalid limit', function(done) { var path=['Account', 'Invoices']; - HttpRequests.get(credentials, path, null, 0, 0, null, function(err) { + HttpRequests.get(credentials, path, null, null, 0, 0, null, function(err) { expect(err).to.be.ok; expect(err.statusCode).to.equal(500); @@ -78,8 +79,7 @@ describe('HttpRequests', function () { it('should successfully return a Softlayer object', function(done) { var path=['Account']; - HttpRequests.get(credentials, path, null, null, null, null, function(err, res) { - + HttpRequests.get(credentials, path, null, null, null, null, null, function(err, res) { expect(err).to.equal(null); expect(res).to.be.ok; expect(res.id).to.equal(credentials.accountId); @@ -94,7 +94,7 @@ describe('HttpRequests', function () { 'Accept': 'application/xml', 'Content-Type': 'application/xml' }; - HttpRequests.get(credentials, path, null, null, null, headers, function(err, res) { + HttpRequests.get(credentials, path, null, null, null, null, headers, function(err, res) { expect(err).to.equal(null); expect(res).to.be.ok; @@ -107,7 +107,7 @@ describe('HttpRequests', function () { var path=['Account']; var mask=['city']; - HttpRequests.get(credentials, path, mask, null, null, null, function(err, res) { + HttpRequests.get(credentials, path, mask, null, null, null, null, function(err, res) { expect(err).to.equal(null); expect(res).to.be.ok; expect(res.city).to.be.ok; //we masked with city, so it should be part of the result @@ -121,14 +121,13 @@ describe('HttpRequests', function () { var path=['Account', ['Invoices']]; var mask=['id']; - HttpRequests.get(credentials, path, mask, 0, 2, null, function(err, res) { + HttpRequests.get(credentials, path, mask, null, 0, 2, null, function(err, res) { expect(err).to.equal(null); expect(res).to.be.ok; expect(res.length).to.equal(2); done(); }); }); - }); -}); \ No newline at end of file +}); diff --git a/test/softlayer-test.js b/test/softlayer-test.js index cbdf17e..4300bcd 100644 --- a/test/softlayer-test.js +++ b/test/softlayer-test.js @@ -1,12 +1,10 @@ /** * Created by michael.wibmer on 11.03.2015. */ -var fs = require('fs'); -var path = require('path'); +var Promise = require('bluebird'); var expect = require('chai').expect; var SoftLayer = require('../lib/softlayer'); -var credentials = JSON.parse(fs.readFileSync(path.normalize(__dirname + '/credentials.json', 'utf8'))); - +var credentials = require('./test-utils').loadCredentials(); describe('SoftLayer API', function () { //set higher default timeout due to networking @@ -171,23 +169,20 @@ describe('SoftLayer API', function () { it('should successfully return a masked Softlayer object, and reset the internal service object', function(done) { - var result = null, error = null; - var client = new SoftLayer() .path('Account') .mask(['id']) .auth(credentials.apiUser, credentials.apiKey) .get() .then(function(res) { - result = res; - }, function(err) { - error = err; + expect(res).to.be.ok; + expect(res.id).to.equal(credentials.accountId); + expect(client.service).to.not.be.ok; + }) + .catch(function(err) { + expect(err).to.equal(null); }) .finally(function() { - expect(error).to.equal(null); - expect(result).to.be.ok; - expect(result.id).to.equal(credentials.accountId); - expect(client.service).to.not.be.ok; done(); }); }); @@ -203,8 +198,11 @@ describe('SoftLayer API', function () { expect(err).to.equal(null); expect(res).to.be.ok; expect(res.id).to.equal(credentials.accountId); + + }) + .finally(function() { done(); - }); + }) }); }); @@ -212,8 +210,6 @@ describe('SoftLayer API', function () { it('should successfully return a Softlayer object as xml', function (done) { - var result = null, error = null; - var client = new SoftLayer() .path('Account') .mask(['id']) @@ -224,18 +220,18 @@ describe('SoftLayer API', function () { }) .get() .then(function (res) { - result = res; - }, function (err) { - error = err; + expect(res).to.be.ok; + expect(res).to.contains('?xml'); + expect(client.service).to.not.be.ok; + }) + .catch(function (err) { + expect(err).to.equal(null); }) .finally(function () { - expect(error).to.equal(null); - expect(result).to.be.ok; - expect(result).to.contains('?xml'); - expect(client.service).to.not.be.ok; - done(); + done() }); + }); }); -}); \ No newline at end of file +}); diff --git a/test/test-utils.js b/test/test-utils.js new file mode 100644 index 0000000..a49a59e --- /dev/null +++ b/test/test-utils.js @@ -0,0 +1,20 @@ +var fs = require('fs'); +var path = require('path'); + +exports.loadCredentials = function() { + var credentials = null; + try { + credentials = JSON.parse(fs.readFileSync(path.normalize(__dirname + '/credentials.json', 'utf8'))); + } catch (e) { + //no credentials + } + + if (!credentials && process.env.SOFTLAYER_API_ACCOUNT && process.env.SOFTLAYER_API_USER && process.env.SOFTLAYER_API_KEY) { + credentials = { + accountId: process.env.SOFTLAYER_API_ACCOUNT, + apiUser: process.env.SOFTLAYER_API_USER, + apiKey: process.env.SOFTLAYER_API_USER + } + } + return credentials || {}; +} diff --git a/wercker.yml b/wercker.yml deleted file mode 100644 index 8245549..0000000 --- a/wercker.yml +++ /dev/null @@ -1,5 +0,0 @@ -box: wercker/nodejs@1.4.0 -build: - steps: - - npm-install - - npm-test \ No newline at end of file