Massive overhaul to UsergridAuth, fixed tests, added 1.0 and 2.1 tests
diff --git a/.travis.yml b/.travis.yml
index 3065c40..3c41865 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,7 +6,8 @@
- 'npm install -g grunt-cli'
- 'npm -g install mocha'
script:
-- 'grunt'
+- 'mocha tests --bail --target=1.0'
+- 'mocha tests --bail --target=2.1'
notifications:
email:
on_failure: change
diff --git a/config.json b/config.json
index 157b197..3a82da0 100644
--- a/config.json
+++ b/config.json
@@ -1,13 +1,8 @@
{
- "tests": {
- "collection": "tests"
- },
- "usergrid": {
- "appId": "sandbox",
- "authFallback": "NONE",
- "baseUrl": "https://api.usergrid.com",
- "clientId": "YXA6GXSAACS2EeOYd20aP4G6Lw",
- "clientSecret": "YXA66BeEvgNpJBwc4PAbvZZGTVS_SSw",
- "orgId": "brandon.apigee"
- }
+ "appId": "sandbox",
+ "authFallback": "NONE",
+ "baseUrl": "https://api.usergrid.com",
+ "clientId": "YXA6GXSAACS2EeOYd20aP4G6Lw",
+ "clientSecret": "YXA66BeEvgNpJBwc4PAbvZZGTVS_SSw",
+ "orgId": "brandon.apigee"
}
\ No newline at end of file
diff --git a/helpers/buildUrl.js b/helpers/buildUrl.js
index 6e9ee78..076932d 100644
--- a/helpers/buildUrl.js
+++ b/helpers/buildUrl.js
@@ -2,11 +2,11 @@
var urljoin = require('url-join'),
ok = require('objectkit'),
- config = require('../config.json')
+ config = require('./config')
function buildUrl(options) {
return urljoin(
- ok(config).getIfExists('usergrid.baseUrl'),
+ config.baseUrl,
options.client.orgId,
options.client.appId,
options.type, (typeof options.uuidOrName === 'string') ? options.uuidOrName : ""
diff --git a/helpers/config.js b/helpers/config.js
new file mode 100644
index 0000000..cbf7efc
--- /dev/null
+++ b/helpers/config.js
@@ -0,0 +1,16 @@
+'use strict'
+
+var _ = require('underscore')
+
+_.mixin(require('underscore.string'))
+
+if (/mocha$/i.test(process.argv[1])) {
+ var target = _(_.last(process.argv)).startsWith('--target=') ? _.last(process.argv).replace(/--target=/, '') : '1.0'
+ var config = require('../tests/config.test.json')[target] || require('../config.json')
+ if (target) {
+ config.target = target
+ }
+ module.exports = config
+} else {
+ module.exports = require('../config.json')
+}
\ No newline at end of file
diff --git a/helpers/index.js b/helpers/index.js
index 1c78737..7fe5b91 100644
--- a/helpers/index.js
+++ b/helpers/index.js
@@ -3,7 +3,8 @@
buildUrl = require('./buildUrl'),
userAgent = require('./userAgent'),
is = require('./is'),
- query = require('./query')
+ query = require('./query'),
+ config = require('./config')
module.exports = {
setReadOnly: mutability.setReadOnly,
@@ -12,5 +13,6 @@
buildUrl: buildUrl,
userAgent: userAgent,
is: is,
- query: query
+ query: query,
+ config: config
}
\ No newline at end of file
diff --git a/lib/appAuth.js b/lib/appAuth.js
index 02d32fc..f0b2516 100644
--- a/lib/appAuth.js
+++ b/lib/appAuth.js
@@ -1,17 +1,22 @@
'use strict'
var UsergridAuth = require('./auth'),
- util = require('util')
+ util = require('util'),
+ _ = require('underscore'),
+ ok = require('objectkit')
-var UsergridAppAuth = function(opts) {
+var UsergridAppAuth = function(options) {
var self = this
- if (arguments.length === 3) {
- opts = arguments
+
+ var args = Array.prototype.slice.call(arguments)
+ if (typeof args[0] === 'object') {
+ args = args[0]
}
- self.clientId = (opts.length === 3) ? opts[0] : opts.clientId
- self.clientSecret = (opts.length === 3) ? opts[1] : opts.clientSecret
- self.tokenTtl = (opts.length === 3) ? opts[2] : opts.tokenTtl
+ self.clientId = args.clientId || args[0]
+ self.clientSecret = args.clientSecret || args[1]
+ self.tokenTtl = args.tokenTtl || args[2]
UsergridAuth.call(self)
+ _.extend(self, UsergridAuth)
return self
}
diff --git a/lib/auth.js b/lib/auth.js
index 958623e..db67944 100644
--- a/lib/auth.js
+++ b/lib/auth.js
@@ -1,33 +1,33 @@
'use strict'
-var helpers = require('../helpers')
-
var UsergridAuth = function() {
var self = this
+
self.token = undefined
self.expiry = 0
- helpers.setReadOnly(self, 'hasToken')
- helpers.setReadOnly(self, 'isTokenValid')
- helpers.setReadOnly(self, 'isExpired')
+
+ Object.defineProperty(self, "hasToken", {
+ get: function() {
+ return (typeof self.token === 'string' && self.token.length > 0)
+ },
+ configurable: true
+ })
+
+ Object.defineProperty(self, "isExpired", {
+ get: function() {
+ return (Date.now() >= self.expiry)
+ },
+ configurable: true
+ })
+
+ Object.defineProperty(self, "isTokenValid", {
+ get: function() {
+ return (!self.isExpired && self.hasToken)
+ },
+ configurable: true
+ })
+
return self
}
-Object.defineProperty(UsergridAuth.prototype, "hasToken", {
- get: function() {
- return (typeof this.token === 'string' && this.token.length > 0) ? true : false
- }
-})
-
-Object.defineProperty(UsergridAuth.prototype, "isTokenValid", {
- get: function() {
- return (new Date() >= this.expiry && this.hasToken) ? true : false
- }
-})
-
-Object.defineProperty(UsergridAuth.prototype, "isExpired", {
- get: function() {
- return (new Date() >= this.expiry) ? true : false
- }
-})
-
module.exports = UsergridAuth
\ No newline at end of file
diff --git a/lib/client.js b/lib/client.js
index be23a40..50ed7dd 100644
--- a/lib/client.js
+++ b/lib/client.js
@@ -3,7 +3,7 @@
var UsergridRequest = require('./request'),
request = require('request'),
ok = require('objectkit'),
- config = require('../config.json'),
+ config = require('../helpers/config'),
helpers = require('../helpers'),
UsergridAppAuth = require('./appAuth'),
_ = require('underscore')
@@ -24,16 +24,32 @@
var UsergridClient = function(options) {
var self = this
+ var __appAuth
+
if (arguments.length === 2) {
self.orgId = arguments[0]
self.appId = arguments[1]
- }
+ }
- _.defaults(self, options, ok(config).getIfExists('usergrid'), defaultOptions)
+ _.defaults(self, options, config, defaultOptions)
if (!self.orgId || !self.appId) {
throw new Error('"orgId" and "appId" parameters are required when instantiating UsergridClient')
}
+
+ Object.defineProperty(self, 'appAuth', {
+ get: function() {
+ return __appAuth
+ },
+ set: function(options) {
+ var self = this
+ if (options instanceof UsergridAppAuth) {
+ __appAuth = options
+ } else {
+ __appAuth = new UsergridAppAuth(options)
+ }
+ }
+ })
}
UsergridClient.prototype.GET = function(type, uuidOrName, callback) {
@@ -80,30 +96,8 @@
}, callback || uuidOrName)
}
-Object.defineProperty(UsergridClient.prototype, 'appAuth', {
- get: function() {
- return this._appAuth
- },
- set: function(options) {
- var self = this
- if (options.length === 3) {
- self._appAuth = new UsergridAppAuth(options)
- } else if (options[0] instanceof UsergridAppAuth) {
- self._appAuth = options[0]
- } else if (options instanceof UsergridAppAuth) {
- self._appAuth = options
- } else if (ok(options[0]).has('clientId')) {
- self._appAuth = new UsergridAppAuth({
- clientId: options[0].clientId,
- clientSecret: options[0].clientSecret,
- tokenTtl: options[0].tokenTtl || 3600
- })
- }
- }
-})
-
-UsergridClient.prototype.setAppAuth = function() {
- this.appAuth = _.values(arguments)
+UsergridClient.prototype.setAppAuth = function(options) {
+ this.appAuth = (typeof options === 'string') ? _.values(arguments) : options
}
UsergridClient.prototype.authenticateApp = function(options, callback) {
@@ -112,6 +106,9 @@
if (!(self.appAuth instanceof UsergridAppAuth)) {
throw new Error('App auth context was not defined when attempting to call .authenticateApp()')
}
+ if (!(options.clientId || self.appAuth.clientId) && !(options.clientSecret || self.appAuth.clientSecret)) {
+ throw new Error('authenticateApp() failed because clientId or clientSecret are missing')
+ }
options.type = 'token'
options.client = self
request({
@@ -128,6 +125,7 @@
var token = body.access_token || undefined
self.appAuth.token = token
self.appAuth.expiry = Date.now() + ((body.expires_in ? body.expires_in - 5 : 0) * 1000)
+ self.appAuth.tokenTtl = body.expires_in
callback(error, response, token)
})
}
diff --git a/lib/request.js b/lib/request.js
index 916bf64..fbc6d21 100644
--- a/lib/request.js
+++ b/lib/request.js
@@ -2,15 +2,24 @@
var request = require('request'),
helpers = require('../helpers'),
- UsergridResponse = require('../lib/response')
+ UsergridResponse = require('../lib/response'),
+ util = require('util'),
+ _ = require('underscore')
var UsergridRequest = function(options, callback) {
callback = helpers.cb(callback)
if (typeof options.type !== 'string') {
throw new Error('"type" (or "collection") parameter is required when making a request')
}
+ var headers = helpers.userAgent
+
+ if (options.client.appAuth && options.client.appAuth.isTokenValid) {
+ _.extend(headers, {
+ authorization: util.format("Bearer %s", options.client.appAuth.token)
+ })
+ }
request(helpers.buildUrl(options), {
- headers: helpers.userAgent,
+ headers: headers,
body: options.body,
json: true,
method: options.method
diff --git a/lib/response.js b/lib/response.js
index 6c3a959..5f6340d 100644
--- a/lib/response.js
+++ b/lib/response.js
@@ -10,7 +10,9 @@
_.mixin(require('underscore.string'))
function UsergridResponse(response) {
- if (ok(response.body).has('entities')) {
+ if (!response) {
+ return
+ } else if (ok(response.body).has('entities')) {
var entities = response.body.entities.map(function(en) {
var entity = new UsergridEntity(en)
return (entity.isUser) ? new UsergridUser(entity) : entity
@@ -23,8 +25,7 @@
response.first = _.first(entities) || undefined
response.entity = response.first
response.last = _.last(entities) || undefined
-
- if (ok(response).has('first.isUser') === true) {
+ if (ok(response).getIfExists('metadata.path') === '/users') {
response.user = response.first
response.users = response.entities
}
diff --git a/tests/config.test.json b/tests/config.test.json
new file mode 100644
index 0000000..746c937
--- /dev/null
+++ b/tests/config.test.json
@@ -0,0 +1,18 @@
+{
+ "1.0": {
+ "appId": "sandbox",
+ "baseUrl": "https://api.usergrid.com",
+ "clientId": "YXA6GXSAACS2EeOYd20aP4G6Lw",
+ "clientSecret": "YXA66BeEvgNpJBwc4PAbvZZGTVS_SSw",
+ "orgId": "brandon.apigee",
+ "testCollection": "tests"
+ },
+ "2.1": {
+ "appId": "sdksandbox",
+ "baseUrl": "https://api-connectors-prod.apigee.net/appservices",
+ "clientId": "YXA6WMhAuFJTEeWoggrRE9kXrQ",
+ "clientSecret": "YXA6zZbat7PKgOlN73rpByc36LWaUhw",
+ "orgId": "api-connectors",
+ "testCollection": "nodejs"
+ }
+}
\ No newline at end of file
diff --git a/tests/lib/client.test.js b/tests/lib/client.test.js
index e3238a2..20c71ad 100644
--- a/tests/lib/client.test.js
+++ b/tests/lib/client.test.js
@@ -1,7 +1,7 @@
'use strict'
var should = require('should'),
- config = require('../../config.json'),
+ config = require('../../helpers/config'),
UsergridClient = require('../../lib/client'),
UsergridAppAuth = require('../../lib/appAuth')
@@ -17,9 +17,8 @@
it('should initialize using properties defined in config.json', function() {
var client = new UsergridClient()
- client.should.be.an.instanceof(UsergridClient).with.property('orgId').equal(config.usergrid.orgId)
- client.should.be.an.instanceof(UsergridClient).with.property('appId').equal(config.usergrid.appId)
- Object(client).should.containDeep(config.usergrid)
+ client.should.be.an.instanceof(UsergridClient).with.property('orgId').equal(config.orgId)
+ client.should.be.an.instanceof(UsergridClient).with.property('appId').equal(config.appId)
})
it('should initialize when passing orgId and appId as arguments, taking precedence over config', function() {
@@ -44,8 +43,8 @@
this.timeout(6000)
var response, client
before(function(done) {
- client = new UsergridClient()
- client.GET(config.tests.collection, function(err, usergridResponse) {
+ client = new UsergridClient(config)
+ client.GET(config.testCollection, function(err, usergridResponse) {
response = usergridResponse
done()
})
@@ -53,7 +52,7 @@
it('should not fail when a callback function is not passed', function() {
// note: this test will NOT fail gracefully inside the Mocha event chain
- client.GET(config.tests.collection)
+ client.GET(config.testCollection)
})
it('should return a 200 ok', function() {
@@ -85,7 +84,7 @@
var response, client
before(function(done) {
client = new UsergridClient()
- client.POST(config.tests.collection, {
+ client.POST(config.testCollection, {
author: 'Sir Arthur Conan Doyle'
}, function(err, usergridResponse) {
response = usergridResponse
@@ -96,7 +95,7 @@
it('should not fail when a callback function is not passed', function() {
// note: this test will NOT fail gracefully inside the Mocha event chain
- client.POST(config.tests.collection, {})
+ client.POST(config.testCollection, {})
})
it('should return a 200 ok', function() {
@@ -124,7 +123,7 @@
var response, client
before(function(done) {
client = new UsergridClient()
- client.PUT(config.tests.collection, _uuid, {
+ client.PUT(config.testCollection, _uuid, {
narrator: 'Peter Doyle'
}, function(err, usergridResponse) {
response = usergridResponse
@@ -134,7 +133,7 @@
it('should not fail when a callback function is not passed', function() {
// note: this test will NOT fail gracefully inside the Mocha event chain
- client.PUT(config.tests.collection, _uuid)
+ client.PUT(config.testCollection, _uuid)
})
it('should return a 200 ok', function() {
@@ -162,8 +161,8 @@
var response, client
before(function(done) {
client = new UsergridClient()
- client.DELETE(config.tests.collection, _uuid, function() {
- client.GET(config.tests.collection, _uuid, function(err, usergridResponse) {
+ client.DELETE(config.testCollection, _uuid, function() {
+ client.GET(config.testCollection, _uuid, function(err, usergridResponse) {
response = usergridResponse
done()
})
@@ -172,7 +171,7 @@
it('should not fail when a callback function is not passed', function() {
// note: this test will NOT fail gracefully inside the Mocha event chain
- client.DELETE(config.tests.collection, _uuid)
+ client.DELETE(config.testCollection, _uuid)
})
it('should return a 200 ok', function() {
@@ -181,9 +180,15 @@
response.statusCode.should.not.equal(200)
})
- it('response.error.name should equal "service_resource_not_found"', function() {
- response.error.name.should.equal('service_resource_not_found')
- })
+ if (config.target === '1.0') {
+ it('response.error.name should equal "service_resource_not_found"', function() {
+ response.error.name.should.equal('service_resource_not_found')
+ })
+ } else {
+ it('response.error.name should equal "entity_not_found"', function() {
+ response.error.name.should.equal('entity_not_found')
+ })
+ }
})
describe('authenticateApp()', function() {
@@ -194,7 +199,7 @@
var response, token, client
before(function(done) {
client = new UsergridClient()
- client.setAppAuth(config.usergrid.clientId, config.usergrid.clientSecret, config.usergrid.tokenTtl)
+ client.setAppAuth(config.clientId, config.clientSecret, config.tokenTtl)
client.authenticateApp(function(err, r, t) {
response = r
token = t
@@ -202,6 +207,14 @@
})
})
+ it('should fail when called without a clientId and clientSecret', function() {
+ should(function() {
+ var client = new UsergridClient()
+ client.setAppAuth(undefined, undefined, 0)
+ client.authenticateApp()
+ }).throw()
+ })
+
it('should return a 200 ok', function() {
response.statusCode.should.equal(200)
})
@@ -215,6 +228,10 @@
client.appAuth.should.have.property('token').equal(token)
})
+ it('client.appAuth.isTokenValid should be true', function() {
+ client.appAuth.should.have.property('isTokenValid').which.is.true()
+ })
+
it('client.appAuth.expiry should be set to a future date', function() {
client.appAuth.should.have.property('expiry').greaterThan(Date.now())
})
@@ -223,29 +240,29 @@
describe('appAuth, setAppAuth()', function() {
it('should initialize by passing a list of arguments', function() {
var client = new UsergridClient()
- client.setAppAuth(config.usergrid.clientId, config.usergrid.clientSecret, config.usergrid.tokenTtl)
+ client.setAppAuth(config.clientId, config.clientSecret, config.tokenTtl)
client.appAuth.should.be.instanceof(UsergridAppAuth)
})
it('should initialize by passing an object', function() {
var client = new UsergridClient()
client.setAppAuth({
- clientId: config.usergrid.clientId,
- clientSecret: config.usergrid.clientSecret,
- tokenTtl: config.usergrid.tokenTtl
+ clientId: config.clientId,
+ clientSecret: config.clientSecret,
+ tokenTtl: config.tokenTtl
})
client.appAuth.should.be.instanceof(UsergridAppAuth)
})
it('should initialize by passing an instance of UsergridAppAuth', function() {
var client = new UsergridClient()
- client.setAppAuth(new UsergridAppAuth(config.usergrid.clientId, config.usergrid.clientSecret, config.usergrid.tokenTtl))
+ client.setAppAuth(new UsergridAppAuth(config.clientId, config.clientSecret, config.tokenTtl))
client.appAuth.should.be.instanceof(UsergridAppAuth)
})
it('should initialize by setting to an instance of UsergridAppAuth', function() {
var client = new UsergridClient()
- client.appAuth = new UsergridAppAuth(config.usergrid.clientId, config.usergrid.clientSecret, config.usergrid.tokenTtl)
+ client.appAuth = new UsergridAppAuth(config.clientId, config.clientSecret, config.tokenTtl)
client.appAuth.should.be.instanceof(UsergridAppAuth)
})
})
\ No newline at end of file
diff --git a/tests/lib/response.test.js b/tests/lib/response.test.js
index 367bf17..07ac7da 100644
--- a/tests/lib/response.test.js
+++ b/tests/lib/response.test.js
@@ -1,7 +1,7 @@
'use strict'
var should = require('should'),
- config = require('../../config.json'),
+ config = require('../../helpers/config'),
UsergridClient = require('../../lib/client'),
UsergridEntity = require('../../lib/entity'),
UsergridUser = require('../../lib/user'),
@@ -17,7 +17,7 @@
this.slow(1000)
this.timeout(6000)
- client.GET(config.tests.collection, function(err, usergridResponse) {
+ client.GET(config.testCollection, function(err, usergridResponse) {
_response = usergridResponse
done()
})
@@ -51,7 +51,7 @@
this.slow(1000)
this.timeout(6000)
- client.GET(config.tests.collection, 'BADNAMEORUUID', function(err, usergridResponse) {
+ client.GET(config.testCollection, 'BADNAMEORUUID', function(err, usergridResponse) {
usergridResponse.error.should.be.an.instanceof(UsergridResponseError)
done()
})
@@ -63,13 +63,19 @@
this.slow(1000)
this.timeout(6000)
+ var user = new UsergridUser()
+
it('response.users should be an array of UsergridUser objects', function(done) {
- client.GET('users', function(err, usergridResponse) {
- usergridResponse.users.should.be.an.Array()
- usergridResponse.users.forEach(function(user) {
- user.should.be.an.instanceof(UsergridUser)
+ client.setAppAuth(config.clientId, config.clientSecret, config.tokenTtl)
+ client.authenticateApp(function(err) {
+ client.GET('users', function(err, usergridResponse) {
+ usergridResponse.statusCode.should.equal(200)
+ usergridResponse.users.should.be.an.Array()
+ usergridResponse.users.forEach(function(user) {
+ user.should.be.an.instanceof(UsergridUser)
+ })
+ done()
})
- done()
})
})
})
@@ -80,9 +86,12 @@
this.timeout(6000)
it('response.user should be a UsergridUser object and have a valid uuid matching the first object in response.users', function(done) {
- client.GET('users', function(err, usergridResponse) {
- usergridResponse.user.should.be.an.instanceof(UsergridUser).with.property('uuid').equal(_.first(usergridResponse.users).uuid)
- done()
+ client.setAppAuth(config.clientId, config.clientSecret, config.tokenTtl)
+ client.authenticateApp(function(err) {
+ client.GET('users', function(err, usergridResponse) {
+ usergridResponse.user.should.be.an.instanceof(UsergridUser).with.property('uuid').equal(_.first(usergridResponse.users).uuid)
+ done()
+ })
})
})
})
@@ -117,7 +126,7 @@
this.timeout(6000)
it('should be true when more entities exist', function(done) {
- client.GET(config.tests.collection, function(err, usergridResponse) {
+ client.GET(config.testCollection, function(err, usergridResponse) {
usergridResponse.hasNextPage.should.be.true()
done()
})
diff --git a/tests/lib/responseError.test.js b/tests/lib/responseError.test.js
index ecf232d..0d92cf6 100644
--- a/tests/lib/responseError.test.js
+++ b/tests/lib/responseError.test.js
@@ -1,7 +1,7 @@
'use strict'
var should = require('should'),
- config = require('../../config.json'),
+ config = require('../../helpers/config'),
UsergridClient = require('../../lib/client'),
UsergridResponseError = require('../../lib/responseError')
@@ -16,7 +16,7 @@
this.slow(1000)
this.timeout(6000)
- client.GET(config.tests.collection, 'BADNAMEORUUID', function(err, usergridResponse) {
+ client.GET(config.testCollection, 'BADNAMEORUUID', function(err, usergridResponse) {
_response = usergridResponse
done()
})
@@ -36,7 +36,7 @@
it('response.error should be undefined on a successful response', function(done) {
this.slow(1000)
this.timeout(6000)
- client.GET(config.tests.collection, function(err, usergridResponse) {
+ client.GET(config.testCollection, function(err, usergridResponse) {
usergridResponse.statusCode.should.equal(200)
should(usergridResponse.error).be.undefined()
done()
diff --git a/tests/lib/usergrid.test.js b/tests/lib/usergrid.test.js
index a8e8702..817ee6b 100644
--- a/tests/lib/usergrid.test.js
+++ b/tests/lib/usergrid.test.js
@@ -1,12 +1,18 @@
'use strict'
var should = require('should'),
+ config = require('../../helpers/config'),
Usergrid = require('../../usergrid'),
- UsergridClient = require('../../lib/client')
+ UsergridClient = require('../../lib/client'),
+ util = require('util'),
+ _ = require('underscore')
describe('init() / initSharedInstance()', function() {
it('should be an instance of UsergridClient', function() {
Usergrid.init()
Usergrid.should.be.an.instanceof(UsergridClient)
})
+ it(util.format('should be testing against a Usergrid v%s instance', config.target), function() {
+ util.format('--target=%s', config.target).should.equal(_.last(process.argv))
+ })
})
\ No newline at end of file