mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 05:01:07 +00:00
Coverage on query
This commit is contained in:
@ -72,7 +72,6 @@ import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
|||||||
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
||||||
import com.kingsrook.qqq.backend.javalin.QJavalinAccessLogger;
|
import com.kingsrook.qqq.backend.javalin.QJavalinAccessLogger;
|
||||||
import com.kingsrook.qqq.backend.javalin.QJavalinImplementation;
|
import com.kingsrook.qqq.backend.javalin.QJavalinImplementation;
|
||||||
import com.kingsrook.qqq.backend.javalin.QJavalinUtils;
|
|
||||||
import io.javalin.apibuilder.ApiBuilder;
|
import io.javalin.apibuilder.ApiBuilder;
|
||||||
import io.javalin.apibuilder.EndpointGroup;
|
import io.javalin.apibuilder.EndpointGroup;
|
||||||
import io.javalin.http.ContentType;
|
import io.javalin.http.ContentType;
|
||||||
@ -198,16 +197,7 @@ public class QJavalinApiHandler
|
|||||||
// todo - make sure table is supported in this version
|
// todo - make sure table is supported in this version
|
||||||
|
|
||||||
QTableMetaData table = qInstance.getTable(tableName);
|
QTableMetaData table = qInstance.getTable(tableName);
|
||||||
|
validateTableAndVersion(context, version, table);
|
||||||
if(table == null)
|
|
||||||
{
|
|
||||||
throw (new QNotFoundException("Could not find any resources at path " + context.path()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!getApiVersionRange(table).includes(new APIVersion(version)))
|
|
||||||
{
|
|
||||||
throw (new QNotFoundException("This version of this API does not contain the resource path " + context.path()));
|
|
||||||
}
|
|
||||||
|
|
||||||
GetInput getInput = new GetInput();
|
GetInput getInput = new GetInput();
|
||||||
|
|
||||||
@ -270,16 +260,7 @@ public class QJavalinApiHandler
|
|||||||
// todo - make sure table is supported in this version
|
// todo - make sure table is supported in this version
|
||||||
|
|
||||||
QTableMetaData table = qInstance.getTable(tableName);
|
QTableMetaData table = qInstance.getTable(tableName);
|
||||||
|
validateTableAndVersion(context, version, table);
|
||||||
if(table == null)
|
|
||||||
{
|
|
||||||
throw (new QNotFoundException("Could not find any resources at path " + context.path()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!getApiVersionRange(table).includes(new APIVersion(version)))
|
|
||||||
{
|
|
||||||
throw (new QNotFoundException("This version of this API does not contain the resource path " + context.path()));
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryInput queryInput = new QueryInput();
|
QueryInput queryInput = new QueryInput();
|
||||||
setupSession(context, queryInput);
|
setupSession(context, queryInput);
|
||||||
@ -308,7 +289,18 @@ public class QJavalinApiHandler
|
|||||||
badRequestMessages.add("pageSize must be between 1 and 1000.");
|
badRequestMessages.add("pageSize must be between 1 and 1000.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Integer pageNo = Objects.requireNonNullElse(QJavalinUtils.integerQueryParam(context, "pageNo"), 1);
|
Integer pageNo = 1;
|
||||||
|
if(StringUtils.hasContent(context.queryParam("pageNo")))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pageNo = ValueUtils.getValueAsInteger(context.queryParam("pageNo"));
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
badRequestMessages.add("Could not parse pageNo as an integer");
|
||||||
|
}
|
||||||
|
}
|
||||||
if(pageNo < 1)
|
if(pageNo < 1)
|
||||||
{
|
{
|
||||||
badRequestMessages.add("pageNo must be greater than 0.");
|
badRequestMessages.add("pageNo must be greater than 0.");
|
||||||
@ -432,7 +424,7 @@ public class QJavalinApiHandler
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw (new QBadRequestException("Requested failed with " + badRequestMessages.size() + " reasons: " + StringUtils.join(" \n", badRequestMessages)));
|
throw (new QBadRequestException("Request failed with " + badRequestMessages.size() + " reasons: " + StringUtils.join(" \n", badRequestMessages)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -482,6 +474,30 @@ public class QJavalinApiHandler
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private static void validateTableAndVersion(Context context, String version, QTableMetaData table) throws QNotFoundException
|
||||||
|
{
|
||||||
|
if(table == null)
|
||||||
|
{
|
||||||
|
throw (new QNotFoundException("Could not find any resources at path " + context.path()));
|
||||||
|
}
|
||||||
|
|
||||||
|
APIVersion requestApiVersion = new APIVersion(version);
|
||||||
|
if(!ApiMiddlewareType.getApiInstanceMetaData(qInstance).getSupportedVersions().contains(requestApiVersion))
|
||||||
|
{
|
||||||
|
throw (new QNotFoundException("This version of this API does not contain the resource path " + context.path()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!getApiVersionRange(table).includes(requestApiVersion))
|
||||||
|
{
|
||||||
|
throw (new QNotFoundException("This version of this API does not contain the resource path " + context.path()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -104,4 +104,37 @@ public class APIVersion implements Comparable<APIVersion>
|
|||||||
{
|
{
|
||||||
return (version);
|
return (version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o)
|
||||||
|
{
|
||||||
|
if(this == o)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(o == null || getClass() != o.getClass())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
APIVersion that = (APIVersion) o;
|
||||||
|
return Objects.equals(version, that.version);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Override
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return Objects.hash(version);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,12 +29,12 @@ import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
|
|||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QInstanceValidationException;
|
import com.kingsrook.qqq.backend.core.exceptions.QInstanceValidationException;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertOutput;
|
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.javalin.QJavalinImplementation;
|
import com.kingsrook.qqq.backend.javalin.QJavalinImplementation;
|
||||||
import kong.unirest.HttpResponse;
|
import kong.unirest.HttpResponse;
|
||||||
import kong.unirest.Unirest;
|
import kong.unirest.Unirest;
|
||||||
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.junit.jupiter.api.AfterAll;
|
import org.junit.jupiter.api.AfterAll;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
@ -123,10 +123,7 @@ class QJavalinApiHandlerTest extends BaseTest
|
|||||||
@Test
|
@Test
|
||||||
void testGet200() throws QException
|
void testGet200() throws QException
|
||||||
{
|
{
|
||||||
InsertInput insertInput = new InsertInput();
|
insertTestRecord();
|
||||||
insertInput.setTableName(TestUtils.TABLE_NAME_PERSON);
|
|
||||||
insertInput.setRecords(List.of(new QRecord().withValue("id", 1).withValue("firstName", "Darin").withValue("lastName", "Kelkhoff")));
|
|
||||||
InsertOutput insertOutput = new InsertAction().execute(insertInput);
|
|
||||||
|
|
||||||
HttpResponse<String> response = Unirest.get(BASE_URL + "/api/" + VERSION + "/person/1").asString();
|
HttpResponse<String> response = Unirest.get(BASE_URL + "/api/" + VERSION + "/person/1").asString();
|
||||||
assertEquals(200, response.getStatus());
|
assertEquals(200, response.getStatus());
|
||||||
@ -141,16 +138,12 @@ class QJavalinApiHandlerTest extends BaseTest
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@Test
|
private static void insertTestRecord() throws QException
|
||||||
void testQuery400()
|
|
||||||
{
|
{
|
||||||
HttpResponse<String> response = Unirest.get(BASE_URL + "/api/" + VERSION + "/person/query?asdf=Darin&orderBy=asdf asdf").asString();
|
InsertInput insertInput = new InsertInput();
|
||||||
assertEquals(400, response.getStatus());
|
insertInput.setTableName(TestUtils.TABLE_NAME_PERSON);
|
||||||
JSONObject jsonObject = new JSONObject(response.getBody());
|
insertInput.setRecords(List.of(new QRecord().withValue("id", 1).withValue("firstName", "Darin").withValue("lastName", "Kelkhoff")));
|
||||||
String error = jsonObject.getString("error");
|
new InsertAction().execute(insertInput);
|
||||||
assertThat(error).contains("orderBy direction for field asdf must be either ASC or DESC");
|
|
||||||
assertThat(error).contains("Unrecognized orderBy field name: asdf");
|
|
||||||
assertThat(error).contains("Unrecognized filter criteria field: asdf");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -159,9 +152,49 @@ class QJavalinApiHandlerTest extends BaseTest
|
|||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@Test
|
@Test
|
||||||
void testQuery()
|
void testQuery404()
|
||||||
{
|
{
|
||||||
HttpResponse<String> response = Unirest.get(BASE_URL + "/api/" + VERSION + "/person/query?firstName=Darin&orderBy=firstName desc").asString();
|
assertError(404, BASE_URL + "/api/" + VERSION + "/notATable/query?");
|
||||||
|
assertError(404, BASE_URL + "/api/notAVersion/person/query?");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testQuery400()
|
||||||
|
{
|
||||||
|
String base = BASE_URL + "/api/" + VERSION + "/person/query?";
|
||||||
|
|
||||||
|
assertError("Could not parse pageNo as an integer", base + "pageNo=foo");
|
||||||
|
assertError("pageNo must be greater than 0", base + "pageNo=0");
|
||||||
|
|
||||||
|
assertError("Could not parse pageSize as an integer", base + "pageSize=foo");
|
||||||
|
assertError("pageSize must be between 1 and 1000.", base + "pageSize=0");
|
||||||
|
assertError("pageSize must be between 1 and 1000.", base + "pageSize=1001");
|
||||||
|
|
||||||
|
assertError("booleanOperator must be either AND or OR", base + "booleanOperator=not");
|
||||||
|
assertError("includeCount must be either true or false", base + "includeCount=maybe");
|
||||||
|
|
||||||
|
assertError("orderBy direction for field firstName must be either ASC or DESC", base + "orderBy=firstName foo");
|
||||||
|
assertError("Unrecognized format for orderBy clause: firstName asc foo", base + "orderBy=firstName asc foo");
|
||||||
|
assertError("Unrecognized orderBy field name: foo", base + "orderBy=foo");
|
||||||
|
assertError("Unrecognized filter criteria field: foo", base + "foo=bar");
|
||||||
|
|
||||||
|
assertError("Request failed with 2 reasons", base + "foo=bar&bar=baz");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testQuery200NoParams()
|
||||||
|
{
|
||||||
|
HttpResponse<String> response = Unirest.get(BASE_URL + "/api/" + VERSION + "/person/query").asString();
|
||||||
assertEquals(200, response.getStatus());
|
assertEquals(200, response.getStatus());
|
||||||
JSONObject jsonObject = new JSONObject(response.getBody());
|
JSONObject jsonObject = new JSONObject(response.getBody());
|
||||||
assertEquals(0, jsonObject.getInt("count"));
|
assertEquals(0, jsonObject.getInt("count"));
|
||||||
@ -169,4 +202,69 @@ class QJavalinApiHandlerTest extends BaseTest
|
|||||||
assertEquals(50, jsonObject.getInt("pageSize"));
|
assertEquals(50, jsonObject.getInt("pageSize"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testQuery200SomethingFound() throws QException
|
||||||
|
{
|
||||||
|
insertTestRecord();
|
||||||
|
|
||||||
|
HttpResponse<String> response = Unirest.get(BASE_URL + "/api/" + VERSION + "/person/query").asString();
|
||||||
|
assertEquals(200, response.getStatus());
|
||||||
|
JSONObject jsonObject = new JSONObject(response.getBody());
|
||||||
|
assertEquals(1, jsonObject.getInt("count"));
|
||||||
|
assertEquals(1, jsonObject.getInt("pageNo"));
|
||||||
|
assertEquals(50, jsonObject.getInt("pageSize"));
|
||||||
|
|
||||||
|
JSONArray jsonArray = jsonObject.getJSONArray("records");
|
||||||
|
jsonObject = jsonArray.getJSONObject(0);
|
||||||
|
assertEquals(1, jsonObject.getInt("id"));
|
||||||
|
assertEquals("Darin", jsonObject.getString("firstName"));
|
||||||
|
assertEquals("Kelkhoff", jsonObject.getString("lastName"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testQuery200ManyParams()
|
||||||
|
{
|
||||||
|
HttpResponse<String> response = Unirest.get(BASE_URL + "/api/" + VERSION + "/person/query?pageSize=49&pageNo=2&includeCount=true&booleanOperator=AND&firstName=Darin&orderBy=firstName desc").asString();
|
||||||
|
assertEquals(200, response.getStatus());
|
||||||
|
JSONObject jsonObject = new JSONObject(response.getBody());
|
||||||
|
assertEquals(0, jsonObject.getInt("count"));
|
||||||
|
assertEquals(2, jsonObject.getInt("pageNo"));
|
||||||
|
assertEquals(49, jsonObject.getInt("pageSize"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private void assertError(Integer statusCode, String url)
|
||||||
|
{
|
||||||
|
HttpResponse<String> response = Unirest.get(url).asString();
|
||||||
|
assertEquals(statusCode, response.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private void assertError(String expectedErrorMessage, String url)
|
||||||
|
{
|
||||||
|
HttpResponse<String> response = Unirest.get(url).asString();
|
||||||
|
assertEquals(400, response.getStatus());
|
||||||
|
JSONObject jsonObject = new JSONObject(response.getBody());
|
||||||
|
String error = jsonObject.getString("error");
|
||||||
|
assertThat(error).contains(expectedErrorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Reference in New Issue
Block a user