usergrid-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From snoopd...@apache.org
Subject [19/41] git commit: fixing issues in test cases
Date Tue, 11 Feb 2014 23:21:03 GMT
fixing issues in test cases


Project: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/commit/017cf300
Tree: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/tree/017cf300
Diff: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/diff/017cf300

Branch: refs/heads/master
Commit: 017cf300087a66d70faef91cdbf3d87799b024b8
Parents: 9dfc562
Author: ryan bridges <rbridges@apigee.com>
Authored: Mon Feb 10 14:26:34 2014 -0500
Committer: ryan bridges <rbridges@apigee.com>
Committed: Mon Feb 10 14:26:34 2014 -0500

----------------------------------------------------------------------
 sdks/html5-javascript/Gruntfile.js             |   3 +-
 sdks/html5-javascript/lib/Usergrid.js          | 257 +-----
 sdks/html5-javascript/lib/modules/Asset.js     |   2 +-
 sdks/html5-javascript/lib/modules/Client.js    |  91 +-
 sdks/html5-javascript/lib/modules/Entity.js    |   4 +-
 sdks/html5-javascript/lib/modules/Folder.js    |   2 +-
 sdks/html5-javascript/lib/modules/util/Ajax.js |  24 +-
 sdks/html5-javascript/tests/mocha/test.js      |  71 +-
 sdks/html5-javascript/usergrid.js              | 918 +++++++++++++++-----
 sdks/html5-javascript/usergrid.min.js          |   6 +-
 10 files changed, 807 insertions(+), 571 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/017cf300/sdks/html5-javascript/Gruntfile.js
