You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by ro...@apache.org on 2014/11/13 02:09:12 UTC

[4/8] incubator-usergrid git commit: organized rest IT

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/3993f081/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/RetrieveUsersTest.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/RetrieveUsersTest.java b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/RetrieveUsersTest.java
new file mode 100644
index 0000000..da7d59e
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/RetrieveUsersTest.java
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+package org.apache.usergrid.rest.applications.collection.users;
+
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import java.io.IOException;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.usergrid.rest.AbstractRestIT;
+import org.apache.usergrid.rest.TestContextSetup;
+import org.apache.usergrid.rest.test.resource.CustomCollection;
+
+import static org.junit.Assert.assertEquals;
+
+
+/**
+ * // TODO: Document this
+ *
+ * @author ApigeeCorporation
+ * @since 4.0
+ */
+public class RetrieveUsersTest extends AbstractRestIT {
+    private static final Logger log = LoggerFactory.getLogger( RetrieveUsersTest.class );
+
+    @Rule
+    public TestContextSetup context = new TestContextSetup( this );
+
+
+    @Test // USERGRID-1222
+    public void queryForUsername() throws IOException {
+        CustomCollection users = context.collection( "users" );
+
+        Map props = new HashMap();
+
+        props.put( "username", "Alica" );
+        users.create( props );
+
+        props.put( "username", "Bob" );
+        users.create( props );
+
+        refreshIndex(context.getOrgName(), context.getAppName());
+
+        String query = "select *";
+        String incorrectQuery = "select * where username = 'Alica'";
+
+        assertEquals( users.entityValue( query, "username", 0 ), users.entityValue( incorrectQuery, "username", 0 ) );
+    }
+
+
+    @Test // USERGRID-1727
+    public void userEntityDictionaryHasRoles() throws IOException {
+        CustomCollection users = context.collection( "users" );
+
+        Map props = new HashMap();
+        props.put( "username", "Nina" );
+
+        JsonNode response = users.create( props );
+        refreshIndex(context.getOrgName(), context.getAppName());
+
+        JsonNode entity = response.get( "entities" ).get( 0 );
+        JsonNode metadata = entity.get( "metadata" );
+        JsonNode sets = metadata.get( "sets" );
+        JsonNode rolenames = sets.get( "rolenames" );
+        Assert.assertTrue( "rolenames URL ends with /roles", rolenames.asText().endsWith( "/roles" ) );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/3993f081/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/UserResourceIT.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/UserResourceIT.java b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/UserResourceIT.java
new file mode 100644
index 0000000..43e2b4f
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/UserResourceIT.java
@@ -0,0 +1,1418 @@
+/*
+ * 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.
+ */
+package org.apache.usergrid.rest.applications.collection.users;
+
+
+import com.fasterxml.jackson.databind.JsonNode;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.ws.rs.core.MediaType;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.usergrid.java.client.Client.Query;
+import org.apache.usergrid.java.client.entities.Activity;
+import org.apache.usergrid.java.client.entities.Activity.ActivityObject;
+import org.apache.usergrid.java.client.entities.Entity;
+import org.apache.usergrid.java.client.entities.User;
+import org.apache.usergrid.java.client.response.ApiResponse;
+
+import org.apache.usergrid.cassandra.Concurrent;
+import org.apache.usergrid.management.ApplicationInfo;
+import org.apache.usergrid.management.OrganizationInfo;
+import org.apache.usergrid.rest.AbstractRestIT;
+import org.apache.usergrid.rest.applications.utils.UserRepo;
+import org.apache.usergrid.utils.UUIDUtils;
+
+import com.sun.jersey.api.client.ClientResponse.Status;
+import com.sun.jersey.api.client.UniformInterfaceException;
+import java.io.IOException;
+
+import static org.apache.usergrid.rest.applications.utils.TestUtils.getIdFromSearchResults;
+import static org.apache.usergrid.utils.MapUtils.hashMap;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+
+/**
+ * @author zznate
+ * @author tnine
+ */
+@Concurrent()
+public class UserResourceIT extends AbstractRestIT {
+
+    private static Logger log = LoggerFactory.getLogger( UserResourceIT.class );
+
+
+    @Test
+    public void usernameQuery() throws IOException {
+
+        UserRepo.INSTANCE.load( resource(), access_token );
+        refreshIndex("test-organization", "test-app");
+
+        String ql = "username = 'unq_user*'";
+
+        JsonNode node = mapper.readTree( resource().path( "/test-organization/test-app/users" ).queryParam( "ql", ql )
+                                  .queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                                  .type( MediaType.APPLICATION_JSON_TYPE ).get( String.class ));
+
+        assertEquals( UserRepo.INSTANCE.getByUserName( "unq_user1" ), getIdFromSearchResults( node, 0 ) );
+        assertEquals( UserRepo.INSTANCE.getByUserName( "unq_user2" ), getIdFromSearchResults( node, 1 ) );
+        assertEquals( UserRepo.INSTANCE.getByUserName( "unq_user3" ), getIdFromSearchResults( node, 2 ) );
+    }
+
+
+    @Test
+    public void nameQuery() throws IOException {
+
+        UserRepo.INSTANCE.load( resource(), access_token );
+        refreshIndex("test-organization", "test-app");
+
+        String ql = "name = 'John*'";
+
+        JsonNode node = mapper.readTree( resource().path( "/test-organization/test-app/users" ).queryParam( "ql", ql )
+                                  .queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                                  .type( MediaType.APPLICATION_JSON_TYPE ).get( String.class ));
+
+        assertEquals( UserRepo.INSTANCE.getByUserName( "user2" ), getIdFromSearchResults( node, 0 ) );
+        assertEquals( UserRepo.INSTANCE.getByUserName( "user3" ), getIdFromSearchResults( node, 1 ) );
+    }
+
+
+    @Test
+    public void nameQueryByUUIDs() throws Exception {
+        UserRepo.INSTANCE.load( resource(), access_token );
+        refreshIndex("test-organization", "test-app");
+
+        String ql = "select uuid name = 'John*'";
+
+        ApplicationInfo appInfo = setup.getMgmtSvc().getApplicationInfo( "test-organization/test-app" );
+        OrganizationInfo orgInfo = setup.getMgmtSvc().getOrganizationByName( "test-organization" );
+
+        resource().path( "/" + orgInfo.getUuid() + "/" + appInfo.getId() + "/users" ).queryParam( "ql", ql )
+                  .queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                  .type( MediaType.APPLICATION_JSON_TYPE ).get( String.class );
+    }
+
+
+    @Test
+    public void nameFullTextQuery() throws IOException {
+
+        UserRepo.INSTANCE.load( resource(), access_token );
+        refreshIndex("test-organization", "test-app");
+
+        String ql = "name contains 'Smith' order by name ";
+
+        JsonNode node = mapper.readTree( resource().path( "/test-organization/test-app/users" ).queryParam( "ql", ql )
+                                  .queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                                  .type( MediaType.APPLICATION_JSON_TYPE ).get( String.class ));
+
+        assertEquals( UserRepo.INSTANCE.getByUserName( "user1" ), getIdFromSearchResults( node, 0 ) );
+        assertEquals( UserRepo.INSTANCE.getByUserName( "user2" ), getIdFromSearchResults( node, 1 ) );
+        assertEquals( UserRepo.INSTANCE.getByUserName( "user3" ), getIdFromSearchResults( node, 2 ) );
+    }
+
+
+    /**
+     * Tests that when a full text index is run on a field that isn't full text indexed an error is thrown
+     */
+    @Ignore("No longer relevant because all text fields are full-text indexed with Core Persistence")
+    @Test(expected = UniformInterfaceException.class)
+    public void fullTextQueryNotFullTextIndexed() throws IOException {
+
+        UserRepo.INSTANCE.load( resource(), access_token );
+        refreshIndex("test-organization", "test-app");
+
+        String ql = "username contains 'user' ";
+
+        resource().path( "/test-organization/test-app/users" ).queryParam( "ql", ql )
+                  .queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                  .type( MediaType.APPLICATION_JSON_TYPE ).get( String.class );
+    }
+
+
+    /**
+     * Tests that when a full text index is run on a field that isn't full text indexed an error is thrown
+     */
+    @Ignore("This test is being ignored as users ")
+    @Test(expected = UniformInterfaceException.class)
+    public void fullQueryNotIndexed() throws IOException {
+
+        UserRepo.INSTANCE.load( resource(), access_token );
+        refreshIndex("test-organization", "test-app");
+
+        String ql = "picture = 'foo' ";
+
+        resource().path( "/test-organization/test-app/users" ).queryParam( "ql", ql )
+                  .queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                  .type( MediaType.APPLICATION_JSON_TYPE ).get( String.class );
+    }
+
+
+    /**
+     * Test that when activity is pushed with not actor, it's set to the user who created it
+     */
+    @Test
+    public void emtpyActorActivity() throws IOException {
+        UserRepo.INSTANCE.load( resource(), access_token );
+        UUID userId = UserRepo.INSTANCE.getByUserName( "user1" );
+        refreshIndex("test-organization", "test-app");
+
+        Activity activity = new Activity();
+        activity.setProperty( "email", "rod@rodsimpson.com" );
+        activity.setProperty( "verb", "POST" );
+        activity.setProperty( "content", "Look! more new content" );
+
+        ApiResponse response = client.postUserActivity( userId.toString(), activity );
+
+        assertNull( "Error was: " + response.getErrorDescription(), response.getError() );
+
+        Entity entity = response.getEntities().get( 0 );
+
+        UUID activityId = entity.getUuid();
+
+        assertNotNull( activityId );
+
+        JsonNode actor = getActor( entity );
+
+        UUID actorId = UUIDUtils.tryGetUUID( actor.get( "uuid" ).textValue() );
+
+        assertEquals( userId, actorId );
+
+        assertEquals( "user1@apigee.com", actor.get( "email" ).asText() );
+    }
+
+
+    /**
+     * Insert the uuid and email if they're empty in the request
+     */
+    @Test
+    public void noUUIDorEmail() throws IOException {
+
+        UserRepo.INSTANCE.load( resource(), access_token );
+        refreshIndex("test-organization", "test-app");
+
+        UUID userId = UserRepo.INSTANCE.getByUserName( "user1" );
+
+        Activity activity = new Activity();
+        activity.setProperty( "email", "rod@rodsimpson.com" );
+        activity.setProperty( "verb", "POST" );
+        activity.setProperty( "content", "Look! more new content" );
+
+        // same as above, but with actor partially filled out
+
+        ActivityObject actorPost = new ActivityObject();
+        actorPost.setDisplayName( "Dino" );
+
+        activity.setActor( actorPost );
+
+        ApiResponse response = client.postUserActivity( userId.toString(), activity );
+
+        assertNull( "Error was: " + response.getErrorDescription(), response.getError() );
+
+        Entity entity = response.getEntities().get( 0 );
+
+        UUID activityId = entity.getUuid();
+
+        assertNotNull( activityId );
+
+        JsonNode actor = getActor( entity );
+
+        UUID actorId = UUIDUtils.tryGetUUID( actor.get( "uuid" ).textValue() );
+
+        assertEquals( userId, actorId );
+
+        assertEquals( "user1@apigee.com", actor.get( "email" ).asText() );
+    }
+
+
+    /**
+     * Don't touch the UUID when it's already set in the JSON
+     */
+    @Test
+    public void ignoreUUIDandEmail() throws IOException {
+        UserRepo.INSTANCE.load( resource(), access_token );
+        UUID userId = UserRepo.INSTANCE.getByUserName( "user1" );
+        refreshIndex("test-organization", "test-app");
+
+        UUID testUUID = UUIDUtils.newTimeUUID();
+        String testEmail = "foo@bar.com";
+
+        // same as above, but with actor partially filled out
+        Activity activity = new Activity();
+        activity.setProperty( "email", "rod@rodsimpson.com" );
+        activity.setProperty( "verb", "POST" );
+        activity.setProperty( "content", "Look! more new content" );
+
+        // same as above, but with actor partially filled out
+
+        ActivityObject actorPost = new ActivityObject();
+        actorPost.setDisplayName( "Dino" );
+        actorPost.setUuid( testUUID );
+        actorPost.setDynamicProperty( "email", testEmail );
+
+        activity.setActor( actorPost );
+
+        ApiResponse response = client.postUserActivity( userId.toString(), activity );
+
+        assertNull( "Error was: " + response.getErrorDescription(), response.getError() );
+
+        Entity entity = response.getEntities().get( 0 );
+
+        UUID activityId = entity.getUuid();
+
+        assertNotNull( activityId );
+
+        JsonNode actor = getActor( entity );
+
+        UUID actorId = UUIDUtils.tryGetUUID( actor.get( "uuid" ).textValue() );
+
+        assertEquals( testUUID, actorId );
+
+        assertEquals( testEmail, actor.get( "email" ).asText() );
+    }
+
+
+    /**
+     * Test that when activity is pushed with not actor, it's set to the user who created it
+     */
+    @Test
+    public void userActivitiesDefaultOrder() throws IOException {
+        UserRepo.INSTANCE.load( resource(), access_token );
+        UUID userId = UserRepo.INSTANCE.getByUserName( "user1" );
+        refreshIndex("test-organization", "test-app");
+
+        Activity activity = new Activity();
+        activity.setProperty( "email", "rod@rodsimpson.com" );
+        activity.setProperty( "verb", "POST" );
+        activity.setProperty( "content", "activity 1" );
+
+        ApiResponse response = client.postUserActivity( userId.toString(), activity );
+
+        assertNull( "Error was: " + response.getErrorDescription(), response.getError() );
+
+        refreshIndex("test-organization", "test-app");
+
+        Entity entity = response.getFirstEntity();
+
+        UUID firstActivityId = entity.getUuid();
+
+        activity = new Activity();
+        activity.setProperty( "email", "rod@rodsimpson.com" );
+        activity.setProperty( "verb", "POST" );
+        activity.setProperty( "content", "activity 2" );
+
+        response = client.postUserActivity( userId.toString(), activity );
+
+        assertNull( "Error was: " + response.getErrorDescription(), response.getError() );
+
+        refreshIndex("test-organization", "test-app");
+
+        entity = response.getFirstEntity();
+
+        UUID secondActivityId = entity.getUuid();
+
+        Query query = client.queryActivity();
+
+        entity = query.getResponse().getEntities().get( 0 );
+
+        assertEquals( secondActivityId, entity.getUuid() );
+
+        entity = query.getResponse().getEntities().get( 1 );
+
+        assertEquals( firstActivityId, entity.getUuid() );
+    }
+
+
+    @Test
+    public void getUserWIthEmailUsername() throws IOException {
+        UUID id = UUIDUtils.newTimeUUID();
+
+        String username = "username-email" + "@usergrid.org";
+        String name = "name" + id;
+        String email = "email" + id + "@usergrid.org";
+
+        ApiResponse response = client.createUser( username, name, email, "password" );
+        assertNull( "Error was: " + response.getErrorDescription(), response.getError() );
+
+        refreshIndex("test-organization", "test-app");
+
+        Entity userEntity = response.getEntities().get( 0 );
+
+        // get the user with username property that has an email value
+        JsonNode node = mapper.readTree( resource().path( "/test-organization/test-app/users/" + username )
+                                  .queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                                  .type( MediaType.APPLICATION_JSON_TYPE ).get( String.class ));
+
+        assertEquals( username, node.get( "entities" ).get( 0 ).get( "username" ).asText() );
+        assertEquals( name, node.get( "entities" ).get( 0 ).get( "name" ).asText() );
+        assertEquals( email, node.get( "entities" ).get( 0 ).get( "email" ).asText() );
+
+        // get the user with email property value
+        node = mapper.readTree( resource().path( "/test-organization/test-app/users/" + email )
+                         .queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                         .type( MediaType.APPLICATION_JSON_TYPE ).get( String.class ));
+
+        assertEquals( username, node.get( "entities" ).get( 0 ).get( "username" ).asText() );
+        assertEquals( name, node.get( "entities" ).get( 0 ).get( "name" ).asText() );
+        assertEquals( email, node.get( "entities" ).get( 0 ).get( "email" ).asText() );
+    }
+
+
+    /**
+     * Tests that when querying all users, we get the same result size when using "order by"
+     */
+    @Test
+    public void resultSizeSame() throws IOException {
+        UserRepo.INSTANCE.load( resource(), access_token );
+
+        refreshIndex("test-organization", "test-app");
+
+        UUID userId1 = UserRepo.INSTANCE.getByUserName( "user1" );
+        UUID userId2 = UserRepo.INSTANCE.getByUserName( "user2" );
+        UUID userId3 = UserRepo.INSTANCE.getByUserName( "user3" );
+
+        Query query = client.queryUsers();
+
+        ApiResponse response = query.getResponse();
+
+        assertNull( "Error was: " + response.getErrorDescription(), response.getError() );
+
+        int nonOrderedSize = response.getEntities().size();
+
+        query = client.queryUsers( "order by username" );
+
+        response = query.getResponse();
+
+        int orderedSize = response.getEntities().size();
+
+        assertEquals( "Sizes match", nonOrderedSize, orderedSize );
+
+        int firstEntityIndex = getEntityIndex( userId1, response );
+
+        int secondEntityIndex = getEntityIndex( userId2, response );
+
+        int thirdEntityIndex = getEntityIndex( userId3, response );
+
+        assertTrue( "Ordered correctly", firstEntityIndex < secondEntityIndex );
+
+        assertTrue( "Ordered correctly", secondEntityIndex < thirdEntityIndex );
+    }
+
+
+    private int getEntityIndex( UUID entityId, ApiResponse response ) {
+        List<Entity> entities = response.getEntities();
+
+        for ( int i = 0; i < entities.size(); i++ ) {
+            if ( entityId.equals( entities.get( i ).getUuid() ) ) {
+                return i;
+            }
+        }
+
+        return -1;
+    }
+
+
+    @Test
+    public void clientNameQuery() {
+
+        UUID id = UUIDUtils.newTimeUUID();
+
+        String username = "username" + id;
+        String name = "name" + id;
+
+        ApiResponse response = client.createUser( username, name, id + "@usergrid.org", "password" );
+        assertNull( "Error was: " + response.getErrorDescription(), response.getError() );
+        refreshIndex("test-organization", "test-app");
+
+        UUID createdId = response.getEntities().get( 0 ).getUuid();
+
+        Query results = client.queryUsers( String.format( "name = '%s'", name ) );
+        User user = results.getResponse().getEntities( User.class ).get( 0 );
+
+        assertEquals( createdId, user.getUuid() );
+    }
+
+
+    @Test
+    public void deleteUser() throws IOException  {
+
+        UUID id = UUIDUtils.newTimeUUID();
+
+        String username = "username" + id;
+        String name = "name" + id;
+
+        ApiResponse response = client.createUser( username, name, id + "@usergrid.org", "password" );
+        assertNull( "Error was: " + response.getErrorDescription(), response.getError() );
+        refreshIndex("test-organization", "test-app");
+
+        UUID createdId = response.getEntities().get( 0 ).getUuid();
+
+        JsonNode node = mapper.readTree( resource().path( "/test-organization/test-app/users/" + createdId )
+                                  .queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                                  .type( MediaType.APPLICATION_JSON_TYPE ).delete( String.class ));
+
+        assertNull( node.get( "errors" ) );
+
+        Query results = client.queryUsers( String.format( "username = '%s'", name ) );
+        assertEquals( 0, results.getResponse().getEntities( User.class ).size() );
+
+        // now create that same user again, it should work
+        response = client.createUser( username, name, id + "@usergrid.org", "password" );
+        assertNull( "Error was: " + response.getErrorDescription(), response.getError() );
+        refreshIndex("test-organization", "test-app");
+
+        createdId = response.getEntities().get( 0 ).getUuid();
+
+        assertNotNull( createdId );
+    }
+
+
+    @Test
+    public void singularCollectionName() throws IOException {
+        UUID id = UUIDUtils.newTimeUUID();
+
+        String username = "username1" + id;
+        String name = "name1" + id;
+        String email = "email1" + id + "@usergrid.org";
+
+        ApiResponse response = client.createUser( username, name, email, "password" );
+        assertNull( "Error was: " + response.getErrorDescription(), response.getError() );
+        refreshIndex("test-organization", "test-app");
+
+        UUID firstCreatedId = response.getEntities().get( 0 ).getUuid();
+
+        username = "username2" + id;
+        name = "name2" + id;
+        email = "email2" + id + "@usergrid.org";
+
+        response = client.createUser( username, name, email, "password" );
+        assertNull( "Error was: " + response.getErrorDescription(), response.getError() );
+        refreshIndex("test-organization", "test-app");
+
+        UUID secondCreatedId = response.getEntities().get( 0 ).getUuid();
+
+        // now create a connection of "likes" between the first user and the
+        // second using pluralized form
+
+        // plural collection name
+        String path = String.format( "/test-organization/test-app/users/%s/conn1/%s", firstCreatedId, secondCreatedId );
+
+        JsonNode node = mapper.readTree( resource().path( path ).queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                          .type( MediaType.APPLICATION_JSON_TYPE ).post( String.class ));
+
+        assertEquals( secondCreatedId.toString(), getEntity( node, 0 ).get( "uuid" ).asText() );
+
+        refreshIndex("test-organization", "test-app");
+
+        // singular collection name
+        path = String.format( "/test-organization/test-app/user/%s/conn2/%s", firstCreatedId, secondCreatedId );
+
+        node = mapper.readTree( resource().path( path ).queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                         .type( MediaType.APPLICATION_JSON_TYPE ).post( String.class ));
+
+        assertEquals( secondCreatedId.toString(), getEntity( node, 0 ).get( "uuid" ).asText() );
+
+        refreshIndex("test-organization", "test-app");
+
+        path = String.format( "/test-organization/test-app/users/%s/conn1", firstCreatedId );
+
+        node = mapper.readTree( resource().path( path ).queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                         .type( MediaType.APPLICATION_JSON_TYPE ).get( String.class ));
+
+        assertEquals( secondCreatedId.toString(), getEntity( node, 0 ).get( "uuid" ).asText() );
+
+        path = String.format( "/test-organization/test-app/user/%s/conn1", firstCreatedId );
+
+        node = mapper.readTree( resource().path( path ).queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                         .type( MediaType.APPLICATION_JSON_TYPE ).get( String.class ));
+
+        assertEquals( secondCreatedId.toString(), getEntity( node, 0 ).get( "uuid" ).asText() );
+
+        path = String.format( "/test-organization/test-app/users/%s/conn2", firstCreatedId );
+
+        node = mapper.readTree( resource().path( path ).queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                         .type( MediaType.APPLICATION_JSON_TYPE ).get( String.class ));
+
+        assertEquals( secondCreatedId.toString(), getEntity( node, 0 ).get( "uuid" ).asText() );
+
+        path = String.format( "/test-organization/test-app/user/%s/conn2", firstCreatedId );
+
+        node = mapper.readTree( resource().path( path ).queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                         .type( MediaType.APPLICATION_JSON_TYPE ).get( String.class ));
+
+        assertEquals( secondCreatedId.toString(), getEntity( node, 0 ).get( "uuid" ).asText() );
+    }
+
+
+    @Test
+    public void connectionByNameAndType() throws IOException {
+        UUID id = UUIDUtils.newTimeUUID();
+
+        String username1 = "username1" + id;
+        String name1 = "name1" + id;
+        String email1 = "email1" + id + "@usergrid.org";
+
+        ApiResponse response = client.createUser( username1, name1, email1, "password" );
+        assertNull( "Error was: " + response.getErrorDescription(), response.getError() );
+        refreshIndex("test-organization", "test-app");
+
+        UUID firstCreatedId = response.getEntities().get( 0 ).getUuid();
+
+        String username2 = "username2" + id;
+        String name2 = "name2" + id;
+        String email2 = "email2" + id + "@usergrid.org";
+
+        response = client.createUser( username2, name2, email2, "password" );
+        assertNull( "Error was: " + response.getErrorDescription(), response.getError() );
+        refreshIndex("test-organization", "test-app");
+
+        UUID secondCreatedId = response.getEntities().get( 0 ).getUuid();
+
+        // now create a connection of "likes" between the first user and the
+        // second using pluralized form
+
+        // named entity in collection name
+        String path = String.format( "/test-organization/test-app/users/%s/conn1/users/%s", firstCreatedId, username2 );
+
+        JsonNode node = mapper.readTree( resource().path( path ).queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                          .type( MediaType.APPLICATION_JSON_TYPE ).post( String.class ));
+
+        assertEquals( secondCreatedId.toString(), getEntity( node, 0 ).get( "uuid" ).asText() );
+
+        // named entity in collection name
+        path = String.format( "/test-organization/test-app/users/%s/conn2/users/%s", username1, username2 );
+
+        node = mapper.readTree( resource().path( path ).queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                         .type( MediaType.APPLICATION_JSON_TYPE ).post( String.class ));
+
+        assertEquals( secondCreatedId.toString(), getEntity( node, 0 ).get( "uuid" ).asText() );
+    }
+
+
+    /**
+     * Usergrid-1222 test
+     */
+    @Test
+    public void connectionQuerybyEmail() throws IOException {
+        UUID id = UUIDUtils.newTimeUUID();
+
+        String name = "name1" + id;
+        String email = "email1" + id + "@usergrid.org";
+
+        ApiResponse response = client.createUser( email, name, email, "password" );
+        assertNull( "Error was: " + response.getErrorDescription(), response.getError() );
+        refreshIndex("test-organization", "test-app");
+
+        UUID userId = response.getEntities().get( 0 ).getUuid();
+
+        Entity role = new Entity( "role" );
+        role.setProperty( "name", "connectionQuerybyEmail1" );
+
+        response = client.createEntity( role );
+
+        assertNull( "Error was: " + response.getErrorDescription(), response.getError() );
+
+        UUID roleId1 = response.getEntities().get( 0 ).getUuid();
+
+        //add permissions to the role
+
+        Map<String, String> perms = new HashMap<String, String>();
+        perms.put( "permission", "get:/stuff/**" );
+
+        String path = String.format( "/test-organization/test-app/roles/%s/permissions", roleId1 );
+
+        JsonNode node = mapper.readTree( resource().path( path ).queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                          .type( MediaType.APPLICATION_JSON_TYPE ).post( String.class, perms ));
+
+
+        //Create the second role
+        role = new Entity( "role" );
+        role.setProperty( "name", "connectionQuerybyEmail2" );
+
+        response = client.createEntity( role );
+
+        assertNull( "Error was: " + response.getErrorDescription(), response.getError() );
+
+        UUID roleId2 = response.getEntities().get( 0 ).getUuid();
+
+        //add permissions to the role
+
+        perms = new HashMap<String, String>();
+        perms.put( "permission", "get:/stuff/**" );
+
+        path = String.format( "/test-organization/test-app/roles/%s/permissions", roleId2 );
+
+        node = mapper.readTree( resource().path( path ).queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                         .type( MediaType.APPLICATION_JSON_TYPE ).post( String.class, perms ));
+
+        refreshIndex("test-organization", "test-app");
+
+        //connect the entities where role is the root
+        path = String.format( "/test-organization/test-app/roles/%s/users/%s", roleId1, userId );
+
+        node = mapper.readTree( resource().path( path ).queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                         .type( MediaType.APPLICATION_JSON_TYPE ).post( String.class ));
+
+        // now create a connection of "likes" between the first user and the
+        // second using pluralized form
+
+        assertEquals( userId.toString(), getEntity( node, 0 ).get( "uuid" ).asText() );
+
+        refreshIndex("test-organization", "test-app");
+
+
+        //connect the second role
+        path = String.format( "/test-organization/test-app/roles/%s/users/%s", roleId2, userId );
+
+        node = mapper.readTree( resource().path( path ).queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                         .type( MediaType.APPLICATION_JSON_TYPE ).post( String.class ));
+
+
+        assertEquals( userId.toString(), getEntity( node, 0 ).get( "uuid" ).asText() );
+
+        refreshIndex("test-organization", "test-app");
+
+        //query the second role, it should work
+        path = String.format( "/test-organization/test-app/roles/%s/users", roleId2 );
+
+        node = mapper.readTree( resource().path( path ).queryParam( "access_token", access_token )
+                         .queryParam( "ql", "select%20*%20where%20username%20=%20'" + email + "'" )
+                         .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                         .get( String.class ));
+
+        assertEquals( userId.toString(), getEntity( node, 0 ).get( "uuid" ).asText() );
+
+
+        //query the first role, it should work
+        path = String.format( "/test-organization/test-app/roles/%s/users", roleId1 );
+
+        node = mapper.readTree( resource().path( path ).queryParam( "access_token", access_token )
+                         .queryParam( "ql", "select%20*%20where%20username%20=%20'" + email + "'" )
+                         .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                         .get( String.class ));
+
+        assertEquals( userId.toString(), getEntity( node, 0 ).get( "uuid" ).asText() );
+
+
+        //now delete the first role
+        path = String.format( "/test-organization/test-app/roles/%s", roleId1 );
+
+        node = mapper.readTree( resource().path( path ).queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                         .type( MediaType.APPLICATION_JSON_TYPE ).delete( String.class ));
+
+        //query the first role, it should 404
+        path = String.format( "/test-organization/test-app/roles/%s/users", roleId1 );
+
+        refreshIndex("test-organization", "test-app");
+
+        try {
+            node = mapper.readTree( resource().path( path ).queryParam( "access_token", access_token )
+                             .queryParam( "ql", "select%20*%20where%20username%20=%20'" + email + "'" )
+                             .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                             .get( String.class ));
+        }
+        catch ( UniformInterfaceException e ) {
+            assertEquals( Status.NOT_FOUND, e.getResponse().getClientResponseStatus() );
+        }
+
+        //query the second role, it should work
+        path = String.format( "/test-organization/test-app/roles/%s/users", roleId2 );
+
+        node = mapper.readTree( resource().path( path ).queryParam( "access_token", access_token )
+                         .queryParam( "ql", "select%20*%20where%20username%20=%20'" + email + "'" )
+                         .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                         .get( String.class ));
+
+        assertEquals( userId.toString(), getEntity( node, 0 ).get( "uuid" ).asText() );
+    }
+
+
+    @Test
+    public void connectionByNameAndDynamicType() throws IOException {
+        UUID id = UUIDUtils.newTimeUUID();
+
+        String username1 = "username1" + id;
+        String name1 = "name1" + id;
+        String email1 = "email1" + id + "@usergrid.org";
+
+        ApiResponse response = client.createUser( username1, name1, email1, "password" );
+        assertNull( "Error was: " + response.getErrorDescription(), response.getError() );
+        refreshIndex("test-organization", "test-app");
+
+        UUID firstCreatedId = response.getEntities().get( 0 ).getUuid();
+
+        String name = "pepperoni";
+
+        Entity pizza = new Entity();
+        pizza.setProperty( "name", name );
+        pizza.setType( "pizza" );
+
+        response = client.createEntity( pizza );
+
+        assertNull( "Error was: " + response.getErrorDescription(), response.getError() );
+
+        UUID secondCreatedId = response.getEntities().get( 0 ).getUuid();
+
+        refreshIndex("test-organization", "test-app");
+
+        // now create a connection of "likes" between the first user and the
+        // second using pluralized form
+
+        // named entity in collection name
+        String path = String.format( "/test-organization/test-app/users/%s/conn1/pizzas/%s", firstCreatedId,
+                secondCreatedId );
+
+        JsonNode node = mapper.readTree( resource().path( path ).queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                          .type( MediaType.APPLICATION_JSON_TYPE ).post( String.class ));
+
+        assertEquals( secondCreatedId.toString(), getEntity( node, 0 ).get( "uuid" ).asText() );
+
+        refreshIndex("test-organization", "test-app");
+
+        // named entity in collection name
+        path = String.format( "/test-organization/test-app/users/%s/conn2/pizzas/%s", username1, name );
+
+        node = mapper.readTree( resource().path( path ).queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                         .type( MediaType.APPLICATION_JSON_TYPE ).post( String.class ));
+
+        assertEquals( secondCreatedId.toString(), getEntity( node, 0 ).get( "uuid" ).asText() );
+    }
+
+
+    @Test
+    public void nameUpdate() throws IOException {
+        UUID id = UUIDUtils.newTimeUUID();
+
+        String username = "username" + id;
+        String name = "name" + id;
+        String email = "email" + id + "@usergrid.org";
+
+        ApiResponse response = client.createUser( username, name, email, "password" );
+
+        assertNull( "Error was: " + response.getErrorDescription(), response.getError() );
+        refreshIndex("test-organization", "test-app");
+
+        Entity userEntity = response.getEntities().get( 0 );
+
+        // attempt to log in
+        JsonNode node = mapper.readTree( resource().path( "/test-organization/test-app/token" ).queryParam( "username", username )
+                                  .queryParam( "password", "password" ).queryParam( "grant_type", "password" )
+                                  .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                                  .get( String.class ));
+
+        assertEquals( username, node.get( "user" ).get( "username" ).asText() );
+        assertEquals( name, node.get( "user" ).get( "name" ).asText() );
+        assertEquals( email, node.get( "user" ).get( "email" ).asText() );
+
+        // now update the name and email
+        String newName = "newName";
+        String newEmail = "newEmail" + UUIDUtils.newTimeUUID() + "@usergrid.org";
+
+        userEntity.setProperty( "name", newName );
+        userEntity.setProperty( "email", newEmail );
+        userEntity.setProperty( "password", "newp2ssword" );
+        userEntity.setProperty( "pin", "newp1n" );
+
+        node = mapper.readTree( resource().path( String.format( "/test-organization/test-app/users/%s", username ) )
+                         .queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                         .type( MediaType.APPLICATION_JSON_TYPE ).put( String.class, userEntity.getProperties() ));
+
+        refreshIndex("test-organization", "test-app");
+
+        // now see if we've updated
+        node = mapper.readTree( resource().path( "/test-organization/test-app/token" ).queryParam( "username", username )
+                         .queryParam( "password", "password" ).queryParam( "grant_type", "password" )
+                         .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                         .get( String.class ));
+
+        assertEquals( username, node.get( "user" ).get( "username" ).asText() );
+        assertEquals( newName, node.get( "user" ).get( "name" ).asText() );
+        assertEquals( newEmail, node.get( "user" ).get( "email" ).asText() );
+        assertNull( newEmail, node.get( "user" ).get( "password" ) );
+        assertNull( newEmail, node.get( "user" ).get( "pin" ) );
+    }
+
+
+    /**
+     *
+     * @return
+     */
+    public JsonNode getActor( Entity entity ) {
+        return entity.getProperties().get( "actor" );
+    }
+
+
+    @Test
+    public void test_POST_batch() throws IOException {
+
+        log.info( "UserResourceIT.test_POST_batch" );
+
+        JsonNode node = null;
+
+        List<Map<String, Object>> batch = new ArrayList<Map<String, Object>>();
+
+        Map<String, Object> properties = new LinkedHashMap<String, Object>();
+        properties.put( "username", "test_user_1" );
+        properties.put( "email", "user1@test.com" );
+        batch.add( properties );
+
+        properties = new LinkedHashMap<String, Object>();
+        properties.put( "username", "test_user_2" );
+        batch.add( properties );
+
+        properties = new LinkedHashMap<String, Object>();
+        properties.put( "username", "test_user_3" );
+        batch.add( properties );
+
+        node = mapper.readTree( resource().path( "/test-organization/test-app/users/" ).queryParam( "access_token", access_token )
+                         .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                         .post( String.class, batch ));
+
+        assertNotNull( node );
+        logNode( node );
+    }
+
+
+    @Test
+    public void deactivateUser() throws IOException {
+
+        UUID newUserUuid = UUIDUtils.newTimeUUID();
+
+        String userName = String.format( "test%s", newUserUuid );
+
+        Map<String, String> payload =
+                hashMap( "email", String.format( "%s@anuff.com", newUserUuid ) ).map( "username", userName )
+                                                                                .map( "name", "Ed Anuff" )
+                                                                                .map( "password", "sesame" )
+                                                                                .map( "pin", "1234" );
+
+        resource().path( "/test-organization/test-app/users" ).queryParam( "access_token", access_token )
+                  .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                  .post( String.class, payload );
+
+        refreshIndex("test-organization", "test-app");
+
+        JsonNode response = mapper.readTree( resource().path( "/test-organization/test-app/users" ).queryParam( "access_token", access_token )
+                          .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                          .get( String.class ));
+
+        // disable the user
+
+        Map<String, String> data = new HashMap<String, String>();
+
+        response = mapper.readTree( resource().path( String.format( "/test-organization/test-app/users/%s/deactivate", userName ) )
+                             .queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                             .type( MediaType.APPLICATION_JSON_TYPE ).post( String.class, data ));
+
+        JsonNode entity = getEntity( response, 0 );
+
+        assertFalse( entity.get( "activated" ).asBoolean() );
+        assertNotNull( entity.get( "deactivated" ) );
+    }
+
+
+    @Test
+    public void test_PUT_password_fail() {
+
+        boolean fail = false;
+        try {
+            ApiResponse changeResponse = client.changePassword( "edanuff", "foo", "bar" );
+            fail = changeResponse.getError() != null;
+        }
+        catch ( Exception e ) {
+            fail = true;
+        }
+        assertTrue( fail );
+    }
+
+
+    @Test
+    public void test_GET_user_ok() throws InterruptedException, IOException {
+
+        // TODO figure out what is being overridden? why 400?
+        JsonNode node = mapper.readTree( resource().path( "/test-organization/test-app/users" )
+                .queryParam( "access_token", access_token )
+                .accept( MediaType.APPLICATION_JSON )
+                .type( MediaType.APPLICATION_JSON_TYPE )
+                .get( String.class ));
+
+        String uuid = node.get( "entities" ).get( 0 ).get( "uuid" ).textValue();
+        String email = node.get( "entities" ).get( 0 ).get( "email" ).textValue();
+
+        node = mapper.readTree( resource().path( "/test-organization/test-app/users/" + uuid )
+                .queryParam( "access_token", access_token )
+                .accept( MediaType.APPLICATION_JSON )
+                .type( MediaType.APPLICATION_JSON_TYPE )
+                .get( String.class ));
+        
+        logNode( node );
+        assertEquals( email, node.get( "entities" ).get( 0 ).get( "email" ).textValue() );
+    }
+
+
+    @Test
+    public void test_PUT_password_ok() {
+
+        ApiResponse response = client.changePassword( "edanuff", "sesame", "sesame1" );
+
+        assertNull( response.getError() );
+
+        response = client.authorizeAppUser( "ed@anuff.com", "sesame1" );
+
+        assertNull( response.getError() );
+
+        // if this was successful, we need to re-set the password for other
+        // tests
+        response = client.changePassword( "edanuff", "sesame1", "sesame" );
+
+        assertNull( response.getError() );
+    }
+
+
+    @Test
+    public void setUserPasswordAsAdmin()  throws IOException {
+
+        String newPassword = "foo";
+
+        Map<String, String> data = new HashMap<String, String>();
+        data.put( "newpassword", newPassword );
+
+        // change the password as admin. The old password isn't required
+        JsonNode node = mapper.readTree( resource().path( "/test-organization/test-app/users/edanuff/password" )
+                                  .queryParam( "access_token", adminAccessToken ).accept( MediaType.APPLICATION_JSON )
+                                  .type( MediaType.APPLICATION_JSON_TYPE ).post( String.class, data ));
+
+        assertNull( getError( node ) );
+
+        ApiResponse response = client.authorizeAppUser( "ed@anuff.com", newPassword );
+
+        assertNull( response.getError() );
+    }
+
+
+    @Test
+    public void passwordMismatchErrorUser() {
+        String origPassword = "foo";
+        String newPassword = "bar";
+
+        Map<String, String> data = new HashMap<String, String>();
+        data.put( "newpassword", origPassword );
+
+        // now change the password, with an incorrect old password
+
+        data.put( "oldpassword", origPassword );
+        data.put( "newpassword", newPassword );
+
+        Status responseStatus = null;
+        try {
+            resource().path( "/test-organization/test-app/users/edanuff/password" ).accept( MediaType.APPLICATION_JSON )
+                      .type( MediaType.APPLICATION_JSON_TYPE ).post( String.class, data );
+        }
+        catch ( UniformInterfaceException uie ) {
+            responseStatus = uie.getResponse().getClientResponseStatus();
+        }
+
+        assertNotNull( responseStatus );
+
+        assertEquals( Status.BAD_REQUEST, responseStatus );
+    }
+
+
+    @Test
+    public void addRemoveRole() throws IOException  {
+
+        UUID id = UUIDUtils.newTimeUUID();
+
+        String roleName = "rolename" + id;
+
+        String username = "username" + id;
+        String name = "name" + id;
+        String email = "email" + id + "@usergrid.org";
+
+        ApiResponse response = client.createUser( username, name, email, "password" );
+        assertNull( "Error was: " + response.getErrorDescription(), response.getError() );
+        refreshIndex("test-organization", "test-app");
+
+        UUID createdId = response.getEntities().get( 0 ).getUuid();
+
+        // create Role
+
+        String json = "{\"title\":\"" + roleName + "\",\"name\":\"" + roleName + "\"}";
+        JsonNode node = mapper.readTree( resource().path( "/test-organization/test-app/roles" )
+            .queryParam( "access_token", access_token )
+            .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+            .post( String.class, json ));
+
+        // check it
+        assertNull( node.get( "errors" ) );
+
+        refreshIndex("test-organization", "test-app");
+
+        // add Role
+
+        node = mapper.readTree( resource().path( "/test-organization/test-app/users/" + createdId + "/roles/" + roleName )
+            .queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+            .type( MediaType.APPLICATION_JSON_TYPE ).post( String.class ));
+
+        // check it
+        assertNull( node.get( "errors" ) );
+        assertNotNull( node.get( "entities" ) );
+        assertNotNull( node.get( "entities" ).get( 0 ) );
+        assertNotNull( node.get( "entities" ).get( 0 ).get( "name" ) );
+        assertEquals( node.get( "entities" ).get( 0 ).get( "name" ).asText(), roleName );
+
+        refreshIndex("test-organization", "test-app");
+
+        node = mapper.readTree( resource().path( "/test-organization/test-app/users/" + createdId + "/roles" )
+            .queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+            .type( MediaType.APPLICATION_JSON_TYPE ).get( String.class ));
+        assertNull( node.get( "errors" ) );
+        assertNotNull( node.get( "entities" ) );
+        assertNotNull( node.get( "entities" ).get( 0 ) );
+        assertNotNull( node.get( "entities" ).get( 0 ).get( "name" ) );
+        assertEquals( node.get( "entities" ).get( 0 ).get( "name" ).asText(), roleName );
+
+
+        // remove Role
+
+        node = mapper.readTree( resource().path( "/test-organization/test-app/users/" + createdId + "/roles/" + roleName )
+                         .queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                         .type( MediaType.APPLICATION_JSON_TYPE ).delete( String.class ));
+
+        // check it
+        assertNull( node.get( "errors" ) );
+
+        refreshIndex("test-organization", "test-app");
+
+        node = mapper.readTree( resource().path( "/test-organization/test-app/users/" + createdId + "/roles" )
+                         .queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                         .type( MediaType.APPLICATION_JSON_TYPE ).get( String.class ));
+        assertNull( node.get( "errors" ) );
+        assertTrue( node.get( "entities" ).size() == 0 );
+    }
+
+
+    @Test
+    public void revokeToken() throws Exception {
+
+        String token1 = super.userToken( "edanuff", "sesame" );
+        String token2 = super.userToken( "edanuff", "sesame" );
+
+        JsonNode response = mapper.readTree( resource().path( "/test-organization/test-app/users/edanuff" ).queryParam( "access_token", token1 )
+                          .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                          .get( String.class ));
+
+        assertNotNull( getEntity( response, 0 ) );
+
+        response = mapper.readTree( resource().path( "/test-organization/test-app/users/edanuff" ).queryParam( "access_token", token2 )
+                             .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                             .get( String.class ));
+
+        assertNotNull( getEntity( response, 0 ) );
+
+        // now revoke the tokens
+        response = mapper.readTree( resource().path( "/test-organization/test-app/users/edanuff/revoketokens" )
+                             .queryParam( "access_token", adminAccessToken ).accept( MediaType.APPLICATION_JSON )
+                             .type( MediaType.APPLICATION_JSON_TYPE ).post( String.class ));
+
+        // the tokens shouldn't work
+
+        Status status = null;
+
+        try {
+            response = mapper.readTree( resource().path( "/test-organization/test-app/users/edanuff" ).queryParam( "access_token", token1 )
+                              .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                              .get( String.class ));
+        }
+        catch ( UniformInterfaceException uie ) {
+            status = uie.getResponse().getClientResponseStatus();
+        }
+
+        assertEquals( Status.UNAUTHORIZED, status );
+
+        status = null;
+
+        try {
+            response = mapper.readTree( resource().path( "/test-organization/test-app/users/edanuff" ).queryParam( "access_token", token2 )
+                              .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                              .get( String.class ));
+        }
+        catch ( UniformInterfaceException uie ) {
+            status = uie.getResponse().getClientResponseStatus();
+        }
+
+        assertEquals( Status.UNAUTHORIZED, status );
+
+        String token3 = super.userToken( "edanuff", "sesame" );
+        String token4 = super.userToken( "edanuff", "sesame" );
+
+        response = mapper.readTree( resource().path( "/test-organization/test-app/users/edanuff" ).queryParam( "access_token", token3 )
+                             .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                             .get( String.class ));
+
+        assertNotNull( getEntity( response, 0 ) );
+
+        response = mapper.readTree( resource().path( "/test-organization/test-app/users/edanuff" ).queryParam( "access_token", token4 )
+                             .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                             .get( String.class ));
+
+        assertNotNull( getEntity( response, 0 ) );
+
+        // now revoke the token3
+        response = mapper.readTree( resource().path( "/test-organization/test-app/users/edanuff/revoketoken" )
+                             .queryParam( "access_token", token3 ).queryParam( "token", token3 )
+                             .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                             .post( String.class ));
+
+        // the token3 shouldn't work
+
+        status = null;
+
+        try {
+            response = mapper.readTree( resource().path( "/test-organization/test-app/users/edanuff" ).queryParam( "access_token", token3 )
+                              .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                              .get( String.class ));
+        }
+        catch ( UniformInterfaceException uie ) {
+            status = uie.getResponse().getClientResponseStatus();
+        }
+
+        assertEquals( Status.UNAUTHORIZED, status );
+
+        status = null;
+
+        try {
+            response = mapper.readTree( resource().path( "/test-organization/test-app/users/edanuff" ).queryParam( "access_token", token4 )
+                              .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                              .get( String.class ));
+
+            status = Status.OK;
+        }
+        catch ( UniformInterfaceException uie ) {
+            status = uie.getResponse().getClientResponseStatus();
+        }
+
+        assertEquals( Status.OK, status );
+    }
+
+
+    @Test
+    public void getToken() throws Exception {
+
+        createUser( "test_1", "test_1@test.com", "test123", "Test1 User" ); // client.setApiUrl(apiUrl);
+        createUser( "test_2", "test_2@test.com", "test123", "Test2 User" ); // client.setApiUrl(apiUrl);
+        createUser( "test_3", "test_3@test.com", "test123", "Test3 User" ); // client.setApiUrl(apiUrl);
+        refreshIndex("test-organization", "test-app");
+
+        ApplicationInfo appInfo = setup.getMgmtSvc().getApplicationInfo( "test-organization/test-app" );
+
+        String clientId = setup.getMgmtSvc().getClientIdForApplication( appInfo.getId() );
+        String clientSecret = setup.getMgmtSvc().getClientSecretForApplication( appInfo.getId() );
+
+        JsonNode node = mapper.readTree( resource().path( "/test-organization/test-app/users/test_1/token" ).queryParam( "client_id", clientId )
+                          .queryParam( "client_secret", clientSecret ).accept( MediaType.APPLICATION_JSON )
+                          .type( MediaType.APPLICATION_JSON_TYPE ).get( String.class ));
+
+        String user_token_from_client_credentials = node.get( "access_token" ).asText();
+
+        UUID userId = UUID.fromString( node.get( "user" ).get( "uuid" ).asText() );
+        setup.getMgmtSvc().activateAppUser( appInfo.getId(), userId );
+
+        String user_token_from_java = setup.getMgmtSvc().getAccessTokenForAppUser( appInfo.getId(), userId, 1000000 );
+
+        assertNotNull( user_token_from_client_credentials );
+
+        refreshIndex("test-organization", "test-app");
+
+        Status status = null;
+
+        // bad access token
+        try {
+            resource().path( "/test-organization/test-app/users/test_1/token" ).queryParam( "access_token", "blah" )
+                      .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                      .get( String.class );
+        }
+        catch ( UniformInterfaceException uie ) {
+            status = uie.getResponse().getClientResponseStatus();
+            log.info( "Error Response Body: " + uie.getResponse().getEntity( String.class ) );
+        }
+
+        assertEquals( Status.UNAUTHORIZED, status );
+
+        try {
+            resource().path( "/test-organization/test-app/users/test_2/token" )
+                      .queryParam( "access_token", user_token_from_client_credentials )
+                      .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                      .get( String.class );
+        }
+        catch ( UniformInterfaceException uie ) {
+            status = uie.getResponse().getClientResponseStatus();
+            log.info( "Error Response Body: " + uie.getResponse().getEntity( String.class ) );
+        }
+
+        assertEquals( Status.FORBIDDEN, status );
+
+
+        JsonNode response = null;
+        response = mapper.readTree( resource().path( "/test-organization/test-app/users/test_1" )
+                             .queryParam( "access_token", user_token_from_client_credentials )
+                             .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                             .get( String.class ));
+
+        assertNotNull( getEntity( response, 0 ) );
+
+        response = mapper.readTree( resource().path( "/test-organization/test-app/users/test_1" )
+                             .queryParam( "access_token", user_token_from_java ).accept( MediaType.APPLICATION_JSON )
+                             .type( MediaType.APPLICATION_JSON_TYPE ).get( String.class ));
+
+        assertNotNull( getEntity( response, 0 ) );
+
+        setup.getMgmtSvc().deactivateUser( appInfo.getId(), userId );
+
+        refreshIndex("test-organization", "test-app");
+
+        try {
+            resource().path( "/test-organization/test-app/token" ).queryParam( "grant_type", "password" )
+                      .queryParam( "username", "test_1" ).queryParam( "password", "test123" )
+                      .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                      .get( String.class );
+            fail( "request for deactivated user should fail" );
+        }
+        catch ( UniformInterfaceException uie ) {
+            status = uie.getResponse().getClientResponseStatus();
+            JsonNode body = mapper.readTree( uie.getResponse().getEntity( String.class ));
+            assertEquals( "user not activated", body.findPath( "error_description" ).textValue() );
+        }
+    }
+
+
+    @Test
+    public void delegatePutOnNotFound() throws Exception {
+        String randomName = "user1_" + UUIDUtils.newTimeUUID().toString();
+        createUser( randomName, randomName + "@apigee.com", "password", randomName );
+        refreshIndex("test-organization", "test-app");
+
+        // should update a field
+        JsonNode response = mapper.readTree( resource().path( "/test-organization/test-app/users/" + randomName )
+                                      .queryParam( "access_token", adminAccessToken )
+                                      .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                                      .get( String.class ));
+        logNode( response );
+        assertNotNull( getEntity( response, 0 ) );
+        // PUT on user
+
+        // PUT a new user
+        randomName = "user2_" + UUIDUtils.newTimeUUID().toString();
+        Map<String, String> payload =
+                hashMap( "email", randomName + "@apigee.com" ).map( "username", randomName ).map( "name", randomName )
+                                                              .map( "password", "password" ).map( "pin", "1234" );
+
+        response = mapper.readTree( resource().path( "/test-organization/test-app/users" ).queryParam( "access_token", adminAccessToken )
+                             .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                             .put( String.class, payload ));
+
+        refreshIndex("test-organization", "test-app");
+
+        logNode( response );
+        response = mapper.readTree( resource().path( "/test-organization/test-app/users/" + randomName )
+                             .queryParam( "access_token", adminAccessToken ).accept( MediaType.APPLICATION_JSON )
+                             .type( MediaType.APPLICATION_JSON_TYPE ).get( String.class ));
+
+        assertNotNull( getEntity( response, 0 ) );
+        logNode( response );
+    }
+
+
+    /**
+     * Test that property queries return properties and entity queries return entities.
+     * https://apigeesc.atlassian.net/browse/USERGRID-1715?
+     */
+    @Test
+    public void queryForUuids() throws Exception {
+
+        {
+            final JsonNode response = mapper.readTree( resource().path( "/test-organization/test-app/users/" ).queryParam( "ql",
+                    "select *" )               // query for entities
+                    .queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                    .type( MediaType.APPLICATION_JSON_TYPE ).get( String.class ));
+            assertNotNull( "Entities must exist", response.get( "entities" ) );
+            assertTrue( "Must be some entities", response.get( "entities" ).size() > 0 );
+            assertEquals( "Must be users", "user", response.get( "entities" ).get( 0 ).get( "type" ).asText() );
+            assertNull( "List must not exist", response.get( "list" ) );
+        }
+
+        {
+            final JsonNode response = mapper.readTree( resource().path( "/test-organization/test-app/users/" ).queryParam( "ql",
+                    "select uuid" )            // query for uuid properties
+                    .queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                    .type( MediaType.APPLICATION_JSON_TYPE ).get( String.class ));
+            assertNotNull( "List must exist", response.get( "list" ) );
+            assertTrue( "Must be some list items", response.get( "list" ).size() > 0 );
+            assertNull( "Entities must not exist", response.get( "entries" ) );
+        }
+    }
+
+
+    @Test
+    public void queryForUserUuids() throws Exception {
+
+        UserRepo.INSTANCE.load( resource(), access_token );
+        refreshIndex("test-organization", "test-app");
+
+        Status status = null;
+
+
+        String ql = "uuid = " + UserRepo.INSTANCE.getByUserName( "user1" );
+
+        JsonNode node = mapper.readTree( resource().path( "/test-organization/test-app/users" ).queryParam( "ql", ql )
+                                  .queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                                  .type( MediaType.APPLICATION_JSON_TYPE ).get( String.class ));
+
+
+        Map<String, String> payload = hashMap( "name", "Austin" ).map( "state", "TX" );
+
+        node = mapper.readTree( resource().path( "/test-organization/test-app/curts" ).queryParam( "access_token", access_token )
+                         .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
+                         .post( String.class, payload ));
+
+        UUID userId = UUID.fromString( node.get( "entities" ).get( 0 ).get( "uuid" ).asText() );
+
+        assertNotNull( userId );
+
+        refreshIndex("test-organization", "test-app");
+
+        ql = "uuid = " + userId;
+
+        node = mapper.readTree( resource().path( "/test-organization/test-app/curts" ).queryParam( "ql", ql )
+                         .queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON )
+                         .type( MediaType.APPLICATION_JSON_TYPE ).get( String.class ));
+
+        assertNotNull( node.get( "entities" ).get( 0 ).get( "uuid" ) );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/3993f081/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/extensions/TestResource.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/extensions/TestResource.java b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/extensions/TestResource.java
new file mode 100644
index 0000000..b74a162
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/extensions/TestResource.java
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+package org.apache.usergrid.rest.applications.collection.users.extensions;
+
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.junit.Ignore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+import org.apache.usergrid.rest.applications.users.AbstractUserExtensionResource;
+
+
+@Ignore("Not a test")
+@Component("TestResource")
+@Scope("prototype")
+@Produces(MediaType.APPLICATION_JSON)
+public class TestResource extends AbstractUserExtensionResource {
+
+    private static Logger log = LoggerFactory.getLogger( TestResource.class );
+
+
+    public TestResource() {
+        log.info( "TestResource" );
+    }
+
+
+    @GET
+    public String sayHello() {
+        return "{\"message\" : \"hello\"" + ( getUserResource().getUserUuid() != null ?
+                                              ", \"user\" : \"" + getUserResource().getUserUuid() + "\"" : "" ) + " }";
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/3993f081/stack/rest/src/test/java/org/apache/usergrid/rest/applications/events/ApplicationRequestCounterIT.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/events/ApplicationRequestCounterIT.java b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/events/ApplicationRequestCounterIT.java
new file mode 100644
index 0000000..bf63844
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/events/ApplicationRequestCounterIT.java
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+package org.apache.usergrid.rest.applications.events;
+
+
+import java.util.UUID;
+
+import javax.ws.rs.core.MediaType;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.usergrid.cassandra.Concurrent;
+import org.apache.usergrid.persistence.EntityManager;
+import org.apache.usergrid.persistence.EntityManagerFactory;
+import org.apache.usergrid.persistence.index.query.Query;
+import org.apache.usergrid.persistence.Results;
+import org.apache.usergrid.persistence.index.query.CounterResolution;
+import org.apache.usergrid.rest.AbstractRestIT;
+import org.apache.usergrid.services.ServiceManager;
+import org.apache.usergrid.utils.UUIDUtils;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+
+/**
+ * Invoke application request counters
+ *
+ * @author realbeast
+ */
+@Concurrent()
+public class ApplicationRequestCounterIT extends AbstractRestIT {
+    private static final Logger log = LoggerFactory.getLogger( ApplicationRequestCounterIT.class );
+    long ts = System.currentTimeMillis() - ( 24 * 60 * 60 * 1000 );
+
+
+    @Test
+    public void applicationrequestInternalCounters() throws Exception {
+        // Get application id
+        JsonNode node = mapper.readTree( resource().path( "/test-organization/test-app" ).queryParam( "access_token", access_token )
+                .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE ).get( String.class ));
+
+        assertNotNull( node.get( "entities" ) );
+
+        String uuid = node.get( "application" ).asText();
+        assertEquals( true, UUIDUtils.isUUID( uuid ) );
+
+        refreshIndex("test-organization", "test-app");
+
+        UUID applicationId = UUID.fromString( uuid );
+        EntityManagerFactory emf = setup.getEmf();
+        EntityManager em = emf.getEntityManager( applicationId );
+
+        int beforeTotalCall = getCounter( em, ServiceManager.APPLICATION_REQUESTS );
+        int beforeCall = getCounter( em, ServiceManager.APPLICATION_REQUESTS_PER.concat( "get" ) );
+
+        // call
+        node = mapper.readTree( resource().path( "/test-organization/test-app/counters" ).queryParam( "resolution", "all" )
+                .queryParam( "counter", "application.requests" ).queryParam( "access_token", adminToken() )
+                .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE ).get( String.class ));
+
+        assertNotNull( node.get( "counters" ) );
+
+        int afterTotalCall = getCounter( em, ServiceManager.APPLICATION_REQUESTS );
+        int afterCall = getCounter( em, ServiceManager.APPLICATION_REQUESTS_PER.concat( "get" ) );
+
+        assertEquals( 1, afterCall - beforeCall );
+        assertEquals( 1, afterTotalCall - beforeTotalCall );
+    }
+
+
+    private int getCounter( EntityManager em, String key ) throws Exception {
+        Query query = new Query();
+        query.addCounterFilter( key + ":*:*:*" );
+        query.setStartTime( ts );
+        query.setFinishTime( System.currentTimeMillis() );
+        query.setResolution( CounterResolution.ALL );
+        Results r = em.getAggregateCounters( query );
+        return ( int ) r.getCounters().get( 0 ).getValues().get( 0 ).getValue();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/3993f081/stack/rest/src/test/java/org/apache/usergrid/rest/applications/queries/AndOrQueryTest.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/queries/AndOrQueryTest.java b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/queries/AndOrQueryTest.java
new file mode 100644
index 0000000..942044d
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/queries/AndOrQueryTest.java
@@ -0,0 +1,203 @@
+/*
+ * 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.
+ */
+package org.apache.usergrid.rest.applications.queries;
+
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import java.io.IOException;
+import org.apache.commons.lang.RandomStringUtils;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.apache.usergrid.rest.AbstractRestIT;
+import org.apache.usergrid.rest.TestContextSetup;
+import org.apache.usergrid.rest.test.resource.CustomCollection;
+
+import static org.junit.Assert.assertEquals;
+import static org.apache.usergrid.utils.MapUtils.hashMap;
+
+
+/**
+ * // TODO: Document this
+ *
+ * @author ApigeeCorporation
+ * @since 4.0
+ */
+public class AndOrQueryTest extends AbstractRestIT {
+
+    @Rule
+    public TestContextSetup context = new TestContextSetup( this );
+
+
+    @Test //USERGRID-900
+    public void queriesWithAndPastLimit() throws IOException {
+
+        CustomCollection activities = context.collection( "activities" );
+
+        long created = 0;
+        Map actor = hashMap( "displayName", "Erin" );
+        Map props = new HashMap();
+
+        props.put( "actor", actor );
+        props.put( "verb", "go" );
+        props.put( "content", "bragh" );
+
+
+        for ( int i = 0; i < 2000; i++ ) {
+            if ( i < 1000 ) {
+                props.put( "madeup", false );
+            }
+            else {
+                props.put( "madeup", true );
+            }
+
+            props.put( "ordinal", i );
+            JsonNode activity = activities.create( props );
+            if ( i == 0 ) {
+                created = activity.findValue( "created" ).longValue();
+            }
+        }
+
+        this.refreshIndex( context.getAppUuid() );
+
+        String errorQuery = "select * where created >= " + created + "AND madeup = true";
+        JsonNode incorrectNode = activities.withQuery( errorQuery ).get();
+
+        assertEquals( 10, incorrectNode.get( "entities" ).size() );
+    }
+
+
+    @Test //USERGRID-1475
+    public void displayFullQueriesInLimit() throws IOException {
+
+        CustomCollection activities = context.collection( "activities" );
+
+        Map actor = hashMap( "displayName", "Erin" );
+        Map props = new HashMap();
+        props.put( "actor", actor );
+        props.put( "content", "bragh" );
+
+        for ( int i = 0; i < 20; i++ ) {
+
+            if ( i < 10 ) {
+                props.put( "verb", "go" );
+            }
+            else {
+                props.put( "verb", "stop" );
+            }
+
+            props.put( "ordinal", i );
+            JsonNode activity = activities.create( props );
+        }
+
+        this.refreshIndex( context.getAppUuid() );
+
+        String query = "select * where not verb = 'go'";
+        JsonNode incorrectNode = activities.query( query, "limit", Integer.toString( 10 ) );
+
+        assertEquals( 10, incorrectNode.get( "entities" ).size() );
+
+        for ( int i = 0; i < 10; i++ ) {
+            assertEquals( 19 - i, incorrectNode.get( "entities" ).get( i ).get( "ordinal" ).intValue() );
+            assertEquals( "stop", incorrectNode.get( "entities" ).get( i ).get( "verb" ).textValue() );
+        }
+    }
+
+
+    @Test //USERGRID-1615
+    public void queryReturnCount() throws Exception {
+
+        CustomCollection activities = context.collection( "activities" );
+
+        Map actor = hashMap( "displayName", "Erin" );
+        Map props = new HashMap();
+
+        int numValuesTested = 20;
+
+
+        props.put( "actor", actor );
+        props.put( "verb", "go" );
+        props.put( "content", "bragh" );
+
+        JsonNode[] correctValues = activities.createEntitiesWithOrdinal( props, numValuesTested );
+
+        this.refreshIndex( context.getAppUuid() );
+
+        String inCorrectQuery = "select * where verb = 'go' and ordinal >= 10 ";
+
+        activities.verificationOfQueryResults( correctValues, true, inCorrectQuery );
+    }
+
+
+    @Test //Check to make sure that asc works
+    public void queryCheckAsc() throws Exception {
+
+        CustomCollection madeupStuff = context.collection( "imagination" + RandomStringUtils.randomAlphabetic(5));
+        Map character = hashMap( "WhoHelpedYou", "Ruff" );
+
+        JsonNode[] correctValues;
+        correctValues = madeupStuff.createEntitiesWithOrdinal( character, 10 );
+
+        this.refreshIndex( context.getAppUuid() );
+
+        String inquisitiveQuery = "select * where Ordinal gte 0 and Ordinal lte 10 "
+                + "or WhoHelpedYou eq 'Ruff' ORDER BY Ordinal asc";
+
+        int totalEntitiesContained = madeupStuff.verificationOfQueryResults( correctValues, false, inquisitiveQuery );
+
+        assertEquals( 10, totalEntitiesContained );
+    }
+
+
+    @Ignore("Test to make sure all 1000 exist with a regular query")
+    public void queryReturnCheck() throws Exception {
+        CustomCollection madeupStuff = context.collection( "imagination" );
+        Map character = hashMap( "WhoHelpedYou", "Ruff" );
+
+        int numOfEntities = 1000;
+
+        JsonNode[] correctValues = madeupStuff.createEntitiesWithOrdinal( character, numOfEntities );
+
+        this.refreshIndex( context.getAppUuid() );
+
+        String inquisitiveQuery = "select * where Ordinal >= 0 and Ordinal <= 2000 or WhoHelpedYou = 'Ruff'";
+
+        int totalEntitiesContained = madeupStuff.verificationOfQueryResults( correctValues, true, inquisitiveQuery );
+
+        assertEquals( numOfEntities, totalEntitiesContained );
+    }
+
+
+    @Ignore
+    public void queryReturnCheckWithShortHand() throws IOException {
+        CustomCollection madeupStuff = context.collection( "imagination" );
+        Map character = hashMap( "WhoHelpedYou", "Ruff" );
+
+        madeupStuff.createEntitiesWithOrdinal( character, 1000 );
+
+        this.refreshIndex( context.getAppUuid() );
+
+        String inquisitiveQuery = "select * where Ordinal gte 0 and Ordinal lte 2000 or WhoHelpedYou eq 'Ruff'";
+
+        int totalEntitiesContained = madeupStuff.countEntities( inquisitiveQuery );
+
+        assertEquals( 1000, totalEntitiesContained );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/3993f081/stack/rest/src/test/java/org/apache/usergrid/rest/applications/queries/BadGrammarQueryTest.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/queries/BadGrammarQueryTest.java b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/queries/BadGrammarQueryTest.java
new file mode 100644
index 0000000..0ac0558
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/queries/BadGrammarQueryTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+package org.apache.usergrid.rest.applications.queries;
+
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.junit.Rule;
+import org.junit.Test;
+import org.apache.usergrid.rest.AbstractRestIT;
+import org.apache.usergrid.rest.TestContextSetup;
+import org.apache.usergrid.rest.test.resource.CustomCollection;
+
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.UniformInterfaceException;
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.apache.usergrid.utils.MapUtils.hashMap;
+
+
+/**
+ * @author tnine
+ */
+public class BadGrammarQueryTest extends AbstractRestIT {
+
+    @Rule
+    public TestContextSetup context = new TestContextSetup( this );
+
+
+    @Test
+    public void catchBadQueryGrammar() throws IOException {
+
+        CustomCollection things = context.collection( "things" );
+
+        Map actor = hashMap( "displayName", "Erin" );
+        Map props = new HashMap();
+        props.put( "actor", actor );
+        props.put( "content", "bragh" );
+
+        JsonNode activity = things.create( props );
+
+        refreshIndex(context.getOrgName(), context.getAppName());
+
+        String query = "select * where name != 'go'";
+
+        ClientResponse.Status status = null;
+
+        try {
+
+            JsonNode incorrectNode = things.query( query, "limit", Integer.toString( 10 ) );
+            fail( "This should throw an exception" );
+        }
+        catch ( UniformInterfaceException uie ) {
+             status = uie.getResponse().getClientResponseStatus();
+
+
+        }
+
+        assertEquals( 400, status.getStatusCode() );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/3993f081/stack/rest/src/test/java/org/apache/usergrid/rest/applications/queries/GeoPagingTest.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/queries/GeoPagingTest.java b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/queries/GeoPagingTest.java
new file mode 100644
index 0000000..9224029
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/queries/GeoPagingTest.java
@@ -0,0 +1,133 @@
+/*
+ * 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.
+ */
+package org.apache.usergrid.rest.applications.queries;
+
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import java.io.IOException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.apache.usergrid.rest.AbstractRestIT;
+import org.apache.usergrid.rest.TestContextSetup;
+import org.apache.usergrid.rest.test.resource.CustomCollection;
+
+import static org.junit.Assert.assertEquals;
+import static org.apache.usergrid.utils.MapUtils.hashMap;
+
+
+/**
+ * // TODO: Document this
+ *
+ * @author ApigeeCorporation
+ * @since 4.0
+ */
+public class GeoPagingTest extends AbstractRestIT {
+
+    @Rule
+    public TestContextSetup context = new TestContextSetup( this );
+
+
+    @Test //("Test uses up to many resources to run reliably") // USERGRID-1403
+    public void groupQueriesWithGeoPaging() throws IOException {
+
+        CustomCollection groups = context.application().collection( "test1groups" );
+
+        int maxRangeLimit = 2000;
+        long[] index = new long[maxRangeLimit];
+        Map actor = hashMap( "displayName", "Erin" );
+
+        Map props = new HashMap();
+
+        props.put( "actor", actor );
+        Map location = hashMap( "latitude", 37 );
+        location.put( "longitude", -75 );
+        props.put( "location", location );
+        props.put( "verb", "go" );
+        props.put( "content", "bragh" );
+
+        for ( int i = 0; i < 5; i++ ) {
+            String newPath = String.format( "/kero" + i );
+            props.put( "path", newPath );
+            props.put( "ordinal", i );
+            JsonNode activity = groups.create( props );
+            index[i] = activity.findValue( "created" ).longValue();
+        }
+
+        refreshIndex(context.getOrgName(), context.getAppName());
+
+        String query = "select * where location within 20000 of 37,-75 "
+                + " and created > " + index[2] 
+                + " and created < " + index[4] + "";
+
+        JsonNode node = groups.withQuery( query ).get();
+        assertEquals( 1, node.get( "entities" ).size() );
+
+        assertEquals( index[3], node.get( "entities" ).get( 0 ).get( "created" ).longValue() );
+    }
+
+
+    @Test // USERGRID-1401
+    public void groupQueriesWithConsistentResults() throws IOException {
+
+        CustomCollection groups = context.application().collection( "test2groups" );
+
+        int maxRangeLimit = 20;
+        JsonNode[] saved = new JsonNode[maxRangeLimit];
+
+        Map<String, String> actor = hashMap( "displayName", "Erin" );
+        Map<String, Object> props = new HashMap<String, Object>();
+
+        props.put( "actor", actor );
+        Map<String, Integer> location = hashMap( "latitude", 37 );
+        location.put( "longitude", -75 );
+        props.put( "location", location );
+        props.put( "verb", "go" );
+        props.put( "content", "bragh" );
+
+        for ( int i = 0; i < 20; i++ ) {
+            String newPath = String.format( "/kero" + i );
+            props.put( "path", newPath );
+            props.put( "ordinal", i );
+            JsonNode activity = groups.create( props ).get( "entities" ).get( 0 );
+            saved[i] = activity;
+        }
+
+        refreshIndex(context.getOrgName(), context.getAppName());
+
+        JsonNode node = null;
+        for ( int consistent = 0; consistent < 20; consistent++ ) {
+
+            String query = String.format( 
+                "select * where location within 100 of 37, -75 and ordinal >= %d and ordinal < %d", 
+                saved[7].get( "ordinal" ).asLong(), saved[10].get( "ordinal" ).asLong() );
+
+            node = groups.withQuery( query ).get(); //groups.query(query);
+
+            JsonNode entities = node.get( "entities" );
+
+            assertEquals( 3, entities.size() );
+
+            for ( int i = 0; i < 3; i++ ) {
+                // shouldn't start at 10 since you're excluding it above in the query, it should return 9,8,7
+                assertEquals( saved[7 + i], entities.get( i ) );
+            }
+        }
+    }
+}