Merged dev into integration

This commit is contained in:
2025-07-17 12:13:24 -05:00
42 changed files with 304 additions and 173 deletions

View File

@ -161,7 +161,7 @@ public abstract class AbstractHTMLWidgetRenderer extends AbstractWidgetRenderer
public static String linkTableCreateWithDefaultValues(RenderWidgetInput input, String tableName, Map<String, Serializable> defaultValues) throws QException
{
String tablePath = QContext.getQInstance().getTablePath(tableName);
return (tablePath + "/create#defaultValues=" + URLEncoder.encode(JsonUtils.toJson(defaultValues), Charset.defaultCharset()));
return (tablePath + "/create#defaultValues=" + URLEncoder.encode(JsonUtils.toJson(defaultValues), StandardCharsets.UTF_8));
}
@ -229,7 +229,7 @@ public abstract class AbstractHTMLWidgetRenderer extends AbstractWidgetRenderer
}
filter = QQueryFilterDeduper.dedupeFilter(filter);
return (tablePath + "?filter=" + URLEncoder.encode(JsonUtils.toJson(filter), Charset.defaultCharset()));
return (tablePath + "?filter=" + URLEncoder.encode(JsonUtils.toJson(filter), StandardCharsets.UTF_8));
}

View File

@ -25,6 +25,7 @@ package com.kingsrook.qqq.backend.core.actions.dashboard.widgets;
import java.io.Serializable;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@ -300,7 +301,7 @@ public class ChildRecordListRenderer extends AbstractWidgetRenderer
}
String tablePath = QContext.getQInstance().getTablePath(rightTable.getName());
String viewAllLink = tablePath == null ? null : (tablePath + "?filter=" + URLEncoder.encode(JsonUtils.toJson(filter), Charset.defaultCharset()));
String viewAllLink = tablePath == null ? null : (tablePath + "?filter=" + URLEncoder.encode(JsonUtils.toJson(filter), StandardCharsets.UTF_8));
ChildRecordListData widgetData = new ChildRecordListData(widgetLabel, queryOutput, rightTable, tablePath, viewAllLink, totalRows);
widgetData.setOmitFieldNames(omitFieldNames);

View File

@ -24,6 +24,7 @@ package com.kingsrook.qqq.backend.core.actions.dashboard.widgets;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import com.kingsrook.qqq.backend.core.actions.tables.CountAction;
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
@ -194,7 +195,7 @@ public class RecordListWidgetRenderer extends AbstractWidgetRenderer
}
String tablePath = QContext.getQInstance().getTablePath(tableName);
String viewAllLink = tablePath == null ? null : (tablePath + "?filter=" + URLEncoder.encode(JsonUtils.toJson(filter), Charset.defaultCharset()));
String viewAllLink = tablePath == null ? null : (tablePath + "?filter=" + URLEncoder.encode(JsonUtils.toJson(filter), StandardCharsets.UTF_8));
ChildRecordListData widgetData = new ChildRecordListData(input.getQueryParams().get("widgetLabel"), queryOutput, table, tablePath, viewAllLink, totalRows);

View File

@ -331,23 +331,25 @@ public class MetaDataAction
if(metaDataActionCustomizerReference != null)
{
actionCustomizer = QCodeLoader.getAdHoc(MetaDataActionCustomizerInterface.class, metaDataActionCustomizerReference);
LOG.debug("Using new meta-data actionCustomizer of type: " + actionCustomizer.getClass().getSimpleName());
}
if(actionCustomizer == null)
{
/////////////////////////////////////////////////////////////////////////////////////
// check if QInstance is still using the now-deprecated getMetaDataFilter approach //
/////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("deprecation")
QCodeReference metaDataFilterReference = QContext.getQInstance().getMetaDataFilter();
if(metaDataFilterReference != null)
{
LOG.warn("QInstance.metaDataFilter is deprecated in favor of metaDataActionCustomizer.");
actionCustomizer = QCodeLoader.getAdHoc(MetaDataActionCustomizerInterface.class, metaDataFilterReference);
LOG.debug("Using new meta-data actionCustomizer (via metaDataFilter reference) of type: " + actionCustomizer.getClass().getSimpleName());
}
}
if(actionCustomizer == null)
{
actionCustomizer = new DefaultNoopMetaDataActionCustomizer();
LOG.debug("Using new default (allow-all) meta-data actionCustomizer");
}
return (actionCustomizer);

