diff --git a/README.md b/README.md index 24f2bf6..2a7ae28 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ This QBit provides a declarative workflow engine. Define states and transitions, ### Prerequisites -- QQQ application (v0.35.0+) +- QQQ application (v4.1.0+) - Database backend configured ### Installation diff --git a/pom.xml b/pom.xml index 70f2202..d10c528 100644 --- a/pom.xml +++ b/pom.xml @@ -23,7 +23,8 @@ - 0.4.0 + 0.5.0-SNAPSHOT + 4.1.0-RC.21 @@ -69,6 +70,19 @@ + + + + + com.kingsrook.qqq + qqq-bom-pom + ${qqq.version} + pom + import + + + + com.kingsrook.qqq @@ -86,8 +100,10 @@ com.kingsrook.qqq + qqq-frontend-material-dashboard - 0.27.0-RC.1 + 0.42.0-RC.2 diff --git a/src/main/java/com/kingsrook/qbits/workflows/implementations/recordworkflows/InputRecordFilterStep.java b/src/main/java/com/kingsrook/qbits/workflows/implementations/recordworkflows/InputRecordFilterStep.java index 232749b..38b839b 100644 --- a/src/main/java/com/kingsrook/qbits/workflows/implementations/recordworkflows/InputRecordFilterStep.java +++ b/src/main/java/com/kingsrook/qbits/workflows/implementations/recordworkflows/InputRecordFilterStep.java @@ -39,6 +39,7 @@ import com.kingsrook.qbits.workflows.model.Workflow; import com.kingsrook.qbits.workflows.model.WorkflowRevision; import com.kingsrook.qbits.workflows.model.WorkflowStep; import com.kingsrook.qqq.api.actions.GetTableApiFieldsAction; +import com.kingsrook.qqq.api.model.actions.GetTableApiFieldsInput; import com.kingsrook.qqq.api.utils.ApiQueryFilterUtils; import com.kingsrook.qqq.backend.core.actions.tables.GetAction; import com.kingsrook.qqq.backend.core.context.QContext; @@ -254,7 +255,7 @@ public class InputRecordFilterStep extends WorkflowStepType implements WorkflowS String apiName = workflowRevision.getValueString("apiName"); String apiVersion = workflowRevision.getValueString("apiVersion"); String tableName = workflow.getValueString("tableName"); - Map tableApiFields = GetTableApiFieldsAction.getTableApiFieldMap(new GetTableApiFieldsAction.ApiNameVersionAndTableName(apiName, apiVersion, tableName)); + Map tableApiFields = GetTableApiFieldsAction.getTableApiFieldMap(new GetTableApiFieldsInput().withApiName(apiName).withVersion(apiVersion).withTableName(tableName)); ArrayList badRequestMessages = new ArrayList<>(); ApiQueryFilterUtils.manageCriteriaFields(filter, tableApiFields, badRequestMessages, apiName, apiVersion, new QueryInput(tableName).withFilter(filter)); errors.addAll(badRequestMessages); diff --git a/src/main/java/com/kingsrook/qbits/workflows/implementations/recordworkflows/RecordWorkflowUtils.java b/src/main/java/com/kingsrook/qbits/workflows/implementations/recordworkflows/RecordWorkflowUtils.java index afef4ba..f484e57 100644 --- a/src/main/java/com/kingsrook/qbits/workflows/implementations/recordworkflows/RecordWorkflowUtils.java +++ b/src/main/java/com/kingsrook/qbits/workflows/implementations/recordworkflows/RecordWorkflowUtils.java @@ -31,6 +31,7 @@ import com.kingsrook.qbits.workflows.execution.WorkflowExecutionContext; import com.kingsrook.qbits.workflows.model.Workflow; import com.kingsrook.qbits.workflows.model.WorkflowRevision; import com.kingsrook.qqq.api.actions.GetTableApiFieldsAction; +import com.kingsrook.qqq.api.model.actions.GetTableApiFieldsInput; import com.kingsrook.qqq.api.utils.ApiQueryFilterUtils; import com.kingsrook.qqq.backend.core.actions.tables.CountAction; import com.kingsrook.qqq.backend.core.actions.tables.DeleteAction; @@ -179,7 +180,7 @@ public class RecordWorkflowUtils { WorkflowRevision workflowRevision = context.getWorkflowRevision(); Workflow workflow = context.getWorkflow(); - Map tableApiFields = GetTableApiFieldsAction.getTableApiFieldMap(new GetTableApiFieldsAction.ApiNameVersionAndTableName(workflowRevision.getApiName(), workflowRevision.getApiVersion(), workflow.getTableName())); + Map tableApiFields = GetTableApiFieldsAction.getTableApiFieldMap(new GetTableApiFieldsInput().withApiName(workflowRevision.getApiName()).withVersion(workflowRevision.getApiVersion()).withTableName(workflow.getTableName())); List badRequestMessages = new ArrayList<>(); CountInput countInput = new CountInput(context.getWorkflow().getTableName()) diff --git a/src/main/java/com/kingsrook/qbits/workflows/implementations/recordworkflows/RunRecordWorkflowExtractStep.java b/src/main/java/com/kingsrook/qbits/workflows/implementations/recordworkflows/RunRecordWorkflowExtractStep.java index db15b49..cd20501 100644 --- a/src/main/java/com/kingsrook/qbits/workflows/implementations/recordworkflows/RunRecordWorkflowExtractStep.java +++ b/src/main/java/com/kingsrook/qbits/workflows/implementations/recordworkflows/RunRecordWorkflowExtractStep.java @@ -78,9 +78,9 @@ public class RunRecordWorkflowExtractStep extends ExtractViaQueryStep ** Make sure associations are fetched (so api records have children!) *******************************************************************************/ @Override - protected void customizeInputPreQuery(QueryInput queryInput) + protected void customizeInputPreQuery(RunBackendStepInput runBackendStepInput, QueryInput queryInput) { - super.customizeInputPreQuery(queryInput); + super.customizeInputPreQuery(runBackendStepInput, queryInput); queryInput.setIncludeAssociations(true); } diff --git a/src/test/java/com/kingsrook/qbits/workflows/BaseTest.java b/src/test/java/com/kingsrook/qbits/workflows/BaseTest.java index 38fa93e..fbe5e7a 100644 --- a/src/test/java/com/kingsrook/qbits/workflows/BaseTest.java +++ b/src/test/java/com/kingsrook/qbits/workflows/BaseTest.java @@ -142,7 +142,7 @@ public class BaseTest // basic definition of an instance // ///////////////////////////////////// QInstance qInstance = new QInstance(); - qInstance.setAuthentication(new QAuthenticationMetaData().withType(QAuthenticationType.FULLY_ANONYMOUS)); + qInstance.withInstanceDefaultAuthentication(new QAuthenticationMetaData().withType(QAuthenticationType.FULLY_ANONYMOUS)); qInstance.addBackend(new RDBMSBackendMetaData() .withName(RDBMS_BACKEND_NAME) .withVendor("h2") diff --git a/src/test/java/com/kingsrook/qbits/workflows/metadata/WorkflowTestAssertionFormAdjusterTest.java b/src/test/java/com/kingsrook/qbits/workflows/metadata/WorkflowTestAssertionFormAdjusterTest.java new file mode 100644 index 0000000..c47a4e9 --- /dev/null +++ b/src/test/java/com/kingsrook/qbits/workflows/metadata/WorkflowTestAssertionFormAdjusterTest.java @@ -0,0 +1,106 @@ +/* + * QQQ - Low-code Application Framework for Engineers. + * Copyright (C) 2021-2025. 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.qbits.workflows.metadata; + + +import java.io.Serializable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import com.kingsrook.qbits.workflows.BaseTest; +import com.kingsrook.qbits.workflows.WorkflowsTestDataSource; +import com.kingsrook.qbits.workflows.implementations.recordworkflows.RecordWorkflowsDefinition; +import com.kingsrook.qbits.workflows.model.Workflow; +import com.kingsrook.qbits.workflows.model.WorkflowTestScenario; +import com.kingsrook.qqq.backend.core.actions.processes.RunProcessAction; +import com.kingsrook.qqq.backend.core.actions.tables.InsertAction; +import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessInput; +import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessOutput; +import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput; +import com.kingsrook.qqq.backend.core.utils.JsonUtils; +import com.kingsrook.qqq.frontend.materialdashboard.actions.formadjuster.RunFormAdjusterProcess; +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; + + +/******************************************************************************* + ** Runs the workflows form adjusters through the current Material Dashboard + ** form-adjuster process, the same way the UI API's table form-adjuster route + ** does (path params + multipart-style form params) - not by calling them directly. + *******************************************************************************/ +class WorkflowTestAssertionFormAdjusterTest extends BaseTest +{ + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testVariableNameAdjusterThroughMaterialDashboardProcess() throws Exception + { + + Workflow workflow = WorkflowsTestDataSource.insertWorkflowAndInitialRevision(RecordWorkflowsDefinition.WORKFLOW_TYPE, TABLE_NAME_PERSON); + Integer scenarioId = new InsertAction().execute(new InsertInput(WorkflowTestScenario.TABLE_NAME).withRecordEntity( + new WorkflowTestScenario().withWorkflowId(workflow.getId()).withName("s").withApiName(API_NAME).withApiVersion(V3).withApiJson("{}"))).getRecords().get(0).getValueInteger("id"); + + Map output = runAdjuster("WorkflowTestAssertion.variableName", RunFormAdjusterProcess.EVENT_ON_CHANGE, + TABLE_NAME_PERSON + ".firstName", Map.of("workflowTestScenarioId", scenarioId)); + + @SuppressWarnings("unchecked") + Map expectedValueField = (Map) ((Map) output.get("updatedFieldMetaData")).get("expectedValue"); + assertNotNull(expectedValueField); + assertTrue(String.valueOf(expectedValueField.get("label")).startsWith("Expected Value ("), "label: " + expectedValueField.get("label")); + assertEquals(List.of("expectedValue"), output.get("fieldsToClear")); + } + + + + /*************************************************************************** + ** + ***************************************************************************/ + private Map runAdjuster(String identifier, String event, String newValue, Map allValues) throws Exception + { + Map> formParams = new HashMap<>(); + formParams.put("event", List.of(event)); + formParams.put("fieldName", List.of("variableName")); + formParams.put("newValue", List.of(newValue)); + formParams.put("allValues", List.of(JsonUtils.toJson(allValues))); + + RunProcessInput input = new RunProcessInput(); + input.setProcessName(RunFormAdjusterProcess.NAME); + input.setFrontendStepBehavior(RunProcessInput.FrontendStepBehavior.SKIP); + input.addValue("pathParams", new HashMap<>(Map.of("identifier", identifier, "event", event))); + input.addValue("formParams", (Serializable) formParams); + + RunProcessOutput processOutput = new RunProcessAction().execute(input); + if(processOutput.getException().isPresent()) + { + throw (processOutput.getException().get()); + } + + @SuppressWarnings("unchecked") + Map result = JsonUtils.toObject(processOutput.getValueString("responseString"), Map.class); + return (result); + } + +}