diff --git a/qqq-middleware-javalin/pom.xml b/qqq-middleware-javalin/pom.xml index a07cbb4f..2f2386dd 100644 --- a/qqq-middleware-javalin/pom.xml +++ b/qqq-middleware-javalin/pom.xml @@ -138,6 +138,17 @@ + + org.jacoco + jacoco-maven-plugin + + + com/kingsrook/qqq/middleware/javalin/executors/io/*.class + com/kingsrook/qqq/middleware/javalin/tools/codegenerators/*.class + com/kingsrook/qqq/middleware/javalin/specs/**/*.class + + + diff --git a/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/tools/codegenerators/ExecutorCodeGenerator.java b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/tools/codegenerators/ExecutorCodeGenerator.java index 92a79cbd..1ab8a0eb 100644 --- a/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/tools/codegenerators/ExecutorCodeGenerator.java +++ b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/tools/codegenerators/ExecutorCodeGenerator.java @@ -80,7 +80,7 @@ class ExecutorCodeGenerator /*************************************************************************** ** ***************************************************************************/ - private void writeAllFiles(String rootPath, String baseName) throws IOException + void writeAllFiles(String rootPath, String baseName) throws IOException { if(baseName.endsWith("Executor")) { diff --git a/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/tools/codegenerators/SpecCodeGenerator.java b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/tools/codegenerators/SpecCodeGenerator.java index 64af0f2f..5a5e09c2 100644 --- a/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/tools/codegenerators/SpecCodeGenerator.java +++ b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/tools/codegenerators/SpecCodeGenerator.java @@ -89,7 +89,7 @@ class SpecCodeGenerator /*************************************************************************** ** ***************************************************************************/ - private void writeAllFiles(String rootPath, String version, String baseName) throws IOException + void writeAllFiles(String rootPath, String version, String baseName) throws IOException { writeAllFiles(rootPath, version, baseName, baseName); } diff --git a/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/backend/javalin/QJavalinProcessHandlerTest.java b/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/backend/javalin/QJavalinProcessHandlerTest.java index be0483aa..563ad04a 100644 --- a/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/backend/javalin/QJavalinProcessHandlerTest.java +++ b/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/backend/javalin/QJavalinProcessHandlerTest.java @@ -190,7 +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 + ** Note: ported to v1 *******************************************************************************/ @Test public void test_processInitGoingAsync() throws InterruptedException @@ -242,6 +242,7 @@ class QJavalinProcessHandlerTest extends QJavalinTestBase /******************************************************************************* ** test running a step a process that goes async ** + ** Note: ported to v1 *******************************************************************************/ @Test public void test_processStepGoingAsync() throws InterruptedException @@ -348,6 +349,7 @@ class QJavalinProcessHandlerTest extends QJavalinTestBase /******************************************************************************* ** test init'ing a process that goes async and then throws ** + ** Note: ported to v1 *******************************************************************************/ @Test public void test_processInitGoingAsyncThenThrowing() throws InterruptedException diff --git a/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/middleware/javalin/QMiddlewareApiSpecHandlerTest.java b/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/middleware/javalin/QMiddlewareApiSpecHandlerTest.java new file mode 100644 index 00000000..c4e66445 --- /dev/null +++ b/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/middleware/javalin/QMiddlewareApiSpecHandlerTest.java @@ -0,0 +1,152 @@ +/* + * 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 . + */ + +package com.kingsrook.qqq.middleware.javalin; + + +import java.util.List; +import java.util.Map; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.kingsrook.qqq.backend.core.utils.JsonUtils; +import com.kingsrook.qqq.backend.core.utils.YamlUtils; +import com.kingsrook.qqq.middleware.javalin.specs.AbstractMiddlewareVersion; +import com.kingsrook.qqq.middleware.javalin.specs.v1.MiddlewareVersionV1; +import io.javalin.Javalin; +import kong.unirest.HttpResponse; +import kong.unirest.Unirest; +import org.json.JSONObject; +import org.junit.jupiter.api.BeforeAll; +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 QMiddlewareApiSpecHandler + *******************************************************************************/ +class QMiddlewareApiSpecHandlerTest +{ + private static int PORT = 6264; + + protected static Javalin service; + + + + /******************************************************************************* + ** + *******************************************************************************/ + @BeforeAll + static void beforeAll() + { + service = Javalin.create(config -> + { + List middlewareVersionList = List.of(new MiddlewareVersionV1()); + config.router.apiBuilder(new QMiddlewareApiSpecHandler(middlewareVersionList).defineJavalinEndpointGroup()); + } + ).start(PORT); + } + + + + /*************************************************************************** + ** + ***************************************************************************/ + private String getBaseUrlAndPath() + { + return "http://localhost:" + PORT + "/qqq"; + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testIndex() + { + HttpResponse response = Unirest.get(getBaseUrlAndPath()).asString(); + assertEquals(200, response.getStatus()); + assertThat(response.getBody()).contains(" response = Unirest.get(getBaseUrlAndPath() + "/versions.json").asString(); + assertEquals(200, response.getStatus()); + JSONObject object = new JSONObject(response.getBody()); + object.getJSONArray("supportedVersions"); + assertEquals("v1", object.getString("currentVersion")); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testSpecYaml() throws JsonProcessingException + { + HttpResponse response = Unirest.get(getBaseUrlAndPath() + "/v1/openapi.yaml").asString(); + assertEquals(200, response.getStatus()); + Map map = YamlUtils.toMap(response.getBody()); + assertTrue(map.containsKey("openapi")); + assertTrue(map.containsKey("info")); + assertTrue(map.containsKey("paths")); + assertTrue(map.containsKey("components")); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testSpecJson() throws JsonProcessingException + { + HttpResponse response = Unirest.get(getBaseUrlAndPath() + "/v1/openapi.json").asString(); + assertEquals(200, response.getStatus()); + JSONObject map = JsonUtils.toJSONObject(response.getBody()); + assertTrue(map.has("openapi")); + assertTrue(map.has("info")); + assertTrue(map.has("paths")); + assertTrue(map.has("components")); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testServeResources() + { + HttpResponse response = Unirest.get("http://localhost:" + PORT + "/api/docs/js/rapidoc.min.js").asString(); + assertEquals(200, response.getStatus()); + } + +} diff --git a/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/ToSchemaTest.java b/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/ToSchemaTest.java new file mode 100644 index 00000000..e9ec9a57 --- /dev/null +++ b/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/ToSchemaTest.java @@ -0,0 +1,59 @@ +/* + * 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 . + */ + +package com.kingsrook.qqq.middleware.javalin.schemabuilder; + + +import com.kingsrook.qqq.middleware.javalin.schemabuilder.annotations.OpenAPIDescription; +import com.kingsrook.qqq.openapi.model.Schema; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + + +/******************************************************************************* + ** Unit test for ToSchema + *******************************************************************************/ +class ToSchemaTest +{ + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void test() + { + Schema schema = new TestsToSchema().toSchema(); + Schema myFieldSchema = schema.getProperties().get("myField"); + assertEquals("This is a field", myFieldSchema.getDescription()); + } + + + + /*************************************************************************** + ** + ***************************************************************************/ + public static class TestsToSchema implements ToSchema + { + @OpenAPIDescription("This is a field") + private String myField; + } + +} \ No newline at end of file diff --git a/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/middleware/javalin/specs/SpecTestBase.java b/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/middleware/javalin/specs/SpecTestBase.java index 9969827a..d658c101 100644 --- a/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/middleware/javalin/specs/SpecTestBase.java +++ b/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/middleware/javalin/specs/SpecTestBase.java @@ -22,6 +22,9 @@ package com.kingsrook.qqq.middleware.javalin.specs; +import java.util.Collections; +import java.util.List; +import com.kingsrook.qqq.backend.core.model.metadata.QInstance; import com.kingsrook.qqq.backend.core.modules.backend.implementations.memory.MemoryRecordStore; import com.kingsrook.qqq.backend.javalin.TestUtils; import io.javalin.Javalin; @@ -46,6 +49,18 @@ public abstract class SpecTestBase ***************************************************************************/ protected abstract AbstractEndpointSpec getSpec(); + + + /*************************************************************************** + ** + ***************************************************************************/ + protected List> getAdditionalSpecs() + { + return (Collections.emptyList()); + } + + + /*************************************************************************** ** ***************************************************************************/ @@ -98,9 +113,17 @@ public abstract class SpecTestBase { service = Javalin.create(config -> { + QInstance qInstance = TestUtils.defineInstance(); + AbstractEndpointSpec spec = getSpec(); - spec.setQInstance(TestUtils.defineInstance()); + spec.setQInstance(qInstance); config.router.apiBuilder(() -> spec.defineRoute(getVersion())); + + for(AbstractEndpointSpec additionalSpec : getAdditionalSpecs()) + { + additionalSpec.setQInstance(qInstance); + config.router.apiBuilder(() -> additionalSpec.defineRoute(getVersion())); + } } ).start(PORT); } diff --git a/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/middleware/javalin/specs/v1/ProcessStatusSpecV1Test.java b/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/middleware/javalin/specs/v1/ProcessStatusSpecV1Test.java new file mode 100644 index 00000000..ed045652 --- /dev/null +++ b/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/middleware/javalin/specs/v1/ProcessStatusSpecV1Test.java @@ -0,0 +1,323 @@ +/* + * 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 . + */ + +package com.kingsrook.qqq.middleware.javalin.specs.v1; + + +import java.util.List; +import java.util.concurrent.TimeUnit; +import com.kingsrook.qqq.backend.core.logging.QLogger; +import com.kingsrook.qqq.backend.core.processes.implementations.mock.MockBackendStep; +import com.kingsrook.qqq.backend.core.utils.JsonUtils; +import com.kingsrook.qqq.backend.core.utils.SleepUtils; +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.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + + +/******************************************************************************* + ** Unit test for ProcessStatusSpecV1 + *******************************************************************************/ +class ProcessStatusSpecV1Test extends SpecTestBase +{ + private static final int MORE_THAN_TIMEOUT = 500; + private static final int TIMEOUT = 300; + private static final int LESS_THAN_TIMEOUT = 50; + + + + /*************************************************************************** + ** + ***************************************************************************/ + @Override + protected AbstractEndpointSpec getSpec() + { + return new ProcessStatusSpecV1(); + } + + + + /*************************************************************************** + ** + ***************************************************************************/ + @Override + protected List> getAdditionalSpecs() + { + return List.of(new ProcessInitSpecV1(), new ProcessStepSpecV1()); + } + + + + /*************************************************************************** + ** + ***************************************************************************/ + @Override + protected String getVersion() + { + return "v1"; + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @AfterEach + void afterEach() + { + QLogger.deactivateCollectingLoggerForClass(MockBackendStep.class); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testInitWentAsync() + { + ///////////////////////////////////////// + // init process, which should go async // + ///////////////////////////////////////// + String processBasePath = getBaseUrlAndPath() + "/processes/" + TestUtils.PROCESS_NAME_SIMPLE_SLEEP; + HttpResponse response = Unirest.post(processBasePath + "/init") + .multiPartContent() + .field("stepTimeoutMillis", String.valueOf(TIMEOUT)) + .field("values", new JSONObject() + .put(TestUtils.SleeperStep.FIELD_SLEEP_MILLIS, MORE_THAN_TIMEOUT) + .toString()) + .asString(); + + /////////////////////////////////// + // assert we got back job-status // + /////////////////////////////////// + assertEquals(200, response.getStatus()); + JSONObject jsonObject = assertProcessStepWentAsyncResponse(response); + 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"); + + ///////////////////////////////////////////// + // request job status before sleep is done // + ///////////////////////////////////////////// + response = Unirest.get(processBasePath + "/" + processUUID + "/status/" + jobUUID).asString(); + jsonObject = assertProcessStepRunningResponse(response); + + /////////////////////////////////// + // sleep, to let that job finish // + /////////////////////////////////// + SleepUtils.sleep(MORE_THAN_TIMEOUT, TimeUnit.MILLISECONDS); + + //////////////////////////////////////////////////////// + // request job status again, get back results instead // + //////////////////////////////////////////////////////// + response = Unirest.get(processBasePath + "/" + processUUID + "/status/" + jobUUID).asString(); + jsonObject = assertProcessStepCompleteResponse(response); + } + + + + /******************************************************************************* + ** test running a step a process that goes async + ** + *******************************************************************************/ + @Test + public void test_processStepGoingAsync() throws InterruptedException + { + /////////////////////////////////////////////////////////// + // first init the process, to get its UUID // + // note this process doesn't sleep until its second step // + /////////////////////////////////////////////////////////// + String processBasePath = getBaseUrlAndPath() + "/processes/" + TestUtils.PROCESS_NAME_SLEEP_INTERACTIVE; + HttpResponse response = Unirest.post(processBasePath + "/init") + .multiPartContent() + .field("values", new JSONObject() + .put(TestUtils.SleeperStep.FIELD_SLEEP_MILLIS, MORE_THAN_TIMEOUT) + .toString()) + .asString(); + + JSONObject jsonObject = assertProcessStepCompleteResponse(response); + String processUUID = jsonObject.getString("processUUID"); + String nextStep = jsonObject.getString("nextStep"); + assertNotNull(processUUID, "Process UUID should not be null."); + assertNotNull(nextStep, "There should be a next step"); + assertFalse(jsonObject.getJSONObject("values").has("didSleep"), "There should not (yet) be a value from the backend step"); + + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // second, run the 'nextStep' (the backend step, that sleeps). run it with a long enough sleep so that it'll go async // + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + response = Unirest.post(processBasePath + "/" + processUUID + "/step/" + nextStep) + .multiPartContent() + .field("stepTimeoutMillis", String.valueOf(TIMEOUT)) + .asString(); + + jsonObject = assertProcessStepWentAsyncResponse(response); + String jobUUID = jsonObject.getString("jobUUID"); + + /////////////////////////////////// + // sleep, to let that job finish // + /////////////////////////////////// + Thread.sleep(MORE_THAN_TIMEOUT); + + /////////////////////////////// + // third, request job status // + /////////////////////////////// + response = Unirest.get(processBasePath + "/" + processUUID + "/status/" + jobUUID).asString(); + + jsonObject = assertProcessStepCompleteResponse(response); + String nextStep2 = jsonObject.getString("nextStep"); + assertNotNull(nextStep2, "There be one more next step"); + assertNotEquals(nextStep, nextStep2, "The next step should be different this time."); + assertTrue(jsonObject.getJSONObject("values").has("didSleep"), "There should be a value from the backend step"); + } + + + + /******************************************************************************* + ** test init'ing a process that goes async and then throws + ** + *******************************************************************************/ + @Test + public void test_processInitGoingAsyncThenThrowing() throws InterruptedException + { + String processBasePath = getBaseUrlAndPath() + "/processes/" + TestUtils.PROCESS_NAME_SIMPLE_THROW; + HttpResponse response = Unirest.post(processBasePath + "/init") + .multiPartContent() + .field("stepTimeoutMillis", String.valueOf(TIMEOUT)) + .field("values", new JSONObject() + .put(TestUtils.SleeperStep.FIELD_SLEEP_MILLIS, MORE_THAN_TIMEOUT) + .toString()) + .asString(); + + JSONObject jsonObject = assertProcessStepWentAsyncResponse(response); + String processUUID = jsonObject.getString("processUUID"); + String jobUUID = jsonObject.getString("jobUUID"); + + ///////////////////////////////////////////// + // request job status before sleep is done // + ///////////////////////////////////////////// + response = Unirest.get(processBasePath + "/" + processUUID + "/status/" + jobUUID).asString(); + jsonObject = assertProcessStepRunningResponse(response); + + /////////////////////////////////// + // sleep, to let that job finish // + /////////////////////////////////// + Thread.sleep(MORE_THAN_TIMEOUT); + + ///////////////////////////////////////////////////////////// + // request job status again, get back error status instead // + ///////////////////////////////////////////////////////////// + response = Unirest.get(processBasePath + "/" + processUUID + "/status/" + jobUUID).asString(); + jsonObject = assertProcessStepErrorResponse(response); + } + + + + /******************************************************************************* + ** every time a process step (or init) has gone async, expect what the + ** response should look like + *******************************************************************************/ + private JSONObject assertProcessStepWentAsyncResponse(HttpResponse response) + { + assertEquals(200, response.getStatus()); + JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody()); + + assertEquals("JOB_STARTED", jsonObject.getString("type")); + + assertTrue(jsonObject.has("processUUID"), "Async-started response should have a processUUID"); + assertTrue(jsonObject.has("jobUUID"), "Async-started response should have a jobUUID"); + + assertFalse(jsonObject.has("values"), "Async-started response should NOT have values"); + assertFalse(jsonObject.has("error"), "Async-started response should NOT have error"); + + return (jsonObject); + } + + + + /*************************************************************************** + ** + ***************************************************************************/ + private JSONObject assertProcessStepRunningResponse(HttpResponse response) + { + assertEquals(200, response.getStatus()); + JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody()); + + assertEquals("RUNNING", jsonObject.getString("type"), "Step Running response should have type=RUNNING"); + + assertFalse(jsonObject.has("values"), "Step Running response should NOT have values"); + assertFalse(jsonObject.has("error"), "Step Running response should NOT have error"); + + return (jsonObject); + } + + + + /******************************************************************************* + ** every time a process step (sync or async) completes, expect certain things + ** to be (and not to be) in the json response. + *******************************************************************************/ + private JSONObject assertProcessStepCompleteResponse(HttpResponse response) + { + assertEquals(200, response.getStatus()); + JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody()); + + assertEquals("COMPLETE", jsonObject.getString("type"), "Step Running response should have type=COMPLETE"); + assertTrue(jsonObject.has("values"), "Step Complete response should have values"); + + assertFalse(jsonObject.has("jobUUID"), "Step Complete response should not have a jobUUID"); + assertFalse(jsonObject.has("error"), "Step Complete response should not have an error"); + + return (jsonObject); + } + + + + /******************************************************************************* + ** every time a process step (sync or async) has an error, expect certain things + ** to be (and not to be) in the json response. + *******************************************************************************/ + private JSONObject assertProcessStepErrorResponse(HttpResponse response) + { + assertEquals(200, response.getStatus()); + JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody()); + + assertEquals("ERROR", jsonObject.getString("type"), "Step Running response should have type=ERROR"); + assertTrue(jsonObject.has("error"), "Step Error response should have an error"); + + assertFalse(jsonObject.has("jobUUID"), "Step Error response should not have a jobUUID"); + assertFalse(jsonObject.has("values"), "Step Error response should not have values"); + + return (jsonObject); + } + +} \ No newline at end of file diff --git a/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/middleware/javalin/tools/codegenerators/ExecutorCodeGeneratorTest.java b/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/middleware/javalin/tools/codegenerators/ExecutorCodeGeneratorTest.java new file mode 100644 index 00000000..bded2d84 --- /dev/null +++ b/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/middleware/javalin/tools/codegenerators/ExecutorCodeGeneratorTest.java @@ -0,0 +1,56 @@ +/* + * 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 . + */ + +package com.kingsrook.qqq.middleware.javalin.tools.codegenerators; + + +import java.io.File; +import java.io.IOException; +import java.util.UUID; +import org.apache.commons.io.FileUtils; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertTrue; + + +/******************************************************************************* + ** Unit test for ExecutorCodeGenerator + *******************************************************************************/ +class ExecutorCodeGeneratorTest +{ + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void test() throws IOException + { + String rootPath = "/tmp/" + UUID.randomUUID() + "/"; + File dir = new File(rootPath + "/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/executors/io"); + assertTrue(dir.mkdirs()); + new ExecutorCodeGenerator().writeAllFiles(rootPath, "SomeTest"); + + File anExpectedFile = new File(dir.getAbsolutePath() + "/SomeTestOutputInterface.java"); + assertTrue(anExpectedFile.exists()); + + FileUtils.deleteDirectory(new File(rootPath)); + } + +} \ No newline at end of file diff --git a/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/middleware/javalin/tools/codegenerators/SpecCodeGeneratorTest.java b/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/middleware/javalin/tools/codegenerators/SpecCodeGeneratorTest.java new file mode 100644 index 00000000..38023197 --- /dev/null +++ b/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/middleware/javalin/tools/codegenerators/SpecCodeGeneratorTest.java @@ -0,0 +1,56 @@ +/* + * 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 . + */ + +package com.kingsrook.qqq.middleware.javalin.tools.codegenerators; + + +import java.io.File; +import java.io.IOException; +import java.util.UUID; +import org.apache.commons.io.FileUtils; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertTrue; + + +/******************************************************************************* + ** Unit test for SpecCodeGenerator + *******************************************************************************/ +class SpecCodeGeneratorTest +{ + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void test() throws IOException + { + String rootPath = "/tmp/" + UUID.randomUUID() + "/"; + File dir = new File(rootPath + "/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/specs/v1/responses"); + assertTrue(dir.mkdirs()); + new SpecCodeGenerator().writeAllFiles(rootPath, "v1", "SomeTest"); + + File anExpectedFile = new File(dir.getAbsolutePath() + "/SomeTestResponseV1.java"); + assertTrue(anExpectedFile.exists()); + + FileUtils.deleteDirectory(new File(rootPath)); + } + +} \ No newline at end of file