7 changed files with 503 additions and 39 deletions
@ -0,0 +1,472 @@ |
|||
/** |
|||
* Copyright © 2016-2025 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.cf.configuration; |
|||
|
|||
import org.junit.jupiter.api.Test; |
|||
import org.junit.jupiter.api.extension.ExtendWith; |
|||
import org.junit.jupiter.params.ParameterizedTest; |
|||
import org.junit.jupiter.params.provider.NullAndEmptySource; |
|||
import org.junit.jupiter.params.provider.ValueSource; |
|||
import org.mockito.junit.jupiter.MockitoExtension; |
|||
import org.thingsboard.server.common.data.cf.CalculatedFieldType; |
|||
import org.thingsboard.server.common.data.relation.EntitySearchDirection; |
|||
|
|||
import java.util.Arrays; |
|||
import java.util.HashMap; |
|||
import java.util.Map; |
|||
|
|||
import static org.assertj.core.api.Assertions.assertThat; |
|||
import static org.assertj.core.api.Assertions.assertThatThrownBy; |
|||
import static org.mockito.Mockito.mock; |
|||
import static org.mockito.Mockito.verify; |
|||
import static org.thingsboard.server.common.data.cf.configuration.GeofencingCalculatedFieldConfiguration.ENTITY_ID_LATITUDE_ARGUMENT_KEY; |
|||
import static org.thingsboard.server.common.data.cf.configuration.GeofencingCalculatedFieldConfiguration.ENTITY_ID_LONGITUDE_ARGUMENT_KEY; |
|||
|
|||
@ExtendWith(MockitoExtension.class) |
|||
public class GeofencingCalculatedFieldConfigurationTest { |
|||
|
|||
@Test |
|||
void typeShouldBeGeofencing() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
assertThat(cfg.getType()).isEqualTo(CalculatedFieldType.GEOFENCING); |
|||
} |
|||
|
|||
@Test |
|||
void validateShouldThrowWhenArgumentsNull() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
cfg.setArguments(null); |
|||
|
|||
assertThatThrownBy(cfg::validate) |
|||
.isInstanceOf(IllegalArgumentException.class) |
|||
.hasMessage("Geofencing calculated field arguments must be specified!"); |
|||
} |
|||
|
|||
@Test |
|||
void validateShouldThrowWhenLatitudeArgIsMissing() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
var arguments = new HashMap<String, Argument>(); |
|||
arguments.put(ENTITY_ID_LATITUDE_ARGUMENT_KEY, null); |
|||
arguments.put(ENTITY_ID_LONGITUDE_ARGUMENT_KEY, toArgument("longitude", ArgumentType.TS_LATEST)); |
|||
cfg.setArguments(arguments); |
|||
|
|||
assertThatThrownBy(cfg::validate) |
|||
.isInstanceOf(IllegalArgumentException.class) |
|||
.hasMessage("Missing required coordinates argument: " + ENTITY_ID_LATITUDE_ARGUMENT_KEY + "!"); |
|||
} |
|||
|
|||
@Test |
|||
void validateShouldThrowWhenLongitudeArgIsMissing() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
var arguments = new HashMap<String, Argument>(); |
|||
arguments.put(ENTITY_ID_LATITUDE_ARGUMENT_KEY, toArgument("latitude", ArgumentType.TS_LATEST)); |
|||
arguments.put(ENTITY_ID_LONGITUDE_ARGUMENT_KEY, null); |
|||
cfg.setArguments(arguments); |
|||
|
|||
assertThatThrownBy(cfg::validate) |
|||
.isInstanceOf(IllegalArgumentException.class) |
|||
.hasMessage("Missing required coordinates argument: " + ENTITY_ID_LONGITUDE_ARGUMENT_KEY + "!"); |
|||
} |
|||
|
|||
@Test |
|||
void validateShouldThrowWhenLatitudeReferenceKeyIsNull() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
cfg.setArguments(Map.of( |
|||
ENTITY_ID_LATITUDE_ARGUMENT_KEY, toArgument(null), |
|||
ENTITY_ID_LONGITUDE_ARGUMENT_KEY, toArgument("longitude", ArgumentType.TS_LATEST)) |
|||
); |
|||
|
|||
assertThatThrownBy(cfg::validate) |
|||
.isInstanceOf(IllegalArgumentException.class) |
|||
.hasMessage("Missing or invalid reference entity key for argument: " + ENTITY_ID_LATITUDE_ARGUMENT_KEY); |
|||
} |
|||
|
|||
@Test |
|||
void validateShouldThrowWhenLongitudeReferenceKeyIsNull() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
cfg.setArguments(Map.of( |
|||
ENTITY_ID_LATITUDE_ARGUMENT_KEY, toArgument("latitude", ArgumentType.TS_LATEST), |
|||
ENTITY_ID_LONGITUDE_ARGUMENT_KEY, toArgument(null)) |
|||
); |
|||
|
|||
assertThatThrownBy(cfg::validate) |
|||
.isInstanceOf(IllegalArgumentException.class) |
|||
.hasMessage("Missing or invalid reference entity key for argument: " + ENTITY_ID_LONGITUDE_ARGUMENT_KEY); |
|||
} |
|||
|
|||
@Test |
|||
void validateShouldThrowWhenLatitudeReferenceKeyTypeIsNull() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
cfg.setArguments(Map.of( |
|||
ENTITY_ID_LATITUDE_ARGUMENT_KEY, toArgument(new ReferencedEntityKey("latitude", null, null)), |
|||
ENTITY_ID_LONGITUDE_ARGUMENT_KEY, toArgument("longitude", ArgumentType.TS_LATEST)) |
|||
); |
|||
|
|||
assertThatThrownBy(cfg::validate) |
|||
.isInstanceOf(IllegalArgumentException.class) |
|||
.hasMessage("Missing or invalid reference entity key for argument: " + ENTITY_ID_LATITUDE_ARGUMENT_KEY); |
|||
} |
|||
|
|||
@Test |
|||
void validateShouldThrowWhenReferenceKeyTypeIsNull() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
cfg.setArguments(Map.of( |
|||
ENTITY_ID_LATITUDE_ARGUMENT_KEY, toArgument("latitude", ArgumentType.TS_LATEST), |
|||
ENTITY_ID_LONGITUDE_ARGUMENT_KEY, toArgument(new ReferencedEntityKey("longitude", null, null))) |
|||
); |
|||
|
|||
assertThatThrownBy(cfg::validate) |
|||
.isInstanceOf(IllegalArgumentException.class) |
|||
.hasMessage("Missing or invalid reference entity key for argument: " + ENTITY_ID_LONGITUDE_ARGUMENT_KEY); |
|||
} |
|||
|
|||
@Test |
|||
void validateShouldThrowWhenLatitudeArgHasWrongArgumentType() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
cfg.setArguments(Map.of( |
|||
ENTITY_ID_LATITUDE_ARGUMENT_KEY, toArgument("latitude", ArgumentType.ATTRIBUTE), |
|||
ENTITY_ID_LONGITUDE_ARGUMENT_KEY, toArgument("longitude", ArgumentType.TS_LATEST) |
|||
)); |
|||
|
|||
assertThatThrownBy(cfg::validate) |
|||
.isInstanceOf(IllegalArgumentException.class) |
|||
.hasMessage("Argument '" + ENTITY_ID_LATITUDE_ARGUMENT_KEY + "' must be of type TS_LATEST!"); |
|||
} |
|||
|
|||
@Test |
|||
void validateShouldThrowWhenLongitudeArgHasWrongArgumentType() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
cfg.setArguments(Map.of( |
|||
ENTITY_ID_LATITUDE_ARGUMENT_KEY, toArgument("latitude", ArgumentType.TS_LATEST), |
|||
ENTITY_ID_LONGITUDE_ARGUMENT_KEY, toArgument("longitude", ArgumentType.ATTRIBUTE) |
|||
)); |
|||
|
|||
assertThatThrownBy(cfg::validate) |
|||
.isInstanceOf(IllegalArgumentException.class) |
|||
.hasMessage("Argument '" + ENTITY_ID_LONGITUDE_ARGUMENT_KEY + "' must be of type TS_LATEST!"); |
|||
} |
|||
|
|||
@Test |
|||
void validateShouldThrowWhenLatitudeArgHasDynamicSource() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
|
|||
Argument latitudeArg = toArgument("latitude", ArgumentType.TS_LATEST); |
|||
var refDynamicSourceConfiguration = new RelationQueryDynamicSourceConfiguration(); |
|||
latitudeArg.setRefDynamicSourceConfiguration(refDynamicSourceConfiguration); |
|||
|
|||
Argument longitudeArg = toArgument("longitude", ArgumentType.TS_LATEST); |
|||
|
|||
cfg.setArguments(Map.of(ENTITY_ID_LATITUDE_ARGUMENT_KEY, latitudeArg, ENTITY_ID_LONGITUDE_ARGUMENT_KEY, longitudeArg)); |
|||
|
|||
assertThatThrownBy(cfg::validate) |
|||
.isInstanceOf(IllegalArgumentException.class) |
|||
.hasMessage("Dynamic source is not allowed for '" + ENTITY_ID_LATITUDE_ARGUMENT_KEY + "' argument!"); |
|||
} |
|||
|
|||
@Test |
|||
void validateShouldThrowWhenLongitudeArgHasDynamicSource() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
|
|||
Argument latitudeArg = toArgument("latitude", ArgumentType.TS_LATEST); |
|||
Argument longitudeArg = toArgument("longitude", ArgumentType.TS_LATEST); |
|||
var refDynamicSourceConfiguration = new RelationQueryDynamicSourceConfiguration(); |
|||
longitudeArg.setRefDynamicSourceConfiguration(refDynamicSourceConfiguration); |
|||
|
|||
cfg.setArguments(Map.of(ENTITY_ID_LATITUDE_ARGUMENT_KEY, latitudeArg, ENTITY_ID_LONGITUDE_ARGUMENT_KEY, longitudeArg)); |
|||
|
|||
assertThatThrownBy(cfg::validate) |
|||
.isInstanceOf(IllegalArgumentException.class) |
|||
.hasMessage("Dynamic source is not allowed for '" + ENTITY_ID_LONGITUDE_ARGUMENT_KEY + "' argument!"); |
|||
} |
|||
|
|||
@Test |
|||
void validateShouldThrowWhenGeofencingArgumentsMissing() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
cfg.setArguments(Map.of( |
|||
ENTITY_ID_LATITUDE_ARGUMENT_KEY, toArgument("latitude", ArgumentType.TS_LATEST), |
|||
ENTITY_ID_LONGITUDE_ARGUMENT_KEY, toArgument("longitude", ArgumentType.TS_LATEST) |
|||
)); |
|||
|
|||
assertThatThrownBy(cfg::validate) |
|||
.isInstanceOf(IllegalArgumentException.class) |
|||
.hasMessage("Geofencing calculated field must contain at least one geofencing zone group defined!"); |
|||
} |
|||
|
|||
@Test |
|||
void validateShouldThrowWhenZoneGroupArgumentIsNull() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
var arguments = new HashMap<String, Argument>(); |
|||
arguments.put(ENTITY_ID_LATITUDE_ARGUMENT_KEY, toArgument("latitude", ArgumentType.TS_LATEST)); |
|||
arguments.put(ENTITY_ID_LONGITUDE_ARGUMENT_KEY, toArgument("longitude", ArgumentType.TS_LATEST)); |
|||
arguments.put("someZones", null); |
|||
|
|||
cfg.setArguments(arguments); |
|||
|
|||
assertThatThrownBy(cfg::validate) |
|||
.isInstanceOf(IllegalArgumentException.class) |
|||
.hasMessage("Geofencing calculated field must contain at least one geofencing zone group defined!"); |
|||
} |
|||
|
|||
@Test |
|||
void validateShouldThrowWhenZoneGroupArgumentHasInvalidArgumentType() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
var arguments = new HashMap<String, Argument>(); |
|||
arguments.put(ENTITY_ID_LATITUDE_ARGUMENT_KEY, toArgument("latitude", ArgumentType.TS_LATEST)); |
|||
arguments.put(ENTITY_ID_LONGITUDE_ARGUMENT_KEY, toArgument("longitude", ArgumentType.TS_LATEST)); |
|||
arguments.put("allowedZones", toArgument("allowedZone", ArgumentType.TS_LATEST)); |
|||
|
|||
cfg.setArguments(arguments); |
|||
|
|||
assertThatThrownBy(cfg::validate) |
|||
.isInstanceOf(IllegalArgumentException.class) |
|||
.hasMessage("Argument 'allowedZones' must be of type ATTRIBUTE!"); |
|||
} |
|||
|
|||
@Test |
|||
void validateShouldCallDynamicSourceConfigValidationWhenZoneGroupArgumentHasDynamicSourceConfiguration() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
var arguments = new HashMap<String, Argument>(); |
|||
arguments.put(ENTITY_ID_LATITUDE_ARGUMENT_KEY, toArgument("latitude", ArgumentType.TS_LATEST)); |
|||
arguments.put(ENTITY_ID_LONGITUDE_ARGUMENT_KEY, toArgument("longitude", ArgumentType.TS_LATEST)); |
|||
Argument allowedZonesArg = toArgument("allowedZone", ArgumentType.ATTRIBUTE); |
|||
var refDynamicSourceConfigurationMock = mock(RelationQueryDynamicSourceConfiguration.class); |
|||
allowedZonesArg.setRefDynamicSourceConfiguration(refDynamicSourceConfigurationMock); |
|||
arguments.put("allowedZones", allowedZonesArg); |
|||
|
|||
ZoneGroupConfiguration allowedZoneConfiguration = new ZoneGroupConfiguration("allowedZone", Arrays.asList(GeofencingEvent.values())); |
|||
Map<String, ZoneGroupConfiguration> zoneGroupConfigurations = Map.of("allowedZones", allowedZoneConfiguration); |
|||
|
|||
cfg.setArguments(arguments); |
|||
cfg.setZoneGroupConfigurations(zoneGroupConfigurations); |
|||
|
|||
cfg.validate(); |
|||
|
|||
verify(refDynamicSourceConfigurationMock).validate(); |
|||
} |
|||
|
|||
@Test |
|||
void validateShouldThrowWhenZoneGroupConfigurationIsMissing() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
var arguments = new HashMap<String, Argument>(); |
|||
arguments.put(ENTITY_ID_LATITUDE_ARGUMENT_KEY, toArgument("latitude", ArgumentType.TS_LATEST)); |
|||
arguments.put(ENTITY_ID_LONGITUDE_ARGUMENT_KEY, toArgument("longitude", ArgumentType.TS_LATEST)); |
|||
Argument allowedZonesArg = toArgument("allowedZone", ArgumentType.ATTRIBUTE); |
|||
var refDynamicSourceConfigurationMock = mock(RelationQueryDynamicSourceConfiguration.class); |
|||
allowedZonesArg.setRefDynamicSourceConfiguration(refDynamicSourceConfigurationMock); |
|||
arguments.put("allowedZones", allowedZonesArg); |
|||
|
|||
cfg.setArguments(arguments); |
|||
cfg.setZoneGroupConfigurations(null); |
|||
cfg.setCreateRelationsWithMatchedZones(false); |
|||
|
|||
assertThatThrownBy(cfg::validate) |
|||
.isInstanceOf(IllegalArgumentException.class) |
|||
.hasMessage("Zone groups configuration should be specified!"); |
|||
} |
|||
|
|||
@Test |
|||
void validateShouldThrowWhenReportTelemetryPrefixDuplicate() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
var arguments = new HashMap<String, Argument>(); |
|||
arguments.put(ENTITY_ID_LATITUDE_ARGUMENT_KEY, toArgument("latitude", ArgumentType.TS_LATEST)); |
|||
arguments.put(ENTITY_ID_LONGITUDE_ARGUMENT_KEY, toArgument("longitude", ArgumentType.TS_LATEST)); |
|||
Argument allowedZonesArg = toArgument("allowedZone", ArgumentType.ATTRIBUTE); |
|||
Argument restrictedZonesArg = toArgument("restrictedZone", ArgumentType.ATTRIBUTE); |
|||
var refDynamicSourceConfigurationMock = mock(RelationQueryDynamicSourceConfiguration.class); |
|||
allowedZonesArg.setRefDynamicSourceConfiguration(refDynamicSourceConfigurationMock); |
|||
arguments.put("allowedZones", allowedZonesArg); |
|||
arguments.put("restrictedZones", restrictedZonesArg); |
|||
|
|||
ZoneGroupConfiguration allowedZoneConfiguration = new ZoneGroupConfiguration("theSamePrefixTest", Arrays.asList(GeofencingEvent.values())); |
|||
ZoneGroupConfiguration restrictedZoneConfiguration = new ZoneGroupConfiguration("theSamePrefixTest", Arrays.asList(GeofencingEvent.values())); |
|||
Map<String, ZoneGroupConfiguration> zoneGroupConfigurations = Map.of("allowedZones", allowedZoneConfiguration, "restrictedZones", restrictedZoneConfiguration); |
|||
|
|||
cfg.setArguments(arguments); |
|||
cfg.setZoneGroupConfigurations(zoneGroupConfigurations); |
|||
cfg.setCreateRelationsWithMatchedZones(false); |
|||
|
|||
assertThatThrownBy(cfg::validate) |
|||
.isInstanceOf(IllegalArgumentException.class) |
|||
.hasMessage("Duplicate report telemetry prefix found: 'theSamePrefixTest'. Must be unique!"); |
|||
} |
|||
|
|||
@Test |
|||
void validateShouldThrowWhenZoneGroupArgumentConfigurationIsMissing() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
var arguments = new HashMap<String, Argument>(); |
|||
arguments.put(ENTITY_ID_LATITUDE_ARGUMENT_KEY, toArgument("latitude", ArgumentType.TS_LATEST)); |
|||
arguments.put(ENTITY_ID_LONGITUDE_ARGUMENT_KEY, toArgument("longitude", ArgumentType.TS_LATEST)); |
|||
Argument allowedZonesArg = toArgument("allowedZone", ArgumentType.ATTRIBUTE); |
|||
var refDynamicSourceConfigurationMock = mock(RelationQueryDynamicSourceConfiguration.class); |
|||
allowedZonesArg.setRefDynamicSourceConfiguration(refDynamicSourceConfigurationMock); |
|||
arguments.put("allowedZones", allowedZonesArg); |
|||
|
|||
ZoneGroupConfiguration allowedZoneConfiguration = new ZoneGroupConfiguration("allowedZone", Arrays.asList(GeofencingEvent.values())); |
|||
Map<String, ZoneGroupConfiguration> zoneGroupConfigurations = Map.of("someOtherZones", allowedZoneConfiguration); |
|||
|
|||
cfg.setArguments(arguments); |
|||
cfg.setZoneGroupConfigurations(zoneGroupConfigurations); |
|||
cfg.setCreateRelationsWithMatchedZones(false); |
|||
|
|||
assertThatThrownBy(cfg::validate) |
|||
.isInstanceOf(IllegalArgumentException.class) |
|||
.hasMessage("Zone group configuration is not configured for 'allowedZones' argument!"); |
|||
} |
|||
|
|||
@Test |
|||
void validateShouldThrowWhenZoneGroupConfigurationReportEventsAreNotSpecified() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
var arguments = new HashMap<String, Argument>(); |
|||
arguments.put(ENTITY_ID_LATITUDE_ARGUMENT_KEY, toArgument("latitude", ArgumentType.TS_LATEST)); |
|||
arguments.put(ENTITY_ID_LONGITUDE_ARGUMENT_KEY, toArgument("longitude", ArgumentType.TS_LATEST)); |
|||
Argument allowedZonesArg = toArgument("allowedZone", ArgumentType.ATTRIBUTE); |
|||
var refDynamicSourceConfigurationMock = mock(RelationQueryDynamicSourceConfiguration.class); |
|||
allowedZonesArg.setRefDynamicSourceConfiguration(refDynamicSourceConfigurationMock); |
|||
arguments.put("allowedZones", allowedZonesArg); |
|||
|
|||
ZoneGroupConfiguration allowedZoneConfiguration = new ZoneGroupConfiguration("allowedZone", null); |
|||
Map<String, ZoneGroupConfiguration> zoneGroupConfigurations = Map.of("allowedZones", allowedZoneConfiguration); |
|||
|
|||
cfg.setArguments(arguments); |
|||
cfg.setZoneGroupConfigurations(zoneGroupConfigurations); |
|||
cfg.setCreateRelationsWithMatchedZones(false); |
|||
|
|||
assertThatThrownBy(cfg::validate) |
|||
.isInstanceOf(IllegalArgumentException.class) |
|||
.hasMessage("Zone group configuration report events must be specified for 'allowedZones' argument!"); |
|||
} |
|||
|
|||
@ParameterizedTest |
|||
@NullAndEmptySource |
|||
@ValueSource(strings = " ") |
|||
void validateShouldThrowWhenZoneGroupConfigurationTelemetryPrefixIsBlankOrNull(String reportTelemetryPrefix) { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
var arguments = new HashMap<String, Argument>(); |
|||
arguments.put(ENTITY_ID_LATITUDE_ARGUMENT_KEY, toArgument("latitude", ArgumentType.TS_LATEST)); |
|||
arguments.put(ENTITY_ID_LONGITUDE_ARGUMENT_KEY, toArgument("longitude", ArgumentType.TS_LATEST)); |
|||
Argument allowedZonesArg = toArgument("allowedZone", ArgumentType.ATTRIBUTE); |
|||
var refDynamicSourceConfigurationMock = mock(RelationQueryDynamicSourceConfiguration.class); |
|||
allowedZonesArg.setRefDynamicSourceConfiguration(refDynamicSourceConfigurationMock); |
|||
arguments.put("allowedZones", allowedZonesArg); |
|||
|
|||
ZoneGroupConfiguration allowedZoneConfiguration = new ZoneGroupConfiguration(reportTelemetryPrefix, Arrays.asList(GeofencingEvent.values())); |
|||
Map<String, ZoneGroupConfiguration> zoneGroupConfigurations = Map.of("allowedZones", allowedZoneConfiguration); |
|||
|
|||
cfg.setArguments(arguments); |
|||
cfg.setZoneGroupConfigurations(zoneGroupConfigurations); |
|||
cfg.setCreateRelationsWithMatchedZones(false); |
|||
|
|||
assertThatThrownBy(cfg::validate) |
|||
.isInstanceOf(IllegalArgumentException.class) |
|||
.hasMessage("Report telemetry prefix should be specified for 'allowedZones' argument!"); |
|||
} |
|||
|
|||
@ParameterizedTest |
|||
@NullAndEmptySource |
|||
@ValueSource(strings = " ") |
|||
void validateShouldThrowWhenHasBlankOrNullZoneRelationType(String zoneRelationType) { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
var arguments = new HashMap<String, Argument>(); |
|||
arguments.put(ENTITY_ID_LATITUDE_ARGUMENT_KEY, toArgument("latitude", ArgumentType.TS_LATEST)); |
|||
arguments.put(ENTITY_ID_LONGITUDE_ARGUMENT_KEY, toArgument("longitude", ArgumentType.TS_LATEST)); |
|||
Argument allowedZonesArg = toArgument("allowedZone", ArgumentType.ATTRIBUTE); |
|||
var refDynamicSourceConfigurationMock = mock(RelationQueryDynamicSourceConfiguration.class); |
|||
allowedZonesArg.setRefDynamicSourceConfiguration(refDynamicSourceConfigurationMock); |
|||
arguments.put("allowedZones", allowedZonesArg); |
|||
|
|||
ZoneGroupConfiguration allowedZoneConfiguration = new ZoneGroupConfiguration("allowedZone", Arrays.asList(GeofencingEvent.values())); |
|||
Map<String, ZoneGroupConfiguration> zoneGroupConfigurations = Map.of("allowedZones", allowedZoneConfiguration); |
|||
|
|||
cfg.setArguments(arguments); |
|||
cfg.setZoneGroupConfigurations(zoneGroupConfigurations); |
|||
cfg.setCreateRelationsWithMatchedZones(true); |
|||
cfg.setZoneRelationType(zoneRelationType); |
|||
cfg.setZoneRelationDirection(EntitySearchDirection.TO); |
|||
|
|||
assertThatThrownBy(cfg::validate) |
|||
.isInstanceOf(IllegalArgumentException.class) |
|||
.hasMessage("Zone relation type must be specified to create relations with matched zones!"); |
|||
} |
|||
|
|||
@Test |
|||
void validateShouldThrowWhenNoZoneRelationDirectionSpecified() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
var arguments = new HashMap<String, Argument>(); |
|||
arguments.put(ENTITY_ID_LATITUDE_ARGUMENT_KEY, toArgument("latitude", ArgumentType.TS_LATEST)); |
|||
arguments.put(ENTITY_ID_LONGITUDE_ARGUMENT_KEY, toArgument("longitude", ArgumentType.TS_LATEST)); |
|||
Argument allowedZonesArg = toArgument("allowedZone", ArgumentType.ATTRIBUTE); |
|||
var refDynamicSourceConfigurationMock = mock(RelationQueryDynamicSourceConfiguration.class); |
|||
allowedZonesArg.setRefDynamicSourceConfiguration(refDynamicSourceConfigurationMock); |
|||
arguments.put("allowedZones", allowedZonesArg); |
|||
|
|||
ZoneGroupConfiguration allowedZoneConfiguration = new ZoneGroupConfiguration("allowedZone", Arrays.asList(GeofencingEvent.values())); |
|||
Map<String, ZoneGroupConfiguration> zoneGroupConfigurations = Map.of("allowedZones", allowedZoneConfiguration); |
|||
|
|||
cfg.setArguments(arguments); |
|||
cfg.setZoneGroupConfigurations(zoneGroupConfigurations); |
|||
cfg.setCreateRelationsWithMatchedZones(true); |
|||
cfg.setZoneRelationType("SomeRelationType"); |
|||
|
|||
assertThatThrownBy(cfg::validate) |
|||
.isInstanceOf(IllegalArgumentException.class) |
|||
.hasMessage("Zone relation direction must be specified to create relations with matched zones!"); |
|||
} |
|||
|
|||
@Test |
|||
void scheduledUpdateDisabledWhenIntervalIsZero() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
cfg.setScheduledUpdateIntervalSec(0); |
|||
assertThat(cfg.isScheduledUpdateEnabled()).isFalse(); |
|||
} |
|||
|
|||
@Test |
|||
void scheduledUpdateDisabledWhenIntervalIsGreaterThanZeroButArgumentsAreEmpty() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
cfg.setArguments(Map.of()); |
|||
cfg.setScheduledUpdateIntervalSec(60); |
|||
assertThat(cfg.isScheduledUpdateEnabled()).isFalse(); |
|||
} |
|||
|
|||
@Test |
|||
void scheduledUpdateDisabledWhenIntervalIsGreaterThanZeroButDynamicArgumentsAreMissing() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
cfg.setArguments(Map.of(ENTITY_ID_LATITUDE_ARGUMENT_KEY, toArgument("latitude", ArgumentType.TS_LATEST))); |
|||
cfg.setScheduledUpdateIntervalSec(60); |
|||
assertThat(cfg.isScheduledUpdateEnabled()).isFalse(); |
|||
} |
|||
|
|||
@Test |
|||
void scheduledUpdateEnabledWhenIntervalIsGreaterThanZeroAndDynamicArgumentsPresent() { |
|||
var cfg = new GeofencingCalculatedFieldConfiguration(); |
|||
Argument someDynamicArgument = toArgument("someDynamicArgument", ArgumentType.ATTRIBUTE); |
|||
someDynamicArgument.setRefDynamicSourceConfiguration(new RelationQueryDynamicSourceConfiguration()); |
|||
cfg.setArguments(Map.of("someDynamicArugument", someDynamicArgument)); |
|||
cfg.setScheduledUpdateIntervalSec(60); |
|||
assertThat(cfg.isScheduledUpdateEnabled()).isTrue(); |
|||
} |
|||
|
|||
|
|||
private Argument toArgument(String key, ArgumentType type) { |
|||
var referencedEntityKey = new ReferencedEntityKey(key, type, null); |
|||
return toArgument(referencedEntityKey); |
|||
} |
|||
|
|||
private Argument toArgument(ReferencedEntityKey referencedEntityKey) { |
|||
Argument argument = new Argument(); |
|||
argument.setRefEntityKey(referencedEntityKey); |
|||
return argument; |
|||
} |
|||
|
|||
} |
|||
Loading…
Reference in new issue