View File

@ -1028,16 +1028,16 @@ public class QInstanceEnricher
.withCode(new QCodeReference(BulkInsertReceiveValueMappingStep.class));
int i = 0;
process.addStep(i++, prepareFileUploadStep);
process.addStep(i++, uploadScreen);
process.withStep(i++, prepareFileUploadStep);
process.withStep(i++, uploadScreen);
process.addStep(i++, prepareFileMappingStep);
process.addStep(i++, fileMappingScreen);
process.addStep(i++, receiveFileMappingStep);
process.withStep(i++, prepareFileMappingStep);
process.withStep(i++, fileMappingScreen);
process.withStep(i++, receiveFileMappingStep);
process.addStep(i++, prepareValueMappingStep);
process.addStep(i++, valueMappingScreen);
process.addStep(i++, receiveValueMappingStep);
process.withStep(i++, prepareValueMappingStep);
process.withStep(i++, valueMappingScreen);
process.withStep(i++, receiveValueMappingStep);
process.getFrontendStep(StreamedETLWithFrontendProcess.STEP_NAME_REVIEW).setRecordListFields(editableFields);
@ -1097,7 +1097,7 @@ public class QInstanceEnricher
Fields whose switches are off will not be updated."""))
.withComponent(new QFrontendComponentMetaData().withType(QComponentType.BULK_EDIT_FORM));
process.addStep(0, editScreen);
process.withStep(0, editScreen);
process.getFrontendStep("review").setRecordListFields(editableFields);
qInstance.addProcess(process);
}

View File

@ -241,8 +241,10 @@ public class QInstanceValidator
/***************************************************************************
**
* this method still supports the deprecated MetaDataFilter (plus its
* replacement, MetaDataActionCustomizer
***************************************************************************/
@SuppressWarnings("deprecation")
private void validateInstanceAttributes(QInstance qInstance)
{
if(qInstance.getMetaDataFilter() != null)

View File

@ -213,7 +213,7 @@ public class QProcessMetaData implements QAppChildMetaData, MetaDataWithPermissi
{
if(stepList != null)
{
stepList.forEach(this::addStep);
stepList.forEach(this::withStep);
}
return (this);
@ -231,7 +231,7 @@ public class QProcessMetaData implements QAppChildMetaData, MetaDataWithPermissi
{
index = this.stepList.size();
}
addStep(index, step);
withStep(index, step);
return (this);
}

View File

@ -176,7 +176,7 @@ public class ScriptsMetaDataProvider
.withLoadStepClass(RunRecordScriptLoadStep.class)
.getProcessMetaData();
processMetaData.addStep(0, new QFrontendStepMetaData()
processMetaData.withStep(0, new QFrontendStepMetaData()
.withName("input")
.withComponent(new QFrontendComponentMetaData().withType(QComponentType.EDIT_FORM))
.withFormField(new QFieldMetaData("scriptId", QFieldType.INTEGER).withPossibleValueSourceName(Script.TABLE_NAME)

View File

@ -83,8 +83,8 @@ public class BasicETLProcess
return new QProcessMetaData()
.withName(PROCESS_NAME)
.addStep(extractFunction)
.addStep(transformFunction)
.addStep(loadFunction);
.withStep(extractFunction)
.withStep(transformFunction)
.withStep(loadFunction);
}
}

View File

@ -68,6 +68,6 @@ public class StreamedETLProcess
return new QProcessMetaData()
.withName(PROCESS_NAME)
.addStep(etlFunction);
.withStep(etlFunction);
}
}

View File

@ -191,11 +191,11 @@ public class StreamedETLWithFrontendProcess
.withComponent(new QFrontendComponentMetaData().withType(QComponentType.PROCESS_SUMMARY_RESULTS));
return new QProcessMetaData()
.addStep(previewStep)
.addStep(reviewStep)
.addStep(validateStep)
.addStep(executeStep)
.addStep(resultStep);
.withStep(previewStep)
.withStep(reviewStep)
.withStep(validateStep)
.withStep(executeStep)
.withStep(resultStep);
}

View File

@ -91,7 +91,7 @@ public class GarbageCollectorProcessMetaDataProducer
.withInputData(new QFunctionInputMetaData()
.withField(new QFieldMetaData("joinedTablesToAlsoDelete", QFieldType.STRING).withDefaultValue(joinedTablesToAlsoDelete)));
processMetaData.addStep(0, new QFrontendStepMetaData()
processMetaData.withStep(0, new QFrontendStepMetaData()
.withName("input")
.withLabel("Input")
.withComponent(new QFrontendComponentMetaData().withType(QComponentType.HELP_TEXT).withValue("text", """

