CE-607 Instance validation for section-fields from join tables

This commit is contained in:
2023-08-08 16:21:28 -05:00
parent 3406929e75
commit 05f2341099
3 changed files with 80 additions and 6 deletions

View File

@ -438,11 +438,14 @@ public class QInstanceValidator
for(QFieldSection section : table.getSections()) for(QFieldSection section : table.getSections())
{ {
validateTableSection(qInstance, table, section, fieldNamesInSections); validateTableSection(qInstance, table, section, fieldNamesInSections);
if(assertCondition(section.getTier() != null, "Table " + tableName + " " + section.getName() + " is missing its tier"))
{
if(section.getTier().equals(Tier.T1)) if(section.getTier().equals(Tier.T1))
{ {
assertCondition(tier1Section == null, "Table " + tableName + " has more than 1 section listed as Tier 1"); assertCondition(tier1Section == null, "Table " + tableName + " has more than 1 section listed as Tier 1");
tier1Section = section; tier1Section = section;
} }
}
assertCondition(!usedSectionNames.contains(section.getName()), "Table " + tableName + " has more than 1 section named " + section.getName()); assertCondition(!usedSectionNames.contains(section.getName()), "Table " + tableName + " has more than 1 section named " + section.getName());
usedSectionNames.add(section.getName()); usedSectionNames.add(section.getName());
@ -1099,13 +1102,34 @@ public class QInstanceValidator
boolean hasFields = CollectionUtils.nullSafeHasContents(section.getFieldNames()); boolean hasFields = CollectionUtils.nullSafeHasContents(section.getFieldNames());
boolean hasWidget = StringUtils.hasContent(section.getWidgetName()); boolean hasWidget = StringUtils.hasContent(section.getWidgetName());
if(assertCondition(hasFields || hasWidget, "Table " + table.getName() + " section " + section.getName() + " does not have any fields or a widget.")) String sectionPrefix = "Table " + table.getName() + " section " + section.getName() + " ";
if(assertCondition(hasFields || hasWidget, sectionPrefix + "does not have any fields or a widget."))
{ {
if(table.getFields() != null && hasFields) if(table.getFields() != null && hasFields)
{ {
for(String fieldName : section.getFieldNames()) for(String fieldName : section.getFieldNames())
{ {
assertCondition(table.getFields().containsKey(fieldName), "Table " + table.getName() + " section " + section.getName() + " specifies fieldName " + fieldName + ", which is not a field on this table."); if(fieldName.contains("."))
{
String[] parts = fieldName.split("\\.");
String otherTableName = parts[0];
String foreignFieldName = parts[1];
if(assertCondition(qInstance.getTable(otherTableName) != null, sectionPrefix + "join-field " + fieldName + ", which is referencing an unrecognized table name [" + otherTableName + "]"))
{
List<ExposedJoin> matchedExposedJoins = CollectionUtils.nonNullList(table.getExposedJoins()).stream().filter(ej -> otherTableName.equals(ej.getJoinTable())).toList();
if(assertCondition(CollectionUtils.nullSafeHasContents(matchedExposedJoins), sectionPrefix + "join-field " + fieldName + ", referencing table [" + otherTableName + "] which is not an exposed join on this table."))
{
assertCondition(!matchedExposedJoins.get(0).getIsMany(), sectionPrefix + "join-field " + fieldName + " references an is-many join, which is not supported.");
}
assertCondition(qInstance.getTable(otherTableName).getFields().containsKey(foreignFieldName), sectionPrefix + "join-field " + fieldName + " specifies a fieldName [" + foreignFieldName + "] which does not exist in that table [" + otherTableName + "].");
}
}
else
{
assertCondition(table.getFields().containsKey(fieldName), sectionPrefix + "specifies fieldName " + fieldName + ", which is not a field on this table.");
}
assertCondition(!fieldNamesInSections.contains(fieldName), "Table " + table.getName() + " has field " + fieldName + " listed more than once in its field sections."); assertCondition(!fieldNamesInSections.contains(fieldName), "Table " + table.getName() + " has field " + fieldName + " listed more than once in its field sections.");
fieldNamesInSections.add(fieldName); fieldNamesInSections.add(fieldName);
@ -1113,7 +1137,7 @@ public class QInstanceValidator
} }
else if(hasWidget) else if(hasWidget)
{ {
assertCondition(qInstance.getWidget(section.getWidgetName()) != null, "Table " + table.getName() + " section " + section.getName() + " specifies widget " + section.getWidgetName() + ", which is not a widget in this instance."); assertCondition(qInstance.getWidget(section.getWidgetName()) != null, sectionPrefix + "specifies widget " + section.getWidgetName() + ", which is not a widget in this instance.");
} }
} }
} }

View File

@ -822,6 +822,55 @@ class QInstanceValidatorTest extends BaseTest
/*******************************************************************************
**
*******************************************************************************/
@Test
void testSectionsWithJoinFields()
{
Consumer<QTableMetaData> putAllFieldsInASection = table -> table.addSection(new QFieldSection()
.withName("section0")
.withTier(Tier.T1)
.withFieldNames(new ArrayList<>(table.getFields().keySet())));
assertValidationFailureReasons(qInstance ->
{
QTableMetaData table = qInstance.getTable(TestUtils.TABLE_NAME_ORDER);
putAllFieldsInASection.accept(table);
table.getSections().get(0).getFieldNames().add(TestUtils.TABLE_NAME_LINE_ITEM + ".sku");
}, "orderLine.sku references an is-many join, which is not supported");
assertValidationSuccess(qInstance ->
{
QTableMetaData table = qInstance.getTable(TestUtils.TABLE_NAME_LINE_ITEM);
putAllFieldsInASection.accept(table);
table.getSections().get(0).getFieldNames().add(TestUtils.TABLE_NAME_ORDER + ".orderNo");
});
assertValidationFailureReasons(qInstance ->
{
QTableMetaData table = qInstance.getTable(TestUtils.TABLE_NAME_LINE_ITEM);
putAllFieldsInASection.accept(table);
table.getSections().get(0).getFieldNames().add(TestUtils.TABLE_NAME_ORDER + ".asdf");
}, "order.asdf specifies a fieldName [asdf] which does not exist in that table [order].");
assertValidationFailureReasons(qInstance ->
{
QTableMetaData table = qInstance.getTable(TestUtils.TABLE_NAME_LINE_ITEM);
putAllFieldsInASection.accept(table);
table.getSections().get(0).getFieldNames().add("foo.bar");
}, "unrecognized table name [foo]");
assertValidationFailureReasons(qInstance ->
{
QTableMetaData table = qInstance.getTable(TestUtils.TABLE_NAME_LINE_ITEM);
putAllFieldsInASection.accept(table);
table.getSections().get(0).getFieldNames().add(TestUtils.TABLE_NAME_SHAPE + ".id");
}, "[shape] which is not an exposed join on this table");
}
/******************************************************************************* /*******************************************************************************
** **
*******************************************************************************/ *******************************************************************************/

View File

@ -590,6 +590,7 @@ public class TestUtils
.withFieldName("order.storeId") .withFieldName("order.storeId")
.withJoinNameChain(List.of("orderLineItem"))) .withJoinNameChain(List.of("orderLineItem")))
.withAssociation(new Association().withName("extrinsics").withAssociatedTableName(TABLE_NAME_LINE_ITEM_EXTRINSIC).withJoinName("lineItemLineItemExtrinsic")) .withAssociation(new Association().withName("extrinsics").withAssociatedTableName(TABLE_NAME_LINE_ITEM_EXTRINSIC).withJoinName("lineItemLineItemExtrinsic"))
.withExposedJoin(new ExposedJoin().withJoinTable(TABLE_NAME_ORDER))
.withField(new QFieldMetaData("id", QFieldType.INTEGER).withIsEditable(false)) .withField(new QFieldMetaData("id", QFieldType.INTEGER).withIsEditable(false))
.withField(new QFieldMetaData("createDate", QFieldType.DATE_TIME).withIsEditable(false)) .withField(new QFieldMetaData("createDate", QFieldType.DATE_TIME).withIsEditable(false))
.withField(new QFieldMetaData("modifyDate", QFieldType.DATE_TIME).withIsEditable(false)) .withField(new QFieldMetaData("modifyDate", QFieldType.DATE_TIME).withIsEditable(false))