| /* |
| * 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 org.apache.usergrid.rest.test.resource.model.Collection; |
| import org.apache.usergrid.rest.test.resource.model.Entity; |
| import org.apache.usergrid.rest.test.resource.model.QueryParameters; |
| import org.junit.Test; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.io.IOException; |
| import java.util.List; |
| |
| import static org.junit.Assert.*; |
| |
| |
| /** |
| * // TODO: Document this |
| * |
| * @since 4.0 |
| */ |
| public class AndOrQueryTest extends QueryTestBase { |
| private static final Logger logger = LoggerFactory.getLogger(AndOrQueryTest.class); |
| |
| |
| /** |
| * Test an inclusive AND query to ensure the correct results are returned |
| * |
| * @throws IOException |
| */ |
| @Test |
| public void queryAndInclusive() throws IOException { |
| int numOfEntities = 20; |
| String collectionName = "apples"; |
| // create our test entities |
| generateTestEntities(numOfEntities, collectionName); |
| // Query where madeup = true (the last half) and the last quarter of entries |
| QueryParameters params = new QueryParameters() |
| .setQuery("select * where madeup = true AND ordinal >= " + (numOfEntities - numOfEntities / 4)); |
| Collection coll = this.app().collection(collectionName).get(params); |
| // results should have madeup = true and ordinal 15-19 |
| assertEquals(numOfEntities / 4, coll.getResponse().getEntityCount()); |
| // loop though entities that were returned, and test against the ordinals and values we are |
| // expecting, starting with the last entity and decrementing |
| int index = 19; |
| while (coll.hasNext()) { |
| Entity activity = coll.next(); |
| // ensure the 'madeup' property is set to true |
| assertTrue(Boolean.parseBoolean(activity.get("madeup").toString())); |
| // make sure the correct ordinal properties are returned |
| assertEquals(index--, Long.parseLong(activity.get("ordinal").toString())); |
| } |
| |
| } |
| @Test |
| public void someTestProp() throws IOException { |
| int numOfEntities = 20; |
| String collectionName = "bananas"; |
| // create our test entities |
| generateTestEntities(numOfEntities, collectionName); |
| // Query where madeup = true (the last half) and the last quarter of entries |
| QueryParameters params = new QueryParameters() |
| .setQuery("where sometestprop = 'testprop'"); |
| Collection coll = this.app().collection(collectionName).get(params); |
| // results should have madeup = true and ordinal 15-19 |
| assertEquals(10, coll.getResponse().getEntityCount()); |
| |
| |
| } |
| |
| @Test |
| public void someTestPropPartialContains() throws IOException { |
| int numOfEntities = 20; |
| String collectionName = "cantaloupes"; |
| // create our test entities |
| generateTestEntities(numOfEntities, collectionName); |
| // Query where madeup = true (the last half) and the last quarter of entries |
| QueryParameters params = new QueryParameters() |
| .setQuery("where sometestprop contains 'test*'"); |
| Collection coll = this.app().collection(collectionName).get(params); |
| // results should have madeup = true and ordinal 15-19 |
| assertEquals(10, coll.getResponse().getEntityCount()); |
| |
| |
| } |
| |
| /** |
| * Test an exclusive AND query to ensure the correct results are returned |
| * |
| * @throws IOException |
| */ |
| @Test |
| public void queryAndExclusive() throws IOException { |
| int numOfEntities = 20; |
| String collectionName = "dates"; |
| |
| generateTestEntities(numOfEntities, collectionName); |
| |
| //Query where madeup = true (the last half) and NOT the last quarter of entries |
| QueryParameters params = new QueryParameters() |
| .setQuery("select * where madeup = true AND NOT ordinal >= " + (numOfEntities - numOfEntities / 4)); |
| Collection coll = this.app().collection(collectionName).get(params); |
| //results should have madeup = true and ordinal 10-14 |
| assertEquals(numOfEntities / 4, coll.getResponse().getEntityCount()); |
| // loop though entities that were returned, and test against the ordinals and values we are |
| // expecting, starting with the last expected entity and decrementing |
| int index = 14; |
| while (coll.hasNext()) { |
| Entity entity = coll.next(); |
| //ensure the 'madeup' property is set to true |
| assertTrue(Boolean.parseBoolean(entity.get("madeup").toString())); |
| //make sure the correct ordinal properties are returned |
| assertEquals(index--, Long.parseLong(entity.get("ordinal").toString())); |
| } |
| } |
| |
| /** |
| * Test an inclusive OR query to ensure the correct results are returned |
| * |
| * @throws IOException |
| */ |
| @Test |
| public void queryOrInclusive() throws IOException { |
| int numOfEntities = 20; |
| String collectionName = "elderberries"; |
| |
| generateTestEntities(numOfEntities, collectionName); |
| |
| //Query where madeup = false (the first half) or the last quarter of entries |
| QueryParameters params = new QueryParameters() |
| .setQuery("select * where madeup = false OR ordinal >= " + (numOfEntities - numOfEntities / 4)) |
| .setLimit((numOfEntities)); |
| Collection coll = this.app().collection(collectionName).get(params); |
| int index = numOfEntities - 1; |
| int count = 0; |
| int returnSize = coll.getResponse().getEntityCount(); |
| //loop through the returned results |
| for (int i = 0; i < returnSize; i++, index--) { |
| count++; |
| Entity entity = coll.getResponse().getEntities().get(i); |
| logger.info(String.valueOf(entity.get("ordinal")) + " " + String.valueOf(entity.get("madeup"))); |
| //if the entity is in the first half, the property "madeup" should be false |
| if (index < numOfEntities / 2) { |
| assertFalse(Boolean.parseBoolean(String.valueOf(entity.get("madeup")))); |
| } |
| //else if the entity is in the second half, the property "madeup" should be true |
| else if (index >= (numOfEntities - numOfEntities / 4)) { |
| assertTrue(Boolean.parseBoolean(String.valueOf(entity.get("madeup")))); |
| } |
| //test to ensure that the ordinal is in the first half (where "madeup = false") |
| //OR that the ordinal is in the last quarter of the entity list (where "ordinal >= (numOfEntities - numOfEntities / 4))") |
| long ordinal = Long.parseLong(String.valueOf(entity.get("ordinal"))); |
| assertTrue(ordinal < (numOfEntities / 2) || ordinal >= (numOfEntities - numOfEntities / 4)); |
| } |
| //results should have madeup = false or ordinal 0-9,15-19 |
| //A total of 15 entities should be returned |
| assertEquals(3 * numOfEntities / 4, count); |
| } |
| |
| /** |
| * Test an exclusive OR query to ensure the correct results are returned |
| * |
| * @throws IOException |
| */ |
| @Test |
| public void queryOrExclusive() throws IOException { |
| int numOfEntities = 30; |
| String collectionName = "figs"; |
| |
| generateTestEntities(numOfEntities, collectionName); |
| |
| //Query where the verb = 'go' (half) OR the last quarter by ordinal, but NOT where verb = 'go' AND the ordinal is in the last quarter |
| QueryParameters params = new QueryParameters() |
| .setQuery("select * where (verb = 'go' OR ordinal >= " + (numOfEntities - numOfEntities / 4) + ") AND NOT (verb = 'go' AND ordinal >= " + (numOfEntities - numOfEntities / 4) + ")") |
| .setLimit((numOfEntities)); |
| Collection coll = this.app().collection(collectionName).get(params); |
| |
| int index = numOfEntities - 1; |
| int count = 0; |
| int returnSize = coll.getResponse().getEntityCount(); |
| for (int i = 0; i < returnSize; i++, index--) { |
| count++; |
| Entity entity = coll.getResponse().getEntities().get(i); |
| long ordinal = Long.parseLong(String.valueOf(entity.get("ordinal"))); |
| logger.info(ordinal + " " + String.valueOf(entity.get("verb"))); |
| //if the entity is in the first three quarters, the property "verb" should be "go" |
| if (ordinal < (numOfEntities - numOfEntities / 4)) { |
| assertEquals("go", String.valueOf(entity.get("verb"))); |
| } |
| //if the entity is in the last quarter, the property "verb" should be "stop" |
| else if (ordinal >= (numOfEntities - numOfEntities / 4)) { |
| assertEquals("stop", String.valueOf(entity.get("verb"))); |
| } |
| } |
| //results should be even ordinals in the first 3 quarters and odd ordinals from the last quarter |
| //Should return 1 more than half the number of entities |
| assertEquals(1 + numOfEntities / 2, count); |
| } |
| |
| /** |
| * Ensure limit is respected in queries |
| * 1. Query all entities where "madeup = true" |
| * 2. Limit the query to half of the number of entities |
| * 3. Ensure the correct entities are returned |
| * |
| * @throws IOException |
| */ |
| @Test |
| public void queryWithAndPastLimit() throws IOException { |
| int numValuesTested = 40; |
| |
| String collectionName = "grapes"; |
| generateTestEntities(numValuesTested, collectionName); |
| //3. Query all entities where "madeup = true" |
| String errorQuery = "select * where madeup = true"; |
| QueryParameters params = new QueryParameters() |
| .setQuery(errorQuery) |
| .setLimit(numValuesTested / 2);//4. Limit the query to half of the number of entities |
| Collection coll = this.app().collection(collectionName).get(params); |
| //5. Ensure the correct entities are returned |
| assertEquals(numValuesTested / 2, coll.getResponse().getEntityCount()); |
| while (coll.hasNext()) { |
| assertTrue(Boolean.parseBoolean(coll.next().get("madeup").toString())); |
| } |
| } |
| |
| |
| /** |
| * Test negated query |
| * 1. Query all entities where "NOT verb = 'go'" |
| * 2. Limit the query to half of the number of entities |
| * 3. Ensure the returned entities have "verb = 'stop'" |
| * |
| * @throws IOException |
| */ |
| @Test |
| public void queryNegated() throws IOException { |
| int numValuesTested = 20; |
| |
| String collectionName = "huckleberries"; |
| generateTestEntities(numValuesTested, collectionName); |
| //1. Query all entities where "NOT verb = 'go'" |
| String query = "select * where not verb = 'go'"; |
| //2. Limit the query to half of the number of entities |
| QueryParameters params = new QueryParameters().setQuery(query).setLimit(numValuesTested / 2); |
| Collection coll = this.app().collection(collectionName).get(params); |
| //3. Ensure the returned entities have "verb = 'stop'" |
| assertEquals(numValuesTested / 2, coll.getResponse().getEntityCount()); |
| while (coll.hasNext()) { |
| assertEquals("stop", coll.next().get("verb").toString()); |
| } |
| |
| |
| } |
| |
| /** |
| * Ensure queries return a subset of entities in the correct order |
| * 1. Query for a subset of the entities |
| * 2. Validate that the correct entities are returned |
| * |
| * @throws Exception |
| */ |
| @Test |
| public void queryReturnCount() throws Exception { |
| int numValuesTested = 20; |
| |
| String collectionName = "lemons"; |
| generateTestEntities(numValuesTested, collectionName); |
| //1. Query for a subset of the entities |
| String inCorrectQuery = "select * where ordinal >= " + (numValuesTested / 2) + " order by ordinal asc"; |
| QueryParameters params = new QueryParameters().setQuery(inCorrectQuery).setLimit(numValuesTested / 2); |
| Collection coll = this.app().collection(collectionName).get(params); |
| //2. Validate that the correct entities are returned |
| assertEquals(numValuesTested / 2, coll.getResponse().getEntityCount()); |
| |
| List<Entity> entitiesReturned = coll.getResponse().getEntities(); |
| for (int i = 0; i < numValuesTested / 2; i++) { |
| assertEquals(numValuesTested / 2 + i, Integer.parseInt(entitiesReturned.get(i).get("ordinal").toString())); |
| } |
| |
| } |
| |
| /** |
| * Validate sort order with AND/OR query |
| * 1. Use AND/OR query to retrieve entities |
| * 2. Verify the order of results |
| * |
| * @throws Exception |
| */ |
| @Test |
| public void queryCheckAsc() throws Exception { |
| int numOfEntities = 20; |
| String collectionName = "melons"; |
| |
| generateTestEntities(numOfEntities, collectionName); |
| |
| //2. Use AND/OR query to retrieve entities |
| String inquisitiveQuery = "select * where Ordinal gte 0 and Ordinal lte " + (numOfEntities / 2) |
| + " or WhoHelpedYou eq 'Ruff' ORDER BY Ordinal asc"; |
| QueryParameters params = new QueryParameters().setQuery(inquisitiveQuery).setLimit(numOfEntities / 2); |
| Collection activities = this.app().collection(collectionName).get(params); |
| |
| //3. Verify the order of results |
| assertEquals(numOfEntities / 2, activities.getResponse().getEntityCount()); |
| List<Entity> entitiesReturned = activities.getResponse().getEntities(); |
| for (int i = 0; i < numOfEntities / 2; i++) { |
| assertEquals(i, Integer.parseInt(entitiesReturned.get(i).get("ordinal").toString())); |
| } |
| } |
| |
| |
| /** |
| * Test a standard query |
| * 1. Issue a query |
| * 2. validate that a full page of (10) entities is returned |
| * |
| * @throws Exception |
| */ |
| @Test |
| public void queryReturnCheck() throws Exception { |
| int numOfEntities = 20; |
| String collectionName = "nectarines"; |
| |
| generateTestEntities(numOfEntities, collectionName); |
| |
| //2. Issue a query |
| String inquisitiveQuery = String.format("select * where ordinal >= 0 and ordinal <= %d or WhoHelpedYou = 'Ruff' ORDER BY created", numOfEntities); |
| QueryParameters params = new QueryParameters().setQuery(inquisitiveQuery); |
| Collection coll = this.app().collection(collectionName).get(params); |
| |
| //3. validate that a full page of (10) entities is returned |
| assertEquals(10, coll.getResponse().getEntityCount()); |
| List<Entity> entitiesReturned = coll.getResponse().getEntities(); |
| for (int i = 0; i < 10; i++) { |
| assertEquals(i, Integer.parseInt(entitiesReturned.get(i).get("ordinal").toString())); |
| } |
| } |
| |
| /** |
| * Test a standard query using alphanumeric operators |
| * 1. Issue a query using alphanumeric operators |
| * 2. validate that a full page of (10) entities is returned |
| * |
| * @throws Exception |
| */ |
| @Test |
| public void queryReturnCheckWithShortHand() throws Exception { |
| int numOfEntities = 10; |
| String collectionName = "oranges"; |
| |
| generateTestEntities(numOfEntities, collectionName); |
| |
| //2. Issue a query using alphanumeric operators |
| String inquisitiveQuery = "select * where Ordinal gte 0 and Ordinal lte 2000 or WhoHelpedYou eq 'Ruff' ORDER BY created"; |
| QueryParameters params = new QueryParameters().setQuery(inquisitiveQuery); |
| Collection activities = this.app().collection(collectionName).get(params); |
| |
| //3. validate that a full page of (10) entities is returned |
| assertEquals(10, activities.getResponse().getEntityCount()); |
| List<Entity> entitiesReturned = activities.getResponse().getEntities(); |
| for (int i = 0; i < 10; i++) { |
| assertEquals(i, Integer.parseInt(entitiesReturned.get(i).get("ordinal").toString())); |
| } |
| } |
| |
| } |