diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/fields/DateTimeDisplayValueBehavior.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/fields/DateTimeDisplayValueBehavior.java index b480ae8e..5345a53d 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/fields/DateTimeDisplayValueBehavior.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/fields/DateTimeDisplayValueBehavior.java @@ -39,13 +39,16 @@ import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair; /******************************************************************************* - ** + ** Field Display Behavior class for customizing the display values used + ** in date-time fields *******************************************************************************/ public class DateTimeDisplayValueBehavior implements FieldDisplayBehavior { private static final QLogger LOG = QLogger.getLogger(DateTimeDisplayValueBehavior.class); private String zoneIdFromFieldName; + private String fallbackZoneId; + private String defaultZoneId; private static DateTimeDisplayValueBehavior NOOP = new DateTimeDisplayValueBehavior(); @@ -112,14 +115,35 @@ public class DateTimeDisplayValueBehavior implements FieldDisplayBehavior validateBehaviorConfiguration(QTableMetaData tableMetaData, QFieldMetaData fieldMetaData) { - List errors = new ArrayList<>(); - String errorSuffix = " field [" + fieldMetaData.getName() + "] in table [" + tableMetaData.getName() + "]"; + List errors = new ArrayList<>(); + String errorSuffix = " field [" + fieldMetaData.getName() + "] in table [" + tableMetaData.getName() + "]"; if(!QFieldType.DATE_TIME.equals(fieldMetaData.getType())) { errors.add("A DateTimeDisplayValueBehavior was a applied to a non-DATE_TIME" + errorSuffix); } + ////////////////////////////////////////////////// + // validate rules if zoneIdFromFieldName is set // + ////////////////////////////////////////////////// if(StringUtils.hasContent(zoneIdFromFieldName)) { + if(StringUtils.hasContent(defaultZoneId)) + { + errors.add("You may not specify both zoneIdFromFieldName and defaultZoneId in DateTimeDisplayValueBehavior on" + errorSuffix); + } + if(!tableMetaData.getFields().containsKey(zoneIdFromFieldName)) { errors.add("Unrecognized field name [" + zoneIdFromFieldName + "] for [zoneIdFromFieldName] in DateTimeDisplayValueBehavior on" + errorSuffix); @@ -156,6 +188,50 @@ public class DateTimeDisplayValueBehavior implements FieldDisplayBehavior, List> testOne = setup -> + { + DateTimeDisplayValueBehavior dateTimeDisplayValueBehavior = new DateTimeDisplayValueBehavior(); + setup.accept(dateTimeDisplayValueBehavior); + return (dateTimeDisplayValueBehavior.validateBehaviorConfiguration(table, field)); + }; + + /////////////////// + // valid configs // + /////////////////// + assertThat(testOne.apply(b -> b.toString())).isEmpty(); // default setup (noop use-case) is valid + assertThat(testOne.apply(b -> b.withZoneIdFromFieldName("timeZone"))).isEmpty(); + assertThat(testOne.apply(b -> b.withZoneIdFromFieldName("timeZone").withFallbackZoneId("UTC"))).isEmpty(); + assertThat(testOne.apply(b -> b.withZoneIdFromFieldName("timeZone").withFallbackZoneId("America/Chicago"))).isEmpty(); + assertThat(testOne.apply(b -> b.withDefaultZoneId("UTC"))).isEmpty(); + assertThat(testOne.apply(b -> b.withDefaultZoneId("America/Chicago"))).isEmpty(); + + ///////////////////// + // invalid configs // + ///////////////////// + assertThat(testOne.apply(b -> b.withZoneIdFromFieldName("notAField"))) + .hasSize(1).first().asString() + .contains("Unrecognized field name"); + + assertThat(testOne.apply(b -> b.withZoneIdFromFieldName("id"))) + .hasSize(1).first().asString() + .contains("A non-STRING type [INTEGER] was specified as the zoneIdFromFieldName field"); + + assertThat(testOne.apply(b -> b.withZoneIdFromFieldName("timeZone").withDefaultZoneId("UTC"))) + .hasSize(1).first().asString() + .contains("You may not specify both zoneIdFromFieldName and defaultZoneId"); + + assertThat(testOne.apply(b -> b.withDefaultZoneId("UTC").withFallbackZoneId("UTC"))) + .hasSize(2) + .anyMatch(s -> s.contains("You may not specify both defaultZoneId and fallbackZoneId")) + .anyMatch(s -> s.contains("You may only set fallbackZoneId if using zoneIdFromFieldName")); + + assertThat(testOne.apply(b -> b.withFallbackZoneId("UTC"))) + .hasSize(1).first().asString() + .contains("You may only set fallbackZoneId if using zoneIdFromFieldName"); + + assertThat(testOne.apply(b -> b.withDefaultZoneId("notAZone"))) + .hasSize(1).first().asString() + .contains("Invalid ZoneId [notAZone] for [defaultZoneId]"); + + assertThat(testOne.apply(b -> b.withZoneIdFromFieldName("timeZone").withFallbackZoneId("notAZone"))) + .hasSize(1).first().asString() + .contains("Invalid ZoneId [notAZone] for [fallbackZoneId]"); + + assertThat(new DateTimeDisplayValueBehavior().validateBehaviorConfiguration(table, table.getField("firstName"))) + .hasSize(1).first().asString() + .contains("non-DATE_TIME field [firstName]"); + } + } \ No newline at end of file