Implemented connect, disconnect, and getConnections on UsergridClient
diff --git a/helpers/build.js b/helpers/build.js
index 5f5f8c9..8c7ed82 100644
--- a/helpers/build.js
+++ b/helpers/build.js
@@ -14,7 +14,8 @@
config.baseUrl,
options.client.orgId,
options.client.appId,
- options.type, (_.isString(options.uuidOrName) ? options.uuidOrName : "")
+ options.type,
+ _.isString(options.uuidOrName) ? options.uuidOrName : ""
)
},
GET: function(client, args) {
@@ -26,7 +27,7 @@
client.GET(query, optionalCallback)
client.GET({
query: query, // takes precedence
- type: type, // required only if query not defined
+ type: type, // required 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
@@ -39,7 +40,8 @@
method: 'GET'
}
- if (_.isObject(args[0]) && !_.isFunction(args[0]) && !(args[0] instanceof UsergridQuery)) {
+ // if a preformatted options argument passed, assign it to options
+ if (_.isObject(args[0]) && !_.isFunction(args[0]) && args.length <= 2) {
_.assign(options, args[0])
}
@@ -68,7 +70,7 @@
client.PUT({
*entity = alias to body*
query: query, // takes precedence over type/body
- type: type, // required only if query not defined
+ type: type, // required 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
@@ -81,7 +83,8 @@
method: 'PUT'
}
- if (_.isObject(args[0]) && !_.isFunction(args[0]) && !(args[0] instanceof UsergridEntity) && !(args[0] instanceof UsergridQuery)) {
+ // if a preformatted options argument passed, assign it to options
+ if (_.isObject(args[0]) && !_.isFunction(args[0]) && args.length <= 2) {
_.assign(options, args[0])
}
@@ -104,7 +107,6 @@
return options
},
-
POST: function(client, args) {
/* POST supports the following constructor patterns:
@@ -114,7 +116,7 @@
client.POST(entityOrEntities, optionalCallback)
client.POST({
*entity, entities = alias to body*
- type: type, // required if type is not inferred
+ type: type, // required
body: bodyObjectOrArray or entityOrEntities, // if the first entity includes type, type will be inferred from body
}, optionalCallback)
@@ -125,21 +127,22 @@
method: 'POST'
}
- if (_.isObject(args[0]) && !_.isFunction(args[0]) && !(args[0] instanceof UsergridEntity)) {
+ // if a preformatted options argument passed, assign it to options
+ if (_.isObject(args[0]) && !_.isFunction(args[0]) && args.length <= 2) {
_.assign(options, args[0])
}
- options.callback = helpers.cb(_.last(args.filter(_.isFunction)))
+ options.callback = helpers.cb(_.last(args.filter(_.isFunction)))
options.body = _.first([options.entities, options.entity, options.body, args[1], args[0]].filter(function(property) {
return _.isArray(property) && _.isObject(property[0]) && !_.isFunction(property[0]) || _.isObject(property) && !_.isFunction(property)
}))
-
+
if (typeof options.body !== 'object') {
throw new Error('"body" parameter is required when making a POST request')
}
- options.body = _.isArray(options.body) ? options.body : [options.body]
+ options.body = _.isArray(options.body) ? options.body : [options.body]
options.type = _.first([options.type, args[0], options.body[0].type].filter(_.isString))
return options
@@ -154,7 +157,7 @@
client.DELETE({
*uuid, name* = alias to nameOrUuid*
uuidOrName: uuidOrName,
- type: type, // required if type is not inferred
+ type: type, // required if query not defined
query: query // takes precedence over type/uuid
}, optionalCallback)
@@ -165,13 +168,13 @@
method: 'DELETE'
}
- if (_.isObject(args[0]) && !_.isFunction(args[0]) && !(args[0] instanceof UsergridQuery)) {
+ // if a preformatted options argument passed, assign it to options
+ if (_.isObject(args[0]) && !_.isFunction(args[0]) && args.length <= 2) {
_.assign(options, args[0])
}
options.callback = helpers.cb(_.last(args.filter(_.isFunction)))
-
- options.type = _.first([options.type, args[0]._type, args[0]].filter(_.isString))
+ options.type = _.first([options.type, ok(options).getIfExists('entity.type'), args[0]._type, args[0]].filter(_.isString))
options.entity = _.first([options.entity, args[0]].filter(function(property) {
return (property instanceof UsergridEntity)
}))
@@ -186,5 +189,152 @@
}
return options
+ },
+ connection: function(client, args) {
+
+ /* connect supports the following constructor patterns:
+
+ client.connect(entity, "relationship", toEntity);
+ // POST entity.type/entity.uuid/"relationship"/toEntity.uuid
+
+ client.connect("type", <uuidOrName>, "relationship", <toUuid>);
+ // POST type/uuidOrName/relationship/toUuid
+
+ client.connect("type", <uuidOrName>, "relationship", "toType", "toName");
+ // POST type/uuidOrName/relationship/toType/toName
+
+ client.connect({
+ entity: { // or UsergridEntity
+ type: "type",
+ uuidOrName: <uuidOrName>
+ },
+ relationship: "likes",
+ to: { // or UsergridEntity
+ "type": "(required if not using uuid)",
+ "uuidOrName": <uuidOrName>,
+ "name": "alias to uuidOrName" // if uuid not specified, requires "type"
+ "uuid": "alias to uuidOrName"
+ }
+ );
+
+ disconnect supports the identical patters, but uses DELETE instead of POST; it is therefore a reference to this function
+
+ */
+
+ var options = {
+ entity: {},
+ to: {},
+ callback: helpers.cb(_.last(args.filter(_.isFunction)))
+ }
+
+ // if a preformatted options argument passed, assign it to options
+ if (_.isObject(args[0]) && !_.isFunction(args[0]) && args.length <= 2) {
+ _.assign(options, args[0])
+ }
+
+ // handle DELETE using "from" preposition
+ if (_.isObject(options.from)) {
+ options.to = options.from
+ }
+
+ if (_.isObject(args[0]) && !_.isFunction(args[0]) && _.isString(args[1]) && _.isObject(args[2]) && !_.isFunction(args[2])) {
+ _.assign(options.entity, args[0])
+ options.relationship = _.first([options.relationship, args[1]].filter(_.isString))
+ _.assign(options.to, args[2])
+ } else {
+ options.entity.type = _.first([options.entity.type, args[0]].filter(_.isString))
+ options.relationship = _.first([options.relationship, args[2]].filter(_.isString))
+
+ // when using 'name', arg3 and arg4 must both be strings
+ options.to.type = _.isString(args[3]) && !_.isUuid(args[3]) && _.isString(args[4]) ? args[3] : undefined
+ }
+
+ options.entity.uuidOrName = _.first([options.entity.uuidOrName, options.entity.uuid, options.entity.name, args[1]].filter(_.isString))
+ options.to.uuidOrName = _.first([options.to.uuidOrName, options.to.uuid, options.to.name, args[4], args[3]].filter(_.isString))
+
+ if (!_.isString(options.entity.uuidOrName)) {
+ throw new Error('source entity "uuidOrName" is required when connecting or disconnecting entities')
+ }
+
+ if (!_.isString(options.to.uuidOrName)) {
+ throw new Error('target entity "uuidOrName" is required when connecting or disconnecting entities')
+ }
+
+ if (!_.isString(options.to.type) && !_.isUuid(options.to.uuidOrName)) {
+ throw new Error('target "type" (collection name) parameter is required connecting or disconnecting entities by name')
+ }
+
+ options.uri = urljoin(
+ config.baseUrl,
+ client.orgId,
+ client.appId,
+ _.isString(options.entity.type) ? options.entity.type : "",
+ _.isString(options.entity.uuidOrName) ? options.entity.uuidOrName : "",
+ options.relationship,
+ _.isString(options.to.type) ? options.to.type : "",
+ _.isString(options.to.uuidOrName) ? options.to.uuidOrName : ""
+ )
+
+ return options
+ },
+ getConnections: function(client, args) {
+ /* getConnections supports the following constructor patterns:
+
+ client.getConnections(direction, entity, "relationship");
+ // GET OUT: /entity.type/entity.uuid/connections/relationship
+ // GET IN: /entity.type/entity.uuid/connecting/relationship
+
+ client.getConnections(direction, "type", "<uuidOrName>", "relationship");
+ // GET OUT: /type/uuidOrName/connections/relationship
+ // GET IN: /type/uuidOrName/connecting/relationship
+
+ client.getConnections({
+ type: "type", // or inferred, if second argument is an entity
+ uuidOrName: "<uuidOrName>" // if entity not specified
+ relationship: "relationship",
+ direction: OUT or IN
+ );
+ // GET OUT: /entity.type/entity.uuid/connections/relationship
+ // GET IN: /entity.type/entity.uuid/connecting/relationship
+
+ */
+
+ var options = {
+ callback: helpers.cb(_.last(args.filter(_.isFunction)))
+ }
+
+ // if a preformatted options argument passed, assign it to options
+ if (_.isObject(args[0]) && !_.isFunction(args[0]) && args.length <= 2) {
+ _.assign(options, args[0])
+ } else if (_.isObject(args[1]) && !_.isFunction(args[1])) {
+ _.assign(options, args[1])
+ }
+
+ options.direction = _.first([options.direction, args[0]].filter(function(d) {
+ return (d === "IN" || d === "OUT")
+ }))
+ options.relationship = _.first([options.relationship, args[3], args[2]].filter(_.isString))
+ options.uuidOrName = _.first([options.uuidOrName, options.uuid, options.name, args[2]].filter(_.isString))
+ options.type = _.first([options.type, args[1]].filter(_.isString))
+
+ if (!_.isString(options.type)) {
+ throw new Error('"type" (collection name) parameter is required when retrieving connections')
+ }
+
+ if (!_.isString(options.uuidOrName)) {
+ throw new Error('target entity "uuidOrName" is required when retrieving connections')
+ }
+
+ options.uri = urljoin(
+ config.baseUrl,
+ client.orgId,
+ client.appId,
+ _.isString(options.type) ? options.type : "",
+ _.isString(options.uuidOrName) ? options.uuidOrName : "",
+ options.direction === "IN" ? "connecting" : "connections",
+ options.relationship
+ )
+
+ return options
}
}
\ No newline at end of file
diff --git a/lib/client.js b/lib/client.js
index 611bda3..ad82cd1 100644
--- a/lib/client.js
+++ b/lib/client.js
@@ -3,6 +3,7 @@
var UsergridRequest = require('./request'),
request = require('request'),
helpers = require('../helpers'),
+ UsergridResponse = require('./response'),
UsergridAppAuth = require('./appAuth'),
UsergridUserAuth = require('./userAuth'),
UsergridUser = require('./user'),
@@ -51,96 +52,132 @@
})
}
-UsergridClient.prototype.GET = function() {
- return new UsergridRequest(helpers.build.GET(this, Array.prototype.slice.call(arguments)))
-}
+UsergridClient.prototype = {
+ GET: function() {
+ return new UsergridRequest(helpers.build.GET(this, Array.prototype.slice.call(arguments)))
+ },
+ PUT: function() {
+ return new UsergridRequest(helpers.build.PUT(this, Array.prototype.slice.call(arguments)))
+ },
+ POST: function() {
+ return new UsergridRequest(helpers.build.POST(this, Array.prototype.slice.call(arguments)))
+ },
+ DELETE: function() {
+ return new UsergridRequest(helpers.build.DELETE(this, Array.prototype.slice.call(arguments)))
+ },
+ connections: {
+ DIRECTION_IN: "IN",
+ DIRECTION_OUT: "OUT"
+ },
+ connect: function() {
+ var options = helpers.build.connection(this, Array.prototype.slice.call(arguments))
+ request({
+ uri: options.uri,
+ headers: helpers.userAgent,
+ method: 'POST',
+ json: true
+ }, function(error, response) {
+ var usergridResponse = new UsergridResponse(response)
+ options.callback(error, usergridResponse, usergridResponse.entities)
+ })
+ },
+ disconnect: function(options, callback) {
+ var options = helpers.build.connection(this, Array.prototype.slice.call(arguments))
+ request({
+ uri: options.uri,
+ headers: helpers.userAgent,
+ method: 'DELETE',
+ json: true
+ }, function(error, response) {
+ var usergridResponse = new UsergridResponse(response)
+ options.callback(error, usergridResponse, usergridResponse.entities)
+ })
+ },
+ getConnections: function(options, callback) {
+ var options = helpers.build.getConnections(this, Array.prototype.slice.call(arguments))
+ request({
+ uri: options.uri,
+ headers: helpers.userAgent,
+ method: 'GET',
+ json: true
+ }, function(error, response) {
+ var usergridResponse = new UsergridResponse(response)
+ options.callback(error, usergridResponse, usergridResponse.entities)
+ })
+ },
+ setAppAuth: function(options) {
+ this.appAuth = (typeof options === 'string') ? _.values(arguments) : options
+ },
+ authenticateApp: function(options, callback) {
+ var self = this
+ callback = helpers.cb(callback || options)
-UsergridClient.prototype.PUT = function() {
- return new UsergridRequest(helpers.build.PUT(this, Array.prototype.slice.call(arguments)))
-}
+ options = (options instanceof UsergridAppAuth) ? options : self.appAuth || new UsergridAppAuth(options)
-UsergridClient.prototype.POST = function() {
- return new UsergridRequest(helpers.build.POST(this, Array.prototype.slice.call(arguments)))
-}
-
-UsergridClient.prototype.DELETE = function() {
- return new UsergridRequest(helpers.build.DELETE(this, Array.prototype.slice.call(arguments)))
-}
-
-UsergridClient.prototype.setAppAuth = function(options) {
- this.appAuth = (typeof options === 'string') ? _.values(arguments) : options
-}
-
-UsergridClient.prototype.authenticateApp = function(options, callback) {
- var self = this
- callback = helpers.cb(callback || options)
-
- options = (options instanceof UsergridAppAuth) ? options : self.appAuth || new UsergridAppAuth(options)
-
- if (!(options instanceof UsergridAppAuth)) {
- throw new Error('App auth context was not defined when attempting to call .authenticateApp()')
- } else if (!options.clientId || !options.clientSecret) {
- throw new Error('authenticateApp() failed because clientId or clientSecret are missing')
- }
-
- options.type = 'token'
- options.client = self
- request({
- uri: helpers.build.url(options),
- headers: helpers.userAgent,
- body: {
- grant_type: 'client_credentials',
- client_id: options.clientId,
- client_secret: options.clientSecret
- },
- method: 'POST',
- json: true
- }, function(error, response, body) {
- if (self.appAuth && response.statusCode === 200) {
- self.appAuth.token = body.access_token
- self.appAuth.expiry = helpers.time.expiry(body.expires_in)
- self.appAuth.tokenTtl = body.expires_in
+ if (!(options instanceof UsergridAppAuth)) {
+ throw new Error('App auth context was not defined when attempting to call .authenticateApp()')
+ } else if (!options.clientId || !options.clientSecret) {
+ throw new Error('authenticateApp() failed because clientId or clientSecret are missing')
}
- callback(error, response, body.access_token)
- })
-}
-UsergridClient.prototype.authenticateUser = function(options, callback) {
- var self = this
- callback = helpers.cb(callback || options)
+ options.type = 'token'
+ options.client = self
+ request({
+ uri: helpers.build.url(options),
+ headers: helpers.userAgent,
+ body: {
+ grant_type: 'client_credentials',
+ client_id: options.clientId,
+ client_secret: options.clientSecret
+ },
+ method: 'POST',
+ json: true
+ }, function(error, response, body) {
+ if (self.appAuth && response.statusCode === 200) {
+ self.appAuth.token = body.access_token
+ self.appAuth.expiry = helpers.time.expiry(body.expires_in)
+ self.appAuth.tokenTtl = body.expires_in
+ }
+ callback(error, response, body.access_token)
+ })
+ },
+ authenticateUser: function(options, callback) {
+ var self = this
+ callback = helpers.cb(callback || options)
- if (!options.username && !options.email && !options.password) {
- throw new Error('authenticateUser() failed because username/email and password are missing')
- } else if (!options.password) {
- throw new Error('authenticateUser() failed because password is missing')
- }
-
- options.type = 'token'
- options.client = self
- request({
- uri: helpers.build.url(options),
- headers: helpers.userAgent,
- body: options.username ? {
- grant_type: 'password',
- username: options.username,
- password: options.password
- } : {
- grant_type: 'password',
- email: options.email,
- password: options.password
- },
- method: 'POST',
- json: true
- }, function(error, response, body) {
- if (response.statusCode === 200) {
- self.currentUser = new UsergridUser(body.user)
- self.currentUser.auth = new UsergridUserAuth(body.user)
- self.currentUser.auth.token = body.access_token
- self.currentUser.auth.expiry = helpers.time.expiry(body.expires_in)
- self.currentUser.auth.tokenTtl = body.expires_in
+ if (!options.username && !options.email && !options.password) {
+ throw new Error('authenticateUser() failed because username/email and password are missing')
+ } else if (!options.password) {
+ throw new Error('authenticateUser() failed because password is missing')
}
- callback(error, response, body.access_token)
- })
+
+ options.type = 'token'
+ options.client = self
+ request({
+ uri: helpers.build.url(options),
+ headers: helpers.userAgent,
+ body: options.username ? {
+ grant_type: 'password',
+ username: options.username,
+ password: options.password
+ } : {
+ grant_type: 'password',
+ email: options.email,
+ password: options.password
+ },
+ method: 'POST',
+ json: true
+ }, function(error, response, body) {
+ if (response.statusCode === 200) {
+ self.currentUser = new UsergridUser(body.user)
+ self.currentUser.auth = new UsergridUserAuth(body.user)
+ self.currentUser.auth.token = body.access_token
+ self.currentUser.auth.expiry = helpers.time.expiry(body.expires_in)
+ self.currentUser.auth.tokenTtl = body.expires_in
+ }
+ callback(error, response, body.access_token)
+ })
+ }
}
module.exports = UsergridClient
\ No newline at end of file
diff --git a/lib/request.js b/lib/request.js
index edd0860..2a8160a 100644
--- a/lib/request.js
+++ b/lib/request.js
@@ -10,8 +10,8 @@
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')
+ if (!_.isString(options.type)) {
+ throw new Error('"type" (collection name) parameter is required when making a request')
}
var headers = helpers.userAgent
@@ -21,7 +21,6 @@
authorization: util.format("Bearer %s", options.client.appAuth.token)
})
}
-
request(helpers.build.url(options), {
headers: headers,
body: options.body,
@@ -32,7 +31,8 @@
limit: options.query._limit
} : undefined
}, function(error, response) {
- options.callback(error, new UsergridResponse(response))
+ var usergridResponse = new UsergridResponse(response)
+ options.callback(error, usergridResponse, usergridResponse.entities)
})
}
diff --git a/tests/lib/client.test.js b/tests/lib/client.test.js
index 09995fe..c1196d1 100644
--- a/tests/lib/client.test.js
+++ b/tests/lib/client.test.js
@@ -1,6 +1,7 @@
'use strict'
var should = require('should'),
+ urljoin = require('url-join'),
config = require('../../helpers').config,
UsergridClient = require('../../lib/client'),
UsergridEntity = require('../../lib/entity'),
@@ -496,6 +497,281 @@
})
})
+describe('connect()', function() {
+
+ this.slow(_slow)
+ this.timeout(_timeout)
+
+ var response,
+ client = new UsergridClient(),
+ query = new UsergridQuery(config.test.collection).eq('name', 'testNameOne').or.eq('name', 'testNameTwo').asc('name')
+
+ before(function(done) {
+ // Create the entities we're going to use for connections
+ client.POST(config.test.collection, [{
+ "name": "testNameOne"
+ }, {
+ "name": "testNameTwo"
+ }], function() {
+ client.GET(query, function(err, usergridResponse) {
+ response = usergridResponse
+ done()
+ })
+ })
+ })
+
+ it('should connect entities by passing UsergridEntity objects as parameters', function(done) {
+ var entity1 = response.first
+ var entity2 = response.last
+
+ var relationship = "foos"
+
+ client.connect(entity1, relationship, entity2, function(err, usergridResponse) {
+ usergridResponse.statusCode.should.equal(200)
+ client.getConnections(client.connections.DIRECTION_OUT, entity1, relationship, function(err, usergridResponse) {
+ usergridResponse.first.metadata.connecting[relationship].should.equal(urljoin(
+ "/",
+ config.test.collection,
+ entity1.uuid,
+ relationship,
+ entity2.uuid,
+ "connecting",
+ relationship
+ ))
+ done()
+ })
+ })
+ })
+
+ it('should connect entities by passing source type, source uuid, and target uuid as parameters', function(done) {
+ var entity1 = response.first
+ var entity2 = response.last
+
+ var relationship = "bars"
+
+ client.connect(entity1.type, entity1.uuid, relationship, entity2.uuid, function(err, usergridResponse) {
+ usergridResponse.statusCode.should.equal(200)
+ client.getConnections(client.connections.DIRECTION_OUT, entity1, relationship, function(err, usergridResponse) {
+ usergridResponse.first.metadata.connecting[relationship].should.equal(urljoin(
+ "/",
+ config.test.collection,
+ entity1.uuid,
+ relationship,
+ entity2.uuid,
+ "connecting",
+ relationship
+ ))
+ done()
+ })
+ })
+ })
+
+ it('should connect entities by passing source type, source name, target type, and target name as parameters', function(done) {
+ var entity1 = response.first
+ var entity2 = response.last
+
+ var relationship = "bazzes"
+
+ client.connect(entity1.type, entity1.name, relationship, entity2.type, entity2.name, function(err, usergridResponse) {
+ usergridResponse.statusCode.should.equal(200)
+ client.getConnections(client.connections.DIRECTION_OUT, entity1, relationship, function(err, usergridResponse) {
+ usergridResponse.first.metadata.connecting[relationship].should.equal(urljoin(
+ "/",
+ config.test.collection,
+ entity1.uuid,
+ relationship,
+ entity2.uuid,
+ "connecting",
+ relationship
+ ))
+ done()
+ })
+ })
+ })
+
+ it('should connect entities by passing a preconfigured options object', function(done) {
+ var entity1 = response.first
+ var entity2 = response.last
+
+ var options = {
+ entity: entity1,
+ relationship: "quxes",
+ to: entity2
+ }
+
+ client.connect(options, function(err, usergridResponse) {
+ usergridResponse.statusCode.should.equal(200)
+ client.getConnections(client.connections.DIRECTION_OUT, entity1, options.relationship, function(err, usergridResponse) {
+ usergridResponse.first.metadata.connecting[options.relationship].should.equal(urljoin(
+ "/",
+ config.test.collection,
+ entity1.uuid,
+ options.relationship,
+ entity2.uuid,
+ "connecting",
+ options.relationship
+ ))
+ done()
+ })
+ })
+ })
+
+ it('should fail to connect entities when specifying target name without type', function() {
+ var entity1 = response.first
+ var entity2 = response.last
+
+ should(function() {
+ client.connect(entity1.type, entity1.name, "test", entity2.name, function(err, usergridResponse) {})
+ }).throw()
+ })
+})
+
+describe('getConnections()', function() {
+
+ this.slow(_slow)
+ this.timeout(_timeout)
+
+ var response,
+ client = new UsergridClient(),
+ query = new UsergridQuery(config.test.collection).eq('name', 'testNameOne').or.eq('name', 'testNameTwo').asc('name')
+
+ before(function(done) {
+ client.GET(query, function(err, usergridResponse) {
+ response = usergridResponse
+ done()
+ })
+ })
+
+ it('should get an entity\'s outbound connections', function(done) {
+ var entity1 = response.first
+ var entity2 = response.last
+
+ var relationship = "foos"
+
+ client.getConnections(client.connections.DIRECTION_OUT, entity1, relationship, function(err, usergridResponse) {
+ usergridResponse.first.metadata.connecting[relationship].should.equal(urljoin(
+ "/",
+ config.test.collection,
+ entity1.uuid,
+ relationship,
+ entity2.uuid,
+ "connecting",
+ relationship
+ ))
+ done()
+ })
+ })
+
+ it('should get an entity\'s inbound connections', function(done) {
+ var entity1 = response.first
+ var entity2 = response.last
+
+ var relationship = "foos"
+
+ client.getConnections(client.connections.DIRECTION_IN, entity2, relationship, function(err, usergridResponse) {
+ usergridResponse.first.metadata.connections[relationship].should.equal(urljoin(
+ "/",
+ config.test.collection,
+ entity2.uuid,
+ "connecting",
+ entity1.uuid,
+ relationship
+ ))
+ done()
+ })
+ })
+})
+
+describe('disconnect()', function() {
+
+ this.slow(_slow)
+ this.timeout(_timeout)
+
+ var response,
+ client = new UsergridClient(),
+ query = new UsergridQuery(config.test.collection).eq('name', 'testNameOne').or.eq('name', 'testNameTwo').asc('name')
+
+ before(function(done) {
+ client.GET(query, function(err, usergridResponse) {
+ response = usergridResponse
+ done()
+ })
+ })
+
+ it('should disconnect entities by passing UsergridEntity objects as parameters', function(done) {
+ var entity1 = response.first
+ var entity2 = response.last
+
+ var relationship = "foos"
+
+ client.disconnect(entity1, relationship, entity2, function(err, usergridResponse) {
+ usergridResponse.statusCode.should.equal(200)
+ client.getConnections(client.connections.DIRECTION_OUT, entity1, relationship, function(err, usergridResponse) {
+ usergridResponse.entities.should.be.an.Array().with.lengthOf(0)
+ done()
+ })
+ })
+ })
+
+ it('should disconnect entities by passing source type, source uuid, and target uuid as parameters', function(done) {
+ var entity1 = response.first
+ var entity2 = response.last
+
+ var relationship = "bars"
+
+ client.disconnect(entity1.type, entity1.uuid, relationship, entity2.uuid, function(err, usergridResponse) {
+ usergridResponse.statusCode.should.equal(200)
+ client.getConnections(client.connections.DIRECTION_OUT, entity1, relationship, function(err, usergridResponse) {
+ usergridResponse.entities.should.be.an.Array().with.lengthOf(0)
+ done()
+ })
+ })
+ })
+
+ it('should disconnect entities by passing source type, source name, target type, and target name as parameters', function(done) {
+ var entity1 = response.first
+ var entity2 = response.last
+
+ var relationship = "bazzes"
+
+ client.disconnect(entity1.type, entity1.name, relationship, entity2.type, entity2.name, function(err, usergridResponse) {
+ usergridResponse.statusCode.should.equal(200)
+ client.getConnections(client.connections.DIRECTION_OUT, entity1, relationship, function(err, usergridResponse) {
+ usergridResponse.entities.should.be.an.Array().with.lengthOf(0)
+ done()
+ })
+ })
+ })
+
+ it('should disconnect entities by passing a preconfigured options object', function(done) {
+ var entity1 = response.first
+ var entity2 = response.last
+
+ var options = {
+ entity: entity1,
+ relationship: "quxes",
+ to: entity2
+ }
+
+ client.disconnect(options, function(err, usergridResponse) {
+ usergridResponse.statusCode.should.equal(200)
+ client.getConnections(client.connections.DIRECTION_OUT, entity1, options.relationship, function(err, usergridResponse) {
+ usergridResponse.entities.should.be.an.Array().with.lengthOf(0)
+ done()
+ })
+ })
+ })
+
+ it('should fail to disconnect entities when specifying target name without type', function() {
+ var entity1 = response.first
+ var entity2 = response.last
+
+ should(function() {
+ client.disconnect(entity1.type, entity1.name, "test", entity2.name, function(err, usergridResponse) {})
+ }).throw()
+ })
+})
+
describe('authenticateApp()', function() {
this.slow(_slow)
@@ -613,7 +889,7 @@
it('client.currentUser should have an email', function() {
client.currentUser.should.have.property('email')
- })
+ })
it('client.currentUser and client.currentUser.auth should not store password', function() {
client.currentUser.should.not.have.property('password')