Added UsergridUser class and re-worked entity > user subclassing
diff --git a/.travis.yml b/.travis.yml
index b960342..8b981a0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,7 +5,7 @@
 - 'npm install'
 - 'npm -g install mocha'
 script: 
-- 'mocha tests'
+- 'grunt'
 notifications:
   email:
     on_failure: change
diff --git a/helpers/mutability.js b/helpers/mutability.js
index 4d51dcc..9800e1d 100644
--- a/helpers/mutability.js
+++ b/helpers/mutability.js
@@ -1,15 +1,40 @@
+'use strict'
+
+var ok = require('objectkit')
+
 function setReadOnly(obj, key) {
-    if (typeof obj[key] === 'object') {
+    if (typeof obj[key] === 'array') {
+        return obj[key].forEach(function(k) {
+            setReadOnly(obj, k)
+        })
+    } else if (typeof obj[key] === 'object') {
         return Object.freeze(obj[key])
     } else if (typeof obj === 'object' && key === undefined) {
         return Object.freeze(obj)
+    } else if (ok(obj).has(key)) {
+        return Object.defineProperty(obj, key, {
+            configurable: false,
+            writable: false
+        })
     } else {
-        return Object.defineProperty(obj, key, { configurable: false, writable: false })
+        return obj
     }
 }
 
 function setWritable(obj, key) {
-    return Object.defineProperty(obj, key, { configurable: true, writable: true })
+    // Note that once Object.freeze is called on an object, it cannot be unfrozen
+    if (typeof obj[key] === 'array') {
+        return obj[key].forEach(function(k) {
+            setWritable(obj, k)
+        })
+    } else if (ok(obj).has(key)) {
+        return Object.defineProperty(obj, key, {
+            configurable: true,
+            writable: true
+        })
+    } else {
+        return obj
+    }
 }
 
 module.exports = {
diff --git a/lib/appAuth.js b/lib/appAuth.js
index 875d0ac..02d32fc 100644
--- a/lib/appAuth.js
+++ b/lib/appAuth.js
@@ -3,14 +3,14 @@
 var UsergridAuth = require('./auth'),
     util = require('util')
 
-var UsergridAppAuth = function(options) {
+var UsergridAppAuth = function(opts) {
     var self = this
     if (arguments.length === 3) {
-        options = arguments
+        opts = arguments
     }
-    self.clientId = (options.length === 3) ? options[0] : options.clientId
-    self.clientSecret = (options.length === 3) ? options[1] : options.clientSecret
-    self.tokenTtl = (options.length === 3) ? options[2] : options.tokenTtl
+    self.clientId = (opts.length === 3) ? opts[0] : opts.clientId
+    self.clientSecret = (opts.length === 3) ? opts[1] : opts.clientSecret
+    self.tokenTtl = (opts.length === 3) ? opts[2] : opts.tokenTtl
     UsergridAuth.call(self)
     return self
 }
diff --git a/lib/entity.js b/lib/entity.js
index d7af669..2ba4efb 100644
--- a/lib/entity.js
+++ b/lib/entity.js
@@ -1,10 +1,27 @@
 'use strict'
 
-var _ = require('underscore')
+var _ = require('underscore'),
+    helpers = require('../helpers'),
+    ok = require('objectkit')
 
 var UsergridEntity = function(object) {
     var self = this
     _.extend(self, object)
+
+    Object.defineProperty(self, 'isUser', {
+        get: function() {
+            return (self.type.toLowerCase() === 'user')
+        }
+    })
+
+    Object.defineProperty(self, 'hasAsset', {
+        get: function() {
+            return ok(self).has(['file', 'file-metadata'])
+        }
+    })
+
+    helpers.setReadOnly(self, ['uuid', 'name', 'type', 'created', 'modified', 'file', 'file-metadata'])
+
     return self
 }
 
diff --git a/lib/query.js b/lib/query.js
index 2169803..dcdad93 100644
--- a/lib/query.js
+++ b/lib/query.js
@@ -10,9 +10,8 @@
 
     var query = '',
         queryString,
-        sort
-
-    var __nextIsNot = false
+        sort,
+        __nextIsNot = false
 
     // builder pattern
     var self = {
diff --git a/lib/response.js b/lib/response.js
index 4d8a2d2..ef4a7c1 100644
--- a/lib/response.js
+++ b/lib/response.js
@@ -2,6 +2,7 @@
 
 var ok = require('objectkit'),
     UsergridEntity = require('./entity.js'),
+    UsergridUser = require('./user.js'),
     UsergridResponseError = require('./responseError.js'),
     helpers = require('../helpers'),
     _ = require('underscore')
@@ -10,44 +11,25 @@
 
 function UsergridResponse(response) {
     if (ok(response.body).has('entities')) {
-        var entities = response.body.entities.map(function(entity) {
-            return new UsergridEntity(entity)
+        var entities = response.body.entities.map(function(en) {
+            var entity = new UsergridEntity(en)
+            return (entity.isUser) ? new UsergridUser(entity) : entity
         })
         _.extend(response, {
             metadata: _.map(response.body, _.clone),
             entities: entities
         })
+        delete response.metadata.entities
         response.first = _.first(entities) || undefined
         response.entity = response.first
         response.last = _.last(entities) || undefined
 
-        delete response.metadata.entities
-        helpers.setReadOnly(response.metadata)
-
-        entities.forEach(function(entity) {
-            // set uuid immutable
-            helpers.setReadOnly(entity, 'uuid')
-
-            // set type immutable
-            helpers.setReadOnly(entity, 'type')
-
-            // if not type user, set name immutable
-            if (!(_(entity.type.toLowerCase()).startsWith('user'))) {
-                helpers.setReadOnly(entity, 'name')
-            }
-        })
-
-        // if response contains users, add UsergridUser references
-        if (response.first !== undefined && (_(response.first.type.toLowerCase()).startsWith('user'))) {
-            if (response.entities.length === 1) {
-                response.user = response.first
-            } else {
-                response.users = function() {
-                    return this.entities
-                }
-            }
+        if (ok(response).has('first.isUser') === true) {
+            response.user = response.first
+            response.users = response.entities
         }
-        response.entities = entities
+
+        helpers.setReadOnly(response.metadata)
     } else {
         response.error = new UsergridResponseError(response.body)
     }
diff --git a/lib/user.js b/lib/user.js
index e69de29..36b0253 100644
--- a/lib/user.js
+++ b/lib/user.js
@@ -0,0 +1,25 @@
+'use strict'
+
+var UsergridEntity = require('./entity'),
+    helpers = require('../helpers'),
+    ok = require('objectkit'),
+    _ = require('underscore'),
+    util = require('util')
+
+var UsergridUser = function(object) {
+
+    if (!ok(object).has('email') && !ok(object).has('username')) {
+        // This is not a user entity
+        return object
+    }
+
+    var self = this
+    _.extend(self, object, UsergridEntity)
+    UsergridEntity.call(self)
+    helpers.setWritable(self, 'name')
+    return self
+}
+
+util.inherits(UsergridUser, UsergridEntity)
+
+module.exports = UsergridUser
\ No newline at end of file
diff --git a/tests/lib/client.test.js b/tests/lib/client.test.js
index dde8507..69e0013 100644
--- a/tests/lib/client.test.js
+++ b/tests/lib/client.test.js
@@ -5,7 +5,6 @@
     UsergridClient = require('../../lib/client'),
     UsergridAppAuth = require('../../lib/appAuth')
 
-var _collection = config.tests.collection
 var _uuid = null
 
 describe('initialization', function() {
@@ -45,7 +44,7 @@
     var response, client
     before(function(done) {
         client = new UsergridClient()
-        client.GET(_collection, function(err, usergridResponse) {
+        client.GET(config.tests.collection, function(err, usergridResponse) {
             response = usergridResponse
             done()
         })
@@ -53,7 +52,7 @@
 
     it('should not fail when a callback function is not passed', function() {
         // note: this test will NOT fail gracefully inside the Mocha event chain
-        client.GET(_collection)
+        client.GET(config.tests.collection)
     })
 
     it('should return a 200 ok', function() {
@@ -85,7 +84,7 @@
     var response, client
     before(function(done) {
         client = new UsergridClient()
-        client.POST(_collection, {
+        client.POST(config.tests.collection, {
             author: 'Sir Arthur Conan Doyle'
         }, function(err, usergridResponse) {
             response = usergridResponse
@@ -96,7 +95,7 @@
 
     it('should not fail when a callback function is not passed', function() {
         // note: this test will NOT fail gracefully inside the Mocha event chain
-        client.POST(_collection, {})
+        client.POST(config.tests.collection, {})
     })
 
     it('should return a 200 ok', function() {
@@ -124,7 +123,7 @@
     var response, client
     before(function(done) {
         client = new UsergridClient()
-        client.PUT(_collection, _uuid, {
+        client.PUT(config.tests.collection, _uuid, {
             narrator: 'Peter Doyle'
         }, function(err, usergridResponse) {
             response = usergridResponse
@@ -134,7 +133,7 @@
 
     it('should not fail when a callback function is not passed', function() {
         // note: this test will NOT fail gracefully inside the Mocha event chain
-        client.PUT(_collection, _uuid)
+        client.PUT(config.tests.collection, _uuid)
     })
 
     it('should return a 200 ok', function() {
@@ -162,8 +161,8 @@
     var response, client
     before(function(done) {
         client = new UsergridClient()
-        client.DELETE(_collection, _uuid, function() {
-            client.GET(_collection, _uuid, function(err, usergridResponse) {
+        client.DELETE(config.tests.collection, _uuid, function() {
+            client.GET(config.tests.collection, _uuid, function(err, usergridResponse) {
                 response = usergridResponse
                 done()
             })
@@ -172,7 +171,7 @@
 
     it('should not fail when a callback function is not passed', function() {
         // note: this test will NOT fail gracefully inside the Mocha event chain
-        client.DELETE(_collection, _uuid)
+        client.DELETE(config.tests.collection, _uuid)
     })
 
     it('should return a 200 ok', function() {
@@ -220,7 +219,7 @@
     })
 })
 
-describe('appAuth / setAppAuth()', function() {
+describe('appAuth, setAppAuth()', function() {
     it('should initialize by passing a list of arguments', function() {
         var client = new UsergridClient()
         client.setAppAuth(config.usergrid.clientId, config.usergrid.clientSecret, config.usergrid.tokenTtl)
diff --git a/tests/lib/response.test.js b/tests/lib/response.test.js
index 26c062e..381a743 100644
--- a/tests/lib/response.test.js
+++ b/tests/lib/response.test.js
@@ -4,10 +4,10 @@
     config = require('../../config.json'),
     UsergridClient = require('../../lib/client'),
     UsergridEntity = require('../../lib/entity'),
+    UsergridUser = require('../../lib/user'),
     UsergridResponseError = require('../../lib/responseError'),
     _ = require('underscore')
 
-var _collection = config.tests.collection
 var client = new UsergridClient()
 
 var _response
@@ -17,7 +17,7 @@
     this.slow(1000)
     this.timeout(6000)
 
-    client.GET(_collection, function(err, usergridResponse) {
+    client.GET(config.tests.collection, function(err, usergridResponse) {
         _response = usergridResponse
         done()
     })
@@ -51,9 +51,37 @@
         this.slow(1000)
         this.timeout(6000)
 
-        client.GET(_collection, 'BADNAMEORUUID', function(err, usergridResponse) {
-            usergridResponse.statusCode.should.not.equal(200)
-            usergridResponse.error.should.be.an.instanceof(UsergridResponseError).with.keys(['name', 'description', 'exception'])
+        client.GET(config.tests.collection, 'BADNAMEORUUID', function(err, usergridResponse) {
+            usergridResponse.error.should.be.an.instanceof(UsergridResponseError)
+            done()
+        })
+    })
+})
+
+describe('users', function() {
+
+    this.slow(1000)
+    this.timeout(6000)
+
+    it('response.users should be an array of UsergridUser objects', function(done) {
+        client.GET('users', function(err, usergridResponse) {
+            usergridResponse.users.should.be.an.Array()
+            usergridResponse.users.forEach(function(user) {
+                user.should.be.an.instanceof(UsergridUser)
+            })
+            done()
+        })
+    })
+})
+
+describe('user', function() {
+
+    this.slow(1000)
+    this.timeout(6000)
+
+    it('response.user should be a UsergridUser object and have a valid uuid matching the first object in response.users', function(done) {
+        client.GET('users', function(err, usergridResponse) {
+            usergridResponse.user.should.be.an.instanceof(UsergridUser).with.property('uuid').equal(_.first(usergridResponse.users).uuid)
             done()
         })
     })
@@ -68,7 +96,7 @@
     })
 })
 
-describe('first / entity', function() {
+describe('first, entity', function() {
     it('response.first should be a UsergridEntity object and have a valid uuid matching the first object in response.entities', function() {
         _response.first.should.be.an.instanceof(UsergridEntity).with.property('uuid').equal(_.first(_response.entities).uuid)
     })
diff --git a/tests/lib/responseError.test.js b/tests/lib/responseError.test.js
new file mode 100644
index 0000000..d44071e
--- /dev/null
+++ b/tests/lib/responseError.test.js
@@ -0,0 +1,33 @@
+'use strict'
+
+var should = require('should'),
+    config = require('../../config.json'),
+    UsergridClient = require('../../lib/client'),
+    UsergridResponseError = require('../../lib/responseError')
+
+var client = new UsergridClient()
+
+var _response
+
+describe('name, description, exception', function() {
+
+    before(function(done) {
+
+        this.slow(1000)
+        this.timeout(6000)
+
+        client.GET(config.tests.collection, 'BADNAMEORUUID', function(err, usergridResponse) {
+            _response = usergridResponse
+            done()
+        })
+    })
+
+    it('response should have a status code greater than or equal to 400', function() {
+        _response.statusCode.should.be.greaterThanOrEqual(400)
+    })
+
+    it('response.error should be a UsergridResponseError object with name, description, and exception keys', function() {
+        _response.statusCode.should.not.equal(200)
+        _response.error.should.be.an.instanceof(UsergridResponseError).with.keys(['name', 'description', 'exception'])
+    })
+})
\ No newline at end of file
diff --git a/tests/main.test.js b/tests/main.test.js
index 324d305..32f2890 100644
--- a/tests/main.test.js
+++ b/tests/main.test.js
@@ -1,17 +1,21 @@
 'use strict'
 
-describe.skip('Usergrid', function() {
+describe('Usergrid', function() {
     return require('./lib/usergrid.test')
 })
 
-describe.skip('UsergridClient', function() {
+describe('UsergridClient', function() {
     return require('./lib/client.test')
 })
 
-describe.skip('UsergridQuery', function() {
+describe('UsergridQuery', function() {
     return require('./lib/query.test')
 })
 
 describe('UsergridResponse', function() {
     return require('./lib/response.test')
+})
+
+describe('UsergridResponseError', function() {
+    return require('./lib/responseError.test')
 })
\ No newline at end of file