View File

@ -81,10 +81,10 @@ public class BasicRunReportProcess
return new QProcessMetaData()
.withName(PROCESS_NAME)
.withIsHidden(true)
.addStep(prepareStep)
.addStep(inputStep)
.addStep(executeStep)
.addStep(accessStep);
.withStep(prepareStep)
.withStep(inputStep)
.withStep(executeStep)
.withStep(accessStep);
}
}

View File

@ -109,10 +109,10 @@ public class RunReportForRecordProcess
return new QProcessMetaData()
.withName(PROCESS_NAME)
.addStep(prepareStep)
.addStep(inputStep)
.addStep(executeStep)
.addStep(accessStep);
.withStep(prepareStep)
.withStep(inputStep)
.withStep(executeStep)
.withStep(accessStep);
}

View File

@ -75,7 +75,7 @@ public class RenderSavedReportMetaDataProducer implements MetaDataProducerInterf
.withTableName(SavedReport.TABLE_NAME)
.withIcon(new QIcon().withName("print"))
.addStep(new QBackendStepMetaData()
.withStep(new QBackendStepMetaData()
.withName("pre")
.withInputData(new QFunctionInputMetaData()
.withField(new QFieldMetaData(SES_PROVIDER_NAME, QFieldType.STRING))
@ -86,7 +86,7 @@ public class RenderSavedReportMetaDataProducer implements MetaDataProducerInterf
.withRecordListMetaData(new QRecordListMetaData().withTableName(SavedReport.TABLE_NAME)))
.withCode(new QCodeReference(RenderSavedReportPreStep.class)))
.addStep(new QFrontendStepMetaData()
.withStep(new QFrontendStepMetaData()
.withName("input")
.withComponent(new QFrontendComponentMetaData().withType(QComponentType.EDIT_FORM))
.withFormField(new QFieldMetaData(FIELD_NAME_REPORT_FORMAT, QFieldType.STRING)
@ -97,13 +97,13 @@ public class RenderSavedReportMetaDataProducer implements MetaDataProducerInterf
.withComponent(new QFrontendComponentMetaData().withType(QComponentType.WIDGET)
.withValue("widgetName", SavedReportsMetaDataProvider.RENDER_REPORT_PROCESS_VALUES_WIDGET)))
.addStep(new QBackendStepMetaData()
.withStep(new QBackendStepMetaData()
.withName("execute")
.withInputData(new QFunctionInputMetaData().withRecordListMetaData(new QRecordListMetaData()
.withTableName(SavedReport.TABLE_NAME)))
.withCode(new QCodeReference(RenderSavedReportExecuteStep.class)))
.addStep(new QFrontendStepMetaData()
.withStep(new QFrontendStepMetaData()
.withName("output")
.withComponent(new QFrontendComponentMetaData().withType(QComponentType.DOWNLOAD_FORM))
.withComponent(new NoCodeWidgetFrontendComponentMetaData()

View File

@ -59,13 +59,13 @@ public class RunScheduledReportMetaDataProducer implements MetaDataProducerInter
.withTableName(ScheduledReport.TABLE_NAME)
.withIcon(new QIcon().withName("print"))
.addStep(new QBackendStepMetaData()
.withStep(new QBackendStepMetaData()
.withName("execute")
.withInputData(new QFunctionInputMetaData().withRecordListMetaData(new QRecordListMetaData()
.withTableName(ScheduledReport.TABLE_NAME)))
.withCode(new QCodeReference(RunScheduledReportExecuteStep.class)))
.addStep(new QFrontendStepMetaData()
.withStep(new QFrontendStepMetaData()
.withName("results")
.withComponent(new NoCodeWidgetFrontendComponentMetaData()
.withOutput(new WidgetHtmlLine().withVelocityTemplate("Success")))); // todo!!!

View File

@ -37,6 +37,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.kingsrook.qqq.backend.core.logging.QLogger;
@ -84,6 +85,7 @@ public class JsonUtils
** Internally using jackson - so jackson annotations apply!
**
*******************************************************************************/
@Deprecated(since = "since toJsonCustomized was added, which uses jackson's newer builder object for customization")
public static String toJson(Object object, Consumer<ObjectMapper> objectMapperCustomizer)
{
try
@ -105,6 +107,34 @@ public class JsonUtils
/*******************************************************************************
** Serialize any object into a JSON String - with customizations on the Jackson
** ObjectMapper.
**
** Internally using jackson - so jackson annotations apply!
**
*******************************************************************************/
public static String toJsonCustomized(Object object, Consumer<JsonMapper.Builder> jsonMapperCustomizer)
{
try
{
JsonMapper.Builder jsonMapperBuilder = newJsonMapperBuilder();
if(jsonMapperCustomizer != null)
{
jsonMapperCustomizer.accept(jsonMapperBuilder);
}
String jsonResult = jsonMapperBuilder.build().writeValueAsString(object);
return (jsonResult);
}
catch(JsonProcessingException e)
{
LOG.error("Error serializing object of type [" + object.getClass().getSimpleName() + "] to json", e);
throw new IllegalArgumentException("Error in JSON Serialization", e);
}
}
/*******************************************************************************
** Serialize any object into a "pretty" / formatted JSON String.
**
@ -168,7 +198,6 @@ public class JsonUtils
/*******************************************************************************
** De-serialize a json string into an object of the specified class - with
** customizations on the Jackson ObjectMapper.
**.
**
** Internally using jackson - so jackson annotations apply!
**
@ -242,6 +271,23 @@ public class JsonUtils
/*******************************************************************************
** Standard private method to build jackson JsonMapperBuilder with standard features.
**
*******************************************************************************/
private static JsonMapper.Builder newJsonMapperBuilder()
{
JsonMapper.Builder jsonMapperBuilder = JsonMapper.builder();
jsonMapperBuilder.addModule(new JavaTimeModule());
jsonMapperBuilder.serializationInclusion(JsonInclude.Include.NON_NULL);
jsonMapperBuilder.serializationInclusion(JsonInclude.Include.NON_EMPTY);
jsonMapperBuilder.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
jsonMapperBuilder.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
return (jsonMapperBuilder);
}
/*******************************************************************************
** Standard private method to build jackson ObjectMapper with standard features.
**

View File

@ -26,9 +26,11 @@ import java.util.Map;
import java.util.function.Consumer;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
import com.kingsrook.qqq.backend.core.logging.QLogger;
@ -62,7 +64,7 @@ public class YamlUtils
*******************************************************************************/
public static String toYaml(Object object)
{
return toYaml(object, null);
return toYamlCustomized(object, null);
}
@ -70,6 +72,7 @@ public class YamlUtils
/*******************************************************************************
**
*******************************************************************************/
@Deprecated(since = "since toYamlCustomized was added, which uses jackson's newer builder object for customization")
public static String toYaml(Object object, Consumer<ObjectMapper> objectMapperCustomizer)
{
try
@ -96,4 +99,36 @@ public class YamlUtils
}
}
/*******************************************************************************
**
*******************************************************************************/
public static String toYamlCustomized(Object object, Consumer<YAMLMapper.Builder> yamlMapperCustomizer)
{
try
{
YAMLFactory yamlFactory = new YAMLFactory()
.disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER);
YAMLMapper.Builder yamlMapperBuilder = YAMLMapper.builder(yamlFactory);
yamlMapperBuilder.serializationInclusion(JsonInclude.Include.NON_NULL);
yamlMapperBuilder.serializationInclusion(JsonInclude.Include.NON_EMPTY);
if(yamlMapperCustomizer != null)
{
yamlMapperCustomizer.accept(yamlMapperBuilder);
}
YAMLMapper yamlMapper = yamlMapperBuilder.build();
yamlMapper.findAndRegisterModules();
return (yamlMapper.writeValueAsString(object));
}
catch(Exception e)
{
LOG.error("Error serializing object of type [" + object.getClass().getSimpleName() + "] to yaml", e);
throw new IllegalArgumentException("Error in YAML Serialization", e);
}
}
}

View File

@ -31,8 +31,6 @@ import java.util.stream.Collectors;
import com.kingsrook.qqq.backend.core.BaseTest;
import com.kingsrook.qqq.backend.core.context.QContext;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.logging.QCollectingLogger;
import com.kingsrook.qqq.backend.core.logging.QLogger;
import com.kingsrook.qqq.backend.core.model.actions.metadata.MetaDataInput;
import com.kingsrook.qqq.backend.core.model.actions.metadata.MetaDataOutput;
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
@ -367,8 +365,6 @@ class MetaDataActionTest extends BaseTest
@Deprecated(since = "migrated to metaDataCustomizer")
void testFilter() throws QException
{
QCollectingLogger collectingLogger = QLogger.activateCollectingLoggerForClass(MetaDataAction.class);
//////////////////////////////////////////////////////
// run default version, and assert tables are found //
//////////////////////////////////////////////////////
@ -379,7 +375,6 @@ class MetaDataActionTest extends BaseTest
// run again (with the same instance as before) to assert about memoization of the filter based on the QInstance //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
new MetaDataAction().execute(new MetaDataInput());
assertThat(collectingLogger.getCollectedMessages()).filteredOn(clm -> clm.getMessage().contains("Using new default")).hasSize(1);
/////////////////////////////////////////////////////////////
// set up new instance to use a custom filter, to deny all //
@ -398,9 +393,6 @@ class MetaDataActionTest extends BaseTest
// run again (with the same instance as before) to assert about memoization of the filter based on the QInstance //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
new MetaDataAction().execute(new MetaDataInput());
assertThat(collectingLogger.getCollectedMessages()).filteredOn(clm -> clm.getMessage().contains("actionCustomizer (via metaDataFilter reference) of type: DenyAllFilter")).hasSize(1);
QLogger.deactivateCollectingLoggerForClass(MetaDataAction.class);
////////////////////////////////////////////////////////////
// run now with the AllowAllFilter, confirm we get tables //
@ -420,8 +412,6 @@ class MetaDataActionTest extends BaseTest
@Test
void testCustomizer() throws QException
{
QCollectingLogger collectingLogger = QLogger.activateCollectingLoggerForClass(MetaDataAction.class);
//////////////////////////////////////////////////////
// run default version, and assert tables are found //
//////////////////////////////////////////////////////
@ -432,7 +422,6 @@ class MetaDataActionTest extends BaseTest
// run again (with the same instance as before) to assert about memoization of the filter based on the QInstance //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
new MetaDataAction().execute(new MetaDataInput());
assertThat(collectingLogger.getCollectedMessages()).filteredOn(clm -> clm.getMessage().contains("Using new default")).hasSize(1);
/////////////////////////////////////////////////////////////
// set up new instance to use a custom filter, to deny all //
@ -449,11 +438,9 @@ class MetaDataActionTest extends BaseTest
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// run again (with the same instance as before) to assert about memoization of the filter based on the QInstance //
// mmm, we stopped loggin about it, so, we'll... assume the memoization is good //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
new MetaDataAction().execute(new MetaDataInput());
assertThat(collectingLogger.getCollectedMessages()).filteredOn(clm -> clm.getMessage().contains("meta-data actionCustomizer of type: DenyAllFilteringCustomizer")).hasSize(1);
QLogger.deactivateCollectingLoggerForClass(MetaDataAction.class);
/////////////////////////////////////////////////////////////////////////////////
// run now with the DefaultNoopMetaDataActionCustomizer, confirm we get tables //
@ -470,6 +457,7 @@ class MetaDataActionTest extends BaseTest
/***************************************************************************
**
***************************************************************************/
@SuppressWarnings("deprecation") // the point of this test is to use the deprecated thing.
public static class DenyAllFilter implements MetaDataFilterInterface
{
/***************************************************************************

View File

@ -366,7 +366,7 @@ public class RunProcessTest extends BaseTest
// only put back1 in the step list. //
//////////////////////////////////////
))
.addOptionalStep(front1)
.withOptionalStep(front1)
);
////////////////////////////////////////////////////////////

View File

@ -164,13 +164,13 @@ public class RunProcessUpdateStepListTest extends BaseTest
.withName(STEP_END)
));
process.addOptionalStep(new QFrontendStepMetaData().withName(STEP_A));
process.addOptionalStep(new QBackendStepMetaData().withName(STEP_B).withCode(new QCodeReference(NoopBackendStep.class)));
process.addOptionalStep(new QFrontendStepMetaData().withName(STEP_C));
process.withOptionalStep(new QFrontendStepMetaData().withName(STEP_A));
process.withOptionalStep(new QBackendStepMetaData().withName(STEP_B).withCode(new QCodeReference(NoopBackendStep.class)));
process.withOptionalStep(new QFrontendStepMetaData().withName(STEP_C));
process.addOptionalStep(new QBackendStepMetaData().withName(STEP_1).withCode(new QCodeReference(NoopBackendStep.class)));
process.addOptionalStep(new QFrontendStepMetaData().withName(STEP_2));
process.addOptionalStep(new QBackendStepMetaData().withName(STEP_3).withCode(new QCodeReference(NoopBackendStep.class)));
process.withOptionalStep(new QBackendStepMetaData().withName(STEP_1).withCode(new QCodeReference(NoopBackendStep.class)));
process.withOptionalStep(new QFrontendStepMetaData().withName(STEP_2));
process.withOptionalStep(new QBackendStepMetaData().withName(STEP_3).withCode(new QCodeReference(NoopBackendStep.class)));
return (process);
}

View File

@ -576,7 +576,7 @@ class QInstanceEnricherTest extends BaseTest
QProcessMetaData process = new QProcessMetaData();
process.setName("test");
process.withStepList(List.of(new QBackendStepMetaData().withName("execute").withCode(new QCodeReference(TestUtils.IncreaseBirthdateStep.class))));
process.addOptionalStep(new QFrontendStepMetaData()
process.withOptionalStep(new QFrontendStepMetaData()
.withName("screen")
.withViewField(new QFieldMetaData("myField", QFieldType.STRING)));
qInstance.addProcess(process);

View File

@ -148,8 +148,10 @@ public class QInstanceValidatorTest extends BaseTest
/*******************************************************************************
**
* the point of this method is to test the deprecated member, so, don't need to
* get a compiler warning about usage of deprecated member.
*******************************************************************************/
@SuppressWarnings("deprecation")
@Test
void testMetaDataFilter()
{

View File

@ -370,11 +370,11 @@ public class TestUtils
.withName(PROCESS_NAME_INCREASE_BIRTHDATE)
.withTableName(TABLE_NAME_PERSON_MEMORY)
.addStep(new QFrontendStepMetaData()
.withStep(new QFrontendStepMetaData()
.withName("preview")
)
.addStep(new QBackendStepMetaData()
.withStep(new QBackendStepMetaData()
.withName("doWork")
.withCode(new QCodeReference(IncreaseBirthdateStep.class))
.withInputData(new QFunctionInputMetaData()
@ -383,7 +383,7 @@ public class TestUtils
.withFieldList(List.of(new QFieldMetaData("outputMessage", QFieldType.STRING).withDefaultValue("Success!"))))
)
.addStep(new QFrontendStepMetaData()
.withStep(new QFrontendStepMetaData()
.withName("results")
.withFormField(new QFieldMetaData("outputMessage", QFieldType.STRING))
);
@ -1187,7 +1187,7 @@ public class TestUtils
return new QProcessMetaData()
.withName(PROCESS_NAME_GREET_PEOPLE)
.withTableName(TABLE_NAME_PERSON_MEMORY)
.addStep(new QBackendStepMetaData()
.withStep(new QBackendStepMetaData()
.withName("prepare")
.withCode(new QCodeReference()
.withName(MockBackendStep.class.getName())
@ -1218,13 +1218,13 @@ public class TestUtils
.withName(PROCESS_NAME_GREET_PEOPLE_INTERACTIVE)
.withTableName(TABLE_NAME_PERSON)
.addStep(new QFrontendStepMetaData()
.withStep(new QFrontendStepMetaData()
.withName("setup")
.withFormField(new QFieldMetaData("greetingPrefix", QFieldType.STRING))
.withFormField(new QFieldMetaData("greetingSuffix", QFieldType.STRING))
)
.addStep(new QBackendStepMetaData()
.withStep(new QBackendStepMetaData()
.withName("doWork")
.withCode(new QCodeReference()
.withName(MockBackendStep.class.getName())
@ -1243,7 +1243,7 @@ public class TestUtils
.withFieldList(List.of(new QFieldMetaData("outputMessage", QFieldType.STRING))))
)
.addStep(new QFrontendStepMetaData()
.withStep(new QFrontendStepMetaData()
.withName("results")
.withFormField(new QFieldMetaData("outputMessage", QFieldType.STRING))
);
@ -1264,7 +1264,7 @@ public class TestUtils
return new QProcessMetaData()
.withName(PROCESS_NAME_ADD_TO_PEOPLES_AGE)
.withTableName(TABLE_NAME_PERSON)
.addStep(new QBackendStepMetaData()
.withStep(new QBackendStepMetaData()
.withName("getAgeStatistics")
.withCode(new QCodeReference()
.withName(GetAgeStatistics.class.getName())
@ -1278,7 +1278,7 @@ public class TestUtils
.withFieldList(List.of(
new QFieldMetaData("minAge", QFieldType.INTEGER),
new QFieldMetaData("maxAge", QFieldType.INTEGER)))))
.addStep(new QBackendStepMetaData()
.withStep(new QBackendStepMetaData()
.withName("addAge")
.withCode(new QCodeReference()
.withName(AddAge.class.getName())
@ -1308,7 +1308,7 @@ public class TestUtils
.withTableName(defineTableBasepull().getName()))
.withName(PROCESS_NAME_BASEPULL)
.withTableName(TABLE_NAME_PERSON)
.addStep(new QBackendStepMetaData()
.withStep(new QBackendStepMetaData()
.withName("prepare")
.withCode(new QCodeReference()
.withName(MockBackendStep.class.getName())

View File

@ -24,9 +24,11 @@ package com.kingsrook.qqq.backend.core.utils;
import java.util.Map;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.MapperFeature;
import com.kingsrook.qqq.backend.core.BaseTest;
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
/*******************************************************************************
@ -60,6 +62,47 @@ class YamlUtilsTest extends BaseTest
/***************************************************************************
* simple bean to use in customObjectMapper test
* we'd use a map, but SORT_PROPERTIES_ALPHABETICALLY doesn't apply to maps...
***************************************************************************/
private record SomeBean(String foo, Integer bar) {}
/*******************************************************************************
**
*******************************************************************************/
@Test
void testCustomObjectMapper() throws JsonProcessingException
{
SomeBean someBean = new SomeBean("Hi", 47);
///////////////////////////////////////////////////////////////////
// by default, the fields come out in the order they're declared //
///////////////////////////////////////////////////////////////////
assertEquals("""
foo: "Hi"
bar: 47
""", YamlUtils.toYaml(someBean));
/////////////////////////////////////////////////////////////
// customize the builder to sort properties alphabetically //
// (to assert that doing a customization works) //
/////////////////////////////////////////////////////////////
String outputYaml = YamlUtils.toYamlCustomized(someBean, yamlMapperBuilder ->
{
yamlMapperBuilder.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);
});
assertEquals("""
bar: 47
foo: "Hi"
""", outputYaml);
}
/*******************************************************************************
**
*******************************************************************************/