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/02 17:06:32 UTC

[09/10] usergrid-dotnet git commit: Initial commit of Usergrid .NET SDK into its own rep

http://git-wip-us.apache.org/repos/asf/usergrid-dotnet/blob/94c0483c/Usergrid.Sdk.IntegrationTests/LoginTests.cs
----------------------------------------------------------------------
diff --git a/Usergrid.Sdk.IntegrationTests/LoginTests.cs b/Usergrid.Sdk.IntegrationTests/LoginTests.cs
new file mode 100644
index 0000000..ea2590c
--- /dev/null
+++ b/Usergrid.Sdk.IntegrationTests/LoginTests.cs
@@ -0,0 +1,96 @@
+\ufeff// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// 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.
+
+using NUnit.Framework;
+using Usergrid.Sdk.Model;
+
+namespace Usergrid.Sdk.IntegrationTests
+{
+    [TestFixture]
+    public class LoginTests : BaseTest
+    {
+        [Test]
+        public void ShouldLoginSuccessfullyWithClientCredentials()
+        {
+            var client = new Client(Organization, Application, ApiUri);
+            client.Login(ClientId, ClientSecret, AuthType.Organization);
+        }
+
+		[Test]
+		public void ShouldThrowWithInvalidOrganizationCredentials()
+		{
+			var client = new Client (Organization, Application, ApiUri);
+
+			try
+			{
+				client.Login("Invalid_User_Name", "Invalid_Password", AuthType.Organization);
+				Assert.True(true, "Was expecting login to throw UserGridException");
+			}
+			catch (UsergridException e)
+			{
+				Assert.That (e.Message, Is.EqualTo ("invalid username or password"));
+				Assert.That(e.ErrorCode, Is.EqualTo("invalid_grant"));
+			}
+		}
+
+		[Test]
+		public void ShouldLoginSuccessfullyWithApplicationCredentials()
+		{
+			var client = new Client(Organization, Application, ApiUri);
+			client.Login(ApplicationId, ApplicationSecret, AuthType.Application);
+		}
+
+		[Test]
+		public void ShouldThrowWithInvalidApplicationCredentials()
+		{
+			var client = new Client (Organization, Application, ApiUri);
+
+			try
+			{
+				client.Login("Invalid_User_Name", "Invalid_Password", AuthType.Application);
+				Assert.True(true, "Was expecting login to throw UserGridException");
+			}
+			catch (UsergridException e)
+			{
+				Assert.That (e.Message, Is.EqualTo ("invalid username or password"));
+				Assert.That(e.ErrorCode, Is.EqualTo("invalid_grant"));
+			}
+		}
+
+		[Test]
+		public void ShouldLoginSuccessfullyWithUserCredentials()
+		{
+			var client = new Client(Organization, Application, ApiUri);
+			client.Login(UserId, UserSecret, AuthType.User);
+		}
+
+        [Test]
+        public void ShouldThrowWithInvalidUserCredentials()
+        {
+            var client = new Client(Organization, Application, ApiUri);
+
+            try
+            {
+                client.Login("Invalid_User_Name", "Invalid_Password", AuthType.User);
+                Assert.True(true, "Was expecting login to throw UserGridException");
+            }
+            catch (UsergridException e)
+            {
+				Assert.That (e.Message, Is.EqualTo ("invalid username or password"));
+                Assert.That(e.ErrorCode, Is.EqualTo("invalid_grant"));
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/usergrid-dotnet/blob/94c0483c/Usergrid.Sdk.IntegrationTests/NotificationTests.cs
----------------------------------------------------------------------
diff --git a/Usergrid.Sdk.IntegrationTests/NotificationTests.cs b/Usergrid.Sdk.IntegrationTests/NotificationTests.cs
new file mode 100644
index 0000000..5c27546
--- /dev/null
+++ b/Usergrid.Sdk.IntegrationTests/NotificationTests.cs
@@ -0,0 +1,133 @@
+\ufeff// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// 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.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using NUnit.Framework;
+using Usergrid.Sdk.Model;
+
+namespace Usergrid.Sdk.IntegrationTests
+{
+    [TestFixture]
+    public class NotificationTests : BaseTest
+    {
+        [Test]
+        public void ShouldCreateNotifierForAndroid()
+        {
+            const string notifierName = "test_notifier";
+            var client = InitializeClientAndLogin(AuthType.Organization);
+            DeleteNotifierIfExists(client, notifierName);
+
+            client.CreateNotifierForAndroid(notifierName, GoogleApiKey /*e.g. AIzaSyCkXOtBQ7A9GoJsSLqZlod_YjEfxxxxxxx*/);
+
+            UsergridNotifier usergridNotifier = client.GetNotifier<UsergridNotifier>(notifierName);
+            Assert.That(usergridNotifier, Is.Not.Null);
+            Assert.That(usergridNotifier.Provider, Is.EqualTo("google"));
+            Assert.That(usergridNotifier.Name, Is.EqualTo(notifierName));
+        }
+
+        [Test]
+        public void ShouldCreateNotifierForApple()
+        {
+            const string notifierName = "test_notifier";
+            const string environment = "development";
+            var client = InitializeClientAndLogin(AuthType.Organization);
+            DeleteNotifierIfExists(client, notifierName);
+
+            client.CreateNotifierForApple(notifierName, environment, P12CertificatePath /*e.g. c:\temp\pushtest_dev.p12*/);
+
+            UsergridNotifier usergridNotifier = client.GetNotifier<UsergridNotifier>(notifierName);
+
+            Assert.That(usergridNotifier, Is.Not.Null);
+            Assert.That(usergridNotifier.Environment, Is.EqualTo(environment));
+            Assert.That(usergridNotifier.Provider, Is.EqualTo("apple"));
+            Assert.That(usergridNotifier.Name, Is.EqualTo(notifierName));
+        }
+
+        [Test]
+        public void ShouldPublishNotifications()
+        {
+            //Set up
+            const string appleNotifierName = "apple_notifier";
+            const string googleNotifierName = "google_notifier";
+            const string username = "NotificationTestUser";
+            const string appleTestMessge = "test message for Apple";
+            const string androidTestMessage = "test message for Android";
+
+            var client = InitializeClientAndLogin(AuthType.Organization);
+            CreateAppleNotifier(client,appleNotifierName);            
+            CreateAndroidNotifier(client,googleNotifierName);            
+            CreateUser(username, client);
+
+            //Setup Notifications
+            var appleNotification = new AppleNotification(appleNotifierName, appleTestMessge, "chime");
+            var googleNotification = new AndroidNotification(googleNotifierName, androidTestMessage);
+            //Setup recipients and scheduling
+            INotificationRecipients recipients = new NotificationRecipients().AddUserWithName(username);
+            var schedulerSettings = new NotificationSchedulerSettings {DeliverAt = DateTime.Now.AddDays(1)};
+
+            client.PublishNotification(new Notification[] {appleNotification, googleNotification}, recipients, schedulerSettings);
+
+            //Assert
+            UsergridCollection<dynamic> entities = client.GetEntities<dynamic>("notifications", query: "order by created desc");
+            dynamic notification = entities.FirstOrDefault();
+
+            Assert.IsNotNull(notification);
+            Assert.IsNotNull(notification.uuid);
+            Assert.AreEqual(appleTestMessge, notification.payloads.apple_notifier.aps.alert.Value);
+            Assert.AreEqual("chime", notification.payloads.apple_notifier.aps.sound.Value);
+            Assert.AreEqual(androidTestMessage, notification.payloads.google_notifier.data.Value);
+
+            //Cancel notification and assert it is canceled
+            client.CancelNotification(notification.uuid.Value);
+            dynamic entity = client.GetEntity<dynamic>("notifications", notification.uuid.Value);
+            Assert.AreEqual(entity.state.Value, "CANCELED");
+        }
+
+        private static void CreateUser(string username, IClient client)
+        {
+            var userEntity = new MyUsergridUser {UserName = username};
+            // See if this user exists
+            var userFromUsergrid = client.GetUser<UsergridUser>(username);
+            // Delete if exists
+            if (userFromUsergrid != null) {
+                client.DeleteUser(username);
+            }
+            // Now create the user
+            client.CreateUser(userEntity);
+        }
+
+
+        private void CreateAppleNotifier(IClient client, string notifierName)
+        {
+            DeleteNotifierIfExists(client, notifierName);
+            client.CreateNotifierForApple(notifierName, "development", base.P12CertificatePath);
+        }
+
+        private void CreateAndroidNotifier(IClient client, string notifierName)
+        {
+            DeleteNotifierIfExists(client, notifierName);
+            client.CreateNotifierForAndroid(notifierName, GoogleApiKey);
+        }
+        private static void DeleteNotifierIfExists(IClient client, string notifierName)
+        {
+            var usergridNotifier = client.GetNotifier<UsergridNotifier>(notifierName);
+            if (usergridNotifier != null)
+                client.DeleteNotifier(usergridNotifier.Uuid);
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/usergrid-dotnet/blob/94c0483c/Usergrid.Sdk.IntegrationTests/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/Usergrid.Sdk.IntegrationTests/Properties/AssemblyInfo.cs b/Usergrid.Sdk.IntegrationTests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..690e77a
--- /dev/null
+++ b/Usergrid.Sdk.IntegrationTests/Properties/AssemblyInfo.cs
@@ -0,0 +1,55 @@
+\ufeff// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// 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.
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyTitle("Usergrid.Sdk.IntegrationTests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("Usergrid.Sdk.IntegrationTests")]
+[assembly: AssemblyCopyright("Copyright � Microsoft 2013")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("4ea5bdce-1904-425c-bf6a-1a7fc05a4206")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+
+[assembly: AssemblyVersion("0.1.0.0")]
+[assembly: AssemblyFileVersion("0.1.0.0")]

http://git-wip-us.apache.org/repos/asf/usergrid-dotnet/blob/94c0483c/Usergrid.Sdk.IntegrationTests/UserManagementTests.cs
----------------------------------------------------------------------
diff --git a/Usergrid.Sdk.IntegrationTests/UserManagementTests.cs b/Usergrid.Sdk.IntegrationTests/UserManagementTests.cs
new file mode 100644
index 0000000..843e6f1
--- /dev/null
+++ b/Usergrid.Sdk.IntegrationTests/UserManagementTests.cs
@@ -0,0 +1,96 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// 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.
+
+using NUnit.Framework;
+using Newtonsoft.Json;
+using Usergrid.Sdk.Model;
+
+namespace Usergrid.Sdk.IntegrationTests
+{
+    public class MyUsergridUser : UsergridUser
+    {
+        [JsonProperty("city")]
+        public string City { get; set; }
+
+        [JsonProperty("password")]
+        public string Password { get; set; }
+    }
+
+    [TestFixture]
+    public class UserManagementTests : BaseTest
+    {
+        private IClient _client;
+        [SetUp]
+        public void Setup()
+        {
+            _client = InitializeClientAndLogin(AuthType.Organization);
+            DeleteUserIfExists(_client, "user1");
+        }
+
+        [Test]
+        public void ShouldChangePassword()
+        {
+            MyUsergridUser user = new MyUsergridUser { UserName = "user1", Password = "user1", Email = "user1@gmail.com", City = "city1" };
+            _client.CreateUser(user);
+
+            user = _client.GetUser<MyUsergridUser>("user1");
+            Assert.IsNotNull(user);
+
+            _client.Login("user1", "user1", AuthType.User);
+
+            _client.ChangePassword("user1", "user1", "user1-2");
+
+            _client.Login("user1", "user1-2", AuthType.User);
+        }
+
+        [Test]
+        public void ShouldCreateUser()
+        {
+            MyUsergridUser user = new MyUsergridUser { UserName = "user1", Password = "user1", Email = "user1@gmail.com", City = "city1" };
+            _client.CreateUser(user);
+            user = _client.GetUser<MyUsergridUser>("user1");
+
+            Assert.IsNotNull(user);
+            Assert.AreEqual("user1", user.UserName);
+            Assert.AreEqual("user1@gmail.com", user.Email);
+            Assert.AreEqual("city1", user.City);
+            Assert.IsNull(user.Password);
+
+            _client.DeleteUser("user1");
+        }
+
+        [Test]
+        public void ShouldUpdateUser()
+        {
+            var user = new MyUsergridUser {UserName = "user1", Password = "user1", Email = "user1@gmail.com", City = "city1"};
+                _client.CreateUser(user);
+                user = _client.GetUser<MyUsergridUser>("user1");
+
+            user.Email = "user-2@gmail.com";
+            user.City = "city1-2";
+            user.Password = "user1-2";
+            _client.UpdateUser(user);
+
+            user = _client.GetUser<MyUsergridUser>("user1");
+            Assert.IsNotNull(user);
+            Assert.AreEqual("user1", user.UserName);
+            Assert.AreEqual("user-2@gmail.com", user.Email);
+            Assert.AreEqual("city1-2", user.City);
+            Assert.IsNull(user.Password);
+
+            _client.DeleteUser("user1");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/usergrid-dotnet/blob/94c0483c/Usergrid.Sdk.IntegrationTests/Usergrid.Sdk.IntegrationTests.csproj
----------------------------------------------------------------------
diff --git a/Usergrid.Sdk.IntegrationTests/Usergrid.Sdk.IntegrationTests.csproj b/Usergrid.Sdk.IntegrationTests/Usergrid.Sdk.IntegrationTests.csproj
new file mode 100644
index 0000000..8efabfd
--- /dev/null
+++ b/Usergrid.Sdk.IntegrationTests/Usergrid.Sdk.IntegrationTests.csproj
@@ -0,0 +1,109 @@
+\ufeff<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ 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.
+-->
+
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{0278A0A4-F5E9-41F7-A86E-CD376D3FE5E2}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Usergrid.Sdk.IntegrationTests</RootNamespace>
+    <AssemblyName>Usergrid.Sdk.IntegrationTests</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="nunit.framework">
+      <HintPath>..\packages\NUnit.2.6.2\lib\nunit.framework.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Configuration" />
+    <Reference Include="Newtonsoft.Json">
+      <HintPath>..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll</HintPath>
+    </Reference>
+    <Reference Include="RestSharp">
+      <HintPath>..\packages\RestSharp.104.1\lib\net4\RestSharp.dll</HintPath>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ConnectionTests.cs" />
+    <Compile Include="DeviceTests.cs" />
+    <Compile Include="GroupTests.cs" />
+    <Compile Include="LoginTests.cs" />
+    <Compile Include="NotificationTests.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="UsergridFriend.cs" />
+    <Compile Include="UserManagementTests.cs" />
+    <Compile Include="BaseTest.cs" />
+    <Compile Include="EntityPagingTests.cs" />
+    <Compile Include="EntityCrudTests.cs" />
+    <Compile Include="Friend.cs" />
+    <Compile Include="ActivitiesTests.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+  <ItemGroup>
+    <Content Include="Usergrid.Sdk.IntegrationTests.dll.config">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Usergrid.Sdk\Usergrid.Sdk.csproj">
+      <Project>{437D108F-528C-4B2A-B399-06CF02DEB08B}</Project>
+      <Name>Usergrid.Sdk</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <PropertyGroup>
+    <PostBuildEvent>copy /y $(ProjectDir)MySettings.config $(ProjectDir)$(OutDir)</PostBuildEvent>
+  </PropertyGroup>
+</Project>

http://git-wip-us.apache.org/repos/asf/usergrid-dotnet/blob/94c0483c/Usergrid.Sdk.IntegrationTests/Usergrid.Sdk.IntegrationTests.dll.config
----------------------------------------------------------------------
diff --git a/Usergrid.Sdk.IntegrationTests/Usergrid.Sdk.IntegrationTests.dll.config b/Usergrid.Sdk.IntegrationTests/Usergrid.Sdk.IntegrationTests.dll.config
new file mode 100644
index 0000000..e8fd2e5
--- /dev/null
+++ b/Usergrid.Sdk.IntegrationTests/Usergrid.Sdk.IntegrationTests.dll.config
@@ -0,0 +1,33 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ 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.
+-->
+
+
+<configuration>
+	<appSettings>
+                <add key="apiUri" value="BASE_URI_OF_USERGRID_API" />
+		<add key="organization" value="ORGANIZATION_NAME" />
+		<add key="application" value="APPLICATION_NAME" />
+		<add key="clientId" value="CLIENT_ID" />
+		<add key="clientSecret" value="CLIENT_SECRET" />
+		<add key="applicationId" value="APPLICATION_ID" />
+		<add key="applicationSecret" value="APPLICATION_SECRET" />
+ 		<add key="userId" value="USER_ID" />
+		<add key="userSecret" value="USER_SECRET" />
+	    <add key="P12CertificatePath" value="C:\Path_to\certificate.p12" />
+		<add key="googleApiKey" value="AIzaSyBwPpMkW6FWW-XXXXXXXXXXXXX" />
+</appSettings>
+</configuration>

http://git-wip-us.apache.org/repos/asf/usergrid-dotnet/blob/94c0483c/Usergrid.Sdk.IntegrationTests/UsergridFriend.cs
----------------------------------------------------------------------
diff --git a/Usergrid.Sdk.IntegrationTests/UsergridFriend.cs b/Usergrid.Sdk.IntegrationTests/UsergridFriend.cs
new file mode 100644
index 0000000..d68003c
--- /dev/null
+++ b/Usergrid.Sdk.IntegrationTests/UsergridFriend.cs
@@ -0,0 +1,23 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// 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.
+
+using Usergrid.Sdk.Model;
+
+namespace Usergrid.Sdk.IntegrationTests {
+    public class UsergridFriend : UsergridEntity
+    {
+        public int Age { get; set; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/usergrid-dotnet/blob/94c0483c/Usergrid.Sdk.IntegrationTests/packages.config
----------------------------------------------------------------------
diff --git a/Usergrid.Sdk.IntegrationTests/packages.config b/Usergrid.Sdk.IntegrationTests/packages.config
new file mode 100644
index 0000000..f3b5dc9
--- /dev/null
+++ b/Usergrid.Sdk.IntegrationTests/packages.config
@@ -0,0 +1,24 @@
+\ufeff<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ 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.
+-->
+
+<packages>
+  <package id="Newtonsoft.Json" version="4.5.11" targetFramework="net40" />
+  <package id="NSubstitute" version="1.6.0.0" targetFramework="net40" />
+  <package id="NUnit" version="2.6.2" targetFramework="net40" />
+  <package id="RestSharp" version="104.1" targetFramework="net40" />
+</packages>

http://git-wip-us.apache.org/repos/asf/usergrid-dotnet/blob/94c0483c/Usergrid.Sdk.Tests/AuthenticationManagerTests.cs
----------------------------------------------------------------------
diff --git a/Usergrid.Sdk.Tests/AuthenticationManagerTests.cs b/Usergrid.Sdk.Tests/AuthenticationManagerTests.cs
new file mode 100644
index 0000000..ce79f23
--- /dev/null
+++ b/Usergrid.Sdk.Tests/AuthenticationManagerTests.cs
@@ -0,0 +1,135 @@
+\ufeff// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// 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.
+
+using System.Net;
+using NSubstitute;
+using NUnit.Framework;
+using RestSharp;
+using Usergrid.Sdk.Model;
+using Usergrid.Sdk.Payload;
+using AuthenticationManager = Usergrid.Sdk.Manager.AuthenticationManager;
+
+namespace Usergrid.Sdk.Tests
+{
+    [TestFixture]
+    public class AuthenticationManagerTests
+    {
+        [Test]
+        public void ShouldLoginWithClientCredentialsWithCorrectRequestBodyForAuthTypeClient()
+        {
+            IUsergridRequest request = Helpers.InitializeUserGridRequestWithAccessToken("accessToken");
+
+            const string clientLoginId = "login";
+            const string clientSecret = "secret";
+
+            var authenticationManager = new AuthenticationManager(request);
+            authenticationManager.Login(clientLoginId, clientSecret, AuthType.Organization);
+
+            request
+                .Received(1)
+                .ExecuteJsonRequest<LoginResponse>(
+                    Arg.Any<string>(),
+                    Arg.Any<Method>(),
+                    Arg.Is<ClientIdLoginPayload>(d => d.GrantType == "client_credentials" && d.ClientId == clientLoginId && d.ClientSecret == clientSecret));
+        }
+
+        [Test]
+        public void ShouldLoginWithClientCredentialsWithCorrectRequestBodyForAuthTypeApplication()
+        {
+            IUsergridRequest request = Helpers.InitializeUserGridRequestWithAccessToken("accessToken");
+
+            const string clientLoginId = "login";
+            const string clientSecret = "secret";
+
+            var authenticationManager = new AuthenticationManager(request);
+            authenticationManager.Login(clientLoginId, clientSecret, AuthType.Application);
+
+            request
+                .Received(1)
+                .ExecuteJsonRequest<LoginResponse>(
+                    Arg.Any<string>(),
+                    Arg.Any<Method>(),
+                    Arg.Is<ClientIdLoginPayload>(d => d.GrantType == "client_credentials" && d.ClientId == clientLoginId && d.ClientSecret == clientSecret));
+        }
+
+        [Test]
+        public void ShouldLoginWithUserCredentialsWithCorrectRequestBodyForAuthTypeUser()
+        {
+            IUsergridRequest request = Helpers.InitializeUserGridRequestWithAccessToken("accessToken");
+
+            const string clientLoginId = "login";
+            const string clientSecret = "secret";
+
+            var authenticationManager = new AuthenticationManager(request);
+            authenticationManager.Login(clientLoginId, clientSecret, AuthType.User);
+
+            request
+                .Received(1)
+                .ExecuteJsonRequest<LoginResponse>(
+                    Arg.Any<string>(),
+                    Arg.Any<Method>(),
+                    Arg.Is<UserLoginPayload>(d => d.GrantType == "password" && d.UserName == clientLoginId && d.Password == clientSecret));
+        }
+
+        [Test]
+        public void ShouldNotMakeACallToEndPointWhenLoggingWithAuthTypeNone()
+        {
+            var request = Substitute.For<IUsergridRequest>();
+
+            var authenticationManager = new AuthenticationManager(request);
+            authenticationManager.Login(null, null, AuthType.None);
+
+            request.DidNotReceiveWithAnyArgs().ExecuteJsonRequest<LoginResponse>(Arg.Any<string>(), Arg.Any<Method>(), Arg.Any<object>());
+        }
+
+        [Test]
+        [TestCase(null, AuthType.None)]
+        [TestCase("accessToken1", AuthType.Application)]
+        [TestCase("accessToken2", AuthType.Organization)]
+        [TestCase("accessToken4", AuthType.User)]
+        public void ShouldSetTheAccessToken(string accessToken, AuthType authType)
+        {
+            IUsergridRequest request = Helpers.InitializeUserGridRequestWithAccessToken(accessToken);
+
+            var authenticationManager = new AuthenticationManager(request);
+            authenticationManager.Login(null, null, authType);
+
+            request.Received(1).AccessToken = accessToken;
+        }
+
+        [Test]
+        public void ShouldTranslateToUserGridErrorAndThrowWhenServiceReturnsBadRequest()
+        {
+            const string invalidUsernameOrPassword = "Invalid username or password";
+            const string invalidGrant = "invalid_grant";
+
+            var restResponseContent = new UsergridError {Description = invalidUsernameOrPassword, Error = invalidGrant};
+            var restResponse = Helpers.SetUpRestResponseWithContent<LoginResponse>(HttpStatusCode.BadRequest, restResponseContent);
+            var request = Helpers.SetUpUsergridRequestWithRestResponse(restResponse);
+
+            var authenticationManager = new AuthenticationManager(request);
+            try
+            {
+                authenticationManager.Login(null, null, AuthType.Organization);
+                throw new AssertionException("UserGridException was expected to be thrown here");
+            }
+            catch (UsergridException e)
+            {
+                Assert.AreEqual(invalidGrant, e.ErrorCode);
+                Assert.AreEqual(invalidUsernameOrPassword, e.Message);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/usergrid-dotnet/blob/94c0483c/Usergrid.Sdk.Tests/ClientTests/ActivityTests.cs
----------------------------------------------------------------------
diff --git a/Usergrid.Sdk.Tests/ClientTests/ActivityTests.cs b/Usergrid.Sdk.Tests/ClientTests/ActivityTests.cs
new file mode 100644
index 0000000..5cec130
--- /dev/null
+++ b/Usergrid.Sdk.Tests/ClientTests/ActivityTests.cs
@@ -0,0 +1,86 @@
+\ufeff// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// 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.
+
+using NSubstitute;
+using NUnit.Framework;
+using Usergrid.Sdk.Manager;
+using Usergrid.Sdk.Model;
+
+namespace Usergrid.Sdk.Tests.ClientTests
+{
+    [TestFixture]
+    public class ActivityTests
+    {
+        #region Setup/Teardown
+
+        [SetUp]
+        public void Setup()
+        {
+            _entityManager = Substitute.For<IEntityManager>();
+            _client = new Client(null, null) {EntityManager = _entityManager};
+        }
+
+        #endregion
+
+        private IEntityManager _entityManager;
+        private IClient _client;
+
+        [Test]
+        public void GetGroupActivitiesShouldDelegateToEntityManagerWithCorrectEndpoint()
+        {
+            _client.GetGroupActivities<UsergridActivity>("groupIdentifier");
+
+            _entityManager.Received(1).GetEntities<UsergridActivity>("/groups/groupIdentifier/activities");
+        }
+
+        [Test]
+        public void GetUserActivitiesShouldDelegateToEntityManagerWithCorrectEndpoint()
+        {
+            _client.GetUserActivities<UsergridActivity>("userIdentifier");
+
+            _entityManager.Received(1).GetEntities<UsergridActivity>("/users/userIdentifier/activities");
+        }
+
+        [Test]
+        public void PostActivityShouldDelegateToEntityManagerWithCorrectEndpoint()
+        {
+            var usergridActivity = new UsergridActivity();
+
+            _client.PostActivity("userIdentifier", usergridActivity);
+
+            _entityManager.Received(1).CreateEntity("/users/userIdentifier/activities", usergridActivity);
+        }
+
+        [Test]
+        public void PostActivityToGroupShouldDelegateToEntityManagerWithCorrectEndpoint()
+        {
+            var usergridActivity = new UsergridActivity();
+
+            _client.PostActivityToGroup("groupIdentifier", usergridActivity);
+
+            _entityManager.Received(1).CreateEntity("/groups/groupIdentifier/activities", usergridActivity);
+        }
+
+        [Test]
+        public void PostActivityToUsersFollowersInGroupShouldDelegateToEntityManagerWithCorrectEndpoint()
+        {
+            var usergridActivity = new UsergridActivity();
+
+            _client.PostActivityToUsersFollowersInGroup("userIdentifier", "groupIdentifier", usergridActivity);
+
+            _entityManager.Received(1).CreateEntity("/groups/groupIdentifier/users/userIdentifier/activities", usergridActivity);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/usergrid-dotnet/blob/94c0483c/Usergrid.Sdk.Tests/ClientTests/ConnectionTests.cs
----------------------------------------------------------------------
diff --git a/Usergrid.Sdk.Tests/ClientTests/ConnectionTests.cs b/Usergrid.Sdk.Tests/ClientTests/ConnectionTests.cs
new file mode 100644
index 0000000..6fe0721
--- /dev/null
+++ b/Usergrid.Sdk.Tests/ClientTests/ConnectionTests.cs
@@ -0,0 +1,88 @@
+\ufeff// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// 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.
+
+
+using System.Collections.Generic;
+using NSubstitute;
+using NUnit.Framework;
+using Usergrid.Sdk.Manager;
+using Usergrid.Sdk.Model;
+
+namespace Usergrid.Sdk.Tests.ClientTests
+{
+    [TestFixture]
+    public class ConnectionTests
+    {
+        #region Setup/Teardown
+
+        [SetUp]
+        public void Setup()
+        {
+            _connectionManager = Substitute.For<IConnectionManager>();
+            _client = new Client(null, null) {ConnectionManager = _connectionManager};
+        }
+
+        #endregion
+
+        private IConnectionManager _connectionManager;
+        private IClient _client;
+
+        [Test]
+        public void CreateConnectionShouldDelegateToConnectionManagerWithCorrectParameters()
+        {
+            var connection = new Connection();
+            _client.CreateConnection(connection);
+
+            _connectionManager.Received(1).CreateConnection(connection);
+        }
+
+        [Test]
+        public void DeleteConnectionsShouldDelegateToConnectionManagerWithCorrectParameters()
+        {
+            var connection = new Connection();
+
+            _client.DeleteConnection(connection);
+
+            _connectionManager.Received(1).DeleteConnection(connection);
+        }
+
+        [Test]
+        public void GetConnectionsOfSpecificTypeShouldDelegateToConnectionManagerWithCorrectParameters()
+        {
+            var connection = new Connection();
+            var enityList = new List<UsergridEntity>();
+
+            _connectionManager.GetConnections<UsergridEntity>(connection).Returns(enityList);
+
+            IList<UsergridEntity> returnedEntityList = _client.GetConnections<UsergridEntity>(connection);
+
+            _connectionManager.Received(1).GetConnections<UsergridEntity>(connection);
+            Assert.AreEqual(enityList, returnedEntityList);
+        }
+
+        [Test]
+        public void GetConnectionsShouldDelegateToConnectionManagerWithCorrectParameters()
+        {
+            var connection = new Connection();
+            var enityList = new List<UsergridEntity>();
+            _connectionManager.GetConnections(connection).Returns(enityList);
+
+            IList<UsergridEntity> returnedEntityList = _client.GetConnections(connection);
+
+            _connectionManager.Received(1).GetConnections(connection);
+            Assert.AreEqual(enityList, returnedEntityList);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/usergrid-dotnet/blob/94c0483c/Usergrid.Sdk.Tests/ClientTests/DeviceTests.cs
----------------------------------------------------------------------
diff --git a/Usergrid.Sdk.Tests/ClientTests/DeviceTests.cs b/Usergrid.Sdk.Tests/ClientTests/DeviceTests.cs
new file mode 100644
index 0000000..17307d3
--- /dev/null
+++ b/Usergrid.Sdk.Tests/ClientTests/DeviceTests.cs
@@ -0,0 +1,143 @@
+\ufeff// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// 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.
+
+using NSubstitute;
+using NUnit.Framework;
+using Usergrid.Sdk.Manager;
+using Usergrid.Sdk.Model;
+
+namespace Usergrid.Sdk.Tests.ClientTests
+{
+    [TestFixture]
+    public class DeviceTests
+    {
+        #region Setup/Teardown
+
+        [SetUp]
+        public void Setup()
+        {
+            _entityManager = Substitute.For<IEntityManager>();
+            _client = new Client(null, null) {EntityManager = _entityManager};
+        }
+
+        #endregion
+
+        private IEntityManager _entityManager;
+        private IClient _client;
+
+        [Test]
+        public void CreateDeviceShouldDelegateToEntityManagerWithCorrectCollectionNameAndDevice()
+        {
+            var device = new UsergridDevice();
+
+            _client.CreateDevice(device);
+
+            _entityManager.Received(1).CreateEntity("devices", device);
+        }
+
+        [Test]
+        [ExpectedException(ExpectedException = typeof (UsergridException), ExpectedMessage = "Exception message")]
+        public void CreateDeviceShouldPassOnTheException()
+        {
+            _entityManager
+                .When(m => m.CreateEntity("devices", Arg.Any<UsergridDevice>()))
+                .Do(m => { throw new UsergridException(new UsergridError {Description = "Exception message"}); });
+
+            _client.CreateDevice<UsergridDevice>(null);
+        }
+
+        [Test]
+        public void DeleteDeviceShouldDelegateToEntityManagerrWithCorrectCollectionNameAndIdentfier()
+        {
+            _client.DeleteDevice("deviceName");
+
+            _entityManager.Received(1).DeleteEntity("devices", "deviceName");
+        }
+
+        [Test]
+        [ExpectedException(ExpectedException = typeof (UsergridException), ExpectedMessage = "Exception message")]
+        public void DeleteDeviceShouldPassOnTheException()
+        {
+            _entityManager
+                .When(m => m.DeleteEntity("devices", Arg.Any<string>()))
+                .Do(m => { throw new UsergridException(new UsergridError {Description = "Exception message"}); });
+
+            _client.DeleteDevice(null);
+        }
+
+        [Test]
+        public void GetDeviceShouldDelegateToEntityManagerWithCorrectCollectionNameAndIdentifier()
+        {
+            _client.GetDevice<UsergridDevice>("identifier");
+
+            _entityManager.Received(1).GetEntity<UsergridDevice>("devices", "identifier");
+        }
+
+        [Test]
+        [ExpectedException(ExpectedException = typeof (UsergridException), ExpectedMessage = "Exception message")]
+        public void GetDeviceShouldPassOnTheException()
+        {
+            _entityManager
+                .When(m => m.GetEntity<UsergridDevice>("devices", Arg.Any<string>()))
+                .Do(m => { throw new UsergridException(new UsergridError {Description = "Exception message"}); });
+
+            _client.GetDevice<UsergridDevice>(null);
+        }
+
+        [Test]
+        public void GetDeviceShouldReturnNullForUnexistingDevice()
+        {
+            _entityManager.GetEntity<UsergridDevice>("devices", "identifier").Returns(x => null);
+
+            var usergridDevice = _client.GetDevice<UsergridDevice>("identifier");
+
+            Assert.IsNull(usergridDevice);
+        }
+
+        [Test]
+        public void GetDeviceShouldReturnUsergridDevice()
+        {
+            var usergridDevice = new UsergridDevice();
+            _entityManager.GetEntity<UsergridDevice>("devices", "identifier").Returns(x => usergridDevice);
+
+            var returnedDevice = _client.GetDevice<UsergridDevice>("identifier");
+
+            Assert.AreEqual(usergridDevice, returnedDevice);
+        }
+
+        [Test]
+        public void UpdateDeviceShouldDelegateToEntityManagerrWithCorrectCollectionNameAndDeviceNameAsTheIdentifier()
+        {
+            var device = new UsergridDevice {Name = "deviceName"};
+
+            _client.UpdateDevice(device);
+
+            _entityManager.Received(1).UpdateEntity("devices", device.Name, device);
+        }
+
+        [Test]
+        [ExpectedException(ExpectedException = typeof (UsergridException), ExpectedMessage = "Exception message")]
+        public void UpdateDeviceShouldPassOnTheException()
+        {
+            var device = new UsergridDevice {Name = "deviceName"};
+
+            _entityManager
+                .When(m => m.UpdateEntity("devices", device.Name, device))
+                .Do(m => { throw new UsergridException(new UsergridError {Description = "Exception message"}); });
+
+            _client.UpdateDevice(device);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/usergrid-dotnet/blob/94c0483c/Usergrid.Sdk.Tests/ClientTests/EntityTests.cs
----------------------------------------------------------------------
diff --git a/Usergrid.Sdk.Tests/ClientTests/EntityTests.cs b/Usergrid.Sdk.Tests/ClientTests/EntityTests.cs
new file mode 100644
index 0000000..bf9511d
--- /dev/null
+++ b/Usergrid.Sdk.Tests/ClientTests/EntityTests.cs
@@ -0,0 +1,210 @@
+\ufeff// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// 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.
+
+
+using NSubstitute;
+using NUnit.Framework;
+using Usergrid.Sdk.Manager;
+using Usergrid.Sdk.Model;
+
+namespace Usergrid.Sdk.Tests.ClientTests
+{
+    [TestFixture]
+    public class EntityTests
+    {
+        #region Setup/Teardown
+
+        [SetUp]
+        public void Setup()
+        {
+            _entityManager = Substitute.For<IEntityManager>();
+            _client = new Client(null, null) {EntityManager = _entityManager};
+        }
+
+        #endregion
+
+        private IEntityManager _entityManager;
+        private IClient _client;
+
+
+        [Test]
+        public void CreateEntityShouldDelegateToEntityManagerWithCorrectParameters()
+        {
+            var entity = new {Name = "test"};
+
+            _client.CreateEntity<object>("collection", entity);
+
+            _entityManager.Received(1).CreateEntity<object>("collection", entity);
+        }
+
+        [Test]
+        [ExpectedException(ExpectedException = typeof (UsergridException), ExpectedMessage = "Exception message")]
+        public void CreateEntityShouldPassOnTheException()
+        {
+            _entityManager
+                .When(m => m.CreateEntity(Arg.Any<string>(), Arg.Any<object>()))
+                .Do(m => { throw new UsergridException(new UsergridError {Description = "Exception message"}); });
+
+            _client.CreateEntity<object>(null, null);
+        }
+
+        [Test]
+        public void CreateEntityShouldReturnUserGridEntity()
+        {
+            var entity = new object();
+            _entityManager.CreateEntity("collection", entity).ReturnsForAnyArgs(entity);
+
+            var returnedEntity = _client.CreateEntity("collection", entity);
+
+            Assert.AreEqual(entity, returnedEntity);
+        }
+
+        [Test]
+        public void DeleteEntityShouldDelegateToEntityManagerWithCorrectParameters()
+        {
+            _client.DeleteEntity("collection", "identifier");
+
+            _entityManager.Received(1).DeleteEntity("collection", "identifier");
+        }
+
+        [Test]
+        [ExpectedException(ExpectedException = typeof (UsergridException), ExpectedMessage = "Exception message")]
+        public void DeleteEntityShouldPassOnTheException()
+        {
+            _entityManager
+                .When(m => m.DeleteEntity(Arg.Any<string>(), Arg.Any<string>()))
+                .Do(m => { throw new UsergridException(new UsergridError {Description = "Exception message"}); });
+
+            _client.DeleteEntity(null, null);
+        }
+
+        [Test]
+        public void GetEntitiesShouldDefaultTheLimit()
+        {
+            _client.GetEntities<object>("collection");
+
+            _entityManager.Received(1).GetEntities<object>("collection", 10);
+        }
+
+        [Test]
+        public void GetEntitiesShouldDefaultTheQueryToNull()
+        {
+            _client.GetEntities<object>("collection", 10);
+
+            _entityManager.Received(1).GetEntities<object>("collection", 10, null);
+        }
+
+        [Test]
+        public void GetEntitiesShouldDelegateToEntityManagerWithCorrectParameters()
+        {
+            _client.GetEntities<object>("collection", 20, "query");
+
+            _entityManager.Received(1).GetEntities<object>("collection", 20, "query");
+        }
+
+        [Test]
+        public void GetEntityShouldDelegateToEntityManagerWithCorrectParameters()
+        {
+            _client.GetEntity<object>("collection", "identifier");
+
+            _entityManager.Received(1).GetEntity<object>("collection", "identifier");
+        }
+
+        [Test]
+        [ExpectedException(ExpectedException = typeof (UsergridException), ExpectedMessage = "Exception message")]
+        public void GetEntityShouldPassOnTheException()
+        {
+            _entityManager
+                .When(m => m.GetEntity<object>(Arg.Any<string>(), Arg.Any<string>()))
+                .Do(m => { throw new UsergridException(new UsergridError {Description = "Exception message"}); });
+
+            _client.GetEntity<object>(null, null);
+        }
+
+        [Test]
+        public void GetEntityShouldReturnEntityFromEntityManager()
+        {
+            var entity = new object();
+            _entityManager.GetEntity<object>("collection", "identifier").ReturnsForAnyArgs(entity);
+
+            object createdEntity = _client.GetEntity<object>("collection", "identifier");
+
+            Assert.AreEqual(entity, createdEntity);
+        }
+
+        [Test]
+        public void GetEntityShouldReturnNullForUnexistingEntity()
+        {
+            _entityManager.GetEntity<UsergridEntity>("collection", "identifier").Returns(x => null);
+
+            var usergridEntity = _client.GetEntity<UsergridDevice>("collection", "identifier");
+
+            Assert.IsNull(usergridEntity);
+        }
+
+        [Test]
+        public void GetNextEntitiesShouldDefaultTheQueryToNull()
+        {
+            _client.GetNextEntities<object>("collection");
+
+            _entityManager.Received(1).GetNextEntities<object>("collection", null);
+        }
+
+        [Test]
+        public void GetNextEntitiesShouldDelegateToEntityManagerWithCorrectParameters()
+        {
+            _client.GetNextEntities<object>("collection", "query");
+
+            _entityManager.Received(1).GetNextEntities<object>("collection", "query");
+        }
+
+        [Test]
+        public void GetPreviousEntitiesShouldDefaultTheQueryToNull()
+        {
+            _client.GetPreviousEntities<object>("collection");
+
+            _entityManager.Received(1).GetPreviousEntities<object>("collection", null);
+        }
+
+        [Test]
+        public void GetPreviousEntitiesShouldDelegateToEntityManagerWithCorrectParameters()
+        {
+            _client.GetPreviousEntities<object>("collection", "query");
+
+            _entityManager.Received(1).GetPreviousEntities<object>("collection", "query");
+        }
+
+        [Test]
+        public void UpdateEntityShouldDelegateToEntityManagerWithCorrectParameters()
+        {
+            var entity = new {Name = "test"};
+
+            _client.UpdateEntity<object>("collection", "identifier", entity);
+
+            _entityManager.Received(1).UpdateEntity<object>("collection", "identifier", entity);
+        }
+
+        [Test]
+        [ExpectedException(ExpectedException = typeof (UsergridException), ExpectedMessage = "Exception message")]
+        public void UpdateEntityShouldPassOnTheException()
+        {
+            _entityManager
+                .When(m => m.UpdateEntity(Arg.Any<string>(), Arg.Any<string>(), Arg.Any<object>()))
+                .Do(m => { throw new UsergridException(new UsergridError {Description = "Exception message"}); });
+
+            _client.UpdateEntity<object>(null, null, null);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/usergrid-dotnet/blob/94c0483c/Usergrid.Sdk.Tests/ClientTests/FeedTests.cs
----------------------------------------------------------------------
diff --git a/Usergrid.Sdk.Tests/ClientTests/FeedTests.cs b/Usergrid.Sdk.Tests/ClientTests/FeedTests.cs
new file mode 100644
index 0000000..048e121
--- /dev/null
+++ b/Usergrid.Sdk.Tests/ClientTests/FeedTests.cs
@@ -0,0 +1,65 @@
+\ufeff// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// 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.
+
+
+using NSubstitute;
+using NUnit.Framework;
+using Usergrid.Sdk.Manager;
+using Usergrid.Sdk.Model;
+
+namespace Usergrid.Sdk.Tests.ClientTests
+{
+    [TestFixture]
+    public class FeedTests
+    {
+        #region Setup/Teardown
+
+        [SetUp]
+        public void Setup()
+        {
+            _entityManager = Substitute.For<IEntityManager>();
+            _client = new Client(null, null) {EntityManager = _entityManager};
+        }
+
+        #endregion
+
+        private IEntityManager _entityManager;
+        private IClient _client;
+
+        [Test]
+        public void GetGroupFeedShouldDelegateToEntityManagerWithCorrectEndpoint()
+        {
+            var usergridActivities = new UsergridCollection<UsergridActivity>();
+            _entityManager.GetEntities<UsergridActivity>("/groups/groupIdentifier/feed").Returns(usergridActivities);
+
+            UsergridCollection<UsergridActivity> returnedActivities = _client.GetGroupFeed<UsergridActivity>("groupIdentifier");
+
+            _entityManager.Received(1).GetEntities<UsergridActivity>("/groups/groupIdentifier/feed");
+            Assert.AreEqual(usergridActivities, returnedActivities);
+        }
+
+        [Test]
+        public void GetUserFeedShouldDelegateToEntityManagerWithCorrectEndpoint()
+        {
+            var usergridActivities = new UsergridCollection<UsergridActivity>();
+            _entityManager.GetEntities<UsergridActivity>("/users/userIdentifier/feed").Returns(usergridActivities);
+
+            UsergridCollection<UsergridActivity> returnedActivities = _client.GetUserFeed<UsergridActivity>("userIdentifier");
+
+            _entityManager.Received(1).GetEntities<UsergridActivity>("/users/userIdentifier/feed");
+            Assert.AreEqual(usergridActivities, returnedActivities);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/usergrid-dotnet/blob/94c0483c/Usergrid.Sdk.Tests/ClientTests/GroupTests.cs
----------------------------------------------------------------------
diff --git a/Usergrid.Sdk.Tests/ClientTests/GroupTests.cs b/Usergrid.Sdk.Tests/ClientTests/GroupTests.cs
new file mode 100644
index 0000000..5b9347e
--- /dev/null
+++ b/Usergrid.Sdk.Tests/ClientTests/GroupTests.cs
@@ -0,0 +1,199 @@
+\ufeff// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// 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.
+
+using System;
+using System.Collections.Generic;
+using System.Net;
+using NSubstitute;
+using NUnit.Framework;
+using RestSharp;
+using Usergrid.Sdk.Manager;
+using Usergrid.Sdk.Model;
+using Usergrid.Sdk.Payload;
+
+namespace Usergrid.Sdk.Tests.ClientTests
+{
+    [TestFixture]
+    public class GroupTests
+    {
+        [SetUp]
+        public void Setup()
+        {
+            _entityManager = Substitute.For<IEntityManager>();
+            _request = Substitute.For<IUsergridRequest>();
+            _client = new Client(null, null, request: _request) {EntityManager = _entityManager};
+        }
+
+        private IEntityManager _entityManager;
+        private IClient _client;
+        private IUsergridRequest _request;
+
+        [Test]
+        public void AddUserToGroupShouldDelegateToEntityManagerrWithCorrectConnectionAndIdentifiers()
+        {
+            _client.AddUserToGroup("groupIdentifier", "userIdentifier");
+
+            _entityManager.Received(1).CreateEntity<object>("/groups/groupIdentifier/users/userIdentifier", null);
+        }
+
+        [Test]
+        public void CreateGroupShouldDelegateToEntityManagerWithCorrectCollectionNameAndUser()
+        {
+            var group = new UsergridGroup();
+
+            _client.CreateGroup(group);
+
+            _entityManager.Received(1).CreateEntity("groups", group);
+        }
+
+        [Test]
+        [ExpectedException(ExpectedException = typeof (UsergridException), ExpectedMessage = "Exception message")]
+        public void CreateGroupShouldPassOnTheException()
+        {
+            _entityManager
+                .When(m => m.CreateEntity("groups", Arg.Any<UsergridGroup>()))
+                .Do(m => { throw new UsergridException(new UsergridError {Description = "Exception message"}); });
+
+            _client.CreateGroup<UsergridGroup>(null);
+        }
+
+        [Test]
+        public void DeleteGroupShouldDelegateToEntityManagerrWithCorrectCollectionNameAndIdentfier()
+        {
+            _client.DeleteGroup("groupPath");
+
+            _entityManager.Received(1).DeleteEntity("groups", "groupPath");
+        }
+
+        [Test]
+        [ExpectedException(ExpectedException = typeof (UsergridException), ExpectedMessage = "Exception message")]
+        public void DeleteGroupShouldPassOnTheException()
+        {
+            _entityManager
+                .When(m => m.DeleteEntity("groups", Arg.Any<string>()))
+                .Do(m => { throw new UsergridException(new UsergridError {Description = "Exception message"}); });
+
+            _client.DeleteGroup(null);
+        }
+
+        [Test]
+        public void DeleteUserFromGroupShouldDelegateToEntityManagerrWithCorrectConnectionAndIdentifier()
+        {
+            _client.DeleteUserFromGroup("groupIdentifier", "userIdentifier");
+
+            _entityManager.Received(1).DeleteEntity("/groups/groupIdentifier/users", "userIdentifier");
+        }
+
+        [Test]
+        public void GetGroupShouldDelegateToEntityManagerWithCorrectCollectionNameAndIdentifier()
+        {
+            _client.GetGroup<UsergridGroup>("identifier");
+
+            _entityManager.Received(1).GetEntity<UsergridGroup>("groups", "identifier");
+        }
+
+        [Test]
+        [ExpectedException(ExpectedException = typeof (UsergridException), ExpectedMessage = "Exception message")]
+        public void GetGroupShouldPassOnTheException()
+        {
+            _entityManager
+                .When(m => m.GetEntity<UsergridGroup>("groups", Arg.Any<string>()))
+                .Do(m => { throw new UsergridException(new UsergridError {Description = "Exception message"}); });
+
+            _client.GetGroup<UsergridGroup>(null);
+        }
+
+        [Test]
+        public void GetGroupShouldReturnNullForUnexistingGroup()
+        {
+            _entityManager.GetEntity<UsergridUser>("groups", "identifier").Returns(x => null);
+
+            var usergridGroup = _client.GetGroup<UsergridGroup>("identifier");
+
+            Assert.IsNull(usergridGroup);
+        }
+
+        [Test]
+        public void GetGroupShouldReturnUsergridGroup()
+        {
+            var usergridGroup = new UsergridGroup();
+            _entityManager.GetEntity<UsergridGroup>("groups", "identifier").Returns(x => usergridGroup);
+
+            var returnedGroup = _client.GetGroup<UsergridGroup>("identifier");
+
+            Assert.AreEqual(usergridGroup, returnedGroup);
+        }
+
+        [Test]
+        public void UpdateGroupShouldDelegateToEntityManagerrWithCorrectCollectionNameAndGroupPathAsTheIdentifier()
+        {
+            var group = new UsergridGroup {Path = "groupPath"};
+
+            _client.UpdateGroup(group);
+
+            _entityManager.Received(1).UpdateEntity("groups", group.Path, group);
+        }
+
+        [Test]
+        [ExpectedException(ExpectedException = typeof (UsergridException), ExpectedMessage = "Exception message")]
+        public void UpdateGroupShouldPassOnTheException()
+        {
+            var group = new UsergridGroup {Path = "groupPath"};
+
+            _entityManager
+                .When(m => m.UpdateEntity("groups", group.Path, group))
+                .Do(m => { throw new UsergridException(new UsergridError {Description = "Exception message"}); });
+
+            _client.UpdateGroup(group);
+        }
+
+        [Test]
+        public void GetAllUsersInGroupShouldGetAllUsersInGroup()
+        {
+            var expectedUserList = new List<UsergridUser>() {new UsergridUser() {UserName = "userName", Name = "user1"}};
+            var responseContent = new UsergridGetResponse<UsergridUser>() {Entities = expectedUserList};
+            var restResponse = Helpers.SetUpRestResponseWithContent<UsergridGetResponse<UsergridUser>>(HttpStatusCode.OK, responseContent);
+            
+            _request.ExecuteJsonRequest("/groups/groupName/users", Method.GET).Returns(restResponse);
+
+            var returnedUsers = _client.GetAllUsersInGroup<UsergridUser>("groupName");
+
+            _request.Received(1).ExecuteJsonRequest("/groups/groupName/users", Method.GET);
+            Assert.AreEqual(1, returnedUsers.Count);
+            Assert.AreEqual("userName", returnedUsers[0].UserName);
+            Assert.AreEqual("user1", returnedUsers[0].Name);
+        }
+
+        [Test]
+        public void GetAllUsersInGroupWillThrowWhenBadRequest()
+        {
+            UsergridError error = new UsergridError() {Description = "exception description", Error = "error code"};
+            var restResponse = Helpers.SetUpRestResponseWithContent<UsergridError>(HttpStatusCode.BadRequest, error);
+            
+            _request.ExecuteJsonRequest("/groups/groupName/users", Method.GET).Returns(restResponse);
+
+            try
+            {
+                _client.GetAllUsersInGroup<UsergridUser>("groupName");
+                Assert.Fail("Was expecting Usergrid exception to be thrown.");
+            }
+            catch (UsergridException e)
+            {
+                Assert.AreEqual(error.Description, e.Message);
+                Assert.AreEqual(error.Error, e.ErrorCode);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/usergrid-dotnet/blob/94c0483c/Usergrid.Sdk.Tests/ClientTests/LoginTests.cs
----------------------------------------------------------------------
diff --git a/Usergrid.Sdk.Tests/ClientTests/LoginTests.cs b/Usergrid.Sdk.Tests/ClientTests/LoginTests.cs
new file mode 100644
index 0000000..6094162
--- /dev/null
+++ b/Usergrid.Sdk.Tests/ClientTests/LoginTests.cs
@@ -0,0 +1,67 @@
+\ufeff// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// 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.
+
+using NSubstitute;
+using NUnit.Framework;
+using Usergrid.Sdk.Manager;
+using Usergrid.Sdk.Model;
+
+namespace Usergrid.Sdk.Tests.ClientTests
+{
+    [TestFixture]
+    public class LoginTests
+    {
+        [TestCase("login1", "secret1", AuthType.Application)]
+        [TestCase("login2", "secret2", AuthType.Organization)]
+        [TestCase("login3", "secret3", AuthType.None)]
+        [TestCase("login4", "secret4", AuthType.User)]
+        public void LoginShouldDelegateToAuthenticationManagerWithCorrectParameters(string login, string secret, AuthType authType)
+        {
+            var authenticationManager = Substitute.For<IAuthenticationManager>();
+
+            var client = new Client(null, null) {AuthenticationManager = authenticationManager};
+
+            client.Login(login, secret, authType);
+
+            authenticationManager.Received(1).Login(login, secret, authType);
+        }
+
+        [Test]
+        public void LoginShouldDelegateToAuthenticationManager()
+        {
+            var authenticationManager = Substitute.For<IAuthenticationManager>();
+
+            var client = new Client(null, null) {AuthenticationManager = authenticationManager};
+
+            client.Login(null, null, AuthType.None);
+
+            authenticationManager.Received(1).Login(null, null, AuthType.None);
+        }
+
+        [Test]
+        [ExpectedException(ExpectedException = typeof (UsergridException), ExpectedMessage = "Exception message")]
+        public void LoginShouldPassOnTheException()
+        {
+            var authenticationManager = Substitute.For<IAuthenticationManager>();
+            authenticationManager
+                .When(m => m.Login(null, null, AuthType.None))
+                .Do(m => { throw new UsergridException(new UsergridError {Description = "Exception message"}); });
+
+
+            var client = new Client(null, null) {AuthenticationManager = authenticationManager};
+            client.Login(null, null, AuthType.None);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/usergrid-dotnet/blob/94c0483c/Usergrid.Sdk.Tests/ClientTests/NotificationTests.cs
----------------------------------------------------------------------
diff --git a/Usergrid.Sdk.Tests/ClientTests/NotificationTests.cs b/Usergrid.Sdk.Tests/ClientTests/NotificationTests.cs
new file mode 100644
index 0000000..7f9a5fe
--- /dev/null
+++ b/Usergrid.Sdk.Tests/ClientTests/NotificationTests.cs
@@ -0,0 +1,149 @@
+\ufeff// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// 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.
+
+using System;
+using NSubstitute;
+using NUnit.Framework;
+using Usergrid.Sdk.Manager;
+using Usergrid.Sdk.Model;
+using Usergrid.Sdk.Payload;
+
+namespace Usergrid.Sdk.Tests.ClientTests
+{
+    [TestFixture]
+    public class NotificationTests
+    {
+        #region Setup/Teardown
+
+        [SetUp]
+        public void Setup()
+        {
+            _notificationsManager = Substitute.For<INotificationsManager>();
+            _entityManager = Substitute.For<IEntityManager>();
+            _client = new Client(null, null) {NotificationsManager = _notificationsManager, EntityManager = _entityManager};
+        }
+
+        #endregion
+
+        private INotificationsManager _notificationsManager;
+        private IEntityManager _entityManager;
+        private IClient _client;
+
+        [Test]
+        public void CancelNotificationShouldDelegateToEntityManagerWithCorrectParameters()
+        {
+            _client.CancelNotification("notificationIdentifier");
+
+            _entityManager.Received(1).UpdateEntity("/notifications", "notificationIdentifier", Arg.Is<CancelNotificationPayload>(p => p.Canceled));
+        }
+
+        [Test]
+        public void CreateNotifierForAndroidShouldDelegateToNotificationsManager()
+        {
+            _client.CreateNotifierForAndroid("notifierName", "apiKey");
+
+            _notificationsManager.Received(1).CreateNotifierForAndroid("notifierName", "apiKey");
+        }
+
+        [Test]
+        [ExpectedException(ExpectedException = typeof (UsergridException), ExpectedMessage = "Exception message")]
+        public void CreateNotifierForAndroidShouldPassOnTheException()
+        {
+            _notificationsManager
+                .When(m => m.CreateNotifierForAndroid(Arg.Any<string>(), Arg.Any<string>()))
+                .Do(m => { throw new UsergridException(new UsergridError {Description = "Exception message"}); });
+
+            _client.CreateNotifierForAndroid(null, null);
+        }
+
+        [Test]
+        public void CreateNotifierForAppleShouldDelegateToNotificationsManager()
+        {
+            _client.CreateNotifierForApple("notifierName", "development", "certificateFilePath");
+
+            _notificationsManager.Received(1).CreateNotifierForApple("notifierName", "development", "certificateFilePath");
+        }
+
+        [Test]
+        [ExpectedException(ExpectedException = typeof (UsergridException), ExpectedMessage = "Exception message")]
+        public void CreateNotifierForAppleShouldPassOnTheException()
+        {
+            _notificationsManager
+                .When(m => m.CreateNotifierForApple(Arg.Any<string>(), Arg.Any<string>(), Arg.Any<string>()))
+                .Do(m => { throw new UsergridException(new UsergridError {Description = "Exception message"}); });
+
+            _client.CreateNotifierForApple(null, null, null);
+        }
+
+        [Test]
+        public void DeleteNotifierShouldDelegateToEntityManagerWithCorrectParameters()
+        {
+            _client.DeleteNotifier("notifierIdentifier");
+
+            _entityManager.Received(1).DeleteEntity("/notifiers", "notifierIdentifier");
+        }
+
+        [Test]
+        public void GetNotifierShouldDelegateToEntityManagerWithCorrectParameters()
+        {
+            _client.GetNotifier<UsergridNotifier>("notifierIdentifier");
+
+            _entityManager.Received(1).GetEntity<UsergridNotifier>("/notifiers", "notifierIdentifier");
+        }
+
+        [Test]
+        [ExpectedException(ExpectedException = typeof (UsergridException), ExpectedMessage = "Exception message")]
+        public void GetNotifierShouldPassOnTheException()
+        {
+            _entityManager
+                .When(m => m.GetEntity<UsergridNotifier>(Arg.Any<string>(), Arg.Any<string>()))
+                .Do(m => { throw new UsergridException(new UsergridError {Description = "Exception message"}); });
+
+            _client.GetNotifier<UsergridNotifier>(null);
+        }
+
+        [Test]
+        public void GetNotifierShouldReturnNullForUnexistingNotifier()
+        {
+            _entityManager.GetEntity<UsergridNotifier>("/notifiers", "notifierIdentifier").Returns(x => null);
+
+            var returnedEntity = _client.GetNotifier<UsergridNotifier>("notifierIdentifier");
+
+            Assert.IsNull(returnedEntity);
+        }
+
+        [Test]
+        public void GetNotifierShouldReturnUsergridNotifierFromEntityManager() {
+            var entity = new UsergridNotifier();
+            _entityManager.GetEntity<UsergridNotifier>("/notifiers", "notifierIdentifier").Returns(x => entity);
+
+            var returnedEntity = _client.GetNotifier<UsergridNotifier>("notifierIdentifier");
+
+            Assert.AreEqual(entity, returnedEntity);
+        }
+
+        [Test]
+        public void PublishNotificationShouldDelegateToNotificationsManagerWithCorrectParameters()
+        {
+            var notifications = new Notification[] {new AppleNotification("notifierName", "message", "chime")};
+            INotificationRecipients recipients = new NotificationRecipients().AddUserWithName("username");
+            var schedulerSettings = new NotificationSchedulerSettings {DeliverAt = DateTime.Now.AddDays(1)};
+
+            _client.PublishNotification(notifications, recipients, schedulerSettings);
+
+            _notificationsManager.Received(1).PublishNotification(notifications, recipients, schedulerSettings);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/usergrid-dotnet/blob/94c0483c/Usergrid.Sdk.Tests/ClientTests/UserTests.cs
----------------------------------------------------------------------
diff --git a/Usergrid.Sdk.Tests/ClientTests/UserTests.cs b/Usergrid.Sdk.Tests/ClientTests/UserTests.cs
new file mode 100644
index 0000000..447a3bb
--- /dev/null
+++ b/Usergrid.Sdk.Tests/ClientTests/UserTests.cs
@@ -0,0 +1,153 @@
+\ufeff// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// 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.
+
+using NSubstitute;
+using NUnit.Framework;
+using Usergrid.Sdk.Manager;
+using Usergrid.Sdk.Model;
+
+namespace Usergrid.Sdk.Tests.ClientTests
+{
+    [TestFixture]
+    public class UserTests
+    {
+        #region Setup/Teardown
+
+        [SetUp]
+        public void Setup()
+        {
+            _entityManager = Substitute.For<IEntityManager>();
+            _authenticationManager = Substitute.For<IAuthenticationManager>();
+            _client = new Client(null, null) {EntityManager = _entityManager, AuthenticationManager = _authenticationManager};
+        }
+
+        #endregion
+
+        private IEntityManager _entityManager;
+        private IAuthenticationManager _authenticationManager;
+        private IClient _client;
+
+        [Test]
+        public void ChangePasswordShouldDelegateToAuthenticationManager()
+        {
+            _client.ChangePassword("userName", "oldPassword", "newPassword");
+
+            _authenticationManager.Received(1).ChangePassword("userName", "oldPassword", "newPassword");
+        }
+
+        [Test]
+        public void CreateUserShouldDelegateToEntityManagerWithCorrectCollectionNameAndUser()
+        {
+            var user = new UsergridUser();
+
+            _client.CreateUser(user);
+
+            _entityManager.Received(1).CreateEntity("users", user);
+        }
+
+        [Test]
+        [ExpectedException(ExpectedException = typeof (UsergridException), ExpectedMessage = "Exception message")]
+        public void CreateUserShouldPassOnTheException()
+        {
+            _entityManager
+                .When(m => m.CreateEntity("users", Arg.Any<UsergridUser>()))
+                .Do(m => { throw new UsergridException(new UsergridError {Description = "Exception message"}); });
+
+            _client.CreateUser<UsergridUser>(null);
+        }
+
+        [Test]
+        public void DeleteUserShouldDelegateToEntityManagerrWithCorrectCollectionNameAndIdentfier()
+        {
+            _client.DeleteUser("userName");
+
+            _entityManager.Received(1).DeleteEntity("users", "userName");
+        }
+
+        [Test]
+        [ExpectedException(ExpectedException = typeof (UsergridException), ExpectedMessage = "Exception message")]
+        public void DeleteUserShouldPassOnTheException()
+        {
+            _entityManager
+                .When(m => m.DeleteEntity("users", Arg.Any<string>()))
+                .Do(m => { throw new UsergridException(new UsergridError {Description = "Exception message"}); });
+
+            _client.DeleteUser(null);
+        }
+
+        [Test]
+        public void GetUserShouldDelegateToEntityManagerWithCorrectCollectionNameAndIdentifier()
+        {
+            _client.GetUser<UsergridUser>("identifier");
+
+            _entityManager.Received(1).GetEntity<UsergridUser>("users", "identifier");
+        }
+
+        [Test]
+        [ExpectedException(ExpectedException = typeof (UsergridException), ExpectedMessage = "Exception message")]
+        public void GetUserShouldPassOnTheException()
+        {
+            _entityManager
+                .When(m => m.GetEntity<UsergridUser>("users", Arg.Any<string>()))
+                .Do(m => { throw new UsergridException(new UsergridError {Description = "Exception message"}); });
+
+            _client.GetUser<UsergridUser>(null);
+        }
+
+        [Test]
+        public void GetUserShouldReturnNullForUnexistingUser()
+        {
+            _entityManager.GetEntity<UsergridUser>("users", "identifier").Returns((x) => null);
+
+            var usergridUser = _client.GetUser<UsergridUser>("identifier");
+
+            Assert.IsNull(usergridUser);
+        }
+
+        [Test]
+        public void GetUserShouldReturnUsergridUser()
+        {
+            var usergridUser = new UsergridUser();
+            _entityManager.GetEntity<UsergridUser>("users", "identifier").Returns((x) => usergridUser);
+
+            var returnedUser = _client.GetUser<UsergridUser>("identifier");
+
+            Assert.AreEqual(usergridUser, returnedUser);
+        }
+
+        [Test]
+        public void UpdateUserShouldDelegateToEntityManagerrWithCorrectCollectionNameAndUserNameAsTheIdentifier()
+        {
+            var user = new UsergridUser {UserName = "userName"};
+
+            _client.UpdateUser(user);
+
+            _entityManager.Received(1).UpdateEntity("users", user.UserName, user);
+        }
+
+        [Test]
+        [ExpectedException(ExpectedException = typeof (UsergridException), ExpectedMessage = "Exception message")]
+        public void UpdateUserShouldPassOnTheException()
+        {
+            var user = new UsergridUser {UserName = "userName"};
+
+            _entityManager
+                .When(m => m.UpdateEntity("users", user.UserName, user))
+                .Do(m => { throw new UsergridException(new UsergridError {Description = "Exception message"}); });
+
+            _client.UpdateUser(user);
+        }
+    }
+}