CE-1068 - Check for variabale being not-empty

This commit is contained in:
2024-05-01 16:47:16 -05:00
parent e853c67b67
commit e022284ca7
3 changed files with 83 additions and 17 deletions

View File

@ -30,6 +30,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import com.kingsrook.qqq.backend.core.exceptions.QException; import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.exceptions.QUserFacingException;
import com.kingsrook.qqq.backend.core.instances.QMetaDataVariableInterpreter; import com.kingsrook.qqq.backend.core.instances.QMetaDataVariableInterpreter;
import com.kingsrook.qqq.backend.core.logging.QLogger; import com.kingsrook.qqq.backend.core.logging.QLogger;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.expressions.AbstractFilterExpression; import com.kingsrook.qqq.backend.core.model.actions.tables.query.expressions.AbstractFilterExpression;
@ -469,7 +470,12 @@ public class QQueryFilter implements Serializable, Cloneable
*******************************************************************************/ *******************************************************************************/
private String getBackendName(QFilterCriteria criterion, int valueIndex) private String getBackendName(QFilterCriteria criterion, int valueIndex)
{ {
StringBuilder backendName = new StringBuilder(criterion.getFieldName()); StringBuilder backendName = new StringBuilder();
for(String fieldNameParts : criterion.getFieldName().split("\\."))
{
backendName.append(StringUtils.ucFirst(fieldNameParts));
}
for(String operatorParts : criterion.getOperator().name().split("_")) for(String operatorParts : criterion.getOperator().name().split("_"))
{ {
backendName.append(StringUtils.ucFirst(operatorParts.toLowerCase())); backendName.append(StringUtils.ucFirst(operatorParts.toLowerCase()));
@ -487,7 +493,7 @@ public class QQueryFilter implements Serializable, Cloneable
} }
} }
return (backendName.toString()); return (StringUtils.lcFirst(backendName.toString()));
} }
@ -502,6 +508,8 @@ public class QQueryFilter implements Serializable, Cloneable
*******************************************************************************/ *******************************************************************************/
public void interpretValues(Map<String, Serializable> inputValues) throws QException public void interpretValues(Map<String, Serializable> inputValues) throws QException
{ {
List<Exception> caughtExceptions = new ArrayList<>();
QMetaDataVariableInterpreter variableInterpreter = new QMetaDataVariableInterpreter(); QMetaDataVariableInterpreter variableInterpreter = new QMetaDataVariableInterpreter();
variableInterpreter.addValueMap("input", inputValues); variableInterpreter.addValueMap("input", inputValues);
for(QFilterCriteria criterion : getCriteria()) for(QFilterCriteria criterion : getCriteria())
@ -512,31 +520,45 @@ public class QQueryFilter implements Serializable, Cloneable
for(Serializable value : criterion.getValues()) for(Serializable value : criterion.getValues())
{ {
if(value instanceof AbstractFilterExpression<?>) try
{ {
/////////////////////////////////////////////////////////////////////// if(value instanceof AbstractFilterExpression<?>)
// if a filter variable expression, evaluate the input values, which //
// will replace the variables with the corresponding actual values //
///////////////////////////////////////////////////////////////////////
if(value instanceof FilterVariableExpression filterVariableExpression)
{ {
newValues.add(filterVariableExpression.evaluateInputValues(inputValues)); ///////////////////////////////////////////////////////////////////////
// if a filter variable expression, evaluate the input values, which //
// will replace the variables with the corresponding actual values //
///////////////////////////////////////////////////////////////////////
if(value instanceof FilterVariableExpression filterVariableExpression)
{
newValues.add(filterVariableExpression.evaluateInputValues(inputValues));
}
else
{
newValues.add(value);
}
} }
else else
{ {
newValues.add(value); String valueAsString = ValueUtils.getValueAsString(value);
Serializable interpretedValue = variableInterpreter.interpretForObject(valueAsString);
newValues.add(interpretedValue);
} }
} }
else catch(Exception e)
{ {
String valueAsString = ValueUtils.getValueAsString(value); caughtExceptions.add(e);
Serializable interpretedValue = variableInterpreter.interpretForObject(valueAsString);
newValues.add(interpretedValue);
} }
} }
criterion.setValues(newValues); criterion.setValues(newValues);
} }
} }
if(!caughtExceptions.isEmpty())
{
String message = "Error interpreting filter values: " + StringUtils.joinWithCommasAndAnd(caughtExceptions.stream().map(e -> e.getMessage()).toList());
boolean allUserFacing = caughtExceptions.stream().allMatch(QUserFacingException.class::isInstance);
throw (allUserFacing ? new QUserFacingException(message) : new QException(message));
}
} }

View File