----------------------------------------------------------------------
diff --git a/sdks/html5-javascript/Gruntfile.js b/sdks/html5-javascript/Gruntfile.js
index 58d5a2a..527633d 100644
--- a/sdks/html5-javascript/Gruntfile.js
+++ b/sdks/html5-javascript/Gruntfile.js
@@ -5,9 +5,8 @@ module.exports = function(grunt) {
         "lib/modules/util/Promise.js",
         "lib/modules/util/Ajax.js",
         "lib/modules/util/Storable.js",
-//        "lib/modules/util/KeyStore.js",
         "lib/Usergrid.js",
-//		"lib/modules/Client.js",
+		"lib/modules/Client.js",
 		"lib/modules/Entity.js",
 		"lib/modules/Collection.js",
 		"lib/modules/Group.js",

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/017cf300/sdks/html5-javascript/lib/Usergrid.js
----------------------------------------------------------------------
diff --git a/sdks/html5-javascript/lib/Usergrid.js b/sdks/html5-javascript/lib/Usergrid.js
index 1a4e5dd..f545964 100644
--- a/sdks/html5-javascript/lib/Usergrid.js
+++ b/sdks/html5-javascript/lib/Usergrid.js
@@ -133,18 +133,19 @@ function isFunction(f) {
  *  @return Returns whatever would be returned by the callback. or false.
  */
 function doCallback(callback, params, context) {
+    console.info("CALLED FROM", this.name||(context)?context.name:"UNKNOWN");
 	var returnValue;
 	if (isFunction(callback)) {
 		if (!params) params = [];
 		if (!context) context = this;
 		params.push(context);
-		try {
+		//try {
 			returnValue = callback.apply(context, params);
-		} catch (ex) {
+		/*} catch (ex) {
 			if (console && console.error) {
 				console.error("Callback error:", ex);
 			}
-		}
+		}*/
 	}
 	return returnValue;
 }
@@ -185,7 +186,7 @@ function doCallback(callback, params, context) {
          Prepare our request
          */
         if (!isValidUrl(this.endpoint)) {
-            this.logger.error(endpoint, this.endpoint, /^https:\/\//.test(endpoint), api_uri, orgName, appName);
+            this.logger.error(endpoint, this.endpoint, /^https:\/\//.test(endpoint));
             throw new UsergridError("The provided endpoint is not valid: " + this.endpoint);
         }
         /* a callback to make the request */
@@ -272,254 +273,6 @@ function doCallback(callback, params, context) {
         var entities=this.getEntities();
         return entities[0];
     }
-    Usergrid.Client = function (options) {
-        this.logger = new global.Logger('Usergrid.Client');
-        var self = this;
-        this.getStorage();
-        this.set('api_uri', options.URI || 'https://api.usergrid.com');
-        this.set('orgName', options.orgName);
-        this.set('appName', options.appName);
-        //other options
-        this.set('buildCurl', options.buildCurl || false);
-        this.set('logging', options.logging || false);
-
-        //Moved to Ajax transport layer
-        /*this.set('api_call_timeout', options.callTimeout || 30000);
-         this.set('api_call_timeout_callback', options.callTimeoutCallback || global.NOOP);
-         this.set('api_logout_callback', options.logoutCallback || global.NOOP);*/
-
-
-    };
-    /*
-     Add browser storage capability (defaults to sessionStorage,
-     but you can inject anything that implements window.Storage
-     eg. client._storage=localStorage;
-     */
-    UsergridStorable.mixin(Usergrid.Client);
-    /*
-     Add rudimentary eventing
-     */
-    UsergridEventable.mixin(Usergrid.Client);
-
-    /*
-     *  function for building asset urls
-     *
-     *  @method buildAssetURL
-     *  @public
-     *  @params {string} uuid
-     *  @return {string} assetURL
-     */
-    Usergrid.Client.prototype.buildAssetURL = function(uuid) {
-        var qs = {};
-        var uri_elements=this.get('api_uri','orgName','appName');
-        uri_elements=uri_elements.concat(['assets', uuid, 'data']);
-        var assetURL = uri_elements.join('/');
-        var token = this.getToken();
-        if (token) {
-            qs.access_token = token;
-        }
-        //append params to the path
-        var encoded_params = encodeParams(qs);
-        if (encoded_params) {
-            assetURL += "?" + encoded_params;
-        }
-
-        return assetURL;
-    };
-
-    /*
-     *  function for building asset urls
-     *
-     *  @method buildAssetURL
-     *  @public
-     *  @params {string} uuid
-     *  @return {string} assetURL
-     */
-    Usergrid.Client.prototype.buildEndpointURL = function(endpoint, qs) {
-        qs =qs|| {};
-        var endSlashes=/(^\/|\/$)/g;
-        var assetURL = [endpoint.replace(endSlashes,'')].concat(this.get('api_uri','orgName','appName'));
-        var token = this.getToken();
-        if (token) {qs.access_token = token;}
-        var encoded_params = encodeParams(qs);
-        if (encoded_params) {
-            assetURL += "?" + encoded_params;
-        }
-
-        return assetURL;
-    };
-
-
-    /*
-     *  Main function for making requests to the API.  Can be called directly.
-     *
-     *  options object:
-     *  `method` - http method (GET, POST, PUT, or DELETE), defaults to GET
-     *  `qs` - object containing querystring values to be appended to the uri
-     *  `body` - object containing entity body for POST and PUT requests
-     *  `endpoint` - API endpoint, for example 'users/fred'
-     *  `mQuery` - boolean, set to true if running management query, defaults to false
-     *
-     *  @method request
-     *  @public
-     *  @params {object} options
-     *  @param {function} callback
-     *  @return {callback} callback(err, data)
-     */
-    Usergrid.Client.prototype.request = function (options, callback) {
-        var p = new Promise();
-        var _callback = function (err, data) {
-            p.done(err, data);
-            doCallback(callback, [err, data]);
-        };
-        this.logger = new Logger("Request");
-        var self = this;
-        var method = options.method || 'GET';
-        var endpoint = options.endpoint;
-        var body = options.body || {};
-        var qs = options.qs || {};
-        var mQuery = options.mQuery || false; //is this a query to the management endpoint?
-        /*
-         could also use headers for the token
-         xhr.setRequestHeader("Authorization", "Bearer " + self.getToken());
-         xhr.withCredentials = true;
-         */
-        var api_uri = this.get('api_uri');
-        var orgName = this.get('orgName');
-        var appName = this.get('appName');
-        if (this.getToken())qs.access_token = this.getToken();
-
-        //if(isValidUrl(endpoint)){
-        if (api_uri && orgName && appName) {
-            endpoint = [api_uri, orgName, appName, endpoint].join('/');
-        } else {
-            endpoint = [api_uri, endpoint].join('/');
-            //throw new UsergridInvalidURIError('No Org name or App name specified.', 'no_org_or_app_name_specified');
-        }
-
-        var req = new Usergrid.Request(method, endpoint, qs, body, function (err, response) {
-            if ([
-                "auth_expired_session_token",
-                "auth_missing_credentials",
-                "auth_unverified_oath",
-                "expired_token",
-                "unauthorized",
-                "auth_invalid"
-            ].indexOf(response.error) !== -1) {
-                //throw err;
-            }
-            doCallback(callback, [err, response]);
-            p.done(err, response);
-        });
-
-
-        return p;
-        /*}catch(e){
-         if (typeof(this.logoutCallback) === 'function') {
-         this.logoutCallback(true, 'no_org_or_app_name_specified');
-         }
-         _callback(true, e);
-
-         }*/
-    };
-
-    /*
-     *  Main function for creating new entities - should be called directly.
-     *
-     *  options object: options {data:{'type':'collection_type', 'key':'value'}, uuid:uuid}}
-     *
-     *  @method createEntity
-     *  @public
-     *  @params {object} options
-     *  @param {function} callback
-     *  @return {callback} callback(err, data)
-     */
-    Usergrid.Client.prototype.createEntity = function (options, callback) {
-        // todo: replace the check for new / save on not found code with simple save
-        // when users PUT on no user fix is in place.
-        var getOnExist = options['getOnExist'] || false; //if true, will return entity if one already exists
-        delete options['getOnExist']; //so it doesn't become part of our data model
-        var entity_data = {
-            client: this,
-            data: options
-        };
-        var entity = new Usergrid.Entity(entity_data);
-        var self = this;
-        entity.fetch(function (err, data) {
-            console.log(err, data);
-            //if the fetch doesn't find what we are looking for, or there is no error, do a save
-            var common_errors = ['service_resource_not_found', 'no_name_specified', 'null_pointer'];
-            var okToSave = (err.name && common_errors.indexOf(err.name) !== -1) || (!err && getOnExist);
-
-            if (okToSave) {
-                entity.set(entity_data.data); //add the data again just in case
-                entity.save(function (err, data) {
-                    doCallback(callback, [err, entity, data]);
-                });
-            } else {
-                doCallback(callback, [err, entity, data]);
-            }
-        });
-
-    };
-
-    /*
-     *  Main function for getting existing entities - should be called directly.
-     *
-     *  You must supply a uuid or (username or name). Username only applies to users.
-     *  Name applies to all custom entities
-     *
-     *  options object: options {data:{'type':'collection_type', 'name':'value', 'username':'value'}, uuid:uuid}}
-     *
-     *  @method createEntity
-     *  @public
-     *  @params {object} options
-     *  @param {function} callback
-     *  @return {callback} doCallback(callback, [err, data])
-     */
-    Usergrid.Client.prototype.getEntity = function (options, callback) {
-        var entity_data = {
-            client: this,
-            data: options
-        };
-        var entity = new Usergrid.Entity(entity_data);
-        entity.fetch(function (err, data) {
-            doCallback(callback, [err, entity, data]);
-        });
-    };
-
-    /*
-     *  Main function for restoring an entity from serialized data.
-     *
-     *  serializedObject should have come from entityObject.serialize();
-     *
-     *  @method restoreEntity
-     *  @public
-     *  @param {string} serializedObject
-     *  @return {object} Entity Object
-     */
-    Usergrid.Client.prototype.restoreEntity = function (serializedObject) {
-        return new Usergrid.Entity({ client: this, data: JSON.parse(serializedObject)});
-    };
-    /*
-     *  Main function for creating new collections - should be called directly.
-     *
-     *  options object: options {client:client, type: type, qs:qs}
-     *
-     *  @method createCollection
-     *  @public
-     *  @params {object} options
-     *  @param {function} callback
-     *  @return {callback} callback(err, data)
-     */
-    Usergrid.Client.prototype.createCollection = function (options, callback) {
-        options.client = this;
-        var collection = new Usergrid.Collection(options, function (err, data) {
-            if (typeof(callback) === 'function') {
-                callback(err, collection, data);
-            }
-        });
-    };
 
     //Usergrid.Entity=function(){};
 		//Usergrid.Collection=function(){};

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/017cf300/sdks/html5-javascript/lib/modules/Asset.js
----------------------------------------------------------------------
diff --git a/sdks/html5-javascript/lib/modules/Asset.js b/sdks/html5-javascript/lib/modules/Asset.js
index 0eed742..8af84e1 100644
--- a/sdks/html5-javascript/lib/modules/Asset.js
+++ b/sdks/html5-javascript/lib/modules/Asset.js
@@ -38,7 +38,7 @@ Usergrid.Asset = function(options, callback) {
 		if (err) {
 			doCallback(callback, [true, new Usergrid.Error(data)], self);
 		} else {
-			if (data.entities.length){
+			if (data && data.entities && data.entities.length){
 				self.set(data.entities[0]);
 			}
 			doCallback(callback, [false, self], self);

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/017cf300/sdks/html5-javascript/lib/modules/Client.js
----------------------------------------------------------------------
diff --git a/sdks/html5-javascript/lib/modules/Client.js b/sdks/html5-javascript/lib/modules/Client.js
index 727e257..cf78df7 100644
--- a/sdks/html5-javascript/lib/modules/Client.js
+++ b/sdks/html5-javascript/lib/modules/Client.js
@@ -1,6 +1,6 @@
 (function() {
   var name = 'Client', global = this, overwrittenName = global[name], exports;
-exports = (function() {
+
   Usergrid.Client = function(options) {
     //usergrid endpoint
     this.URI = options.URI || 'https://api.usergrid.com';
@@ -21,10 +21,6 @@ exports = (function() {
     this._callTimeout =  options.callTimeout || 30000; //default to 30 seconds
     this._callTimeoutCallback =  options.callTimeoutCallback || null;
     this.logoutCallback =  options.logoutCallback || null;
-    var self=this;
-    this.keyStore=options.keyStore||new KeyStore('usergrid-javascript-sdk', 2, "data", "key", function(err, ks){
-        self.logger.info("'%s' keystore created.", 'usergrid-javascript-sdk');
-      });
   };
 
   /*
@@ -71,8 +67,21 @@ exports = (function() {
        xhr.withCredentials = true;
        */
     }
-
-    //append params to the path
+      var req = new Usergrid.Request(method, uri, qs, body, function (err, response) {
+          if ([
+              "auth_expired_session_token",
+              "auth_missing_credentials",
+              "auth_unverified_oath",
+              "expired_token",
+              "unauthorized",
+              "auth_invalid"
+          ].indexOf(response.error) !== -1) {
+              //throw err;
+          }
+          doCallback(callback, [err, response]);
+          //p.done(err, response);
+      });
+    /*//append params to the path
     var encoded_params = encodeParams(qs);
     if (encoded_params) {
       uri += "?" + encoded_params;
@@ -175,7 +184,7 @@ exports = (function() {
       this.buildCurlCall(curlOptions);
     }
     this._start = new Date().getTime();
-    xhr.send(body);
+    xhr.send(body);*/
   }
 
   /*
@@ -250,35 +259,33 @@ exports = (function() {
    *  @param {function} callback
    *  @return {callback} callback(err, data)
    */
-  Usergrid.Client.prototype.createEntity = function (options, callback) {
-    // todo: replace the check for new / save on not found code with simple save
-    // when users PUT on no user fix is in place.
-    var getOnExist = options.getOnExist || false; //if true, will return entity if one already exists
-    delete options.getOnExist;//so it doesn't become part of our data model
-    var options = {
-      client:this,
-      data:options
-    };
-    var entity = new Usergrid.Entity(options);
-    entity.fetch(function(err, data) {
-      //if the fetch doesn't find what we are looking for, or there is no error, do a save
-      var okToSave = (err && 'service_resource_not_found' === data.error || 'no_name_specified' === data.error || 'null_pointer' === data.error) || (!err && getOnExist);
-      if(okToSave) {
-        entity.set(options.data); //add the data again just in case
-        entity.save(function(err, data) {
-          if (typeof(callback) === 'function') {
-            callback(err, entity, data);
-          }
+    Usergrid.Client.prototype.createEntity = function (options, callback) {
+        // todo: replace the check for new / save on not found code with simple save
+        // when users PUT on no user fix is in place.
+        var getOnExist = options['getOnExist'] || false; //if true, will return entity if one already exists
+        delete options['getOnExist']; //so it doesn't become part of our data model
+        var entity_data = {
+            client: this,
+            data: options
+        };
+        var entity = new Usergrid.Entity(entity_data);
+        var self = this;
+        entity.fetch(function (err, data) {
+            //if the fetch doesn't find what we are looking for, or there is no error, do a save
+            var common_errors = ['service_resource_not_found', 'no_name_specified', 'null_pointer'];
+            var okToSave = (!err && getOnExist)||(err && err.name && common_errors.indexOf(err.name) !== -1);
+
+            if (okToSave) {
+                entity.set(entity_data.data); //add the data again just in case
+                entity.save(function (err, data) {
+                    doCallback(callback, [err, entity, data]);
+                });
+            } else {
+                doCallback(callback, [null, entity, data]);
+            }
         });
-      } else {
-        if (typeof(callback) === 'function') {
-          callback(err, entity, data);
-        }
-      }
-    });
-
-  };
 
+    };
   /*
    *  Main function for getting existing entities - should be called directly.
    *
@@ -300,9 +307,7 @@ exports = (function() {
     }
     var entity = new Usergrid.Entity(options);
     entity.fetch(function(err, data) {
-      if (typeof(callback) === 'function') {
-        callback(err, entity, data);
-      }
+        doCallback(callback, [err, entity, data]);
     });
   };
 
@@ -340,9 +345,7 @@ exports = (function() {
   Usergrid.Client.prototype.createCollection = function (options, callback) {
     options.client = this;
     var collection = new Usergrid.Collection(options, function(err, data) {
-      if (typeof(callback) === 'function') {
-        callback(err, collection, data);
-      }
+        doCallback(callback, [err, collection, data]);
     });
   };
 
@@ -465,7 +468,7 @@ exports = (function() {
           "height":80,
           "url":user.get("picture"),
           "width":80
-        },
+        }
       },
       "verb":"post",
       "content":content
@@ -846,9 +849,7 @@ exports = (function() {
       return image;
     }
   }
-  return Usergrid.Client;
-}());
-  global[name] =  exports;
+  global[name] =  Usergrid.Client;
   global[name].noConflict = function() {
     if(overwrittenName){
       global[name] = overwrittenName;

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/017cf300/sdks/html5-javascript/lib/modules/Entity.js
----------------------------------------------------------------------
diff --git a/sdks/html5-javascript/lib/modules/Entity.js b/sdks/html5-javascript/lib/modules/Entity.js
index e84e400..05ea970 100644
--- a/sdks/html5-javascript/lib/modules/Entity.js
+++ b/sdks/html5-javascript/lib/modules/Entity.js
@@ -260,7 +260,7 @@ Usergrid.Entity.prototype.fetch = function (callback) {
         if(entity){
             self.set(entity);
         }
-        console.log("AFTER FETCH", self.get(), entity, response);
+        console.log("AFTER FETCH", err, self.get(), entity, response);
         doCallback(callback,[err, entity, self]);
     });
 };
@@ -417,7 +417,7 @@ Usergrid.Entity.prototype.getConnections = function (connection, callback) {
 
     self[connection] = {};
 
-    var length = data.entities.length;
+    var length = (data && data.entities)?data.entities.length:0;
     for (var i = 0; i < length; i++) {
       if (data.entities[i].type === 'user'){
         self[connection][data.entities[i].username] = data.entities[i];

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/017cf300/sdks/html5-javascript/lib/modules/Folder.js
----------------------------------------------------------------------
diff --git a/sdks/html5-javascript/lib/modules/Folder.js b/sdks/html5-javascript/lib/modules/Folder.js
index 11d7521..7e2821f 100644
--- a/sdks/html5-javascript/lib/modules/Folder.js
+++ b/sdks/html5-javascript/lib/modules/Folder.js
@@ -20,7 +20,7 @@ Usergrid.Folder = function(options, callback) {
 		if (err) {
 			doCallback(callback, [true, new Usergrid.Error(data)], self);
 		} else {
-			if (data.entities.length){
+			if (data && data.entities && data.entities.length){
 				self.set(data.entities[0]);
 			}
 			doCallback(callback, [false, self], self);

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/017cf300/sdks/html5-javascript/lib/modules/util/Ajax.js
----------------------------------------------------------------------
diff --git a/sdks/html5-javascript/lib/modules/util/Ajax.js b/sdks/html5-javascript/lib/modules/util/Ajax.js
index e8228ea..5b36ad5 100644
--- a/sdks/html5-javascript/lib/modules/util/Ajax.js
+++ b/sdks/html5-javascript/lib/modules/util/Ajax.js
@@ -2,12 +2,16 @@
 (function() {
     var name = 'Ajax', global = this, overwrittenName = global[name], exports;
 
-    Function.prototype.partial = function() {
+    /*Function.prototype.partial = function() {
         var fn = this,b = [].slice.call(arguments);
         return fn.bind(undefined, b);
+    }*/
+    function partial(fn){
+        var args = Array.prototype.slice.call(arguments,1);
+        return function(){
+            return fn.apply(this, args.concat(Array.prototype.slice(arguments,0)))
+        }
     }
-
-    exports = (function() {
         function Ajax() {
             this.logger=new global.Logger(name);
             var self=this;
@@ -25,7 +29,7 @@
                 }
                 return result;
             }
-            var request = function(m, u, d) {
+            function request(m, u, d) {
                 var p = new Promise(), timeout;
                 self.logger.time(m + ' ' + u);
                 self.logger.timeEnd(m + ' ' + u);
@@ -56,14 +60,12 @@
                 return p;
             };
             this.request=request;
-            this.get = request.partial('GET');
-            this.post = request.partial('POST');
-            this.put = request.partial('PUT');
-            this.delete = request.partial('DELETE');
+            this.get = partial(request, 'GET');
+            this.post = partial(request, 'POST');
+            this.put = partial(request, 'PUT');
+            this.delete = partial(request, 'DELETE');
         }
-        return new Ajax();
-    }());
-    global[name] =  exports;
+    global[name] =  new Ajax();
     global[name].noConflict = function() {
         if(overwrittenName){
             global[name] = overwrittenName;

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/017cf300/sdks/html5-javascript/tests/mocha/test.js
----------------------------------------------------------------------
diff --git a/sdks/html5-javascript/tests/mocha/test.js b/sdks/html5-javascript/tests/mocha/test.js
index ec132a8..50229e1 100644
--- a/sdks/html5-javascript/tests/mocha/test.js
+++ b/sdks/html5-javascript/tests/mocha/test.js
@@ -221,6 +221,7 @@ describe('Usergrid', function() {
 			if (done) done();
 		}
 		before(function(done) {
+            console.log("remove existing dogs");
 			//Make sure our dog doesn't already exist
 			var options = {
 				type: 'dogs',
@@ -234,11 +235,12 @@ describe('Usergrid', function() {
 					assert(!err, "could not retrieve list of dogs: " + dogs.error_description);
 					//we got 50 dogs, now display the Entities:
 					//do doggy cleanup
-					if (dogs.hasNextEntity()) {
+					//if (dogs.hasNextEntity()) {
 						while (dogs.hasNextEntity()) {
 							//get a reference to the dog
 							var dog = dogs.getNextEntity();
 							//notice('removing dog ' + dogname + ' from database');
+                            if(dog === null) continue;
 							dog.destroy(function(err, data) {
 								assert(!err, dog.get('name') + " not removed: " + data.error_description);
 								if (!dogs.hasNextEntity()) {
@@ -246,30 +248,12 @@ describe('Usergrid', function() {
 								}
 							});
 						}
-					} else {
+					//} else {
 						done();
-					}
+					//}
 				}
 			});
 		});
-		before(function(done) {
-			this.timeout(10000);
-			var totalDogs = 30;
-			Array.apply(0, Array(totalDogs)).forEach(function(x, y) {
-				var dogNum = y + 1;
-				var options = {
-					type: 'dogs',
-					name: 'dog' + dogNum,
-					index: y
-				}
-				client.createEntity(options, function(err, dog) {
-					assert(!err, " not created: " + dog.error_description);
-					if (dogNum === totalDogs) {
-						done();
-					}
-				});
-			})
-		});
 		it('should CREATE a new dogs collection', function(done) {
 			var options = {
 				type: 'dogs',
@@ -284,9 +268,28 @@ describe('Usergrid', function() {
 				done();
 			});
 		});
-		it('should RETRIEVE dogs from the collection', function(done) {
-			loop(done);
-		});
+        it('should CREATE dogs in the collection', function(done) {
+            this.timeout(10000);
+            var totalDogs = 30;
+            Array.apply(0, Array(totalDogs)).forEach(function(x, y) {
+                var dogNum = y + 1;
+                var options = {
+                    type: 'dogs',
+                    name: 'dog' + dogNum,
+                    index: y
+                }
+                client.createEntity(options, function(err, dog) {
+                    console.log(err, dog);
+                    assert(!err, "dog not created");
+                    if (dogNum === totalDogs) {
+                        done();
+                    }
+                });
+            })
+        });
+        it('should RETRIEVE dogs from the collection', function(done) {
+            loop(done);
+        });
 		it('should RETRIEVE the next page of dogs from the collection', function(done) {
 			if (dogs.hasNextPage()) {
 				dogs.getNextPage(function(err) {
@@ -425,9 +428,11 @@ describe('Usergrid', function() {
 			req.onload = function() {
 				test_image = req.response;
 				image_type = req.getResponseHeader('Content-Type');
+                console.log(test_image, image_type);
 				done();
 			}
 			req.onerror = function(err) {
+                console.error(err);
 				done();
 			};
 			req.send(null);
@@ -438,9 +443,12 @@ describe('Usergrid', function() {
 				method: 'GET',
 				endpoint: 'Assets'
 			}, function(err, data) {
-				var assets = data.entities.filter(function(asset) {
-					return asset.name === filename
-				});
+				var assets = [];
+                if(data && data.entities && data.entities.length){
+                    assets.concat(data.entities.filter(function(asset) {
+                        return asset.name === filename
+                    }));
+                }
 				if (assets.length) {
 					assets.forEach(function(asset) {
 						client.request({
@@ -460,9 +468,12 @@ describe('Usergrid', function() {
 				method: 'GET',
 				endpoint: 'folders'
 			}, function(err, data) {
-				var folders = data.entities.filter(function(folder) {
-					return folder.name === foldername
-				});
+				var folders = [];
+                if(data && data.entities && data.entities.length){
+                    folders.concat(data.entities.filter(function(folder) {
+                        return folder.name === foldername
+                    }));
+                }
 				if (folders.length) {
 					folders.forEach(function(folder) {
 						client.request({

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/017cf300/sdks/html5-javascript/usergrid.js
----------------------------------------------------------------------
diff --git a/sdks/html5-javascript/usergrid.js b/sdks/html5-javascript/usergrid.js
index 8990b83..542fb38 100644
--- a/sdks/html5-javascript/usergrid.js
+++ b/sdks/html5-javascript/usergrid.js
@@ -1,4 +1,4 @@
-/*! usergrid@0.0.0 2014-02-06 */
+/*! usergrid@0.0.0 2014-02-10 */
 var UsergridEventable = function() {
     throw Error("'UsergridEventable' is not intended to be invoked directly");
 };
@@ -181,68 +181,71 @@ UsergridEventable.mixin = function(destObject) {
 //Ajax
 (function() {
     var name = "Ajax", global = this, overwrittenName = global[name], exports;
-    Function.prototype.partial = function() {
-        var fn = this, b = [].slice.call(arguments);
+    /*Function.prototype.partial = function() {
+        var fn = this,b = [].slice.call(arguments);
         return fn.bind(undefined, b);
-    };
-    exports = function() {
-        function Ajax() {
-            this.logger = new global.Logger(name);
-            var self = this;
-            function encode(data) {
-                var result = "";
-                if (typeof data === "string") {
-                    result = data;
-                } else {
-                    var e = encodeURIComponent;
-                    for (var i in data) {
-                        if (data.hasOwnProperty(i)) {
-                            result += "&" + e(i) + "=" + e(data[i]);
-                        }
+    }*/
+    function partial(fn) {
+        var args = Array.prototype.slice.call(arguments, 1);
+        return function() {
+            return fn.apply(this, args.concat(Array.prototype.slice(arguments, 0)));
+        };
+    }
+    function Ajax() {
+        this.logger = new global.Logger(name);
+        var self = this;
+        function encode(data) {
+            var result = "";
+            if (typeof data === "string") {
+                result = data;
+            } else {
+                var e = encodeURIComponent;
+                for (var i in data) {
+                    if (data.hasOwnProperty(i)) {
+                        result += "&" + e(i) + "=" + e(data[i]);
                     }
                 }
-                return result;
             }
-            var request = function(m, u, d) {
-                var p = new Promise(), timeout;
-                self.logger.time(m + " " + u);
-                self.logger.timeEnd(m + " " + u);
-                (function(xhr) {
-                    xhr.onreadystatechange = function() {
-                        this.readyState ^ 4 || (self.logger.timeEnd(m + " " + u), clearTimeout(timeout), 
-                        p.done(null, this));
-                    };
-                    xhr.onerror = function(response) {
-                        clearTimeout(timeout);
-                        p.done(response, null);
-                    };
-                    xhr.oncomplete = function(response) {
-                        clearTimeout(timeout);
-                        self.info("%s request to %s returned %s", m, u, this.status);
-                    };
-                    xhr.open(m, u);
-                    if (d) {
-                        xhr.setRequestHeader("Content-Type", "application/json");
-                        xhr.setRequestHeader("Accept", "application/json");
-                    }
-                    timeout = setTimeout(function() {
-                        xhr.abort();
-                        p.done("API Call timed out.", null);
-                    }, 3e4);
-                    //TODO stick that timeout in a config variable
-                    xhr.send(encode(d));
-                })(new XMLHttpRequest());
-                return p;
-            };
-            this.request = request;
-            this.get = request.partial("GET");
-            this.post = request.partial("POST");
-            this.put = request.partial("PUT");
-            this.delete = request.partial("DELETE");
-        }
-        return new Ajax();
-    }();
-    global[name] = exports;
+            return result;
+        }
+        function request(m, u, d) {
+            var p = new Promise(), timeout;
+            self.logger.time(m + " " + u);
+            self.logger.timeEnd(m + " " + u);
+            (function(xhr) {
+                xhr.onreadystatechange = function() {
+                    this.readyState ^ 4 || (self.logger.timeEnd(m + " " + u), clearTimeout(timeout), 
+                    p.done(null, this));
+                };
+                xhr.onerror = function(response) {
+                    clearTimeout(timeout);
+                    p.done(response, null);
+                };
+                xhr.oncomplete = function(response) {
+                    clearTimeout(timeout);
+                    self.info("%s request to %s returned %s", m, u, this.status);
+                };
+                xhr.open(m, u);
+                if (d) {
+                    xhr.setRequestHeader("Content-Type", "application/json");
+                    xhr.setRequestHeader("Accept", "application/json");
+                }
+                timeout = setTimeout(function() {
+                    xhr.abort();
+                    p.done("API Call timed out.", null);
+                }, 3e4);
+                //TODO stick that timeout in a config variable
+                xhr.send(encode(d));
+            })(new XMLHttpRequest());
+            return p;
+        }
+        this.request = request;
+        this.get = partial(request, "GET");
+        this.post = partial(request, "POST");
+        this.put = partial(request, "PUT");
+        this.delete = partial(request, "DELETE");
+    }
+    global[name] = new Ajax();
     global[name].noConflict = function() {
         if (overwrittenName) {
             global[name] = overwrittenName;
@@ -491,18 +494,14 @@ function isFunction(f) {
  *  @return Returns whatever would be returned by the callback. or false.
  */
 function doCallback(callback, params, context) {
+    console.info("CALLED FROM", this.name || context ? context.name : "UNKNOWN");
     var returnValue;
     if (isFunction(callback)) {
         if (!params) params = [];
         if (!context) context = this;
         params.push(context);
-        try {
-            returnValue = callback.apply(context, params);
-        } catch (ex) {
-            if (console && console.error) {
-                console.error("Callback error:", ex);
-            }
-        }
+        //try {
+        returnValue = callback.apply(context, params);
     }
     return returnValue;
 }
@@ -539,7 +538,7 @@ function doCallback(callback, params, context) {
          Prepare our request
          */
         if (!isValidUrl(this.endpoint)) {
-            this.logger.error(endpoint, this.endpoint, /^https:\/\//.test(endpoint), api_uri, orgName, appName);
+            this.logger.error(endpoint, this.endpoint, /^https:\/\//.test(endpoint));
             throw new UsergridError("The provided endpoint is not valid: " + this.endpoint);
         }
         /* a callback to make the request */
@@ -629,96 +628,56 @@ function doCallback(callback, params, context) {
         var entities = this.getEntities();
         return entities[0];
     };
-    Usergrid.Client = function(options) {
-        this.logger = new global.Logger("Usergrid.Client");
-        var self = this;
-        this.getStorage();
-        this.set("api_uri", options.URI || "https://api.usergrid.com");
-        this.set("orgName", options.orgName);
-        this.set("appName", options.appName);
-        //other options
-        this.set("buildCurl", options.buildCurl || false);
-        this.set("logging", options.logging || false);
-    };
-    /*
-     Add browser storage capability (defaults to sessionStorage,
-     but you can inject anything that implements window.Storage
-     eg. client._storage=localStorage;
-     */
-    UsergridStorable.mixin(Usergrid.Client);
-    /*
-     Add rudimentary eventing
-     */
-    UsergridEventable.mixin(Usergrid.Client);
-    /*
-     *  function for building asset urls
-     *
-     *  @method buildAssetURL
-     *  @public
-     *  @params {string} uuid
-     *  @return {string} assetURL
-     */
-    Usergrid.Client.prototype.buildAssetURL = function(uuid) {
-        var qs = {};
-        var uri_elements = this.get("api_uri", "orgName", "appName");
-        uri_elements = uri_elements.concat([ "assets", uuid, "data" ]);
-        var assetURL = uri_elements.join("/");
-        var token = this.getToken();
-        if (token) {
-            qs.access_token = token;
-        }
-        //append params to the path
-        var encoded_params = encodeParams(qs);
-        if (encoded_params) {
-            assetURL += "?" + encoded_params;
+    //Usergrid.Entity=function(){};
+    //Usergrid.Collection=function(){};
+    global[name] = Usergrid;
+    global[name].noConflict = function() {
+        if (overwrittenName) {
+            global[name] = overwrittenName;
         }
-        return assetURL;
+        return Usergrid;
     };
-    /*
-     *  function for building asset urls
-     *
-     *  @method buildAssetURL
-     *  @public
-     *  @params {string} uuid
-     *  @return {string} assetURL
-     */
-    Usergrid.Client.prototype.buildEndpointURL = function(endpoint, qs) {
-        qs = qs || {};
-        var endSlashes = /(^\/|\/$)/g;
-        var assetURL = [ endpoint.replace(endSlashes, "") ].concat(this.get("api_uri", "orgName", "appName"));
-        var token = this.getToken();
-        if (token) {
-            qs.access_token = token;
+    return global[name];
+})(this);
+
+(function() {
+    var name = "Client", global = this, overwrittenName = global[name], exports;
+    Usergrid.Client = function(options) {
+        //usergrid endpoint
+        this.URI = options.URI || "https://api.usergrid.com";
+        //Find your Orgname and Appname in the Admin portal (http://apigee.com/usergrid)
+        if (options.orgName) {
+            this.set("orgName", options.orgName);
         }
-        var encoded_params = encodeParams(qs);
-        if (encoded_params) {
-            assetURL += "?" + encoded_params;
+        if (options.appName) {
+            this.set("appName", options.appName);
         }
-        return assetURL;
+        //other options
+        this.buildCurl = options.buildCurl || false;
+        this.logging = options.logging || false;
+        //timeout and callbacks
+        this._callTimeout = options.callTimeout || 3e4;
+        //default to 30 seconds
+        this._callTimeoutCallback = options.callTimeoutCallback || null;
+        this.logoutCallback = options.logoutCallback || null;
     };
     /*
-     *  Main function for making requests to the API.  Can be called directly.
-     *
-     *  options object:
-     *  `method` - http method (GET, POST, PUT, or DELETE), defaults to GET
-     *  `qs` - object containing querystring values to be appended to the uri
-     *  `body` - object containing entity body for POST and PUT requests
-     *  `endpoint` - API endpoint, for example 'users/fred'
-     *  `mQuery` - boolean, set to true if running management query, defaults to false
-     *
-     *  @method request
-     *  @public
-     *  @params {object} options
-     *  @param {function} callback
-     *  @return {callback} callback(err, data)
-     */
+   *  Main function for making requests to the API.  Can be called directly.
+   *
+   *  options object:
+   *  `method` - http method (GET, POST, PUT, or DELETE), defaults to GET
+   *  `qs` - object containing querystring values to be appended to the uri
+   *  `body` - object containing entity body for POST and PUT requests
+   *  `endpoint` - API endpoint, for example 'users/fred'
+   *  `mQuery` - boolean, set to true if running management query, defaults to false
+   *
+   *  @method request
+   *  @public
+   *  @params {object} options
+   *  @param {function} callback
+   *  @return {callback} callback(err, data)
+   */
     Usergrid.Client.prototype.request = function(options, callback) {
-        var p = new Promise();
-        var _callback = function(err, data) {
-            p.done(err, data);
-            doCallback(callback, [ err, data ]);
-        };
-        this.logger = new Logger("Request");
         var self = this;
         var method = options.method || "GET";
         var endpoint = options.endpoint;
@@ -726,39 +685,92 @@ function doCallback(callback, params, context) {
         var qs = options.qs || {};
         var mQuery = options.mQuery || false;
         //is this a query to the management endpoint?
-        /*
-         could also use headers for the token
-         xhr.setRequestHeader("Authorization", "Bearer " + self.getToken());
-         xhr.withCredentials = true;
-         */
-        var api_uri = this.get("api_uri");
         var orgName = this.get("orgName");
         var appName = this.get("appName");
-        if (this.getToken()) qs.access_token = this.getToken();
-        //if(isValidUrl(endpoint)){
-        if (api_uri && orgName && appName) {
-            endpoint = [ api_uri, orgName, appName, endpoint ].join("/");
+        var uri;
+        if (!mQuery && !orgName && !appName) {
+            if (typeof this.logoutCallback === "function") {
+                return this.logoutCallback(true, "no_org_or_app_name_specified");
+            }
+        }
+        if (mQuery) {
+            uri = this.URI + "/" + endpoint;
         } else {
-            endpoint = [ api_uri, endpoint ].join("/");
+            uri = this.URI + "/" + orgName + "/" + appName + "/" + endpoint;
         }
-        var req = new Usergrid.Request(method, endpoint, qs, body, function(err, response) {
+        if (self.getToken()) {
+            qs.access_token = self.getToken();
+        }
+        var req = new Usergrid.Request(method, uri, qs, body, function(err, response) {
             if ([ "auth_expired_session_token", "auth_missing_credentials", "auth_unverified_oath", "expired_token", "unauthorized", "auth_invalid" ].indexOf(response.error) !== -1) {}
             doCallback(callback, [ err, response ]);
-            p.done(err, response);
         });
-        return p;
     };
     /*
-     *  Main function for creating new entities - should be called directly.
-     *
-     *  options object: options {data:{'type':'collection_type', 'key':'value'}, uuid:uuid}}
-     *
-     *  @method createEntity
-     *  @public
-     *  @params {object} options
-     *  @param {function} callback
-     *  @return {callback} callback(err, data)
-     */
+   *  function for building asset urls
+   *
+   *  @method buildAssetURL
+   *  @public
+   *  @params {string} uuid
+   *  @return {string} assetURL
+   */
+    Usergrid.Client.prototype.buildAssetURL = function(uuid) {
+        var self = this;
+        var qs = {};
+        var assetURL = this.URI + "/" + this.orgName + "/" + this.appName + "/assets/" + uuid + "/data";
+        if (self.getToken()) {
+            qs.access_token = self.getToken();
+        }
+        //append params to the path
+        var encoded_params = encodeParams(qs);
+        if (encoded_params) {
+            assetURL += "?" + encoded_params;
+        }
+        return assetURL;
+    };
+    /*
+   *  Main function for creating new groups. Call this directly.
+   *
+   *  @method createGroup
+   *  @public
+   *  @params {string} path
+   *  @param {function} callback
+   *  @return {callback} callback(err, data)
+   */
+    Usergrid.Client.prototype.createGroup = function(options, callback) {
+        var getOnExist = options.getOnExist || false;
+        options = {
+            path: options.path,
+            client: this,
+            data: options
+        };
+        var group = new Usergrid.Group(options);
+        group.fetch(function(err, data) {
+            var okToSave = err && "service_resource_not_found" === data.error || "no_name_specified" === data.error || "null_pointer" === data.error || !err && getOnExist;
+            if (okToSave) {
+                group.save(function(err, data) {
+                    if (typeof callback === "function") {
+                        callback(err, group);
+                    }
+                });
+            } else {
+                if (typeof callback === "function") {
+                    callback(err, group);
+                }
+            }
+        });
+    };
+    /*
+   *  Main function for creating new entities - should be called directly.
+   *
+   *  options object: options {data:{'type':'collection_type', 'key':'value'}, uuid:uuid}}
+   *
+   *  @method createEntity
+   *  @public
+   *  @params {object} options
+   *  @param {function} callback
+   *  @return {callback} callback(err, data)
+   */
     Usergrid.Client.prototype.createEntity = function(options, callback) {
         // todo: replace the check for new / save on not found code with simple save
         // when users PUT on no user fix is in place.
@@ -773,10 +785,9 @@ function doCallback(callback, params, context) {
         var entity = new Usergrid.Entity(entity_data);
         var self = this;
         entity.fetch(function(err, data) {
-            console.log(err, data);
             //if the fetch doesn't find what we are looking for, or there is no error, do a save
             var common_errors = [ "service_resource_not_found", "no_name_specified", "null_pointer" ];
-            var okToSave = err.name && common_errors.indexOf(err.name) !== -1 || !err && getOnExist;
+            var okToSave = !err && getOnExist || err && err.name && common_errors.indexOf(err.name) !== -1;
             if (okToSave) {
                 entity.set(entity_data.data);
                 //add the data again just in case
@@ -784,80 +795,539 @@ function doCallback(callback, params, context) {
                     doCallback(callback, [ err, entity, data ]);
                 });
             } else {
-                doCallback(callback, [ err, entity, data ]);
+                doCallback(callback, [ null, entity, data ]);
             }
         });
     };
     /*
-     *  Main function for getting existing entities - should be called directly.
-     *
-     *  You must supply a uuid or (username or name). Username only applies to users.
-     *  Name applies to all custom entities
-     *
-     *  options object: options {data:{'type':'collection_type', 'name':'value', 'username':'value'}, uuid:uuid}}
-     *
-     *  @method createEntity
-     *  @public
-     *  @params {object} options
-     *  @param {function} callback
-     *  @return {callback} doCallback(callback, [err, data])
-     */
+   *  Main function for getting existing entities - should be called directly.
+   *
+   *  You must supply a uuid or (username or name). Username only applies to users.
+   *  Name applies to all custom entities
+   *
+   *  options object: options {data:{'type':'collection_type', 'name':'value', 'username':'value'}, uuid:uuid}}
+   *
+   *  @method createEntity
+   *  @public
+   *  @params {object} options
+   *  @param {function} callback
+   *  @return {callback} callback(err, data)
+   */
     Usergrid.Client.prototype.getEntity = function(options, callback) {
-        var entity_data = {
+        var options = {
             client: this,
             data: options
         };
-        var entity = new Usergrid.Entity(entity_data);
+        var entity = new Usergrid.Entity(options);
         entity.fetch(function(err, data) {
             doCallback(callback, [ err, entity, data ]);
         });
     };
     /*
-     *  Main function for restoring an entity from serialized data.
-     *
-     *  serializedObject should have come from entityObject.serialize();
-     *
-     *  @method restoreEntity
-     *  @public
-     *  @param {string} serializedObject
-     *  @return {object} Entity Object
-     */
+   *  Main function for restoring an entity from serialized data.
+   *
+   *  serializedObject should have come from entityObject.serialize();
+   *
+   *  @method restoreEntity
+   *  @public
+   *  @param {string} serializedObject
+   *  @return {object} Entity Object
+   */
     Usergrid.Client.prototype.restoreEntity = function(serializedObject) {
-        return new Usergrid.Entity({
+        var data = JSON.parse(serializedObject);
+        var options = {
             client: this,
-            data: JSON.parse(serializedObject)
-        });
+            data: data
+        };
+        var entity = new Usergrid.Entity(options);
+        return entity;
     };
     /*
-     *  Main function for creating new collections - should be called directly.
-     *
-     *  options object: options {client:client, type: type, qs:qs}
-     *
-     *  @method createCollection
-     *  @public
-     *  @params {object} options
-     *  @param {function} callback
-     *  @return {callback} callback(err, data)
-     */
+   *  Main function for creating new collections - should be called directly.
+   *
+   *  options object: options {client:client, type: type, qs:qs}
+   *
+   *  @method createCollection
+   *  @public
+   *  @params {object} options
+   *  @param {function} callback
+   *  @return {callback} callback(err, data)
+   */
     Usergrid.Client.prototype.createCollection = function(options, callback) {
         options.client = this;
         var collection = new Usergrid.Collection(options, function(err, data) {
+            doCallback(callback, [ err, collection, data ]);
+        });
+    };
+    /*
+   *  Main function for restoring a collection from serialized data.
+   *
+   *  serializedObject should have come from collectionObject.serialize();
+   *
+   *  @method restoreCollection
+   *  @public
+   *  @param {string} serializedObject
+   *  @return {object} Collection Object
+   */
+    Usergrid.Client.prototype.restoreCollection = function(serializedObject) {
+        var data = JSON.parse(serializedObject);
+        data.client = this;
+        var collection = new Usergrid.Collection(data);
+        return collection;
+    };
+    /*
+   *  Main function for retrieving a user's activity feed.
+   *
+   *  @method getFeedForUser
+   *  @public
+   *  @params {string} username
+   *  @param {function} callback
+   *  @return {callback} callback(err, data, activities)
+   */
+    Usergrid.Client.prototype.getFeedForUser = function(username, callback) {
+        var options = {
+            method: "GET",
+            endpoint: "users/" + username + "/feed"
+        };
+        this.request(options, function(err, data) {
             if (typeof callback === "function") {
-                callback(err, collection, data);
+                if (err) {
+                    callback(err);
+                } else {
+                    callback(err, data, data.entities);
+                }
             }
         });
     };
-    //Usergrid.Entity=function(){};
-    //Usergrid.Collection=function(){};
-    global[name] = Usergrid;
+    /*
+   *  Function for creating new activities for the current user - should be called directly.
+   *
+   *  //user can be any of the following: "me", a uuid, a username
+   *  Note: the "me" alias will reference the currently logged in user (e.g. 'users/me/activties')
+   *
+   *  //build a json object that looks like this:
+   *  var options =
+   *  {
+   *    "actor" : {
+   *      "displayName" :"myusername",
+   *      "uuid" : "myuserid",
+   *      "username" : "myusername",
+   *      "email" : "myemail",
+   *      "picture": "http://path/to/picture",
+   *      "image" : {
+   *          "duration" : 0,
+   *          "height" : 80,
+   *          "url" : "http://www.gravatar.com/avatar/",
+   *          "width" : 80
+   *      },
+   *    },
+   *    "verb" : "post",
+   *    "content" : "My cool message",
+   *    "lat" : 48.856614,
+   *    "lon" : 2.352222
+   *  }
+   *
+   *  @method createEntity
+   *  @public
+   *  @params {string} user // "me", a uuid, or a username
+   *  @params {object} options
+   *  @param {function} callback
+   *  @return {callback} callback(err, data)
+   */
+    Usergrid.Client.prototype.createUserActivity = function(user, options, callback) {
+        options.type = "users/" + user + "/activities";
+        var options = {
+            client: this,
+            data: options
+        };
+        var entity = new Usergrid.Entity(options);
+        entity.save(function(err, data) {
+            if (typeof callback === "function") {
+                callback(err, entity);
+            }
+        });
+    };
+    /*
+   *  Function for creating user activities with an associated user entity.
+   *
+   *  user object:
+   *  The user object passed into this function is an instance of Usergrid.Entity.
+   *
+   *  @method createUserActivityWithEntity
+   *  @public
+   *  @params {object} user
+   *  @params {string} content
+   *  @param {function} callback
+   *  @return {callback} callback(err, data)
+   */
+    Usergrid.Client.prototype.createUserActivityWithEntity = function(user, content, callback) {
+        var username = user.get("username");
+        var options = {
+            actor: {
+                displayName: username,
+                uuid: user.get("uuid"),
+                username: username,
+                email: user.get("email"),
+                picture: user.get("picture"),
+                image: {
+                    duration: 0,
+                    height: 80,
+                    url: user.get("picture"),
+                    width: 80
+                }
+            },
+            verb: "post",
+            content: content
+        };
+        this.createUserActivity(username, options, callback);
+    };
+    /*
+   *  A private method to get call timing of last call
+   */
+    Usergrid.Client.prototype.calcTimeDiff = function() {
+        var seconds = 0;
+        var time = this._end - this._start;
+        try {
+            seconds = (time / 10 / 60).toFixed(2);
+        } catch (e) {
+            return 0;
+        }
+        return seconds;
+    };
+    /*
+   *  A public method to store the OAuth token for later use - uses localstorage if available
+   *
+   *  @method setToken
+   *  @public
+   *  @params {string} token
+   *  @return none
+   */
+    Usergrid.Client.prototype.setToken = function(token) {
+        this.set("token", token);
+    };
+    /*
+   *  A public method to get the OAuth token
+   *
+   *  @method getToken
+   *  @public
+   *  @return {string} token
+   */
+    Usergrid.Client.prototype.getToken = function() {
+        return this.get("token");
+    };
+    Usergrid.Client.prototype.setObject = function(key, value) {
+        if (value) {
+            value = JSON.stringify(value);
+        }
+        this.set(key, value);
+    };
+    Usergrid.Client.prototype.set = function(key, value) {
+        var keyStore = "apigee_" + key;
+        this[key] = value;
+        if (typeof Storage !== "undefined") {
+            if (value) {
+                localStorage.setItem(keyStore, value);
+            } else {
+                localStorage.removeItem(keyStore);
+            }
+        }
+    };
+    Usergrid.Client.prototype.getObject = function(key) {
+        return JSON.parse(this.get(key));
+    };
+    Usergrid.Client.prototype.get = function(key) {
+        var keyStore = "apigee_" + key;
+        var value = null;
+        if (this[key]) {
+            value = this[key];
+        } else if (typeof Storage !== "undefined") {
+            value = localStorage.getItem(keyStore);
+        }
+        return value;
+    };
+    /*
+   * A public facing helper method for signing up users
+   *
+   * @method signup
+   * @public
+   * @params {string} username
+   * @params {string} password
+   * @params {string} email
+   * @params {string} name
+   * @param {function} callback
+   * @return {callback} callback(err, data)
+   */
+    Usergrid.Client.prototype.signup = function(username, password, email, name, callback) {
+        var self = this;
+        var options = {
+            type: "users",
+            username: username,
+            password: password,
+            email: email,
+            name: name
+        };
+        this.createEntity(options, callback);
+    };
+    /*
+   *
+   *  A public method to log in an app user - stores the token for later use
+   *
+   *  @method login
+   *  @public
+   *  @params {string} username
+   *  @params {string} password
+   *  @param {function} callback
+   *  @return {callback} callback(err, data)
+   */
+    Usergrid.Client.prototype.login = function(username, password, callback) {
+        var self = this;
+        var options = {
+            method: "POST",
+            endpoint: "token",
+            body: {
+                username: username,
+                password: password,
+                grant_type: "password"
+            }
+        };
+        this.request(options, function(err, data) {
+            var user = {};
+            if (err && self.logging) {
+                console.log("error trying to log user in");
+            } else {
+                var options = {
+                    client: self,
+                    data: data.user
+                };
+                user = new Usergrid.Entity(options);
+                self.setToken(data.access_token);
+            }
+            if (typeof callback === "function") {
+                callback(err, data, user);
+            }
+        });
+    };
+    Usergrid.Client.prototype.reAuthenticateLite = function(callback) {
+        var self = this;
+        var options = {
+            method: "GET",
+            endpoint: "management/me",
+            mQuery: true
+        };
+        this.request(options, function(err, response) {
+            if (err && self.logging) {
+                console.log("error trying to re-authenticate user");
+            } else {
+                //save the re-authed token and current email/username
+                self.setToken(response.access_token);
+            }
+            if (typeof callback === "function") {
+                callback(err);
+            }
+        });
+    };
+    Usergrid.Client.prototype.reAuthenticate = function(email, callback) {
+        var self = this;
+        var options = {
+            method: "GET",
+            endpoint: "management/users/" + email,
+            mQuery: true
+        };
+        this.request(options, function(err, response) {
+            var organizations = {};
+            var applications = {};
+            var user = {};
+            var data;
+            if (err && self.logging) {
+                console.log("error trying to full authenticate user");
+            } else {
+                data = response.data;
+                self.setToken(data.token);
+                self.set("email", data.email);
+                //delete next block and corresponding function when iframes are refactored
+                localStorage.setItem("accessToken", data.token);
+                localStorage.setItem("userUUID", data.uuid);
+                localStorage.setItem("userEmail", data.email);
+                //end delete block
+                var userData = {
+                    username: data.username,
+                    email: data.email,
+                    name: data.name,
+                    uuid: data.uuid
+                };
+                var options = {
+                    client: self,
+                    data: userData
+                };
+                user = new Usergrid.Entity(options);
+                organizations = data.organizations;
+                var org = "";
+                try {
+                    //if we have an org stored, then use that one. Otherwise, use the first one.
+                    var existingOrg = self.get("orgName");
+                    org = organizations[existingOrg] ? organizations[existingOrg] : organizations[Object.keys(organizations)[0]];
+                    self.set("orgName", org.name);
+                } catch (e) {
+                    err = true;
+                    if (self.logging) {
+                        console.log("error selecting org");
+                    }
+                }
+                //should always be an org
+                applications = self.parseApplicationsArray(org);
+                self.selectFirstApp(applications);
+                self.setObject("organizations", organizations);
+                self.setObject("applications", applications);
+            }
+            if (typeof callback === "function") {
+                callback(err, data, user, organizations, applications);
+            }
+        });
+    };
+    /*
+   *  A public method to log in an app user with facebook - stores the token for later use
+   *
+   *  @method loginFacebook
+   *  @public
+   *  @params {string} username
+   *  @params {string} password
+   *  @param {function} callback
+   *  @return {callback} callback(err, data)
+   */
+    Usergrid.Client.prototype.loginFacebook = function(facebookToken, callback) {
+        var self = this;
+        var options = {
+            method: "GET",
+            endpoint: "auth/facebook",
+            qs: {
+                fb_access_token: facebookToken
+            }
+        };
+        this.request(options, function(err, data) {
+            var user = {};
+            if (err && self.logging) {
+                console.log("error trying to log user in");
+            } else {
+                var options = {
+                    client: self,
+                    data: data.user
+                };
+                user = new Usergrid.Entity(options);
+                self.setToken(data.access_token);
+            }
+            if (typeof callback === "function") {
+                callback(err, data, user);
+            }
+        });
+    };
+    /*
+   *  A public method to get the currently logged in user entity
+   *
+   *  @method getLoggedInUser
+   *  @public
+   *  @param {function} callback
+   *  @return {callback} callback(err, data)
+   */
+    Usergrid.Client.prototype.getLoggedInUser = function(callback) {
+        if (!this.getToken()) {
+            callback(true, null, null);
+        } else {
+            var self = this;
+            var options = {
+                method: "GET",
+                endpoint: "users/me"
+            };
+            this.request(options, function(err, data) {
+                if (err) {
+                    if (self.logging) {
+                        console.log("error trying to log user in");
+                    }
+                    if (typeof callback === "function") {
+                        callback(err, data, null);
+                    }
+                } else {
+                    var options = {
+                        client: self,
+                        data: data.entities[0]
+                    };
+                    var user = new Usergrid.Entity(options);
+                    if (typeof callback === "function") {
+                        callback(err, data, user);
+                    }
+                }
+            });
+        }
+    };
+    /*
+   *  A public method to test if a user is logged in - does not guarantee that the token is still valid,
+   *  but rather that one exists
+   *
+   *  @method isLoggedIn
+   *  @public
+   *  @return {boolean} Returns true the user is logged in (has token and uuid), false if not
+   */
+    Usergrid.Client.prototype.isLoggedIn = function() {
+        return "undefined" !== typeof this.getToken();
+    };
+    /*
+   *  A public method to log out an app user - clears all user fields from client
+   *
+   *  @method logout
+   *  @public
+   *  @return none
+   */
+    Usergrid.Client.prototype.logout = function() {
+        this.setToken(null);
+    };
+    /*
+   *  A private method to build the curl call to display on the command line
+   *
+   *  @method buildCurlCall
+   *  @private
+   *  @param {object} options
+   *  @return {string} curl
+   */
+    Usergrid.Client.prototype.buildCurlCall = function(options) {
+        var curl = [ "curl" ];
+        var method = (options.method || "GET").toUpperCase();
+        var body = options.body;
+        var uri = options.uri;
+        //curl - add the method to the command (no need to add anything for GET)
+        curl.push("-X");
+        curl.push([ "POST", "PUT", "DELETE" ].indexOf(method) >= 0 ? method : "GET");
+        //curl - append the path
+        curl.push(uri);
+        if ("object" === typeof body && Object.keys(body).length > 0 && [ "POST", "PUT" ].indexOf(method) !== -1) {
+            curl.push("-d");
+            curl.push("'" + JSON.stringify(body) + "'");
+        }
+        curl = curl.join(" ");
+        //log the curl command to the console
+        console.log(curl);
+        return curl;
+    };
+    Usergrid.Client.prototype.getDisplayImage = function(email, picture, size) {
+        size = size || 50;
+        var image = "https://apigee.com/usergrid/images/user_profile.png";
+        try {
+            if (picture) {
+                image = picture;
+            } else if (email.length) {
+                image = "https://secure.gravatar.com/avatar/" + MD5(email) + "?s=" + size + encodeURI("&d=https://apigee.com/usergrid/images/user_profile.png");
+            }
+        } catch (e) {} finally {
+            return image;
+        }
+    };
+    global[name] = Usergrid.Client;
     global[name].noConflict = function() {
         if (overwrittenName) {
             global[name] = overwrittenName;
         }
-        return Usergrid;
+        return exports;
     };
     return global[name];
-})(this);
+})();
 
 /*
  *  A class to Model a Usergrid Entity.
@@ -1059,7 +1529,7 @@ Usergrid.Entity.prototype.fetch = function(callback) {
         if (entity) {
             self.set(entity);
         }
-        console.log("AFTER FETCH", self.get(), entity, response);
+        console.log("AFTER FETCH", err, self.get(), entity, response);
         doCallback(callback, [ err, entity, self ]);
     });
 };
@@ -1206,7 +1676,7 @@ Usergrid.Entity.prototype.getConnections = function(connection, callback) {
             console.log("entity could not be connected");
         }
         self[connection] = {};
-        var length = data.entities.length;
+        var length = data && data.entities ? data.entities.length : 0;
         for (var i = 0; i < length; i++) {
             if (data.entities[i].type === "user") {
                 self[connection][data.entities[i].username] = data.entities[i];
@@ -2307,7 +2777,7 @@ Usergrid.Folder = function(options, callback) {
         if (err) {
             doCallback(callback, [ true, new Usergrid.Error(data) ], self);
         } else {
-            if (data.entities.length) {
+            if (data && data.entities && data.entities.length) {
                 self.set(data.entities[0]);
             }
             doCallback(callback, [ false, self ], self);
@@ -2495,7 +2965,7 @@ Usergrid.Asset = function(options, callback) {
         if (err) {
             doCallback(callback, [ true, new Usergrid.Error(data) ], self);
         } else {
-            if (data.entities.length) {
+            if (data && data.entities && data.entities.length) {
                 self.set(data.entities[0]);
             }
             doCallback(callback, [ false, self ], self);


Mime
View raw message