You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by mr...@apache.org on 2016/09/01 23:52:06 UTC

[45/51] [partial] usergrid-swift git commit: Initial commit of Usergrid Swift SDK.

http://git-wip-us.apache.org/repos/asf/usergrid-swift/blob/8283a6dd/Source/UsergridUser.swift
----------------------------------------------------------------------
diff --git a/Source/UsergridUser.swift b/Source/UsergridUser.swift
new file mode 100644
index 0000000..17415ba
--- /dev/null
+++ b/Source/UsergridUser.swift
@@ -0,0 +1,523 @@
+//
+//  User.swift
+//  UsergridSDK
+//
+//  Created by Robert Walsh on 7/21/15.
+//
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ *
+ */
+
+import Foundation
+
+/// The completion block used for checking email and/or username availablity for new `UsergridUser` objects.
+public typealias UsergridUserAvailabilityCompletion = (error: UsergridResponseError?, available:Bool) -> Void
+
+/// The completion block used for changing the password of `UsergridUser` objects.
+public typealias UsergridUserResetPasswordCompletion = (error: UsergridResponseError?, didSucceed:Bool) -> Void
+
+/**
+`UsergridUser` is a special subclass of `UsergridEntity` that supports functions and properties unique to users.
+*/
+public class UsergridUser : UsergridEntity {
+
+    static let USER_ENTITY_TYPE = "user"
+
+    // MARK: - Instance Properties -
+
+    /// The `UsergridUserAuth` object if this user was authenticated.
+    public var auth: UsergridUserAuth?
+
+    /** 
+    Property helper method for the `UsergridUser` objects `UsergridUserProperties.Name`.
+    
+    Unlike `UsergridEntity` objects, `UsergridUser`'s can change their name property which is why we provide a getter here.
+    */
+    override public var name: String? {
+        set(name) { self[UsergridUserProperties.Name.stringValue] = name }
+        get{ return super.name }
+    }
+
+    /// Property getter and setter helpers for the `UsergridUser` objects `UsergridUserProperties.Username`.
+    public var username: String? {
+        set(username) { self[UsergridUserProperties.Username.stringValue] = username }
+        get { return self.getUserSpecificProperty(.Username) as? String }
+    }
+
+    /// Property getter and setter helpers for the `UsergridUser` objects `UsergridUserProperties.Password`.
+    public var password: String? {
+        set(password) { self[UsergridUserProperties.Password.stringValue] = password }
+        get { return self.getUserSpecificProperty(.Password) as? String }
+    }
+
+    /// Property getter and setter helpers for the `UsergridUser` objects `UsergridUserProperties.Email`.
+    public var email: String? {
+        set(email) { self[UsergridUserProperties.Email.stringValue] = email }
+        get { return self.getUserSpecificProperty(.Email) as? String }
+    }
+
+    /// Property getter and setter helpers for the `UsergridUser` objects `UsergridUserProperties.Age`.
+    public var age: NSNumber? {
+        set(age) { self[UsergridUserProperties.Age.stringValue] = age }
+        get { return self.getUserSpecificProperty(.Age) as? NSNumber }
+    }
+
+    /// Property helper method to get the username or email of the `UsergridUser`.
+    public var usernameOrEmail: String? { return self.username ?? self.email }
+
+    /** 
+    Property getter and setter helpers for the `UsergridUser` objects `UsergridUserProperties.Activated`.
+    
+    Indicates whether the user account has been activated or not.
+    */
+    public var activated: Bool {
+        set(activated) { self[UsergridUserProperties.Activated.stringValue] = activated }
+        get { return self.getUserSpecificProperty(.Activated) as? Bool ?? false }
+    }
+
+    /// Property getter and setter helpers for the `UsergridUser` objects `UsergridUserProperties.Disabled`.
+    public var disabled: Bool {
+        set(disabled) { self[UsergridUserProperties.Disabled.stringValue] = disabled }
+        get { return self.getUserSpecificProperty(.Disabled) as? Bool ?? false }
+    }
+
+    /**
+    Property getter and setter helpers for the `UsergridUser` objects `UsergridUserProperties.Picture`.
+    
+    URL path to user\u2019s profile picture. Defaults to Gravatar for email address.
+    */
+    public var picture: String? {
+        set(picture) { self[UsergridUserProperties.Picture.stringValue] = picture }
+        get { return self.getUserSpecificProperty(.Picture) as? String }
+    }
+
+    /// The UUID or username property value if found.
+    public var uuidOrUsername: String? { return self.uuid ?? self.username }
+
+    // MARK: - Initialization -
+
+    /**
+    Designated initializer for `UsergridUser` objects.
+
+    - parameter name: The name of the user.  Note this is different from the `username` property.
+
+    - returns: A new instance of `UsergridUser`.
+    */
+    public init(name:String? = nil) {
+        super.init(type: UsergridUser.USER_ENTITY_TYPE, name:name, propertyDict:nil)
+    }
+
+    /**
+     The required public initializer for `UsergridEntity` subclasses.
+
+     - parameter type:         The type associated with the `UsergridEntity` object.
+     - parameter name:         The optional name associated with the `UsergridEntity` object.
+     - parameter propertyDict: The optional property dictionary that the `UsergridEntity` object will start out with.
+
+     - returns: A new `UsergridUser` object.
+     */
+    required public init(type: String, name: String?, propertyDict: [String : AnyObject]?) {
+        super.init(type: type, name: name, propertyDict: propertyDict)
+    }
+
+    /**
+    Designated initializer for `UsergridUser` objects.
+
+    - parameter name:         The name of the user.  Note this is different from the `username` property.
+    - parameter propertyDict: The optional property dictionary that the `UsergridEntity` object will start out with.
+
+    - returns: A new instance of `UsergridUser`.
+    */
+    public init(name:String,propertyDict:[String:AnyObject]? = nil) {
+        super.init(type: UsergridUser.USER_ENTITY_TYPE, name:name, propertyDict:propertyDict)
+    }
+
+    /**
+     Convenience initializer for `UsergridUser` objects.
+
+     - parameter name:     The name of the user.  Note this is different from the `username` property.
+     - parameter email:    The user's email.
+     - parameter password: The optional user's password.
+
+     - returns: A new instance of `UsergridUser`.
+     */
+    public convenience init(name:String, email:String, password:String? = nil) {
+        self.init(name:name,email:email,username:nil,password:password)
+    }
+
+    /**
+     Convenience initializer for `UsergridUser` objects.
+
+     - parameter email:    The user's email.
+     - parameter password: The optional user's password.
+
+     - returns: A new instance of `UsergridUser`.
+     */
+    public convenience init(email:String, password:String? = nil) {
+        self.init(name:nil,email:email,username:nil,password:password)
+    }
+
+    /**
+     Convenience initializer for `UsergridUser` objects.
+
+     - parameter name:     The name of the user.  Note this is different from the `username` property.
+     - parameter username: The username of the user.
+     - parameter password: The optional user's password.
+
+     - returns: A new instance of `UsergridUser`.
+     */
+    public convenience init(name:String, username:String, password:String? = nil) {
+        self.init(name:name,email:nil,username:username,password:password)
+    }
+
+    /**
+     Convenience initializer for `UsergridUser` objects.
+
+     - parameter username: The username of the user.
+     - parameter password: The optional user's password.
+
+     - returns: A new instance of `UsergridUser`.
+     */
+    public convenience init(username:String, password:String? = nil) {
+        self.init(name:nil,email:nil,username:username,password:password)
+    }
+
+    /**
+     Convenience initializer for `UsergridUser` objects.
+
+     - parameter name:     The optional name of the user.  Note this is different from the `username` property.
+     - parameter email:    The optional user's email.
+     - parameter username: The optional username of the user.
+     - parameter password: The optional user's password.
+
+     - returns: A new instance of `UsergridUser`.
+     */
+    public convenience init(name:String?, email:String?, username:String?, password:String? = nil) {
+        self.init(name:name)
+        self.email = email
+        self.username = username
+        self.password = password
+    }
+
+    // MARK: - NSCoding -
+
+    /**
+    NSCoding protocol initializer.
+
+    - parameter aDecoder: The decoder.
+
+    - returns: A decoded `UsergridUser` object.
+    */
+    required public init?(coder aDecoder: NSCoder) {
+        self.auth = aDecoder.decodeObjectForKey("auth") as? UsergridUserAuth
+        super.init(coder: aDecoder)
+    }
+
+    /**
+     NSCoding protocol encoder.
+
+     - parameter aCoder: The encoder.
+     */
+    public override func encodeWithCoder(aCoder: NSCoder) {
+        aCoder.encodeObject(self.auth, forKey: "auth")
+        super.encodeWithCoder(aCoder)
+    }
+
+    // MARK: - Class Methods -
+
+    /**
+    Checks the given email and/or username availablity for new `UsergridUser` objects using the shared instance of `UsergridClient`.
+
+    - parameter email:      The optional email address.
+    - parameter username:   The optional username.
+    - parameter completion: The completion block.
+    */
+    public static func checkAvailable(email:String?, username:String?, completion:UsergridUserAvailabilityCompletion) {
+        self.checkAvailable(Usergrid.sharedInstance, email: email, username: username, completion: completion)
+    }
+
+    /**
+     Checks the given email and/or username availablity for new `UsergridUser` objects using with the given `UsergridClient`.
+
+     - parameter client:     The client to use for checking availability.
+     - parameter email:      The optional email address.
+     - parameter username:   The optional username.
+     - parameter completion: The completion block.
+     */
+    public static func checkAvailable(client: UsergridClient, email:String?, username:String?, completion:UsergridUserAvailabilityCompletion) {
+        let query = UsergridQuery(USER_ENTITY_TYPE)
+        if let emailValue = email {
+            query.eq(UsergridUserProperties.Email.stringValue, value: emailValue)
+        }
+        if let usernameValue = username {
+            query.or().eq(UsergridUserProperties.Username.stringValue, value: usernameValue)
+        }
+        client.GET(query) { (response) -> Void in
+            completion(error: response.error, available: response.entity == nil)
+        }
+    }
+
+    // MARK: - Instance Methods -
+
+    /**
+    Creates the user object in Usergrid if the user does not already exist with the shared instance of `UsergridClient`.
+
+    - parameter completion: The optional completion block.
+    */
+    public func create(completion: UsergridResponseCompletion? = nil) {
+        self.create(Usergrid.sharedInstance, completion: completion)
+    }
+
+    /**
+    Creates the user object in Usergrid if the user does not already exist with the given `UsergridClient`.
+
+    - parameter client:     The client to use for creation.
+    - parameter completion: The optional completion block.
+    */
+    public func create(client: UsergridClient, completion: UsergridResponseCompletion? = nil) {
+        client.POST(self) { (response) -> Void in
+            if response.ok, let createdUser = response.user {
+                self.copyInternalsFromEntity(createdUser)
+            }
+            completion?(response: response)
+        }
+    }
+
+    /**
+    Authenticates the specified user using the provided username and password with the shared instance of `UsergridClient`.
+
+    While functionally similar to `UsergridClient.authenticateUser(auth)`, this method does not automatically assign this user to `UsergridClient.currentUser`:
+
+    - parameter username:   The username.
+    - parameter password:   The password.
+    - parameter completion: The optional completion block.
+    */
+    public func login(username:String, password:String, completion: UsergridUserAuthCompletionBlock? = nil) {
+        self.login(Usergrid.sharedInstance, username: username, password: password, completion: completion)
+    }
+
+    /**
+    Authenticates the specified user using the provided username and password.
+
+    While functionally similar to `UsergridClient.authenticateUser(auth)`, this method does not automatically assign this user to `UsergridClient.currentUser`:
+
+    - parameter client:     The client to use for login.
+    - parameter username:   The username.
+    - parameter password:   The password.
+    - parameter completion: The optional completion block.
+    */
+    public func login(client: UsergridClient, username:String, password:String, completion: UsergridUserAuthCompletionBlock? = nil) {
+        let userAuth = UsergridUserAuth(username: username, password: password)
+        client.authenticateUser(userAuth,setAsCurrentUser:false) { (auth, user, error) -> Void in
+            self.auth = userAuth
+            completion?(auth: userAuth, user: user, error: error)
+        }
+    }
+
+     /**
+     Changes the User's current password with the shared instance of `UsergridClient`.
+
+     - parameter old:        The old password.
+     - parameter new:        The new password.
+     - parameter completion: The optional completion block.
+     */
+    public func resetPassword(old:String, new:String, completion:UsergridUserResetPasswordCompletion? = nil) {
+        self.resetPassword(Usergrid.sharedInstance, old: old, new: new, completion: completion)
+    }
+
+    /**
+     Changes the User's current password with the shared instance of `UsergridClient`.
+
+     - parameter client:     The client to use for resetting the password.
+     - parameter old:        The old password.
+     - parameter new:        The new password.
+     - parameter completion: The optional completion block
+     */
+    public func resetPassword(client: UsergridClient, old:String, new:String, completion:UsergridUserResetPasswordCompletion? = nil) {
+        client.resetPassword(self, old: old, new: new, completion: completion)
+    }
+
+    /**
+     Attmepts to reauthenticate using the user's `UsergridUserAuth` instance property with the shared instance of `UsergridClient`.
+
+     - parameter completion: The optional completion block.
+     */
+    public func reauthenticate(completion: UsergridUserAuthCompletionBlock? = nil) {
+        self.reauthenticate(Usergrid.sharedInstance, completion: completion)
+    }
+
+    /**
+     Attmepts to reauthenticate using the user's `UsergridUserAuth` instance property.
+
+     - parameter client:     The client to use for reauthentication.
+     - parameter completion: The optional completion block.
+     */
+    public func reauthenticate(client: UsergridClient, completion: UsergridUserAuthCompletionBlock? = nil) {
+        guard let userAuth = self.auth
+            else {
+                completion?(auth: nil, user: self, error: UsergridResponseError(errorName: "Invalid UsergridUserAuth.", errorDescription: "No UsergridUserAuth found on the UsergridUser."))
+                return
+        }
+
+        client.authenticateUser(userAuth, setAsCurrentUser:self.isEqualToEntity(client.currentUser), completion: completion)
+    }
+
+    /**
+    Invalidates the user token locally and remotely.
+
+    - parameter completion: The optional completion block.
+    */
+    public func logout(completion:UsergridResponseCompletion? = nil) {
+        self.logout(Usergrid.sharedInstance,completion:completion)
+    }
+
+    /**
+    Invalidates the user token locally and remotely.
+
+    - parameter client:     The client to use for logout.
+    - parameter completion: The optional completion block.
+    */
+    public func logout(client: UsergridClient, completion:UsergridResponseCompletion? = nil) {
+        guard let uuidOrUsername = self.uuidOrUsername,
+              let accessToken = self.auth?.accessToken
+            else {
+                completion?(response: UsergridResponse(client:client, errorName:"Logout Failed.", errorDescription:"UUID or Access Token not found on UsergridUser object."))
+                return
+        }
+        
+        client.logoutUser(uuidOrUsername, token: accessToken) { (response) in
+            self.auth = nil
+            completion?(response: response)
+        }
+    }
+
+    /**
+     A special convenience function that connects a `UsergridDevice` to this `UsergridUser` using the shared instance of `UsergridClient`.
+
+     - parameter device:     The device to connect to.  If nil it will use the `UsergridDevice.sharedDevice` instance.
+     - parameter completion: The optional completion block.
+     */
+    public func connectToDevice(device:UsergridDevice? = nil, completion:UsergridResponseCompletion? = nil) {
+        self.connectToDevice(Usergrid.sharedInstance, device: device, completion: completion)
+    }
+
+    /**
+     A special convenience function that connects a `UsergridDevice` to this `UsergridUser`.
+
+     - parameter client:     The `UsergridClient` object to use for connecting.
+     - parameter device:     The device to connect to.  If nil it will use the `UsergridDevice.sharedDevice` instance.
+     - parameter completion: The optional completion block.
+     */
+    public func connectToDevice(client:UsergridClient, device:UsergridDevice? = nil, completion:UsergridResponseCompletion? = nil) {
+        let deviceToConnect = device ?? UsergridDevice.sharedDevice
+        guard let _ = deviceToConnect.uuidOrName
+            else {
+            completion?(response: UsergridResponse(client: client, errorName: "Device cannot be connected to User.", errorDescription: "Device has neither an UUID or name specified."))
+            return
+        }
+
+        self.connect(client, relationship: "", toEntity: deviceToConnect, completion: completion)
+    }
+
+    /**
+     Gets the connected device using the shared instance of `UsergridClient`.
+
+     - parameter completion: The optional completion block.
+     */
+    public func getConnectedDevice(completion:UsergridResponseCompletion? = nil) {
+        self.getConnectedDevice(Usergrid.sharedInstance, completion: completion)
+    }
+
+    /**
+     Gets the connected device.
+
+     - parameter client:     The `UsergridClient` object to use for connecting.
+     - parameter completion: The optional completion block.
+     */
+    public func getConnectedDevice(client:UsergridClient, completion:UsergridResponseCompletion? = nil) {
+        client.getConnections(.Out, entity: self, relationship: "device", completion: completion)
+    }
+
+    /**
+     A special convenience function that disconnects a `UsergridDevice` from this `UsergridUser` using the shared instance of `UsergridClient`.
+
+     - parameter device:     The device to connect to.  If nil it will use the `UsergridDevice.sharedDevice` instance.
+     - parameter completion: The optional completion block.
+     */
+    public func disconnectFromDevice(device:UsergridDevice? = nil, completion:UsergridResponseCompletion? = nil) {
+        self.disconnectFromDevice(Usergrid.sharedInstance, device: device, completion: completion)
+    }
+
+    /**
+     A special convenience function that disconnects a `UsergridDevice` from this `UsergridUser`.
+
+     - parameter client:     The `UsergridClient` object to use for connecting.
+     - parameter device:     The device to connect to.
+     - parameter completion: The optional completion block.
+     */
+    public func disconnectFromDevice(client:UsergridClient, device:UsergridDevice? = nil, completion:UsergridResponseCompletion? = nil) {
+        let deviceToDisconnectFrom = device ?? UsergridDevice.sharedDevice
+        guard let _ = deviceToDisconnectFrom.uuidOrName
+            else {
+                completion?(response: UsergridResponse(client: client, errorName: "Device cannot be disconnected from User.", errorDescription: "Device has neither an UUID or name specified."))
+                return
+        }
+
+        self.disconnect(client, relationship: "", fromEntity: deviceToDisconnectFrom, completion: completion)
+    }
+
+    private func getUserSpecificProperty(userProperty: UsergridUserProperties) -> AnyObject? {
+        var propertyValue: AnyObject? = super[userProperty.stringValue]
+        NSJSONReadingOptions.AllowFragments
+        switch userProperty {
+            case .Activated,.Disabled :
+                propertyValue = propertyValue?.boolValue
+            case .Age :
+                propertyValue = propertyValue?.integerValue
+            case .Name,.Username,.Password,.Email,.Picture :
+                break
+        }
+        return propertyValue
+    }
+
+    /**
+    Subscript for the `UsergridUser` class.
+
+    - Warning: When setting a properties value must be a valid JSON object.
+
+    - Example usage:
+    ```
+    let someName = usergridUser["name"]
+    
+    usergridUser["name"] = someName
+    ```
+    */
+    override public subscript(propertyName: String) -> AnyObject? {
+        get {
+            if let userProperty = UsergridUserProperties.fromString(propertyName) {
+                return self.getUserSpecificProperty(userProperty)
+            } else {
+                return super[propertyName]
+            }
+        }
+        set(propertyValue) {
+            super[propertyName] = propertyValue
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/usergrid-swift/blob/8283a6dd/Tests/ASSET_Tests.swift
----------------------------------------------------------------------
diff --git a/Tests/ASSET_Tests.swift b/Tests/ASSET_Tests.swift
new file mode 100644
index 0000000..c6f860f
--- /dev/null
+++ b/Tests/ASSET_Tests.swift
@@ -0,0 +1,280 @@
+//
+//  ASSET_Tests.swift
+//  UsergridSDK
+//
+//  Created by Robert Walsh on 9/24/15.
+//
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ *
+ */
+
+import XCTest
+@testable import UsergridSDK
+
+class ASSET_Tests: XCTestCase {
+
+    static let collectionName = "books"
+    static let entityUUID = "f4078aca-2fb1-11e5-8eb2-e13f8369aad1"
+    static let pngLocation = "TestAssets/test.png"
+    static let jpgLocation = "TestAssets/UsergridGuy.jpg"
+    static let imageName = "test"
+
+    override func setUp() {
+        super.setUp()
+        Usergrid.initSharedInstance(orgId:ClientCreationTests.orgId, appId: ClientCreationTests.appId)
+        Usergrid.persistCurrentUserInKeychain = false
+    }
+
+    override func tearDown() {
+        Usergrid._sharedClient = nil
+        super.tearDown()
+    }
+
+    func getFullPathOfFile(fileLocation:String) -> String {
+        return (NSBundle(forClass: object_getClass(self)).resourcePath! as NSString).stringByAppendingPathComponent(fileLocation)
+    }
+
+    func test_ASSET_INIT() {
+        var filePath = self.getFullPathOfFile(ASSET_Tests.pngLocation)
+        var image = UIImage(contentsOfFile: filePath)
+        var asset = UsergridAsset(filename:ASSET_Tests.imageName,image: image!)
+        XCTAssertNotNil(asset)
+        XCTAssertNotNil(asset!.data)
+        XCTAssertNotNil(asset!.filename)
+        XCTAssertEqual(asset!.contentType, UsergridImageContentType.Png.stringValue)
+        XCTAssertTrue(asset!.contentLength > 0)
+
+        asset = UsergridAsset(filename:ASSET_Tests.imageName, fileURL: NSURL(fileURLWithPath: filePath))
+        XCTAssertNotNil(asset)
+        XCTAssertNotNil(asset!.data)
+        XCTAssertNotNil(asset!.filename)
+        XCTAssertEqual(asset!.contentType, UsergridImageContentType.Png.stringValue)
+        XCTAssertTrue(asset!.contentLength > 0)
+
+        filePath = self.getFullPathOfFile(ASSET_Tests.jpgLocation)
+        image = UIImage(contentsOfFile: filePath)
+        asset = UsergridAsset(filename:nil,image: image!, imageContentType:.Jpeg)
+        XCTAssertNotNil(asset)
+        XCTAssertNotNil(asset!.data)
+        XCTAssertEqual(asset!.filename,UsergridAsset.DEFAULT_FILE_NAME)
+        XCTAssertEqual(asset!.contentType, UsergridImageContentType.Jpeg.stringValue)
+        XCTAssertTrue(asset!.contentLength > 0)
+    }
+
+    func test_IMAGE_UPLOAD() {
+        let getExpect = self.expectationWithDescription("\(#function)")
+        let uploadProgress : UsergridAssetRequestProgress = { (bytes,expected) in
+            print("UPLOAD PROGRESS BLOCK: BYTES:\(bytes) --- EXPECTED:\(expected)")
+        }
+        let downloadProgress : UsergridAssetRequestProgress = { (bytes,expected) in
+            print("DOWNLOAD PROGRESS BLOCK: BYTES:\(bytes) --- EXPECTED:\(expected)")
+        }
+
+        Usergrid.GET(ASSET_Tests.collectionName, uuidOrName:ASSET_Tests.entityUUID) { (response) in
+            XCTAssertTrue(NSThread.isMainThread())
+
+            let entity = response.first!
+            XCTAssertNotNil(entity)
+            XCTAssertFalse(entity.isUser)
+
+            let imagePath = self.getFullPathOfFile(ASSET_Tests.pngLocation)
+            XCTAssertNotNil(imagePath)
+
+            let localImage = UIImage(contentsOfFile: imagePath)
+            XCTAssertNotNil(localImage)
+
+            let asset = UsergridAsset(filename:ASSET_Tests.imageName,image: localImage!)
+            XCTAssertNotNil(asset)
+
+            entity.uploadAsset(asset!, progress:uploadProgress) { uploadedAsset,response in
+                XCTAssertTrue(NSThread.isMainThread())
+                XCTAssertTrue(response.ok)
+                XCTAssertNil(response.error)
+
+                XCTAssertNotNil(asset)
+                XCTAssertNotNil(uploadedAsset)
+                XCTAssertEqual(uploadedAsset!, asset!)
+
+                XCTAssertTrue(entity.hasAsset)
+                XCTAssertNotNil(entity.fileMetaData)
+                XCTAssertNotNil(entity.fileMetaData!.eTag)
+                XCTAssertNotNil(entity.fileMetaData!.checkSum)
+                XCTAssertNotNil(entity.fileMetaData!.contentType)
+                XCTAssertNotNil(entity.fileMetaData!.lastModifiedDate)
+                XCTAssertEqual(entity.asset!.contentLength, entity.fileMetaData!.contentLength)
+                XCTAssertEqual(entity.asset!.contentType, entity.fileMetaData!.contentType)
+
+                entity.downloadAsset(UsergridImageContentType.Png.stringValue, progress:downloadProgress)
+                { (downloadedAsset, error) -> Void in
+                    XCTAssertTrue(NSThread.isMainThread())
+                    XCTAssertNotNil(downloadedAsset)
+                    XCTAssertNil(error)
+                    let downloadedImage = UIImage(data: downloadedAsset!.data)
+                    XCTAssertEqual(UIImagePNGRepresentation(localImage!), UIImagePNGRepresentation(downloadedImage!))
+                    XCTAssertNotNil(downloadedImage)
+                    getExpect.fulfill()
+                }
+            }
+        }
+        self.waitForExpectationsWithTimeout(100, handler: nil)
+    }
+
+    func deleteUser(user:UsergridUser,expectation:XCTestExpectation) {
+        user.remove() { removeResponse in
+            XCTAssertTrue(NSThread.isMainThread())
+            XCTAssertNotNil(removeResponse)
+            XCTAssertTrue(removeResponse.ok)
+            XCTAssertNotNil(removeResponse.user)
+            XCTAssertNotNil(removeResponse.users)
+            print(removeResponse.error)
+            expectation.fulfill()
+        }
+    }
+
+    func test_ATTACH_ASSET_TO_CURRENT_USER() {
+        let userAssetExpect = self.expectationWithDescription("\(#function)")
+
+        let user = UsergridUser(name:User_Tests.name, email:User_Tests.email, username:User_Tests.username, password:User_Tests.password)
+        let uploadProgress : UsergridAssetRequestProgress = { (bytes,expected) in
+            print("UPLOAD PROGRESS BLOCK: BYTES:\(bytes) --- EXPECTED:\(expected)")
+        }
+        let downloadProgress : UsergridAssetRequestProgress = { (bytes,expected) in
+            print("DOWNLOAD PROGRESS BLOCK: BYTES:\(bytes) --- EXPECTED:\(expected)")
+        }
+
+        UsergridUser.checkAvailable(user.email, username: user.username) { error,available in
+
+            XCTAssertTrue(NSThread.isMainThread())
+            XCTAssertNil(error)
+            XCTAssertTrue(available)
+
+            user.create() { (createResponse) in
+                XCTAssertTrue(NSThread.isMainThread())
+                XCTAssertNotNil(createResponse)
+                XCTAssertTrue(createResponse.ok)
+                XCTAssertNotNil(createResponse.user)
+                XCTAssertNotNil(createResponse.users)
+                XCTAssertNotNil(user.uuid)
+
+                user.login(user.username!, password:User_Tests.password) { (auth, loggedInUser, error) -> Void in
+                    XCTAssertTrue(NSThread.isMainThread())
+                    XCTAssertNil(error)
+                    XCTAssertNotNil(auth)
+                    XCTAssertNotNil(loggedInUser)
+                    XCTAssertEqual(auth, user.auth!)
+
+                    Usergrid.authenticateUser(user.auth!) { auth,currentUser,error in
+                        XCTAssertTrue(NSThread.isMainThread())
+                        XCTAssertNil(error)
+                        XCTAssertNotNil(auth)
+                        XCTAssertEqual(auth, user.auth!)
+
+                        XCTAssertNotNil(currentUser)
+                        XCTAssertNotNil(Usergrid.currentUser)
+                        XCTAssertEqual(currentUser, Usergrid.currentUser!)
+
+                        let imagePath = self.getFullPathOfFile(ASSET_Tests.pngLocation)
+                        XCTAssertNotNil(imagePath)
+
+                        let localImage = UIImage(contentsOfFile: imagePath)
+                        XCTAssertNotNil(localImage)
+
+                        let asset = UsergridAsset(filename:ASSET_Tests.imageName,image: localImage!)
+                        XCTAssertNotNil(asset)
+
+                        Usergrid.currentUser!.uploadAsset(asset!, progress:uploadProgress) { uploadedAsset,response in
+                            XCTAssertTrue(NSThread.isMainThread())
+                            XCTAssertTrue(response.ok)
+                            XCTAssertNil(response.error)
+
+                            XCTAssertNotNil(asset)
+                            XCTAssertNotNil(uploadedAsset)
+                            XCTAssertEqual(uploadedAsset!, asset!)
+
+                            XCTAssertTrue(Usergrid.currentUser!.hasAsset)
+                            XCTAssertNotNil(Usergrid.currentUser!.fileMetaData)
+                            XCTAssertNotNil(Usergrid.currentUser!.fileMetaData!.eTag)
+                            XCTAssertNotNil(Usergrid.currentUser!.fileMetaData!.checkSum)
+                            XCTAssertNotNil(Usergrid.currentUser!.fileMetaData!.contentType)
+                            XCTAssertNotNil(Usergrid.currentUser!.fileMetaData!.lastModifiedDate)
+                            XCTAssertEqual(Usergrid.currentUser!.asset!.contentLength, Usergrid.currentUser!.fileMetaData!.contentLength)
+                            XCTAssertEqual(Usergrid.currentUser!.asset!.contentType, Usergrid.currentUser!.fileMetaData!.contentType)
+
+                            Usergrid.currentUser!.downloadAsset(UsergridImageContentType.Png.stringValue, progress:downloadProgress)
+                                { (downloadedAsset, error) -> Void in
+                                    XCTAssertTrue(NSThread.isMainThread())
+                                    XCTAssertNotNil(downloadedAsset)
+                                    XCTAssertNil(error)
+                                    let downloadedImage = UIImage(data: downloadedAsset!.data)
+                                    XCTAssertEqual(UIImagePNGRepresentation(localImage!), UIImagePNGRepresentation(downloadedImage!))
+                                    XCTAssertNotNil(downloadedImage)
+                                    self.deleteUser(Usergrid.currentUser!,expectation:userAssetExpect)
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        self.waitForExpectationsWithTimeout(100, handler: nil)
+    }
+
+
+    func test_FILE_META_DATA_NSCODING() {
+        let fileMetaDataDict = ["content-type":"image/png",
+                                "etag":"dfa7421ea4f35d33e12ba93979a46b7e",
+                                "checkSum":"dfa7421ea4f35d33e12ba93979a46b7e",
+                                "content-length":1417896,
+                                "last-modified":1455728898545]
+        
+        let fileMetaData = UsergridFileMetaData(fileMetaDataJSON:fileMetaDataDict)
+
+        let fileMetaDataCodingData = NSKeyedArchiver.archivedDataWithRootObject(fileMetaData)
+        let newInstanceFromData = NSKeyedUnarchiver.unarchiveObjectWithData(fileMetaDataCodingData) as? UsergridFileMetaData
+        XCTAssertNotNil(newInstanceFromData)
+
+        if let newInstance = newInstanceFromData {
+            XCTAssertEqual(fileMetaData.eTag,newInstance.eTag)
+            XCTAssertEqual(fileMetaData.checkSum,newInstance.checkSum)
+            XCTAssertEqual(fileMetaData.contentType,newInstance.contentType)
+            XCTAssertEqual(fileMetaData.contentLength,newInstance.contentLength)
+            XCTAssertEqual(fileMetaData.lastModifiedDate,newInstance.lastModifiedDate)
+        }
+    }
+
+    func test_ASSET_NSCODING() {
+        let imagePath = self.getFullPathOfFile(ASSET_Tests.pngLocation)
+        let asset = UsergridAsset(filename:ASSET_Tests.imageName,fileURL: NSURL(fileURLWithPath: imagePath))
+        XCTAssertNotNil(asset)
+
+        if let originalAsset = asset {
+            let assetCodingData = NSKeyedArchiver.archivedDataWithRootObject(originalAsset)
+            let newInstanceFromData = NSKeyedUnarchiver.unarchiveObjectWithData(assetCodingData) as? UsergridAsset
+
+            XCTAssertNotNil(newInstanceFromData)
+
+            if let newInstance = newInstanceFromData {
+                XCTAssertEqual(originalAsset.filename,newInstance.filename)
+                XCTAssertEqual(originalAsset.data,newInstance.data)
+                XCTAssertEqual(originalAsset.originalLocation,newInstance.originalLocation)
+                XCTAssertEqual(originalAsset.contentType,newInstance.contentType)
+                XCTAssertEqual(originalAsset.contentLength,newInstance.contentLength)
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/usergrid-swift/blob/8283a6dd/Tests/AUTH_Tests.swift
----------------------------------------------------------------------
diff --git a/Tests/AUTH_Tests.swift b/Tests/AUTH_Tests.swift
new file mode 100644
index 0000000..80ec695
--- /dev/null
+++ b/Tests/AUTH_Tests.swift
@@ -0,0 +1,132 @@
+//
+//  AUTH_Tests.swift
+//  UsergridSDK
+//
+//  Created by Robert Walsh on 9/17/15.
+//
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ *
+ */
+
+import XCTest
+@testable import UsergridSDK
+
+class AUTH_Tests: XCTestCase {
+
+    var appAuth: UsergridAppAuth!
+    var userAuth: UsergridUserAuth!
+
+    private static let collectionName = "publicevent"
+    private static let entityUUID = "fa015eaa-fe1c-11e3-b94b-63b29addea01"
+
+    override func setUp() {
+        super.setUp()
+        appAuth = UsergridAppAuth(clientId: "b3U6THNcevskEeOQZLcUROUUVA", clientSecret: "b3U6RZHYznP28xieBzQPackFPmmnevU")
+        userAuth = UsergridUserAuth(username: "username", password: "password")
+        Usergrid.initSharedInstance(orgId:ClientCreationTests.orgId, appId: "sdk.demo")
+    }
+
+    override func tearDown() {
+        Usergrid._sharedClient = nil
+        super.tearDown()
+    }
+
+    func test_CLIENT_AUTH() {
+
+        let authExpect = self.expectationWithDescription("\(#function)")
+        Usergrid.authMode = .App
+        Usergrid.authenticateApp(appAuth) { auth,error in
+            XCTAssertTrue(NSThread.isMainThread())
+            XCTAssertNil(error)
+            XCTAssertNotNil(Usergrid.appAuth)
+
+            if let appAuth = Usergrid.appAuth {
+
+                XCTAssertNotNil(appAuth.accessToken)
+                XCTAssertNotNil(appAuth.expiry)
+                XCTAssertNotNil(appAuth.isValid)
+
+                Usergrid.GET(AUTH_Tests.collectionName) { (response) in
+                    XCTAssertTrue(NSThread.isMainThread())
+                    XCTAssertNotNil(response)
+                    XCTAssertTrue(response.hasNextPage)
+                    XCTAssertEqual(response.entities!.count, 10)
+                    XCTAssertEqual(response.first!.type, AUTH_Tests.collectionName)
+                    
+                    authExpect.fulfill()
+                }
+            }
+        }
+        self.waitForExpectationsWithTimeout(100, handler: nil)
+    }
+
+    func test_DESTROY_AUTH() {
+        let auth = UsergridAuth(accessToken: "YWMt91Q2YtWaEeW_Ki2uDueMEwAAAVMUTVSPeOdX-oradxdqirEFz5cPU3GWybs")
+
+        XCTAssertTrue(auth.isValid)
+        XCTAssertNotNil(auth.accessToken)
+        XCTAssertNil(auth.expiry)
+
+        auth.destroy()
+
+        XCTAssertFalse(auth.isValid)
+        XCTAssertNil(auth.accessToken)
+        XCTAssertNil(auth.expiry)
+    }
+
+    func test_APP_AUTH_NSCODING() {
+
+        appAuth.accessToken = "YWMt91Q2YtWaEeW_Ki2uDueMEwAAAVMUTVSPeOdX-oradxdqirEFz5cPU3GWybs"
+        appAuth.expiry = NSDate.distantFuture()
+
+        let authCodingData = NSKeyedArchiver.archivedDataWithRootObject(appAuth)
+        let newInstanceFromData = NSKeyedUnarchiver.unarchiveObjectWithData(authCodingData) as? UsergridAppAuth
+
+        XCTAssertNotNil(newInstanceFromData)
+
+        if let newInstance = newInstanceFromData {
+            XCTAssertTrue(appAuth.isValid)
+            XCTAssertTrue(newInstance.isValid)
+            XCTAssertEqual(appAuth.clientId,newInstance.clientId)
+            XCTAssertEqual(appAuth.accessToken,newInstance.accessToken)
+            XCTAssertEqual(appAuth.expiry,newInstance.expiry)
+        }
+    }
+
+    func test_USER_AUTH_NSCODING() {
+
+        userAuth.accessToken = "YWMt91Q2YtWaEeW_Ki2uDueMEwAAAVMUTVSPeOdX-oradxdqirEFz5cPU3GWybs"
+        userAuth.expiry = NSDate.distantFuture()
+
+        let authCodingData = NSKeyedArchiver.archivedDataWithRootObject(userAuth)
+        let newInstanceFromData = NSKeyedUnarchiver.unarchiveObjectWithData(authCodingData) as? UsergridUserAuth
+
+        XCTAssertNotNil(newInstanceFromData)
+
+        if let newInstance = newInstanceFromData {
+            XCTAssertTrue(userAuth.isValid)
+            XCTAssertTrue(newInstance.isValid)
+            XCTAssertEqual(userAuth.username,newInstance.username)
+            XCTAssertEqual(userAuth.accessToken,newInstance.accessToken)
+            XCTAssertEqual(userAuth.expiry,newInstance.expiry)
+        }
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/usergrid-swift/blob/8283a6dd/Tests/CONNECTION_Tests.swift
----------------------------------------------------------------------
diff --git a/Tests/CONNECTION_Tests.swift b/Tests/CONNECTION_Tests.swift
new file mode 100644
index 0000000..2640778
--- /dev/null
+++ b/Tests/CONNECTION_Tests.swift
@@ -0,0 +1,105 @@
+//
+//  CONNECTION_Tests.swift
+//  UsergridSDK
+//
+//  Created by Robert Walsh on 10/5/15.
+//
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ *
+ */
+
+import XCTest
+@testable import UsergridSDK
+
+class CONNECTION_Tests: XCTestCase {
+
+    let clientAuth = UsergridAppAuth(clientId: "b3U6THNcevskEeOQZLcUROUUVA", clientSecret: "b3U6RZHYznP28xieBzQPackFPmmnevU")
+    private static let collectionName = "publicevent"
+
+    override func setUp() {
+        super.setUp()
+        Usergrid.initSharedInstance(orgId:ClientCreationTests.orgId, appId: "sdk.demo")
+    }
+
+    override func tearDown() {
+        Usergrid._sharedClient = nil
+        super.tearDown()
+    }
+
+    func test_CLIENT_AUTH() {
+
+        let authExpect = self.expectationWithDescription("\(#function)")
+        Usergrid.authMode = .App
+        Usergrid.authenticateApp(clientAuth) { auth,error in
+            XCTAssertTrue(NSThread.isMainThread())
+            XCTAssertNil(error)
+            XCTAssertNotNil(Usergrid.appAuth)
+
+            if let appAuth = Usergrid.appAuth {
+
+                XCTAssertNotNil(appAuth.accessToken)
+                XCTAssertNotNil(appAuth.expiry)
+
+                Usergrid.GET(CONNECTION_Tests.collectionName) { (response) in
+                    XCTAssertTrue(NSThread.isMainThread())
+                    XCTAssertNotNil(response)
+                    XCTAssertTrue(response.ok)
+                    XCTAssertTrue(response.hasNextPage)
+                    XCTAssertEqual(response.entities!.count, 10)
+
+                    let entity = response.first!
+                    let entityToConnect = response.entities![1]
+                    XCTAssertEqual(entity.type, CONNECTION_Tests.collectionName)
+
+                    entity.connect("likes", toEntity: entityToConnect) { (response) -> Void in
+                        XCTAssertTrue(NSThread.isMainThread())
+                        XCTAssertNotNil(response)
+                        XCTAssertTrue(response.ok)
+
+                        entity.getConnections(.Out, relationship: "likes", query:nil) { (response) -> Void in
+                            XCTAssertTrue(NSThread.isMainThread())
+                            XCTAssertNotNil(response)
+                            XCTAssertTrue(response.ok)
+
+                            let connectedEntity = response.first!
+                            XCTAssertNotNil(connectedEntity)
+                            XCTAssertEqual(connectedEntity.uuidOrName, entityToConnect.uuidOrName)
+
+                            entity.disconnect("likes", fromEntity: connectedEntity) { (response) -> Void in
+                                XCTAssertTrue(NSThread.isMainThread())
+                                XCTAssertNotNil(response)
+                                XCTAssertTrue(response.ok)
+
+                                entity.getConnections(.Out, relationship: "likes", query:nil) { (response) -> Void in
+                                    XCTAssertTrue(NSThread.isMainThread())
+                                    XCTAssertNotNil(response)
+                                    XCTAssertTrue(response.ok)
+                                    authExpect.fulfill()
+                                }
+                            }
+                        }
+                    }
+                }
+            } else {
+                authExpect.fulfill()
+            }
+        }
+        self.waitForExpectationsWithTimeout(20, handler: nil)
+    }
+}

http://git-wip-us.apache.org/repos/asf/usergrid-swift/blob/8283a6dd/Tests/ClientCreationTests.swift
----------------------------------------------------------------------
diff --git a/Tests/ClientCreationTests.swift b/Tests/ClientCreationTests.swift
new file mode 100644
index 0000000..40a7de1
--- /dev/null
+++ b/Tests/ClientCreationTests.swift
@@ -0,0 +1,74 @@
+//
+//  ClientCreationTests.swift
+//  UsergridSDK
+//
+//  Created by Robert Walsh on 7/31/15.
+//
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ *
+ */
+
+import XCTest
+@testable import UsergridSDK
+
+class ClientCreationTests: XCTestCase {
+
+    static let orgId = "rwalsh"
+    static let appId = "sandbox"
+
+    override func setUp() {
+        super.setUp()
+        Usergrid.initSharedInstance(orgId:ClientCreationTests.orgId, appId: ClientCreationTests.appId)
+        Usergrid.persistCurrentUserInKeychain = false
+    }
+
+    override func tearDown() {
+        Usergrid._sharedClient = nil
+        super.tearDown()
+    }
+
+    func test_INSTANCE_POINTERS() {
+        XCTAssertNotNil(Usergrid.sharedInstance)
+    }
+
+    func test_CLIENT_PROPERTIES() {
+        XCTAssertEqual(Usergrid.appId, ClientCreationTests.appId)
+        XCTAssertEqual(Usergrid.orgId, ClientCreationTests.orgId)
+        XCTAssertEqual(Usergrid.authMode, UsergridAuthMode.User)
+        XCTAssertEqual(Usergrid.persistCurrentUserInKeychain, false)
+        XCTAssertEqual(Usergrid.baseUrl, UsergridClient.DEFAULT_BASE_URL)
+        XCTAssertEqual(Usergrid.clientAppURL, "\(UsergridClient.DEFAULT_BASE_URL)/\(ClientCreationTests.orgId)/\(ClientCreationTests.appId)" )
+        XCTAssertNil(Usergrid.currentUser)
+        XCTAssertNil(Usergrid.userAuth)
+    }
+
+    func test_CLIENT_NSCODING() {
+        let sharedInstanceAsData = NSKeyedArchiver.archivedDataWithRootObject(Usergrid.sharedInstance)
+        let newInstanceFromData = NSKeyedUnarchiver.unarchiveObjectWithData(sharedInstanceAsData) as? UsergridClient
+
+        XCTAssertNotNil(newInstanceFromData)
+
+        if let newInstance = newInstanceFromData {
+            XCTAssertEqual(Usergrid.appId, newInstance.appId)
+            XCTAssertEqual(Usergrid.orgId, newInstance.orgId)
+            XCTAssertEqual(Usergrid.authMode, newInstance.authMode)
+            XCTAssertEqual(Usergrid.baseUrl, newInstance.baseUrl)
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/usergrid-swift/blob/8283a6dd/Tests/Entity_Tests.swift
----------------------------------------------------------------------
diff --git a/Tests/Entity_Tests.swift b/Tests/Entity_Tests.swift
new file mode 100644
index 0000000..439b67d
--- /dev/null
+++ b/Tests/Entity_Tests.swift
@@ -0,0 +1,173 @@
+//
+//  Entity_Tests.swift
+//  UsergridSDK
+//
+//  Created by Robert Walsh on 9/22/15.
+//
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ *
+ */
+
+import XCTest
+@testable import UsergridSDK
+
+class Entity_Tests: XCTestCase {
+
+    let entity = UsergridEntity(type: "entityType", name:"entityName")
+    let customArrayName = "customArray"
+    let customArrayOriginalValue = [1,2,3,4,5]
+    let customPropertyName = "customProperty"
+    let customPropertyValue = 99
+
+    func test_PUT_PROPERTY() {
+
+        entity.putProperty(customArrayName, value: customArrayOriginalValue)
+
+        let propertyValue = entity[customArrayName] as? [Int]
+        XCTAssertNotNil(propertyValue)
+        XCTAssertEqual(propertyValue!, customArrayOriginalValue)
+    }
+    func test_PUT_PROPERTIES() {
+
+        entity.putProperties([customArrayName:customArrayOriginalValue])
+
+        let propertyValue = entity[customArrayName] as? [Int]
+        XCTAssertNotNil(propertyValue)
+        XCTAssertEqual(propertyValue!, customArrayOriginalValue)
+    }
+    func test_REMOVE_PROPERTY() {
+        entity[customArrayName] = customArrayOriginalValue
+        let propertyValue = entity[customArrayName] as? [Int]
+        XCTAssertNotNil(propertyValue)
+
+        entity.removeProperty(customArrayName)
+
+        XCTAssertNil(entity[customArrayName])
+    }
+    func test_REMOVE_PROPERTIES() {
+        entity[customArrayName] = customArrayOriginalValue
+        let propertyValue = entity[customArrayName] as? [Int]
+        XCTAssertNotNil(propertyValue)
+
+        entity.removeProperties([customArrayName])
+
+        XCTAssertNil(entity[customArrayName])
+    }
+    func test_PUSH() {
+        entity[customArrayName] = customArrayOriginalValue
+
+        entity.append(customArrayName,value:6)
+
+        let newValue = entity[customArrayName] as? [Int]
+        XCTAssertNotNil(newValue)
+        XCTAssertEqual(newValue!, [1,2,3,4,5,6])
+    }
+    func test_APPEND() {
+        entity[customArrayName] = customArrayOriginalValue
+
+        entity.append(customArrayName,value:[6,7])
+
+        let newValue = entity[customArrayName] as? [Int]
+        XCTAssertNotNil(newValue)
+        XCTAssertEqual(newValue!, [1,2,3,4,5,6,7])
+    }
+    func test_INSERT_WITHOUT_INDEX() {
+        entity[customArrayName] = customArrayOriginalValue
+
+        entity.insert(customArrayName,value:6)
+
+        let newValue = entity[customArrayName] as? [Int]
+        XCTAssertNotNil(newValue)
+        XCTAssertEqual(newValue!, [6,1,2,3,4,5])
+    }
+    func test_INSERT_WITH_INDEX() {
+        entity[customArrayName] = customArrayOriginalValue
+
+        entity.insert(customArrayName,value:6,index:1)
+
+        let newValue = entity[customArrayName] as? [Int]
+        XCTAssertNotNil(newValue)
+        XCTAssertEqual(newValue!, [1,6,2,3,4,5])
+    }
+    func test_INSERT_ARRAY_WITHOUT_INDEX() {
+        entity[customArrayName] = customArrayOriginalValue
+
+        entity.insert(customArrayName,value:[6,7])
+
+        let newValue = entity[customArrayName] as? [Int]
+        XCTAssertNotNil(newValue)
+        XCTAssertEqual(newValue!, [6,7,1,2,3,4,5])
+    }
+
+    func test_INSERT_ARRAY_WITH_INDEX() {
+        entity[customArrayName] = customArrayOriginalValue
+
+        entity.insert(customArrayName,value:[6,7],index:1)
+
+        let newValue = entity[customArrayName] as? [Int]
+        XCTAssertNotNil(newValue)
+        XCTAssertEqual(newValue!, [1,6,7,2,3,4,5])
+    }
+
+    func test_INSERT_ARRAY_TO_NON_EXISTENT_PROPERTY() {
+        entity.insert(customArrayName,value:customArrayOriginalValue)
+
+        let newValue = entity[customArrayName] as? [Int]
+        XCTAssertNotNil(newValue)
+        XCTAssertEqual(newValue!, [1,2,3,4,5])
+    }
+
+    func test_INSERT_ARRAY_TO_NON_ARRAY_PROPERTY_WITHOUT_INDEX() {
+        entity[customPropertyName] = customPropertyValue
+
+        entity.insert(customPropertyName,value:customArrayOriginalValue)
+
+        let newValue = entity[customPropertyName] as? [Int]
+        XCTAssertNotNil(newValue)
+        XCTAssertEqual(newValue!, [1,2,3,4,5,99])
+    }
+
+    func test_INSERT_ARRAY_TO_NON_ARRAY_PROPERTY_WITH_INDEX() {
+        entity[customPropertyName] = customPropertyValue
+
+        entity.insert(customPropertyName,value:customArrayOriginalValue,index:1)
+
+        let newValue = entity[customPropertyName] as? [Int]
+        XCTAssertNotNil(newValue)
+        XCTAssertEqual(newValue!, [99,1,2,3,4,5])
+    }
+    func test_POP() {
+        entity[customArrayName] = customArrayOriginalValue
+
+        entity.pop(customArrayName)
+
+        let newValue = entity[customArrayName] as? [Int]
+        XCTAssertNotNil(newValue)
+        XCTAssertEqual(newValue!, [1,2,3,4])
+    }
+    func test_SHIFT() {
+        entity[customArrayName] = customArrayOriginalValue
+
+        entity.shift(customArrayName)
+
+        let newValue = entity[customArrayName] as? [Int]
+        XCTAssertNotNil(newValue)
+        XCTAssertEqual(newValue!, [2,3,4,5])
+    }
+}

http://git-wip-us.apache.org/repos/asf/usergrid-swift/blob/8283a6dd/Tests/GET_Tests.swift
----------------------------------------------------------------------
diff --git a/Tests/GET_Tests.swift b/Tests/GET_Tests.swift
new file mode 100644
index 0000000..2b0331f
--- /dev/null
+++ b/Tests/GET_Tests.swift
@@ -0,0 +1,113 @@
+//
+//  GET_Tests.swift
+//  UsergridSDK
+//
+//  Created by Robert Walsh on 9/2/15.
+//
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ *
+ */
+
+import XCTest
+@testable import UsergridSDK
+
+class GET_Tests: XCTestCase {
+
+    static let collectionName = "books"
+    static let entityUUID = "f4078aca-2fb1-11e5-8eb2-e13f8369aad1"
+
+    let query = UsergridQuery(GET_Tests.collectionName).eq("title", value: "The Sun Also Rises").or().eq("title", value: "The Old Man and the Sea")
+
+    override func setUp() {
+        super.setUp()
+        Usergrid.initSharedInstance(orgId:ClientCreationTests.orgId, appId: ClientCreationTests.appId)
+    }
+
+    override func tearDown() {
+        Usergrid._sharedClient = nil
+        super.tearDown()
+    }
+
+    func test_GET_WITHOUT_QUERY() {
+
+        let getExpect = self.expectationWithDescription("\(#function)")
+        Usergrid.GET(GET_Tests.collectionName) { (response) in
+            XCTAssertTrue(NSThread.isMainThread())
+            XCTAssertNotNil(response)
+            XCTAssertTrue(response.ok)
+            XCTAssertTrue(response.hasNextPage)
+            XCTAssertEqual(response.count, 10)
+            getExpect.fulfill()
+        }
+        self.waitForExpectationsWithTimeout(10, handler: nil)
+    }
+
+    func test_GET_WITH_QUERY() {
+
+        let getExpect = self.expectationWithDescription("\(#function)")
+        Usergrid.GET(self.query) { (response) in
+            XCTAssertTrue(NSThread.isMainThread())
+            XCTAssertNotNil(response)
+            XCTAssertTrue(response.ok)
+            XCTAssertEqual(response.count, 1)
+            getExpect.fulfill()
+        }
+        self.waitForExpectationsWithTimeout(10, handler: nil)
+    }
+
+    func test_GET_WITH_UUID() {
+
+        let getExpect = self.expectationWithDescription("\(#function)")
+        Usergrid.GET(GET_Tests.collectionName, uuidOrName:GET_Tests.entityUUID) { (response) in
+            XCTAssertTrue(NSThread.isMainThread())
+            XCTAssertNotNil(response)
+            XCTAssertTrue(response.ok)
+            let entity = response.first!
+            XCTAssertFalse(response.hasNextPage)
+            XCTAssertEqual(response.count, 1)
+            XCTAssertNotNil(entity)
+            XCTAssertEqual(entity.uuid!, GET_Tests.entityUUID)
+            getExpect.fulfill()
+        }
+        self.waitForExpectationsWithTimeout(10, handler: nil)
+    }
+
+    func test_GET_NEXT_PAGE_WITH_NO_QUERY() {
+
+        let getExpect = self.expectationWithDescription("\(#function)")
+        Usergrid.GET(GET_Tests.collectionName) { (response) in
+            XCTAssertTrue(NSThread.isMainThread())
+            XCTAssertNotNil(response)
+            XCTAssertTrue(response.ok)
+            XCTAssertTrue(response.hasNextPage)
+            XCTAssertEqual(response.count, 10)
+
+            response.loadNextPage() { (nextPageResponse) in
+                XCTAssertTrue(NSThread.isMainThread())
+                XCTAssertTrue(nextPageResponse.ok)
+                XCTAssertNotNil(nextPageResponse)
+                XCTAssertFalse(nextPageResponse.hasNextPage)
+                XCTAssertEqual(nextPageResponse.entities!.count, 7)
+                getExpect.fulfill()
+            }
+        }
+        self.waitForExpectationsWithTimeout(20, handler: nil)
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/usergrid-swift/blob/8283a6dd/Tests/Info.plist
----------------------------------------------------------------------
diff --git a/Tests/Info.plist b/Tests/Info.plist
new file mode 100644
index 0000000..ba72822
--- /dev/null
+++ b/Tests/Info.plist
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIdentifier</key>
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>$(PRODUCT_NAME)</string>
+	<key>CFBundlePackageType</key>
+	<string>BNDL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+</dict>
+</plist>

http://git-wip-us.apache.org/repos/asf/usergrid-swift/blob/8283a6dd/Tests/PUT_Tests.swift
----------------------------------------------------------------------
diff --git a/Tests/PUT_Tests.swift b/Tests/PUT_Tests.swift
new file mode 100644
index 0000000..b1ff3e7
--- /dev/null
+++ b/Tests/PUT_Tests.swift
@@ -0,0 +1,158 @@
+//
+//  PUT_Tests.swift
+//  UsergridSDK
+//
+//  Created by Robert Walsh on 9/11/15.
+//
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ *
+ */
+
+import XCTest
+@testable import UsergridSDK
+
+class PUT_Tests: XCTestCase {
+
+    let query = UsergridQuery(PUT_Tests.collectionName)
+        .eq("title", value: "The Sun Also Rises")
+        .or()
+        .eq("title", value: "The Old Man and the Sea")
+
+    static let collectionName = "books"
+    static let entityUUID = "f4078aca-2fb1-11e5-8eb2-e13f8369aad1"
+
+    override func setUp() {
+        super.setUp()
+        Usergrid.initSharedInstance(orgId:ClientCreationTests.orgId, appId: ClientCreationTests.appId)
+    }
+
+    override func tearDown() {
+        Usergrid._sharedClient = nil
+        super.tearDown()
+    }
+
+    func test_PUT_BY_SPECIFYING_UUID_AS_PARAMETER() {
+
+        let propertyNameToUpdate = "\(#function)"
+        let propertiesNewValue = "\(propertyNameToUpdate)_VALUE"
+        let putExpect = self.expectationWithDescription(propertyNameToUpdate)
+
+        Usergrid.PUT(PUT_Tests.collectionName, uuidOrName: PUT_Tests.entityUUID, jsonBody:[propertyNameToUpdate : propertiesNewValue]) { (response) in
+            XCTAssertTrue(NSThread.isMainThread())
+            XCTAssertNotNil(response)
+            XCTAssertTrue(response.ok)
+            XCTAssertEqual(response.entities!.count, 1)
+            let entity = response.first!
+
+            XCTAssertNotNil(entity)
+            XCTAssertEqual(entity.uuid!, PUT_Tests.entityUUID)
+
+            let updatedPropertyValue = entity[propertyNameToUpdate] as? String
+            XCTAssertNotNil(updatedPropertyValue)
+            XCTAssertEqual(updatedPropertyValue!,propertiesNewValue)
+            putExpect.fulfill()
+        }
+        self.waitForExpectationsWithTimeout(10, handler: nil)
+    }
+
+    func test_PUT_BY_SPECIFYING_UUID_WITHIN_JSON_BODY() {
+
+        let propertyNameToUpdate = "\(#function)"
+        let propertiesNewValue = "\(propertyNameToUpdate)_VALUE"
+        let putExpect = self.expectationWithDescription(propertyNameToUpdate)
+
+        let jsonDictToPut = [UsergridEntityProperties.UUID.stringValue : PUT_Tests.entityUUID, propertyNameToUpdate : propertiesNewValue]
+
+        Usergrid.PUT(PUT_Tests.collectionName, jsonBody: jsonDictToPut) { (response) in
+            XCTAssertTrue(NSThread.isMainThread())
+            XCTAssertNotNil(response)
+            XCTAssertTrue(response.ok)
+            XCTAssertEqual(response.entities!.count, 1)
+            let entity = response.first!
+
+            XCTAssertNotNil(entity)
+            XCTAssertEqual(entity.uuid!, PUT_Tests.entityUUID)
+
+            let updatedPropertyValue = entity[propertyNameToUpdate] as? String
+            XCTAssertNotNil(updatedPropertyValue)
+            XCTAssertEqual(updatedPropertyValue!,propertiesNewValue)
+            putExpect.fulfill()
+        }
+        self.waitForExpectationsWithTimeout(10, handler: nil)
+    }
+
+    func test_PUT_WITH_ENTITY_OBJECT() {
+        let propertyNameToUpdate = "\(#function)"
+        let propertiesNewValue = "\(propertyNameToUpdate)_VALUE"
+        let putExpect = self.expectationWithDescription(propertyNameToUpdate)
+
+        Usergrid.GET(PUT_Tests.collectionName, uuidOrName: PUT_Tests.entityUUID) { (getResponse) in
+            XCTAssertTrue(NSThread.isMainThread())
+            XCTAssertNotNil(getResponse)
+            XCTAssertTrue(getResponse.ok)
+            XCTAssertEqual(getResponse.entities!.count, 1)
+
+            var responseEntity = getResponse.first!
+
+            XCTAssertNotNil(responseEntity)
+            XCTAssertEqual(responseEntity.uuid!, PUT_Tests.entityUUID)
+
+            responseEntity[propertyNameToUpdate] = propertiesNewValue
+
+            Usergrid.PUT(responseEntity) { (putResponse) in
+                XCTAssertTrue(NSThread.isMainThread())
+                XCTAssertNotNil(putResponse)
+                XCTAssertTrue(putResponse.ok)
+                XCTAssertEqual(putResponse.entities!.count, 1)
+                responseEntity = putResponse.first!
+
+                XCTAssertNotNil(responseEntity)
+                XCTAssertEqual(responseEntity.uuid!, PUT_Tests.entityUUID)
+
+                let updatedPropertyValue = responseEntity[propertyNameToUpdate] as? String
+                XCTAssertNotNil(updatedPropertyValue)
+                XCTAssertEqual(updatedPropertyValue!,propertiesNewValue)
+                putExpect.fulfill()
+            }
+        }
+        self.waitForExpectationsWithTimeout(20, handler: nil)
+    }
+
+    func test_PUT_WITH_QUERY() {
+        let propertyNameToUpdate = "\(#function)"
+        let propertiesNewValue = "\(propertyNameToUpdate)_VALUE"
+        let putExpect = self.expectationWithDescription(propertyNameToUpdate)
+
+        Usergrid.PUT(self.query, jsonBody: [propertyNameToUpdate : propertiesNewValue]) { (putResponse) in
+            XCTAssertTrue(NSThread.isMainThread())
+            XCTAssertNotNil(putResponse)
+            XCTAssertTrue(putResponse.ok)
+            XCTAssertEqual(putResponse.entities!.count, 1)
+
+            let responseEntity = putResponse.first!
+            XCTAssertNotNil(responseEntity)
+
+            let updatedPropertyValue = responseEntity[propertyNameToUpdate] as? String
+            XCTAssertNotNil(updatedPropertyValue)
+            XCTAssertEqual(updatedPropertyValue!,propertiesNewValue)
+            putExpect.fulfill()
+        }
+        self.waitForExpectationsWithTimeout(10, handler: nil)
+    }
+}

http://git-wip-us.apache.org/repos/asf/usergrid-swift/blob/8283a6dd/Tests/TestAssets/UsergridGuy.jpg
----------------------------------------------------------------------
diff --git a/Tests/TestAssets/UsergridGuy.jpg b/Tests/TestAssets/UsergridGuy.jpg
new file mode 100644
index 0000000..035dd7b
Binary files /dev/null and b/Tests/TestAssets/UsergridGuy.jpg differ

http://git-wip-us.apache.org/repos/asf/usergrid-swift/blob/8283a6dd/Tests/TestAssets/logo_apigee.png
----------------------------------------------------------------------
diff --git a/Tests/TestAssets/logo_apigee.png b/Tests/TestAssets/logo_apigee.png
new file mode 100644
index 0000000..5113800
Binary files /dev/null and b/Tests/TestAssets/logo_apigee.png differ

http://git-wip-us.apache.org/repos/asf/usergrid-swift/blob/8283a6dd/Tests/TestAssets/test.png
----------------------------------------------------------------------
diff --git a/Tests/TestAssets/test.png b/Tests/TestAssets/test.png
new file mode 100644
index 0000000..4b13eaa
Binary files /dev/null and b/Tests/TestAssets/test.png differ

http://git-wip-us.apache.org/repos/asf/usergrid-swift/blob/8283a6dd/Tests/User_Tests.swift
----------------------------------------------------------------------
diff --git a/Tests/User_Tests.swift b/Tests/User_Tests.swift
new file mode 100644
index 0000000..dcb5545
--- /dev/null
+++ b/Tests/User_Tests.swift
@@ -0,0 +1,399 @@
+//
+//  User_Tests.swift
+//  UsergridSDK
+//
+//  Created by Robert Walsh on 9/14/15.
+//
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ *
+ */
+
+import XCTest
+import CoreLocation
+@testable import UsergridSDK
+
+class User_Tests: XCTestCase {
+
+    var user: UsergridUser!
+
+    static let name = "Robert Walsh"
+    static let age = 29
+    static let email = "handsomeRob741@yahoo.com"
+    static let username = "rwalsh"
+    static let password = "password"
+    static let resetPassword = "password111"
+    static let picture = "http://www.gravatar.com/avatar/e466d447df831ddce35fbc50763fb03a"
+    static let activated = true
+    static let disabled = false
+
+    override func setUp() {
+        super.setUp()
+
+        Usergrid.initSharedInstance(orgId:ClientCreationTests.orgId, appId: ClientCreationTests.appId)
+        Usergrid.persistCurrentUserInKeychain = false
+
+        user = UsergridUser(name:"a_bogus_name", email:User_Tests.email, username:User_Tests.username, password:User_Tests.password)
+        user.name = User_Tests.name
+        user.age = User_Tests.age
+        user.location = CLLocation(latitude: -90, longitude: 100)
+        user.picture = User_Tests.picture
+        user.activated = User_Tests.activated
+        user.disabled = User_Tests.disabled
+    }
+
+    override func tearDown() {
+        Usergrid._sharedClient = nil        
+        super.tearDown()
+    }
+
+    func test_USER_INIT() {
+        user = UsergridUser(email: User_Tests.email, password: User_Tests.password)
+        XCTAssertNotNil(user)
+        XCTAssertNotNil(user.email)
+        XCTAssertNotNil(user.password)
+        XCTAssertEqual(user.email!, User_Tests.email)
+        XCTAssertEqual(user.usernameOrEmail!, User_Tests.email)
+        XCTAssertEqual(user.password!, User_Tests.password)
+        XCTAssertFalse(user.activated)
+        XCTAssertFalse(user.disabled)
+
+        user = UsergridUser(name: User_Tests.name, propertyDict: ["password":User_Tests.password])
+        XCTAssertNotNil(user)
+        XCTAssertNotNil(user.name)
+        XCTAssertNotNil(user.password)
+        XCTAssertEqual(user.name!, User_Tests.name)
+        XCTAssertEqual(user.password!, User_Tests.password)
+        XCTAssertFalse(user.activated)
+        XCTAssertFalse(user.disabled)
+
+        user = UsergridUser(name:User_Tests.name, email: User_Tests.email, password: User_Tests.password)
+        XCTAssertNotNil(user)
+        XCTAssertNotNil(user.name)
+        XCTAssertNotNil(user.email)
+        XCTAssertNotNil(user.password)
+        XCTAssertEqual(user.name!, User_Tests.name)
+        XCTAssertEqual(user.email!, User_Tests.email)
+        XCTAssertEqual(user.usernameOrEmail!, User_Tests.email)
+        XCTAssertEqual(user.password!, User_Tests.password)
+        XCTAssertFalse(user.activated)
+        XCTAssertFalse(user.disabled)
+
+        user = UsergridUser(username: User_Tests.username, password: User_Tests.password)
+        XCTAssertNotNil(user)
+        XCTAssertNotNil(user.username)
+        XCTAssertNotNil(user.password)
+        XCTAssertEqual(user.username!, User_Tests.username)
+        XCTAssertEqual(user.usernameOrEmail!, User_Tests.username)
+        XCTAssertEqual(user.password!, User_Tests.password)
+        XCTAssertFalse(user.activated)
+        XCTAssertFalse(user.disabled)
+
+        user = UsergridUser(name: User_Tests.name, username: User_Tests.username, password: User_Tests.password)
+        XCTAssertNotNil(user)
+        XCTAssertNotNil(user.name)
+        XCTAssertNotNil(user.username)
+        XCTAssertNotNil(user.password)
+        XCTAssertEqual(user.name!, User_Tests.name)
+        XCTAssertEqual(user.username!, User_Tests.username)
+        XCTAssertEqual(user.usernameOrEmail!, User_Tests.username)
+        XCTAssertEqual(user.password!, User_Tests.password)
+        XCTAssertFalse(user.activated)
+        XCTAssertFalse(user.disabled)
+    }
+
+    func test_USERS_AND_PROPERTIES_NOT_NIL() {
+        XCTAssertNotNil(user)
+        XCTAssertNotNil(user.name)
+        XCTAssertNotNil(user.age)
+        XCTAssertNotNil(user.username)
+        XCTAssertNotNil(user.email)
+        XCTAssertNotNil(user.password)
+        XCTAssertNotNil(user.picture)
+        XCTAssertNotNil(user.activated)
+        XCTAssertNotNil(user.disabled)
+    }
+
+    func test_USER_PROPERTIES_WITH_HELPERS() {
+        user["uuid"] = User_Tests.age
+        XCTAssertNil(user.uuid)
+
+        XCTAssertEqual(user.name!, User_Tests.name)
+        XCTAssertEqual(user.age!, User_Tests.age)
+        XCTAssertEqual(user.username!, User_Tests.username)
+        XCTAssertEqual(user.email!, User_Tests.email)
+        XCTAssertEqual(user.password!, User_Tests.password)
+        XCTAssertEqual(user.picture!, User_Tests.picture)
+        XCTAssertTrue(user.activated)
+        XCTAssertFalse(user.disabled)
+    }
+
+    func test_USER_PROPERTIES_WITHOUT_HELPERS() {
+        XCTAssertEqual(user[UsergridUserProperties.Name.stringValue]! as? String, User_Tests.name)
+        XCTAssertEqual(user[UsergridUserProperties.Age.stringValue]! as? Int, User_Tests.age)
+        XCTAssertEqual(user[UsergridUserProperties.Username.stringValue]! as? String, User_Tests.username)
+        XCTAssertEqual(user[UsergridUserProperties.Email.stringValue]! as? String, User_Tests.email)
+        XCTAssertEqual(user[UsergridUserProperties.Password.stringValue]! as? String, User_Tests.password)
+        XCTAssertEqual(user[UsergridUserProperties.Picture.stringValue]! as? String, User_Tests.picture)
+        XCTAssertTrue(user[UsergridUserProperties.Activated.stringValue]! as! Bool)
+        XCTAssertFalse(user[UsergridUserProperties.Disabled.stringValue]! as! Bool)
+    }
+
+    func deleteUser(expectation:XCTestExpectation) {
+        self.user.remove() { removeResponse in
+            XCTAssertTrue(NSThread.isMainThread())
+            XCTAssertNotNil(removeResponse)
+            XCTAssertTrue(removeResponse.ok)
+            XCTAssertNotNil(removeResponse.user)
+            XCTAssertNotNil(removeResponse.users)
+            print(removeResponse.error)
+            expectation.fulfill()
+        }
+    }
+
+    func test_CREATE_AND_DELETE_USER() {
+        let userExpect = self.expectationWithDescription("\(#function)")
+
+        user.save() { (createResponse) in
+            XCTAssertTrue(NSThread.isMainThread())
+            XCTAssertNotNil(createResponse)
+            XCTAssertTrue(createResponse.ok)
+            XCTAssertNotNil(createResponse.user)
+            XCTAssertNotNil(createResponse.users)
+
+            if let createdUser = createResponse.user {
+                XCTAssertTrue(createdUser.isUser)
+                XCTAssertNotNil(createdUser.uuid)
+                XCTAssertNotNil(createdUser.created)
+                XCTAssertNotNil(createdUser.modified)
+                XCTAssertNotNil(createdUser.location)
+                XCTAssertEqual(createdUser.name!, User_Tests.name)
+                XCTAssertEqual(createdUser.age!, User_Tests.age)
+                XCTAssertEqual(createdUser.username!, User_Tests.username)
+                XCTAssertEqual(createdUser.email!, User_Tests.email)
+                XCTAssertEqual(createdUser.picture!, User_Tests.picture)
+                XCTAssertTrue(createdUser.activated)
+                XCTAssertFalse(createdUser.disabled)
+                XCTAssertFalse(createdUser.hasAsset)
+
+                self.deleteUser(userExpect)
+            }
+        }
+        self.waitForExpectationsWithTimeout(100, handler: nil)
+    }
+
+    func test_AUTHENTICATE_USER() {
+        let userExpect = self.expectationWithDescription("\(#function)")
+
+        UsergridUser.checkAvailable(user.email, username: user.username) { error,available in
+
+            XCTAssertTrue(NSThread.isMainThread())
+            XCTAssertNil(error)
+            XCTAssertTrue(available)
+
+            self.user.create() { (createResponse) in
+                XCTAssertTrue(NSThread.isMainThread())
+                XCTAssertNotNil(createResponse)
+                XCTAssertTrue(createResponse.ok)
+                XCTAssertNotNil(createResponse.user)
+                XCTAssertNotNil(createResponse.users)
+                XCTAssertNotNil(self.user.uuid)
+
+                self.user.login(self.user.username!, password:User_Tests.password) { (auth, loggedInUser, error) -> Void in
+                    XCTAssertTrue(NSThread.isMainThread())
+                    XCTAssertNil(error)
+                    XCTAssertNotNil(auth)
+                    XCTAssertNotNil(loggedInUser)
+                    XCTAssertEqual(auth, self.user.auth!)
+
+                    Usergrid.authenticateUser(self.user.auth!) { auth,currentUser,error in
+                        XCTAssertTrue(NSThread.isMainThread())
+                        XCTAssertNil(error)
+                        XCTAssertNotNil(auth)
+                        XCTAssertEqual(auth, self.user.auth!)
+
+                        XCTAssertNotNil(currentUser)
+                        XCTAssertNotNil(Usergrid.currentUser)
+                        XCTAssertEqual(currentUser, Usergrid.currentUser!)
+
+                        self.user.reauthenticate() { auth, reauthedUser, error in
+                            XCTAssertTrue(NSThread.isMainThread())
+                            XCTAssertNil(error)
+                            XCTAssertNotNil(auth)
+                            XCTAssertEqual(auth, self.user.auth!)
+
+                            XCTAssertNotNil(reauthedUser)
+                            XCTAssertNotNil(Usergrid.currentUser)
+
+                            self.user.logout() { response in
+                                XCTAssertTrue(NSThread.isMainThread())
+                                XCTAssertNotNil(response)
+                                XCTAssertTrue(response.ok)
+                                XCTAssertNil(response.error)
+
+                                self.deleteUser(userExpect)
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        self.waitForExpectationsWithTimeout(100, handler: nil)
+    }
+
+    func test_RESET_USER_PASSWORD() {
+        let userExpect = self.expectationWithDescription("\(#function)")
+
+        user.create() { (createResponse) in
+            XCTAssertTrue(NSThread.isMainThread())
+            XCTAssertNotNil(createResponse)
+            XCTAssertTrue(createResponse.ok)
+            XCTAssertNotNil(createResponse.user)
+            XCTAssertNotNil(createResponse.users)
+            XCTAssertNotNil(self.user.uuid)
+
+            self.user.login(self.user.username!, password:User_Tests.password) { (auth, loggedInUser, error) -> Void in
+                XCTAssertTrue(NSThread.isMainThread())
+                XCTAssertNil(error)
+                XCTAssertNotNil(auth)
+                XCTAssertNotNil(loggedInUser)
+                XCTAssertEqual(auth, self.user.auth!)
+
+                self.user.resetPassword(User_Tests.password, new: User_Tests.resetPassword) { error,didSucceed in
+                    XCTAssertTrue(NSThread.isMainThread())
+                    XCTAssertTrue(didSucceed)
+                    XCTAssertNil(error)
+
+                    self.user.login(self.user.username!, password:User_Tests.resetPassword) { (auth, loggedInUser, error) -> Void in
+                        XCTAssertTrue(NSThread.isMainThread())
+                        XCTAssertNil(error)
+                        XCTAssertNotNil(auth)
+                        XCTAssertNotNil(loggedInUser)
+                        XCTAssertEqual(auth, self.user.auth!)
+
+                        self.deleteUser(userExpect)
+                    }
+                }
+            }
+        }
+        self.waitForExpectationsWithTimeout(100, handler: nil)
+    }
+
+    func test_DEVICE_CONNECTION() {
+        let userExpect = self.expectationWithDescription("\(#function)")
+
+        user.create() { createResponse in
+            XCTAssertNotNil(createResponse)
+            XCTAssertTrue(createResponse.ok)
+            XCTAssertNotNil(createResponse.user)
+            XCTAssertNotNil(createResponse.users)
+            XCTAssertNotNil(self.user.uuid)
+
+            self.user.connectToDevice() { connectResponse in
+                XCTAssertNotNil(connectResponse)
+                XCTAssertTrue(connectResponse.ok)
+                XCTAssertNil(connectResponse.error)
+
+                self.user.getConnectedDevice() { getConnectedDeviceResponse in
+                    XCTAssertNotNil(getConnectedDeviceResponse)
+                    XCTAssertTrue(getConnectedDeviceResponse.ok)
+                    XCTAssertNil(getConnectedDeviceResponse.error)
+                    XCTAssertNotNil(getConnectedDeviceResponse.entity)
+
+                    if let responseEntity = getConnectedDeviceResponse.entity {
+                        XCTAssertTrue(responseEntity is UsergridDevice)
+                    }
+
+                    self.user.disconnectFromDevice() { disconnectResponse in
+                        XCTAssertNotNil(disconnectResponse)
+                        XCTAssertTrue(disconnectResponse.ok)
+                        XCTAssertNil(disconnectResponse.error)
+
+                        self.deleteUser(userExpect)
+                    }
+                }
+            }
+        }
+        self.waitForExpectationsWithTimeout(100, handler: nil)
+    }
+
+    func test_DEVICE_CONNECT_FAIL() {
+        let userExpect = self.expectationWithDescription("\(#function)")
+
+        user.create() { createResponse in
+            XCTAssertNotNil(createResponse)
+            XCTAssertTrue(createResponse.ok)
+            XCTAssertNotNil(createResponse.user)
+            XCTAssertNotNil(createResponse.users)
+            XCTAssertNotNil(self.user.uuid)
+
+            self.user.connectToDevice() { connectResponse in
+                XCTAssertNotNil(connectResponse)
+                XCTAssertTrue(connectResponse.ok)
+                XCTAssertNil(connectResponse.error)
+
+                self.user.getConnectedDevice() { getConnectedDeviceResponse in
+                    XCTAssertNotNil(getConnectedDeviceResponse)
+                    XCTAssertTrue(getConnectedDeviceResponse.ok)
+                    XCTAssertNil(getConnectedDeviceResponse.error)
+                    XCTAssertNotNil(getConnectedDeviceResponse.entity)
+
+                    if let responseEntity = getConnectedDeviceResponse.entity {
+                        XCTAssertTrue(responseEntity is UsergridDevice)
+                    }
+
+                    self.user.disconnectFromDevice() { disconnectResponse in
+                        XCTAssertNotNil(disconnectResponse)
+                        XCTAssertTrue(disconnectResponse.ok)
+                        XCTAssertNil(disconnectResponse.error)
+
+                        self.deleteUser(userExpect)
+                    }
+                }
+            }
+        }
+        self.waitForExpectationsWithTimeout(100, handler: nil)
+    }
+
+
+    func test_USER_NSCODING() {
+        let userData = NSKeyedArchiver.archivedDataWithRootObject(user)
+        let newInstanceFromData = NSKeyedUnarchiver.unarchiveObjectWithData(userData) as? UsergridUser
+
+        XCTAssertNotNil(newInstanceFromData)
+
+        if let newInstance = newInstanceFromData {
+            XCTAssertEqual(user.uuid,newInstance.uuid)
+            XCTAssertEqual(user.uuidOrName,newInstance.uuidOrName)
+            XCTAssertEqual(user.uuidOrUsername,newInstance.uuidOrUsername)
+            XCTAssertEqual(user.auth,newInstance.auth)
+            XCTAssertEqual(user.created,newInstance.created)
+            XCTAssertEqual(user.modified,newInstance.modified)
+            XCTAssertEqual(user.location!.coordinate.longitude,newInstance.location!.coordinate.longitude)
+            XCTAssertEqual(user.location!.coordinate.latitude,newInstance.location!.coordinate.latitude)
+            XCTAssertEqual(user.name,newInstance.name)
+            XCTAssertEqual(user.age,newInstance.age)
+            XCTAssertEqual(user.username,newInstance.username)
+            XCTAssertEqual(user.email,newInstance.email)
+            XCTAssertEqual(user.picture,newInstance.picture)
+            XCTAssertEqual(user.activated,newInstance.activated)
+            XCTAssertEqual(user.disabled,newInstance.disabled)
+            XCTAssertEqual(user.hasAsset,newInstance.hasAsset)
+        }
+    }
+}
\ No newline at end of file