@ -26,6 +26,7 @@ import java.io.Serializable;
import java.util.Map; import java.util.Map;
import com.kingsrook.qqq.backend.core.exceptions.QException; import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.exceptions.QUserFacingException; import com.kingsrook.qqq.backend.core.exceptions.QUserFacingException;
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
/******************************************************************************* /*******************************************************************************
@ -57,9 +58,9 @@ public class FilterVariableExpression extends AbstractFilterExpression<Serializa
@Override @Override
public Serializable evaluateInputValues(Map<String, Serializable> inputValues) throws QException public Serializable evaluateInputValues(Map<String, Serializable> inputValues) throws QException
{ {
if(!inputValues.containsKey(variableName)) if(!inputValues.containsKey(variableName) || "".equals(ValueUtils.getValueAsString(inputValues.get(variableName))))
{ {
throw (new QUserFacingException("Missing variable value.")); throw (new QUserFacingException("Missing value for variable: " + variableName));
} }
return (inputValues.get(variableName)); return (inputValues.get(variableName));
} }

View File

@ -23,10 +23,12 @@ package com.kingsrook.qqq.backend.core.actions.tables;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import com.kingsrook.qqq.backend.core.BaseTest; import com.kingsrook.qqq.backend.core.BaseTest;
import com.kingsrook.qqq.backend.core.exceptions.QException; import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.exceptions.QUserFacingException;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria; 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.model.actions.tables.query.QQueryFilter;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.expressions.AbstractFilterExpression; import com.kingsrook.qqq.backend.core.model.actions.tables.query.expressions.AbstractFilterExpression;
@ -35,6 +37,7 @@ import org.junit.jupiter.api.Test;
import static com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator.BETWEEN; import static com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator.BETWEEN;
import static com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator.EQUALS; import static com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator.EQUALS;
import static com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator.IS_BLANK; import static com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator.IS_BLANK;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
@ -65,6 +68,43 @@ class QQueryFilterTest extends BaseTest
/*******************************************************************************
**
*******************************************************************************/
@Test
public void testInterpretValuesNotInMap() throws QException
{
AbstractFilterExpression<Serializable> expression = new FilterVariableExpression()
.withVariableName("clientIdEquals1");
QQueryFilter qQueryFilter = new QQueryFilter(new QFilterCriteria("id", EQUALS, expression));
assertThatThrownBy(() -> qQueryFilter.interpretValues(Collections.emptyMap()))
.isInstanceOf(QUserFacingException.class)
.hasMessageContaining("Missing value for variable: clientIdEquals1");
}
/*******************************************************************************
**
*******************************************************************************/
@Test
public void testInterpretValuesEmptyString() throws QException
{
Map<String, Serializable> inputValues = new HashMap<>();
inputValues.put("clientIdEquals1", "");
AbstractFilterExpression<Serializable> expression = new FilterVariableExpression()
.withVariableName("clientIdEquals1");
QQueryFilter qQueryFilter = new QQueryFilter(new QFilterCriteria("id", EQUALS, expression));
assertThatThrownBy(() -> qQueryFilter.interpretValues(inputValues))
.isInstanceOf(QUserFacingException.class)
.hasMessageContaining("Missing value for variable: clientIdEquals1");
}
/******************************************************************************* /*******************************************************************************
** **
*******************************************************************************/ *******************************************************************************/
@ -78,13 +118,15 @@ class QQueryFilterTest extends BaseTest
FilterVariableExpression fve4 = new FilterVariableExpression(); FilterVariableExpression fve4 = new FilterVariableExpression();
FilterVariableExpression fve5 = new FilterVariableExpression(); FilterVariableExpression fve5 = new FilterVariableExpression();
FilterVariableExpression fve6 = new FilterVariableExpression(); FilterVariableExpression fve6 = new FilterVariableExpression();
FilterVariableExpression fve7 = new FilterVariableExpression();
QQueryFilter qQueryFilter = new QQueryFilter( QQueryFilter qQueryFilter = new QQueryFilter(
new QFilterCriteria("id", EQUALS, fve0), new QFilterCriteria("id", EQUALS, fve0),
new QFilterCriteria("value", IS_BLANK, fve1), new QFilterCriteria("value", IS_BLANK, fve1),
new QFilterCriteria("id", EQUALS, fve2), new QFilterCriteria("id", EQUALS, fve2),
new QFilterCriteria("id", BETWEEN, fve3, fve4), new QFilterCriteria("id", BETWEEN, fve3, fve4),
new QFilterCriteria("id", BETWEEN, fve5, fve6) new QFilterCriteria("id", BETWEEN, fve5, fve6),
new QFilterCriteria("joinTable.someFieldId", EQUALS, fve7)
); );
qQueryFilter.prepForBackend(); qQueryFilter.prepForBackend();
@ -95,6 +137,7 @@ class QQueryFilterTest extends BaseTest
assertEquals("idBetweenTo", fve4.getVariableName()); assertEquals("idBetweenTo", fve4.getVariableName());
assertEquals("idBetweenFrom2", fve5.getVariableName()); assertEquals("idBetweenFrom2", fve5.getVariableName());
assertEquals("idBetweenTo2", fve6.getVariableName()); assertEquals("idBetweenTo2", fve6.getVariableName());
assertEquals("joinTableSomeFieldIdEquals", fve7.getVariableName());
} }
} }