Major overhaul to request builders to support multiple argument types
diff --git a/helpers/build.js b/helpers/build.js
new file mode 100644
index 0000000..911666c
--- /dev/null
+++ b/helpers/build.js
@@ -0,0 +1,191 @@
+'use strict'
+
+var urljoin = require('url-join'),
+ config = require('./config'),
+ cb = require('./cb'),
+ helpers = require('./'),
+ UsergridQuery = require('../lib/query'),
+ UsergridEntity = require('../lib/entity'),
+ ok = require('objectkit'),
+ _ = require('underscore')
+
+module.exports = {
+ url: function(options) {
+ return urljoin(
+ config.baseUrl,
+ options.client.orgId,
+ options.client.appId,
+ options.type, (typeof options.uuidOrName === 'string' ? options.uuidOrName : "")
+ )
+ },
+ GET: function(client, args) {
+
+ /* GET supports the following constructor patterns:
+
+ client.GET('type', 'uuidOrName', optionalCallback)
+ client.GET('type', optionalCallback)
+ client.GET(query, optionalCallback)
+ client.GET({
+ query: query, // takes precedence
+ type: type, // required only if query not defined
+ uuid: uuid, // will be set to nameOrUuid on init (priority)
+ name: name, // will be set to nameOrUuid on init (if no uuid specified)
+ nameOrUuid: nameOrUuid // the definitive key for name or uuid
+ }, optionalCallback)
+
+ */
+
+ var options = {
+ client: client,
+ method: 'GET'
+ }
+
+ if (typeof args[0] === 'object' && !(args[0] instanceof UsergridQuery)) {
+ _.extend(options, args[0])
+ }
+
+ options.callback = helpers.cb(_.last(args.filter(function(property) {
+ return typeof property === 'function'
+ })))
+
+ options.type = options.type || (args[0] instanceof UsergridQuery ? args[0]._type : args[0])
+ options.query = options.query || (args[0] instanceof UsergridQuery ? args[0] : undefined)
+ options.uuidOrName = _.last([options.uuidOrName, options.uuid, options.name, args[1]].filter(function(property) {
+ return (property)
+ }))
+
+ return options
+ },
+ PUT: function(client, args) {
+
+ /* PUT supports the following constructor patterns:
+
+ client.PUT('type', 'uuidOrName', bodyObject, optionalCallback)
+ client.PUT('type', bodyObject, optionalCallback) // if no uuid, will create a new record
+ client.PUT(bodyObjectOrEntity, optionalCallback) // if no uuid, will create a new record; must include type
+ client.PUT(query, bodyObjectOrEntity, optionalCallback) // will update all entities matching query
+ client.PUT(entity, optionalCallback)
+ client.PUT({
+ *entity = alias to body*
+ query: query, // takes precedence over type/body
+ type: type, // required only if query not defined
+ body: bodyObject or bodyObjectOrEntity, // if includes type, type will be inferred from body
+ *uuid, name* = alias to nameOrUuid*
+ nameOrUuid: nameOrUuid // the definitive key for name or uuid
+ }, optionalCallback)
+
+ */
+
+ var options = {
+ client: client,
+ method: 'PUT'
+ }
+
+ if (typeof args[0] === 'object' && !(args[0] instanceof UsergridEntity) && !(args[0] instanceof UsergridQuery)) {
+ _.extend(options, args[0])
+ }
+
+ options.callback = helpers.cb(_.last(args.filter(function(property) {
+ return typeof property === 'function'
+ })))
+
+ options.body = _.first([options.entity, options.body, args[2], args[1], args[0]].filter(function(property) {
+ return typeof property === 'object' && !(property instanceof UsergridQuery)
+ }))
+
+ if (typeof options.body !== 'object') {
+ throw new Error('"body" parameter is required when making a PUT request')
+ }
+
+ options.uuidOrName = _.first([options.nameOrUuid, options.uuid, options.name, options.body.uuid, args[2], args[1], args[0]].filter(function(property) {
+ return typeof property === 'string'
+ }))
+
+ options.type = options.type || (args[0] instanceof UsergridQuery ? args[0]._type : options.body.type || args[0])
+ options.query = options.query || (args[0] instanceof UsergridQuery ? args[0] : undefined)
+
+ return options
+ },
+
+ POST: function(client, args) {
+
+ /* POST supports the following constructor patterns:
+
+ client.POST('type', bodyObjectOrArray, optionalCallback)
+ client.POST(bodyObjectOrArray, optionalCallback) // must include type in body
+ client.POST(entityOrEntities, optionalCallback)
+ client.POST({
+ *entity, entities = alias to body*
+ type: type, // required if type is not inferred
+ body: bodyObjectOrArray or entityOrEntities, // if the first entity includes type, type will be inferred from body
+ }, optionalCallback)
+
+ */
+
+ var options = {
+ client: client,
+ method: 'POST'
+ }
+
+ if (typeof args[0] === 'object' && !(args[0] instanceof UsergridEntity)) {
+ _.extend(options, args[0])
+ }
+
+ options.callback = helpers.cb(_.last(args.filter(function(property) {
+ return typeof property === 'function'
+ })))
+
+ options.body = _.first([options.entities, options.entity, options.body, args[1], args[0]].filter(function(property) {
+ return property instanceof Array && typeof property[0] === 'object' || typeof property === 'object'
+ }))
+ if (typeof options.body !== 'object') {
+ throw new Error('"body" parameter is required when making a POST request')
+ }
+ options.body = options.body instanceof Array ? options.body : [options.body]
+ options.type = options.type || (typeof args[0] === 'string' ? args[0] : options.body[0].type)
+
+ return options
+ },
+ DELETE: function(client, args) {
+
+ /* DELETE supports the following constructor patterns:
+
+ client.DELETE('type', 'uuidOrName', optionalCallback)
+ client.DELETE(entity, optionalCallback) // must include type in body
+ client.DELETE(query, optionalCallback)
+ client.DELETE({
+ *uuid, name* = alias to nameOrUuid*
+ uuidOrName: uuidOrName,
+ type: type, // required if type is not inferred
+ query: query // takes precedence over type/uuid
+ }, optionalCallback)
+
+ */
+
+ var options = {
+ client: client,
+ method: 'DELETE'
+ }
+
+ if (typeof args[0] === 'object' && !(args[0] instanceof UsergridQuery)) {
+ _.extend(options, args[0])
+ }
+
+ options.callback = helpers.cb(_.last(args.filter(function(property) {
+ return typeof property === 'function'
+ })))
+
+ options.type = options.type || (args[0] instanceof UsergridQuery ? args[0]._type : args[0])
+ options.entity = options.entity || (args[0] instanceof UsergridEntity ? args[0] : undefined)
+ options.query = options.query || (args[0] instanceof UsergridQuery ? args[0] : undefined)
+ options.uuidOrName = _.first([options.uuidOrName, options.uuid, options.name, ok(options).getIfExists('entity.uuid'), args[1]].filter(function(property) {
+ return (typeof property === 'string')
+ }))
+
+ if (typeof options.uuidOrName !== 'string' && options.query === undefined) {
+ throw new Error('"uuidOrName" parameter or "query" is required when making a DELETE request')
+ }
+
+ return options
+ }
+}
\ No newline at end of file
diff --git a/helpers/buildUrl.js b/helpers/buildUrl.js
deleted file mode 100644
index 1acdf5e..0000000
--- a/helpers/buildUrl.js
+++ /dev/null
@@ -1,15 +0,0 @@
-'use strict'
-
-var urljoin = require('url-join'),
- config = require('./config')
-
-function buildUrl(options) {
- return urljoin(
- config.baseUrl,
- options.client.orgId,
- options.client.appId,
- options.type, (typeof options.uuidOrName === 'string') ? options.uuidOrName : ""
- )
-}
-
-module.exports = buildUrl
\ No newline at end of file
diff --git a/helpers/config.js b/helpers/config.js
index cbf7efc..9fb5d8d 100644
--- a/helpers/config.js
+++ b/helpers/config.js
@@ -1,7 +1,6 @@
'use strict'
-var _ = require('underscore')
-
+var _ = require('lodash')
_.mixin(require('underscore.string'))
if (/mocha$/i.test(process.argv[1])) {
diff --git a/helpers/index.js b/helpers/index.js
index 7fe5b91..4b08822 100644
--- a/helpers/index.js
+++ b/helpers/index.js
@@ -1,18 +1,15 @@
var mutability = require('./mutability'),
cb = require('./cb'),
- buildUrl = require('./buildUrl'),
+ build = require('./build'),
userAgent = require('./userAgent'),
- is = require('./is'),
query = require('./query'),
- config = require('./config')
+ config = require('./config'),
+ _ = require('lodash')
-module.exports = {
- setReadOnly: mutability.setReadOnly,
- setWritable: mutability.setWritable,
+module.exports = _.extend(module.exports, {
cb: cb,
- buildUrl: buildUrl,
+ build: build,
userAgent: userAgent,
- is: is,
query: query,
config: config
-}
\ No newline at end of file
+}, mutability)
\ No newline at end of file
diff --git a/helpers/is.js b/helpers/is.js
deleted file mode 100644
index a9157f1..0000000
--- a/helpers/is.js
+++ /dev/null
@@ -1,13 +0,0 @@
-'use strict'
-
-module.exports = {
- numeric: function(n) {
- return !isNaN(parseFloat(n)) && isFinite(n)
- },
- uuid: function(s) {
- return (/([a-f\d]{8}(-[a-f\d]{4}){3}-[a-f\d]{12}?)/i).test(s)
- },
- bool: function(b) {
- return typeof(b) === "boolean"
- }
-}
\ No newline at end of file
diff --git a/helpers/mutability.js b/helpers/mutability.js
index 9800e1d..69c06f7 100644
--- a/helpers/mutability.js
+++ b/helpers/mutability.js
@@ -2,42 +2,38 @@
var ok = require('objectkit')
-function setReadOnly(obj, key) {
- if (typeof obj[key] === 'array') {
- return obj[key].forEach(function(k) {
- setReadOnly(obj, k)
- })
- } else if (typeof obj[key] === 'object') {
- return Object.freeze(obj[key])
- } else if (typeof obj === 'object' && key === undefined) {
- return Object.freeze(obj)
- } else if (ok(obj).has(key)) {
- return Object.defineProperty(obj, key, {
- configurable: false,
- writable: false
- })
- } else {
- return obj
- }
-}
-
-function setWritable(obj, key) {
- // Note that once Object.freeze is called on an object, it cannot be unfrozen
- if (typeof obj[key] === 'array') {
- return obj[key].forEach(function(k) {
- setWritable(obj, k)
- })
- } else if (ok(obj).has(key)) {
- return Object.defineProperty(obj, key, {
- configurable: true,
- writable: true
- })
- } else {
- return obj
- }
-}
-
module.exports = {
- setReadOnly: setReadOnly,
- setWritable: setWritable
+ setReadOnly: function(obj, key) {
+ if (typeof obj[key] === 'array') {
+ return obj[key].forEach(function(k) {
+ setReadOnly(obj, k)
+ })
+ } else if (typeof obj[key] === 'object') {
+ return Object.freeze(obj[key])
+ } else if (typeof obj === 'object' && key === undefined) {
+ return Object.freeze(obj)
+ } else if (ok(obj).has(key)) {
+ return Object.defineProperty(obj, key, {
+ configurable: false,
+ writable: false
+ })
+ } else {
+ return obj
+ }
+ },
+ setWritable: function(obj, key) {
+ // Note that once Object.freeze is called on an object, it cannot be unfrozen
+ if (typeof obj[key] === 'array') {
+ return obj[key].forEach(function(k) {
+ setWritable(obj, k)
+ })
+ } else if (ok(obj).has(key)) {
+ return Object.defineProperty(obj, key, {
+ configurable: true,
+ writable: true
+ })
+ } else {
+ return obj
+ }
+ }
}
\ No newline at end of file
diff --git a/helpers/query.js b/helpers/query.js
index 18a630c..9a40f33 100644
--- a/helpers/query.js
+++ b/helpers/query.js
@@ -1,10 +1,12 @@
'use strict'
-var is = require('./is'),
- util = require('util')
+var util = require('util'),
+ _ = require('lodash')
+
+_.mixin(require('lodash-uuid'))
module.exports = {
useQuotesIfRequired: function(value) {
- return (is.numeric(value) || is.uuid(value) || is.bool(value)) ? value : util.format("'%s'", value)
+ return (_.isFinite(value) || _.isUuid(value) || _.isBoolean(value) || _.isObject(value) || _.isArray(value)) ? value : util.format("'%s'", value)
}
}
\ No newline at end of file
diff --git a/lib/client.js b/lib/client.js
index 3328634..b65eb04 100644
--- a/lib/client.js
+++ b/lib/client.js
@@ -1,9 +1,11 @@
'use strict'
var UsergridRequest = require('./request'),
+ UsergridQuery = require('./query'),
+ UsergridEntity = require('./entity'),
request = require('request'),
- config = require('../helpers/config'),
helpers = require('../helpers'),
+ config = helpers.config,
UsergridAppAuth = require('./appAuth'),
_ = require('underscore')
@@ -50,48 +52,20 @@
})
}
-UsergridClient.prototype.GET = function(type, uuidOrName, callback) {
- return new UsergridRequest({
- client: this,
- method: 'GET',
- type: type,
- uuidOrName: typeof uuidOrName === 'string' ? uuidOrName : undefined
- }, callback || uuidOrName)
+UsergridClient.prototype.GET = function() {
+ return new UsergridRequest(helpers.build.GET(this, Array.prototype.slice.call(arguments)))
}
-UsergridClient.prototype.PUT = function(type, uuidOrName, body, callback) {
- if (typeof uuidOrName !== 'string') {
- throw new Error('"uuidOrName" parameter is required when making a PUT request')
- }
- return new UsergridRequest({
- client: this,
- method: 'PUT',
- type: type,
- uuidOrName: typeof uuidOrName === 'string' ? uuidOrName : undefined,
- body: typeof body === 'object' ? body : typeof uuidOrName === 'object' ? uuidOrName : undefined
- }, callback || body || uuidOrName)
+UsergridClient.prototype.PUT = function() {
+ return new UsergridRequest(helpers.build.PUT(this, Array.prototype.slice.call(arguments)))
}
-UsergridClient.prototype.POST = function(type, uuidOrName, body, callback) {
- return new UsergridRequest({
- client: this,
- method: 'POST',
- type: type,
- uuidOrName: typeof uuidOrName === 'string' ? uuidOrName : undefined,
- body: typeof body === 'object' ? body : typeof uuidOrName === 'object' ? uuidOrName : undefined
- }, callback || body || uuidOrName)
+UsergridClient.prototype.POST = function() {
+ return new UsergridRequest(helpers.build.POST(this, Array.prototype.slice.call(arguments)))
}
UsergridClient.prototype.DELETE = function(type, uuidOrName, callback) {
- if (typeof uuidOrName !== 'string') {
- throw new Error('"uuidOrName" parameter is required when making a DELETE request')
- }
- return new UsergridRequest({
- client: this,
- method: 'DELETE',
- type: type,
- uuidOrName: typeof uuidOrName === 'string' ? uuidOrName : undefined
- }, callback || uuidOrName)
+ return new UsergridRequest(helpers.build.DELETE(this, Array.prototype.slice.call(arguments)))
}
UsergridClient.prototype.setAppAuth = function(options) {
@@ -113,7 +87,7 @@
options.type = 'token'
options.client = self
request({
- uri: helpers.buildUrl(options),
+ uri: helpers.build.url(options),
headers: helpers.userAgent,
body: {
grant_type: 'client_credentials',
diff --git a/lib/entity.js b/lib/entity.js
index 2ba4efb..84c838d 100644
--- a/lib/entity.js
+++ b/lib/entity.js
@@ -1,12 +1,21 @@
'use strict'
-var _ = require('underscore'),
- helpers = require('../helpers'),
- ok = require('objectkit')
+var helpers = require('../helpers'),
+ ok = require('objectkit'),
+ _ = require('underscore')
-var UsergridEntity = function(object) {
+var UsergridEntity = function(obj) {
var self = this
- _.extend(self, object)
+
+ if (!obj) {
+ throw new Error('A UsergridEntity object was initialized using an empty argument')
+ }
+
+ _.extend(self, obj)
+
+ if (typeof self.type !== 'string') {
+ throw new Error('"type" (or "collection") parameter is required when initializing a UsergridEntity object')
+ }
Object.defineProperty(self, 'isUser', {
get: function() {
diff --git a/lib/query.js b/lib/query.js
index dcdad93..e661271 100644
--- a/lib/query.js
+++ b/lib/query.js
@@ -8,13 +8,15 @@
var UsergridQuery = function(type) {
+ var self = this
+
var query = '',
queryString,
sort,
__nextIsNot = false
// builder pattern
- var self = {
+ _.extend(self, {
type: function(value) {
self._type = value
return self
@@ -87,7 +89,7 @@
orJoin: function() {
return (query.length > 0 && !_(query).endsWith('or')) ? util.format('%s or', query) : query
}
- }
+ })
// required properties
self._type = self._type || type
diff --git a/lib/request.js b/lib/request.js
index fbc6d21..f7b0cc1 100644
--- a/lib/request.js
+++ b/lib/request.js
@@ -3,14 +3,17 @@
var request = require('request'),
helpers = require('../helpers'),
UsergridResponse = require('../lib/response'),
+ UsergridQuery = require('../lib/query'),
util = require('util'),
_ = require('underscore')
-var UsergridRequest = function(options, callback) {
- callback = helpers.cb(callback)
+var UsergridRequest = function(options) {
+ options.callback = helpers.cb(options.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) {
@@ -18,15 +21,20 @@
authorization: util.format("Bearer %s", options.client.appAuth.token)
})
}
- request(helpers.buildUrl(options), {
+
+ request(helpers.build.url(options), {
headers: headers,
body: options.body,
json: true,
- method: options.method
+ method: options.method,
+ qs: (options.query instanceof UsergridQuery) ? {
+ ql: options.query._ql,
+ limit: options.query._limit
+ } : undefined
}, function(error, response) {
- response = new UsergridResponse(response)
- callback(error, response)
+ options.callback(error, new UsergridResponse(response))
})
+
}
module.exports = UsergridRequest
\ No newline at end of file
diff --git a/lib/response.js b/lib/response.js
index 5f6340d..181341e 100644
--- a/lib/response.js
+++ b/lib/response.js
@@ -5,7 +5,7 @@
UsergridUser = require('./user.js'),
UsergridResponseError = require('./responseError.js'),
helpers = require('../helpers'),
- _ = require('underscore')
+ _ = require('lodash')
_.mixin(require('underscore.string'))
@@ -13,18 +13,23 @@
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
+ if (entity.isUser) {
+ entity = new UsergridUser(entity)
+ }
+ return entity
})
_.extend(response, {
- metadata: _.clone(response.body),
+ metadata: _.cloneDeep(response.body),
entities: entities
})
delete response.metadata.entities
response.first = _.first(entities) || undefined
response.entity = response.first
- response.last = _.last(entities) || undefined
+ response.last = _.last(entities) || undefined
if (ok(response).getIfExists('metadata.path') === '/users') {
response.user = response.first
response.users = response.entities
diff --git a/lib/user.js b/lib/user.js
index 36b0253..4deea07 100644
--- a/lib/user.js
+++ b/lib/user.js
@@ -3,19 +3,18 @@
var UsergridEntity = require('./entity'),
helpers = require('../helpers'),
ok = require('objectkit'),
- _ = require('underscore'),
- util = require('util')
+ util = require('util'),
+ _ = require('underscore')
-var UsergridUser = function(object) {
+var UsergridUser = function(obj) {
- if (!ok(object).has('email') && !ok(object).has('username')) {
- // This is not a user entity
- return object
+ if (!ok(obj).has('email') && !ok(obj).has('username')) {
+ // This is not a user entity, let's try to initalize a standard UsergridEntity
+ throw new Error('"email" or "username" property is required when initializing a UsergridUser object')
}
var self = this
- _.extend(self, object, UsergridEntity)
- UsergridEntity.call(self)
+ _.extend(self, UsergridEntity.call(self, obj))
helpers.setWritable(self, 'name')
return self
}
diff --git a/package.json b/package.json
index 36ed335..38ebe86 100644
--- a/package.json
+++ b/package.json
@@ -1,43 +1,46 @@
{
- "author": "Brandon Shelley",
- "dependencies": {
- "async": "latest",
- "objectkit": "latest",
- "request": "latest",
- "underscore": "latest",
- "underscore.inflection": "latest",
- "underscore.string": "latest",
- "url-join": "latest",
- "volos-analytics-apigee": "latest",
- "volos-analytics-common": "latest",
- "volos-analytics-memory": "latest",
- "volos-cache-apigee": "latest",
- "volos-cache-memory": "latest",
- "volos-cache-redis": "latest",
- "volos-oauth-apigee": "latest",
- "volos-oauth-redis": "latest",
- "volos-quota-apigee": "latest",
- "volos-quota-memory": "latest",
- "volos-quota-redis": "latest"
- },
- "description": "The official Node.js SDK for Usergrid",
- "devDependencies": {
- "grunt": "latest",
- "grunt-codacy": "latest",
- "grunt-mocha-test": "latest",
- "mocha-lcov-reporter": "latest",
- "codacy-coverage": "latest",
- "should": "latest",
- "mocha": "latest"
- },
- "keywords": [],
- "license": "MIT",
- "main": "app.js",
- "name": "usergrid",
- "private": false,
- "scripts": {
- "start": "node app.js",
- "test": "mocha tests"
- },
- "version": "2.0.0"
-}
+ "author": "Brandon Shelley",
+ "dependencies": {
+ "async": "latest",
+ "lodash": "latest",
+ "lodash-inflection": "latest",
+ "lodash-uuid": "latest",
+ "objectkit": "latest",
+ "request": "latest",
+ "underscore": "latest",
+ "underscore.inflection": "latest",
+ "underscore.string": "latest",
+ "url-join": "latest",
+ "volos-analytics-apigee": "latest",
+ "volos-analytics-common": "latest",
+ "volos-analytics-memory": "latest",
+ "volos-cache-apigee": "latest",
+ "volos-cache-memory": "latest",
+ "volos-cache-redis": "latest",
+ "volos-oauth-apigee": "latest",
+ "volos-oauth-redis": "latest",
+ "volos-quota-apigee": "latest",
+ "volos-quota-memory": "latest",
+ "volos-quota-redis": "latest"
+ },
+ "description": "The official Node.js SDK for Usergrid",
+ "devDependencies": {
+ "codacy-coverage": "latest",
+ "grunt": "latest",
+ "grunt-codacy": "latest",
+ "grunt-mocha-test": "latest",
+ "mocha": "latest",
+ "mocha-lcov-reporter": "latest",
+ "should": "latest"
+ },
+ "keywords": [],
+ "license": "MIT",
+ "main": "app.js",
+ "name": "usergrid",
+ "private": false,
+ "scripts": {
+ "start": "node app.js",
+ "test": "mocha tests"
+ },
+ "version": "2.0.0"
+}
\ No newline at end of file
diff --git a/tests/lib/client.test.js b/tests/lib/client.test.js
index 20c71ad..d748fd3 100644
--- a/tests/lib/client.test.js
+++ b/tests/lib/client.test.js
@@ -1,11 +1,18 @@
'use strict'
var should = require('should'),
- config = require('../../helpers/config'),
+ config = require('../../helpers').config,
UsergridClient = require('../../lib/client'),
- UsergridAppAuth = require('../../lib/appAuth')
+ UsergridEntity = require('../../lib/entity'),
+ UsergridQuery = require('../../lib/query'),
+ UsergridAppAuth = require('../../lib/appAuth'),
+ _ = require('underscore')
-var _uuid = null
+_.mixin(require('lodash-uuid'))
+
+var _uuid,
+ _slow = 500,
+ _timeout = 4000
describe('initialization', function() {
it('should fail to initialize without an orgId and appId', function() {
@@ -38,10 +45,10 @@
})
describe('GET()', function() {
+ this.slow(_slow)
+ this.timeout(_timeout)
- this.slow(1000)
- this.timeout(6000)
- var response, client
+ var response, client, query
before(function(done) {
client = new UsergridClient(config)
client.GET(config.testCollection, function(err, usergridResponse) {
@@ -74,11 +81,27 @@
it('response.last should exist and have a valid uuid', function() {
response.last.should.be.an.Object().with.property('uuid').with.a.lengthOf(36)
})
+
+ it('each entity should match the search criteria when passing a UsergridQuery object', function(done) {
+
+ this.slow(_slow)
+ this.timeout(_timeout)
+
+ client = new UsergridClient(config)
+ query = new UsergridQuery(config.testCollection).eq('color', 'black')
+
+ client.GET(query, function(err, usergridResponse) {
+ usergridResponse.entities.forEach(function(entity) {
+ entity.should.be.an.Object().with.property('color').equal('black')
+ })
+ done()
+ })
+ })
})
describe('POST()', function() {
- this.slow(1000)
+ this.slow(_slow)
this.timeout(3000)
var response, client
@@ -113,12 +136,104 @@
it('response.entity.author should equal "Sir Arthur Conan Doyle"', function() {
response.entity.should.have.property('author').equal('Sir Arthur Conan Doyle')
})
+
+ it('should support creating an entity by passing a UsergridEntity object', function(done) {
+
+ this.slow(_slow)
+ this.timeout(_timeout)
+
+ var entity = new UsergridEntity({
+ type: config.testCollection,
+ restaurant: "Dino's Deep Dish",
+ cuisine: "pizza"
+ })
+
+ client.POST(entity, function(err, usergridResponse) {
+ usergridResponse.entity.should.be.an.Object().with.property('restaurant').equal(entity.restaurant)
+ done()
+ })
+ })
+
+ it('should support creating an entity by passing type and a body object', function(done) {
+
+ this.slow(_slow)
+ this.timeout(_timeout)
+
+ client.POST(config.testCollection, {
+ restaurant: "Dino's Deep Dish",
+ cuisine: "pizza"
+ }, function(err, usergridResponse) {
+ usergridResponse.entity.should.be.an.Object().with.property('restaurant').equal("Dino's Deep Dish")
+ done()
+ })
+ })
+
+ it('should support creating an entity by passing a body object that includes type', function(done) {
+
+ this.slow(_slow)
+ this.timeout(_timeout)
+
+ client.POST({
+ type: config.testCollection,
+ restaurant: "Dino's Deep Dish",
+ cuisine: "pizza"
+ }, function(err, usergridResponse) {
+ usergridResponse.entity.should.be.an.Object().with.property('restaurant').equal("Dino's Deep Dish")
+ done()
+ })
+ })
+
+ it('should support creating an entity by passing an array of UsergridEntity objects', function(done) {
+
+ this.slow(_slow)
+ this.timeout(_timeout)
+
+ var entities = [
+ new UsergridEntity({
+ type: config.testCollection,
+ restaurant: "Dino's Deep Dish",
+ cuisine: "pizza"
+ }), new UsergridEntity({
+ type: config.testCollection,
+ restaurant: "Chipotle",
+ cuisine: "mexican"
+ })
+ ]
+
+ client.POST(entities, function(err, usergridResponse) {
+ usergridResponse.entities.forEach(function(entity) {
+ entity.should.be.an.Object().with.property('restaurant').equal(entity.restaurant)
+ })
+ done()
+ })
+ })
+
+ it('should support creating an entity by passing a preformatted POST builder object', function(done) {
+
+ this.slow(_slow)
+ this.timeout(_timeout)
+
+ var options = {
+ type: config.testCollection,
+ body: {
+ restaurant: "Chipotle",
+ cuisine: "mexican"
+ }
+ }
+
+ client.POST(options, function(err, usergridResponse) {
+ usergridResponse.entities.forEach(function(entity) {
+ entity.should.be.an.Object().with.property('restaurant').equal(entity.restaurant)
+ })
+ done()
+ })
+ })
})
describe('PUT()', function() {
- this.slow(1000)
- this.timeout(3000)
+ this.slow(_slow)
+ this.timeout(_timeout)
var response, client
before(function(done) {
@@ -133,30 +248,134 @@
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.testCollection, _uuid)
+ client.PUT(config.testCollection, _uuid, {})
})
it('should return a 200 ok', function() {
response.statusCode.should.equal(200)
})
- it('response.entities should be an array', function() {
+ it('response.entities should be an array with a single entity', function() {
response.entities.should.be.an.Array().with.a.lengthOf(1)
})
- it('response.entity should exist and its uuid should the uuid from the previous POST requets', function() {
+ it('response.entity should exist and its uuid should the uuid from the previous POST request', function() {
response.entity.should.be.an.Object().with.property('uuid').equal(_uuid)
})
- it('response.entity.narrator should equal "Peter Doyle"', function() {
+ it('response.entity.narrator should be updated to "Peter Doyle"', function() {
response.entity.should.have.property('narrator').equal('Peter Doyle')
})
+
+ it('should create a new entity when no uuid or name is passed', function(done) {
+
+ this.slow(_slow)
+ this.timeout(_timeout)
+
+ var newEntity = new UsergridEntity({
+ type: config.testCollection,
+ author: 'Frank Mills'
+ })
+
+ client.PUT(newEntity, function(err, usergridResponse) {
+ usergridResponse.entity.should.be.an.Object()
+ usergridResponse.entity.should.have.property('uuid').with.a.lengthOf(36)
+ usergridResponse.entity.should.have.property('author').equal('Frank Mills')
+ usergridResponse.entity.created.should.equal(usergridResponse.entity.modified)
+ done()
+ })
+ })
+
+ it('should support updating the entity by passing a UsergridEntity object', function(done) {
+
+ this.slow(_slow)
+ this.timeout(_timeout)
+
+ var updateEntity = _.extend(response.entity, {
+ publisher: {
+ name: "George Newns",
+ date: "14 October 1892",
+ country: "United Kingdom"
+ }
+ })
+
+ client.PUT(updateEntity, function(err, usergridResponse) {
+ usergridResponse.entity.should.be.an.Object().with.property('publisher').deepEqual(updateEntity.publisher)
+ done()
+ })
+ })
+
+ it('should support updating an entity by passing type and a body object', function(done) {
+
+ this.slow(_slow)
+ this.timeout(_timeout)
+
+ client.PUT(config.testCollection, {
+ uuid: response.entity.uuid,
+ updateByPassingTypeAndBody: true
+ }, function(err, usergridResponse) {
+ usergridResponse.entity.should.be.an.Object().with.property('updateByPassingTypeAndBody').equal(true)
+ done()
+ })
+ })
+
+ it('should support updating an entity by passing a body object that includes type', function(done) {
+
+ this.slow(_slow)
+ this.timeout(_timeout)
+
+ client.PUT(config.testCollection, {
+ type: config.testCollection,
+ uuid: response.entity.uuid,
+ updateByPassingBodyIncludingType: true
+ }, function(err, usergridResponse) {
+ usergridResponse.entity.should.be.an.Object().with.property('updateByPassingBodyIncludingType').equal(true)
+ done()
+ })
+ })
+
+ it('should support updating a set of entities by passing an UsergridQuery object', function(done) {
+
+ this.slow(_slow)
+ this.timeout(_timeout)
+
+ var query = new UsergridQuery(config.testCollection).eq('cuisine', 'pizza').limit(2)
+ var body = {
+ testUuid: _.uuid()
+ }
+
+ client.PUT(query, body, function(err, usergridResponse) {
+ usergridResponse.entities.forEach(function(entity) {
+ entity.should.be.an.Object().with.property('testUuid').equal(body.testUuid)
+ })
+ done()
+ })
+ })
+
+ it('should support updating an entity by passing a preformatted PUT builder object', function(done) {
+
+ this.slow(_slow)
+ this.timeout(_timeout)
+
+ var options = {
+ uuidOrName: response.entity.uuid,
+ type: config.testCollection,
+ body: {
+ relatedUuid: _.uuid()
+ }
+ }
+
+ client.PUT(options, function(err, usergridResponse) {
+ usergridResponse.entity.should.be.an.Object().with.property('relatedUuid').equal(options.body.relatedUuid)
+ done()
+ })
+ })
})
describe('DELETE()', function() {
- this.slow(1000)
- this.timeout(6000)
+ this.slow(_slow)
+ this.timeout(_timeout)
var response, client
before(function(done) {
@@ -189,12 +408,96 @@
response.error.name.should.equal('entity_not_found')
})
}
+
+ it('should support deleting an entity by passing a UsergridEntity object', function(done) {
+
+ this.slow(_slow + 1000)
+ this.timeout(_timeout + 1000)
+
+ var entity = new UsergridEntity({
+ type: config.testCollection,
+ command: "CTRL+ALT+DEL"
+ })
+
+ client.POST(entity, function(err, usergridResponse) {
+ client.DELETE(usergridResponse.entity, function() {
+ client.GET(config.testCollection, usergridResponse.entity.uuid, function(err, delResponse) {
+ delResponse.error.name.should.equal((config.target === '1.0') ? 'service_resource_not_found' : 'entity_not_found')
+ done()
+ })
+ })
+ })
+ })
+
+ it('should support deleting an entity by passing type and uuid', function(done) {
+
+ this.slow(_slow + 1000)
+ this.timeout(_timeout + 1000)
+
+ var body = {
+ command: "CTRL+ALT+DEL"
+ }
+
+ client.POST(config.testCollection, body, function(err, usergridResponse) {
+ client.DELETE(config.testCollection, usergridResponse.entity.uuid, function() {
+ client.GET(config.testCollection, usergridResponse.entity.uuid, function(err, delResponse) {
+ delResponse.error.name.should.equal((config.target === '1.0') ? 'service_resource_not_found' : 'entity_not_found')
+ done()
+ })
+ })
+ })
+ })
+
+ it('should support deleting multiple entities by passing a UsergridQuery object', function(done) {
+
+ this.slow(_slow + 1000)
+ this.timeout(_timeout + 1000)
+
+ var entity = new UsergridEntity({
+ type: config.testCollection,
+ command: "CMD+TAB"
+ })
+
+ var query = new UsergridQuery(config.testCollection).eq('command', 'CMD+TAB')
+
+ client.POST([entity, entity, entity, entity], function(err, usergridResponse) {
+ client.DELETE(query, function() {
+ client.GET(query, function(err, delResponse) {
+ delResponse.entities.should.be.an.Array().with.lengthOf(0)
+ done()
+ })
+ })
+ })
+ })
+
+ it('should support deleting an entity by passing a preformatted DELETE builder object', function(done) {
+
+ this.slow(_slow + 1000)
+ this.timeout(_timeout + 1000)
+
+ var options = {
+ type: config.testCollection,
+ body: {
+ restaurant: "IHOP",
+ cuisine: "breakfast"
+ }
+ }
+
+ client.POST(options, function(err, usergridResponse) {
+ client.DELETE(_.extend(options, {uuid: usergridResponse.entity.uuid}), function() {
+ client.GET(config.testCollection, usergridResponse.entity.uuid, function(err, delResponse) {
+ delResponse.error.name.should.equal((config.target === '1.0') ? 'service_resource_not_found' : 'entity_not_found')
+ done()
+ })
+ })
+ })
+ })
})
describe('authenticateApp()', function() {
- this.slow(1000)
- this.timeout(6000)
+ this.slow(_slow)
+ this.timeout(_timeout)
var response, token, client
before(function(done) {
diff --git a/tests/lib/query.test.js b/tests/lib/query.test.js
index 1f9ab9b..6b3d298 100644
--- a/tests/lib/query.test.js
+++ b/tests/lib/query.test.js
@@ -1,7 +1,9 @@
'use strict'
var should = require('should'),
- UsergridQuery = require('../../lib/query')
+ UsergridQuery = require('../../lib/query'),
+ UsergridClient = require('../../lib/client'),
+ config = require('../../helpers').config
describe('_type', function() {
it('_type should equal "cats" when passing "type" as a parameter to UsergridQuery', function() {
diff --git a/tests/lib/response.test.js b/tests/lib/response.test.js
index ee04173..ee2b43d 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('../../helpers/config'),
+ config = require('../../helpers').config,
UsergridClient = require('../../lib/client'),
UsergridEntity = require('../../lib/entity'),
UsergridUser = require('../../lib/user'),
@@ -84,15 +84,24 @@
this.slow(1000)
this.timeout(6000)
+ var user
+
it('response.user should be a UsergridUser object and have a valid uuid matching the first object in response.users', function(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)
+ user = usergridResponse.user
+ user.should.be.an.instanceof(UsergridUser).with.property('uuid').equal(_.first(usergridResponse.entities).uuid)
done()
})
})
})
+
+ it('response.user should also be a UsergridEntity object', function(done) {
+ user.isUser.should.be.true()
+ user.should.be.an.instanceof(UsergridEntity)
+ done()
+ })
})
describe('entities', function() {
diff --git a/tests/lib/responseError.test.js b/tests/lib/responseError.test.js
index 0d92cf6..c00dcba 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('../../helpers/config'),
+ config = require('../../helpers').config,
UsergridClient = require('../../lib/client'),
UsergridResponseError = require('../../lib/responseError')
diff --git a/tests/lib/usergrid.test.js b/tests/lib/usergrid.test.js
index 817ee6b..59ce575 100644
--- a/tests/lib/usergrid.test.js
+++ b/tests/lib/usergrid.test.js
@@ -1,7 +1,7 @@
'use strict'
var should = require('should'),
- config = require('../../helpers/config'),
+ config = require('../../helpers').config,
Usergrid = require('../../usergrid'),
UsergridClient = require('../../lib/client'),
util = require('util'),