mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-19 05:30:43 +00:00
CE-1887 Initial (not quite finished) version 1 middleware api spec
This commit is contained in:
@ -0,0 +1,356 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2024. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.qqq.api.wip;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
import io.javalin.config.Key;
|
||||
import io.javalin.http.Context;
|
||||
import io.javalin.http.HandlerType;
|
||||
import io.javalin.http.HttpStatus;
|
||||
import io.javalin.json.JsonMapper;
|
||||
import io.javalin.plugin.ContextPlugin;
|
||||
import io.javalin.security.RouteRole;
|
||||
import jakarta.servlet.ServletOutputStream;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class TestContext implements Context
|
||||
{
|
||||
private Map<String, String> queryParams = new LinkedHashMap<>();
|
||||
private Map<String, String> pathParams = new LinkedHashMap<>();
|
||||
private Map<String, String> formParams = new LinkedHashMap<>();
|
||||
|
||||
private InputStream result;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Constructor
|
||||
**
|
||||
*******************************************************************************/
|
||||
public TestContext()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
public TestContext withQueryParam(String key, String value)
|
||||
{
|
||||
queryParams.put(key, value);
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
public TestContext withPathParam(String key, String value)
|
||||
{
|
||||
pathParams.put(key, value);
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
public TestContext withFormParam(String key, String value)
|
||||
{
|
||||
formParams.put(key, value);
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public String queryParam(String key)
|
||||
{
|
||||
return queryParams.get(key);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public String formParam(String key)
|
||||
{
|
||||
return formParams.get(key);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public boolean strictContentTypes()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public HttpServletRequest req()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public HttpServletResponse res()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public HandlerType handlerType()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public String matchedPath()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public String endpointHandlerPath()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public <T> T appData(Key<T> key)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public JsonMapper jsonMapper()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public <T> T with(Class<? extends ContextPlugin<?, T>> aClass)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public String pathParam(String key)
|
||||
{
|
||||
return pathParams.get(key);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public Map<String, String> pathParamMap()
|
||||
{
|
||||
return pathParams;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public ServletOutputStream outputStream()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public Context minSizeForCompression(int i)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public Context result(InputStream inputStream)
|
||||
{
|
||||
this.result = inputStream;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public InputStream resultInputStream()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public void future(Supplier<? extends CompletableFuture<?>> supplier)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public void redirect(String s, HttpStatus httpStatus)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public void writeJsonStream(Stream<?> stream)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public Context skipRemainingHandlers()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public Set<RouteRole> routeRoles()
|
||||
{
|
||||
return Set.of();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for response
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getResultAsString() throws IOException
|
||||
{
|
||||
byte[] bytes = IOUtils.readFully(result, result.available());
|
||||
return new String(bytes, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2024. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.qqq.api.wip;
|
||||
|
||||
|
||||
import java.util.Map;
|
||||
import com.kingsrook.qqq.openapi.model.Schema;
|
||||
import com.kingsrook.qqq.openapi.model.Type;
|
||||
import org.assertj.core.api.AbstractStringAssert;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class TestUtils
|
||||
{
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
private static void assertStringVsSchema(String string, Schema schema, String path)
|
||||
{
|
||||
String description = "At path " + path;
|
||||
final AbstractStringAssert<?> assertion = assertThat(string).describedAs(description);
|
||||
|
||||
Type type = Type.valueOf(schema.getType().toUpperCase());
|
||||
switch(type)
|
||||
{
|
||||
case OBJECT ->
|
||||
{
|
||||
assertion.startsWith("{");
|
||||
JSONObject object = new JSONObject(string);
|
||||
|
||||
for(Map.Entry<String, Schema> entry : schema.getProperties().entrySet())
|
||||
{
|
||||
// todo deal with optional
|
||||
Object subObject = object.get(entry.getKey());
|
||||
assertStringVsSchema(subObject.toString(), entry.getValue(), path + "/" + entry.getKey());
|
||||
}
|
||||
}
|
||||
case ARRAY ->
|
||||
{
|
||||
assertion.startsWith("[");
|
||||
JSONArray array = new JSONArray(string);
|
||||
|
||||
for(int i = 0; i < array.length(); i++)
|
||||
{
|
||||
Object subObject = array.get(i);
|
||||
assertStringVsSchema(subObject.toString(), schema.getItems(), path + "[" + i + "]");
|
||||
}
|
||||
}
|
||||
case BOOLEAN ->
|
||||
{
|
||||
assertion.matches("(true|false)");
|
||||
}
|
||||
case INTEGER ->
|
||||
{
|
||||
assertion.matches("-?\\d+");
|
||||
}
|
||||
case NUMBER ->
|
||||
{
|
||||
assertion.matches("-?\\d+(\\.\\d+)?");
|
||||
}
|
||||
case STRING ->
|
||||
{
|
||||
assertion.matches("\".*\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2024. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.qqq.api.wip.v1;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.api.wip.TestContext;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Unit test for QueryGetSpecV1
|
||||
*******************************************************************************/
|
||||
class QueryGetSpecV1Test
|
||||
{
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Test
|
||||
void testBuildInput() throws Exception
|
||||
{
|
||||
TestContext context = new TestContext()
|
||||
.withPathParam("table", "person")
|
||||
.withQueryParam("filter", "{}");
|
||||
|
||||
// QueryMiddlewareInput queryMiddlewareInput = new QueryGetSpecV1().buildInput(context);
|
||||
// assertEquals("person", queryMiddlewareInput.getTable());
|
||||
// assertNotNull(queryMiddlewareInput.getFilter());
|
||||
// assertEquals(0, queryMiddlewareInput.getFilter().getCriteria().size());
|
||||
// assertEquals(0, queryMiddlewareInput.getFilter().getOrderBys().size());
|
||||
// assertNull(queryMiddlewareInput.getQueryJoins());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Test
|
||||
void testBuildOutput() throws Exception
|
||||
{
|
||||
TestContext context = new TestContext();
|
||||
QueryOutput queryOutput = new QueryOutput(new QueryInput());
|
||||
queryOutput.addRecord(new QRecord().withValue("firstName", "Darin").withDisplayValue("firstName", "Darin"));
|
||||
|
||||
// QueryGetSpecV1 queryGetSpecV1 = new QueryGetSpecV1();
|
||||
// queryGetSpecV1.buildOutput(context, new QueryMiddlewareOutput(queryOutput));
|
||||
// String resultJson = context.getResultAsString();
|
||||
// TestUtils.assertResultJsonVsSpec(queryGetSpecV1.defineSimpleSuccessResponse(), resultJson);
|
||||
}
|
||||
|
||||
}
|
@ -57,6 +57,7 @@ class QJavalinProcessHandlerTest extends QJavalinTestBase
|
||||
/*******************************************************************************
|
||||
** test running a process
|
||||
**
|
||||
** Note: ported to v1
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void test_processGreetInit()
|
||||
@ -73,6 +74,7 @@ class QJavalinProcessHandlerTest extends QJavalinTestBase
|
||||
/*******************************************************************************
|
||||
** test running a process that requires rows, but we didn't tell it how to get them.
|
||||
**
|
||||
** Note: ported to v1
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void test_processRequiresRowsButNotSpecified()
|
||||
@ -90,6 +92,7 @@ class QJavalinProcessHandlerTest extends QJavalinTestBase
|
||||
/*******************************************************************************
|
||||
** test running a process and telling it rows to load via recordIds param
|
||||
**
|
||||
** Note: ported to v1
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void test_processRequiresRowsWithRecordIdParam()
|
||||
@ -108,6 +111,7 @@ class QJavalinProcessHandlerTest extends QJavalinTestBase
|
||||
/*******************************************************************************
|
||||
** test running a process and telling it rows to load via filter JSON
|
||||
**
|
||||
** Note: ported to v1
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void test_processRequiresRowsWithFilterJSON()
|
||||
@ -169,6 +173,7 @@ class QJavalinProcessHandlerTest extends QJavalinTestBase
|
||||
/*******************************************************************************
|
||||
** test running a process with field values on the query string
|
||||
**
|
||||
** Note: ported to v1
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void test_processGreetInitWithQueryValues()
|
||||
@ -185,6 +190,7 @@ class QJavalinProcessHandlerTest extends QJavalinTestBase
|
||||
/*******************************************************************************
|
||||
** test init'ing a process that goes async
|
||||
**
|
||||
** Note: ported to v1, but needs todo more - the status part too in a higher-level
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void test_processInitGoingAsync() throws InterruptedException
|
||||
@ -221,6 +227,7 @@ class QJavalinProcessHandlerTest extends QJavalinTestBase
|
||||
/*******************************************************************************
|
||||
** test init'ing a process that does NOT goes async
|
||||
**
|
||||
** Note: not ported to v1, but feels redundant, so, not going to.
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void test_processInitNotGoingAsync()
|
||||
|
@ -24,11 +24,17 @@ package com.kingsrook.qqq.backend.javalin;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
import io.javalin.config.Key;
|
||||
import io.javalin.http.Context;
|
||||
import io.javalin.http.HandlerType;
|
||||
import io.javalin.http.HttpStatus;
|
||||
import io.javalin.json.JsonMapper;
|
||||
import io.javalin.plugin.ContextPlugin;
|
||||
import io.javalin.security.RouteRole;
|
||||
import jakarta.servlet.ServletOutputStream;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
@ -133,6 +139,14 @@ class QJavalinUtilsTest
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean strictContentTypes()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@ -157,17 +171,6 @@ class QJavalinUtilsTest
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public <T> T appAttribute(@NotNull String s)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@ -204,6 +207,30 @@ class QJavalinUtilsTest
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public <T> T appData(@NotNull Key<T> key)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull JsonMapper jsonMapper()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public <T> T with(@NotNull Class<? extends ContextPlugin<?, T>> aClass)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@ -240,6 +267,14 @@ class QJavalinUtilsTest
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull Context minSizeForCompression(int i)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@ -283,5 +318,29 @@ class QJavalinUtilsTest
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void writeJsonStream(@NotNull Stream<?> stream)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull Context skipRemainingHandlers()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull Set<RouteRole> routeRoles()
|
||||
{
|
||||
return Set.of();
|
||||
}
|
||||
}
|
||||
}
|
@ -62,6 +62,10 @@ import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.joins.JoinOn;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.joins.JoinType;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.joins.QJoinMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.layout.QAppMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.permissions.PermissionLevel;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.permissions.QPermissionRules;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.PVSValueFormatAndFields;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSource;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSourceType;
|
||||
@ -189,11 +193,35 @@ public class TestUtils
|
||||
throw new IllegalStateException("Error adding script tables to instance");
|
||||
}
|
||||
|
||||
defineApps(qInstance);
|
||||
|
||||
return (qInstance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void defineApps(QInstance qInstance)
|
||||
{
|
||||
QAppMetaData childApp = new QAppMetaData()
|
||||
.withName("childApp")
|
||||
.withLabel("Child App")
|
||||
.withIcon(new QIcon().withName("child_friendly"))
|
||||
.withPermissionRules(new QPermissionRules().withLevel(PermissionLevel.NOT_PROTECTED))
|
||||
.withChild(qInstance.getProcess(PROCESS_NAME_GREET_PEOPLE_INTERACTIVE));
|
||||
qInstance.addApp(childApp);
|
||||
|
||||
QAppMetaData exampleApp = new QAppMetaData()
|
||||
.withName("homeApp")
|
||||
.withLabel("Home App")
|
||||
.withIcon(new QIcon().withName("home"))
|
||||
.withPermissionRules(new QPermissionRules().withLevel(PermissionLevel.NOT_PROTECTED))
|
||||
.withChild(childApp)
|
||||
.withChild(qInstance.getTable(TABLE_NAME_PERSON));
|
||||
qInstance.addApp(exampleApp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@ -690,7 +718,7 @@ public class TestUtils
|
||||
{
|
||||
return (new RenderWidgetOutput(new RawHTML("title",
|
||||
QContext.getQSession().getValue(QSession.VALUE_KEY_USER_TIMEZONE_OFFSET_MINUTES)
|
||||
+ "|" + QContext.getQSession().getValue(QSession.VALUE_KEY_USER_TIMEZONE)
|
||||
+ "|" + QContext.getQSession().getValue(QSession.VALUE_KEY_USER_TIMEZONE)
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2024. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.qqq.middleware.javalin.schemabuilder;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
import com.kingsrook.qqq.middleware.javalin.specs.v1.responses.AuthenticationMetaDataResponseV1;
|
||||
import com.kingsrook.qqq.middleware.javalin.specs.v1.responses.MetaDataResponseV1;
|
||||
import com.kingsrook.qqq.middleware.javalin.specs.v1.responses.ProcessInitOrStepOrStatusResponseV1;
|
||||
import com.kingsrook.qqq.middleware.javalin.specs.v1.responses.components.AppTreeNode;
|
||||
import com.kingsrook.qqq.openapi.model.Schema;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Unit test for SchemaBuilder
|
||||
*******************************************************************************/
|
||||
class SchemaBuilderTest
|
||||
{
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void testIncludesAOneOf()
|
||||
{
|
||||
Schema schema = new SchemaBuilder().classToSchema(AuthenticationMetaDataResponseV1.class);
|
||||
System.out.println(schema);
|
||||
|
||||
Schema valuesSchema = schema.getProperties().get("values");
|
||||
List<Schema> oneOf = valuesSchema.getOneOf();
|
||||
assertEquals(2, oneOf.size());
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void testUsesIncludeProperties()
|
||||
{
|
||||
Schema schema = new SchemaBuilder().classToSchema(ProcessInitOrStepOrStatusResponseV1.TypedResponse.class);
|
||||
for(Schema oneOf : schema.getOneOf())
|
||||
{
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// all of the wrapped one-of schemas should contain these fields from the parent class //
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
assertTrue(oneOf.getProperties().containsKey("type"));
|
||||
assertTrue(oneOf.getProperties().containsKey("processUUID"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void testDescriptionOnGetters()
|
||||
{
|
||||
Schema schema = new SchemaBuilder().classToSchema(MetaDataResponseV1.class);
|
||||
assertTrue(schema.getProperties().containsKey("apps"));
|
||||
assertNotNull(schema.getProperties().get("apps").getDescription());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void testRecursive()
|
||||
{
|
||||
Schema schema = new SchemaBuilder().classToSchema(AppTreeNode.class);
|
||||
Schema childrenSchema = schema.getProperties().get("children");
|
||||
assertNotNull(childrenSchema.getItems());
|
||||
System.out.println(schema);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2024. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.qqq.middleware.javalin.specs;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.modules.backend.implementations.memory.MemoryRecordStore;
|
||||
import com.kingsrook.qqq.backend.javalin.TestUtils;
|
||||
import io.javalin.Javalin;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public abstract class SpecTestBase
|
||||
{
|
||||
private static int PORT = 6263;
|
||||
|
||||
protected static Javalin service;
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
protected abstract AbstractEndpointSpec<?, ?, ?> getSpec();
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
protected abstract String getVersion();
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
protected String getBaseUrlAndPath()
|
||||
{
|
||||
return "http://localhost:" + PORT + "/qqq/" + getVersion();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@BeforeEach
|
||||
@AfterEach
|
||||
void beforeAndAfterEach()
|
||||
{
|
||||
MemoryRecordStore.fullReset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@BeforeEach
|
||||
void beforeEach() throws Exception
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// during initial dev here, we were having issues running multiple tests together, //
|
||||
// where the second (but not first, and not any after second) would fail w/ javalin //
|
||||
// not responding... so, this "works" - to constantly change our port, and stop //
|
||||
// and restart aggresively... could be optimized, but it works. //
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
PORT++;
|
||||
if(service != null)
|
||||
{
|
||||
service.stop();
|
||||
service = null;
|
||||
}
|
||||
|
||||
if(service == null)
|
||||
{
|
||||
service = Javalin.create(config ->
|
||||
{
|
||||
config.router.apiBuilder(() -> getSpec().defineRoute(getVersion()));
|
||||
}
|
||||
).start(PORT);
|
||||
}
|
||||
|
||||
TestUtils.primeTestDatabase();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@AfterAll
|
||||
static void afterAll()
|
||||
{
|
||||
if(service != null)
|
||||
{
|
||||
service.stop();
|
||||
service = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2024. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.qqq.middleware.javalin.specs.v1;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
|
||||
import com.kingsrook.qqq.middleware.javalin.specs.AbstractEndpointSpec;
|
||||
import com.kingsrook.qqq.middleware.javalin.specs.SpecTestBase;
|
||||
import kong.unirest.HttpResponse;
|
||||
import kong.unirest.Unirest;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Unit test for AuthenticationMetaDataSpecV1
|
||||
*******************************************************************************/
|
||||
class AuthenticationMetaDataSpecV1Test extends SpecTestBase
|
||||
{
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
protected AbstractEndpointSpec<?, ?, ?> getSpec()
|
||||
{
|
||||
return new AuthenticationMetaDataSpecV1();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
protected String getVersion()
|
||||
{
|
||||
return "v1";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void test()
|
||||
{
|
||||
HttpResponse<String> response = Unirest.get(getBaseUrlAndPath() + "/metaData/authentication").asString();
|
||||
assertEquals(200, response.getStatus());
|
||||
JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody());
|
||||
assertNotNull(jsonObject);
|
||||
assertTrue(jsonObject.has("name"));
|
||||
assertTrue(jsonObject.has("type"));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2024. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.qqq.middleware.javalin.specs.v1;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
|
||||
import com.kingsrook.qqq.middleware.javalin.specs.AbstractEndpointSpec;
|
||||
import com.kingsrook.qqq.middleware.javalin.specs.SpecTestBase;
|
||||
import kong.unirest.HttpResponse;
|
||||
import kong.unirest.Unirest;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Unit test for ManageSessionV1
|
||||
*******************************************************************************/
|
||||
class ManageSessionSpecV1Test extends SpecTestBase
|
||||
{
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
protected AbstractEndpointSpec<?, ?, ?> getSpec()
|
||||
{
|
||||
return new ManageSessionSpecV1();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
protected String getVersion()
|
||||
{
|
||||
return "v1";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void test()
|
||||
{
|
||||
String body = """
|
||||
{
|
||||
"accessToken": "abcdefg"
|
||||
}
|
||||
""";
|
||||
|
||||
HttpResponse<String> response = Unirest.post(getBaseUrlAndPath() + "/manageSession")
|
||||
.header("Content-Type", "application/json")
|
||||
.body(body)
|
||||
.asString();
|
||||
|
||||
assertEquals(200, response.getStatus());
|
||||
JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody());
|
||||
assertNotNull(jsonObject);
|
||||
assertTrue(jsonObject.has("uuid"));
|
||||
assertThat(response.getHeaders().get("Set-Cookie")).anyMatch(s -> s.contains("sessionUUID"));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2024. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.qqq.middleware.javalin.specs.v1;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
|
||||
import com.kingsrook.qqq.middleware.javalin.specs.AbstractEndpointSpec;
|
||||
import com.kingsrook.qqq.middleware.javalin.specs.SpecTestBase;
|
||||
import kong.unirest.HttpResponse;
|
||||
import kong.unirest.Unirest;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Unit test for MetaDataSpecV1
|
||||
*******************************************************************************/
|
||||
class MetaDataSpecV1Test extends SpecTestBase
|
||||
{
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
protected AbstractEndpointSpec<?, ?, ?> getSpec()
|
||||
{
|
||||
return new MetaDataSpecV1();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
protected String getVersion()
|
||||
{
|
||||
return "v1";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void test()
|
||||
{
|
||||
HttpResponse<String> response = Unirest.get(getBaseUrlAndPath() + "/metaData").asString();
|
||||
assertEquals(200, response.getStatus());
|
||||
JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody());
|
||||
assertThat(jsonObject.getJSONObject("tables").length()).isGreaterThanOrEqualTo(1);
|
||||
assertThat(jsonObject.getJSONObject("processes").length()).isGreaterThanOrEqualTo(1);
|
||||
assertThat(jsonObject.getJSONObject("apps").length()).isGreaterThanOrEqualTo(1);
|
||||
assertThat(jsonObject.getJSONArray("appTree").length()).isGreaterThanOrEqualTo(1);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,219 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2024. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.qqq.middleware.javalin.specs.v1;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
import com.kingsrook.qqq.backend.core.logging.QCollectingLogger;
|
||||
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
|
||||
import com.kingsrook.qqq.backend.core.processes.implementations.mock.MockBackendStep;
|
||||
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
|
||||
import com.kingsrook.qqq.backend.javalin.TestUtils;
|
||||
import com.kingsrook.qqq.middleware.javalin.specs.AbstractEndpointSpec;
|
||||
import com.kingsrook.qqq.middleware.javalin.specs.SpecTestBase;
|
||||
import kong.unirest.HttpResponse;
|
||||
import kong.unirest.Unirest;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Unit test for ProcessInitSpecV1
|
||||
*******************************************************************************/
|
||||
class ProcessInitSpecV1Test extends SpecTestBase
|
||||
{
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
protected AbstractEndpointSpec<?, ?, ?> getSpec()
|
||||
{
|
||||
return new ProcessInitSpecV1();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
protected String getVersion()
|
||||
{
|
||||
return "v1";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@AfterEach
|
||||
void afterEach()
|
||||
{
|
||||
QLogger.deactivateCollectingLoggerForClass(MockBackendStep.class);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void testGetInitialRecordsFromRecordIdsParam()
|
||||
{
|
||||
QCollectingLogger collectingLogger = QLogger.activateCollectingLoggerForClass(MockBackendStep.class);
|
||||
|
||||
HttpResponse<String> response = Unirest.post(getBaseUrlAndPath() + "/processes/greet/init")
|
||||
.multiPartContent()
|
||||
.field("recordsParam", "recordIds")
|
||||
.field("recordIds", "2,3")
|
||||
.asString();
|
||||
|
||||
assertEquals(200, response.getStatus());
|
||||
JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody());
|
||||
assertNotNull(jsonObject);
|
||||
assertEquals("COMPLETE", jsonObject.getString("type"));
|
||||
assertEquals("null X null", jsonObject.getJSONObject("values").getString("outputMessage")); // these nulls are because we didn't pass values for some fields.
|
||||
|
||||
assertThat(collectingLogger.getCollectedMessages())
|
||||
.filteredOn(clm -> clm.getMessage().contains("We are mocking"))
|
||||
.hasSize(2);
|
||||
// todo - also request records
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void testGetInitialRecordsFromFilterParam()
|
||||
{
|
||||
QCollectingLogger collectingLogger = QLogger.activateCollectingLoggerForClass(MockBackendStep.class);
|
||||
|
||||
QQueryFilter queryFilter = new QQueryFilter()
|
||||
.withCriteria(new QFilterCriteria()
|
||||
.withFieldName("id")
|
||||
.withOperator(QCriteriaOperator.IN)
|
||||
.withValues(List.of(3, 4, 5)));
|
||||
String filterJSON = JsonUtils.toJson(queryFilter);
|
||||
|
||||
HttpResponse<String> response = Unirest.post(getBaseUrlAndPath() + "/processes/greet/init")
|
||||
.multiPartContent()
|
||||
.field("recordsParam", "filterJSON")
|
||||
.field("filterJSON", filterJSON)
|
||||
.asString();
|
||||
|
||||
assertEquals(200, response.getStatus());
|
||||
JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody());
|
||||
assertNotNull(jsonObject);
|
||||
assertEquals("COMPLETE", jsonObject.getString("type"));
|
||||
assertEquals("null X null", jsonObject.getJSONObject("values").getString("outputMessage"));
|
||||
|
||||
assertThat(collectingLogger.getCollectedMessages())
|
||||
.filteredOn(clm -> clm.getMessage().contains("We are mocking"))
|
||||
.hasSize(3);
|
||||
// todo - also request records
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void testRequiresRowsButNotSpecified()
|
||||
{
|
||||
HttpResponse<String> response = Unirest.post(getBaseUrlAndPath() + "/processes/greet/init")
|
||||
.multiPartContent()
|
||||
.asString();
|
||||
|
||||
assertEquals(200, response.getStatus());
|
||||
JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody());
|
||||
assertNotNull(jsonObject);
|
||||
assertEquals("ERROR", jsonObject.getString("type"));
|
||||
assertTrue(jsonObject.has("error"));
|
||||
assertTrue(jsonObject.getString("error").contains("Missing input records"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void testFieldValues()
|
||||
{
|
||||
HttpResponse<String> response = Unirest.post(getBaseUrlAndPath() + "/processes/greet/init")
|
||||
.multiPartContent()
|
||||
.field("recordsParam", "recordIds")
|
||||
.field("recordIds", "2,3")
|
||||
.field("values", new JSONObject()
|
||||
.put("greetingPrefix", "Hey")
|
||||
.put("greetingSuffix", "Jude")
|
||||
.toString()
|
||||
)
|
||||
.asString();
|
||||
|
||||
assertEquals(200, response.getStatus());
|
||||
JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody());
|
||||
assertNotNull(jsonObject);
|
||||
assertEquals("COMPLETE", jsonObject.getString("type"));
|
||||
assertEquals("Hey X Jude", jsonObject.getJSONObject("values").getString("outputMessage"));
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void testInitGoingAsync()
|
||||
{
|
||||
HttpResponse<String> response = Unirest.post(getBaseUrlAndPath() + "/processes/" + TestUtils.PROCESS_NAME_SIMPLE_SLEEP + "/init")
|
||||
.multiPartContent()
|
||||
.field("stepTimeoutMillis", "50")
|
||||
.field("values", new JSONObject()
|
||||
.put(TestUtils.SleeperStep.FIELD_SLEEP_MILLIS, 500)
|
||||
.toString()
|
||||
)
|
||||
.asString();
|
||||
|
||||
assertEquals(200, response.getStatus());
|
||||
JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody());
|
||||
String processUUID = jsonObject.getString("processUUID");
|
||||
String jobUUID = jsonObject.getString("jobUUID");
|
||||
assertNotNull(processUUID, "Process UUID should not be null.");
|
||||
assertNotNull(jobUUID, "Job UUID should not be null");
|
||||
|
||||
// todo - in a higher-level test, resume test_processInitGoingAsync at the // request job status before sleep is done // line
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2024. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.qqq.middleware.javalin.specs.v1;
|
||||
|
||||
|
||||
import java.util.Map;
|
||||
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
|
||||
import com.kingsrook.qqq.middleware.javalin.specs.AbstractEndpointSpec;
|
||||
import com.kingsrook.qqq.middleware.javalin.specs.SpecTestBase;
|
||||
import kong.unirest.HttpResponse;
|
||||
import kong.unirest.Unirest;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Unit test for ProcessMetaDataSpecV1
|
||||
*******************************************************************************/
|
||||
class ProcessMetaDataSpecV1Test extends SpecTestBase
|
||||
{
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
protected AbstractEndpointSpec<?, ?, ?> getSpec()
|
||||
{
|
||||
return new ProcessMetaDataSpecV1();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
protected String getVersion()
|
||||
{
|
||||
return "v1";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void test()
|
||||
{
|
||||
HttpResponse<String> response = Unirest.get(getBaseUrlAndPath() + "/metaData/process/greetInteractive").asString();
|
||||
|
||||
assertEquals(200, response.getStatus());
|
||||
JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody());
|
||||
assertEquals("greetInteractive", jsonObject.getString("name"));
|
||||
assertEquals("Greet Interactive", jsonObject.getString("label"));
|
||||
assertEquals("person", jsonObject.getString("tableName"));
|
||||
|
||||
JSONArray frontendSteps = jsonObject.getJSONArray("frontendSteps");
|
||||
JSONObject setupStep = frontendSteps.getJSONObject(0);
|
||||
assertEquals("Setup", setupStep.getString("label"));
|
||||
JSONArray setupFields = setupStep.getJSONArray("formFields");
|
||||
assertEquals(2, setupFields.length());
|
||||
assertTrue(setupFields.toList().stream().anyMatch(field -> "greetingPrefix".equals(((Map<?, ?>) field).get("name"))));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** test the process-level meta-data endpoint for a non-real name
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void testNotFound()
|
||||
{
|
||||
HttpResponse<String> response = Unirest.get(getBaseUrlAndPath() + "/metaData/process/notAnActualProcess").asString();
|
||||
|
||||
assertEquals(HttpStatus.NOT_FOUND_404, response.getStatus());
|
||||
JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody());
|
||||
assertEquals(1, jsonObject.keySet().size(), "Number of top-level keys");
|
||||
String error = jsonObject.getString("error");
|
||||
assertThat(error).contains("Process").contains("notAnActualProcess").contains("not found");
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user