[awattar] added tests for refresh logic

Signed-off-by: Thomas Leber <thomas@tl-photography.at>
This commit is contained in:
Thomas Leber 2024-12-23 12:23:30 +01:00
parent c5eec4e87e
commit 3b2ccadeba
4 changed files with 73 additions and 5 deletions

View File

@ -20,7 +20,6 @@ import java.time.temporal.ChronoUnit;
import javax.measure.quantity.Time; import javax.measure.quantity.Time;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.unit.Units; import org.openhab.core.library.unit.Units;

View File

@ -40,7 +40,6 @@ import org.openhab.binding.awattar.internal.AwattarBestPriceResult;
import org.openhab.binding.awattar.internal.AwattarConsecutiveBestPriceResult; import org.openhab.binding.awattar.internal.AwattarConsecutiveBestPriceResult;
import org.openhab.binding.awattar.internal.AwattarNonConsecutiveBestPriceResult; import org.openhab.binding.awattar.internal.AwattarNonConsecutiveBestPriceResult;
import org.openhab.binding.awattar.internal.AwattarPrice; import org.openhab.binding.awattar.internal.AwattarPrice;
import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.QuantityType;

View File

@ -12,8 +12,6 @@
*/ */
package org.openhab.binding.awattar.internal.handler; package org.openhab.binding.awattar.internal.handler;
import static java.time.temporal.ChronoUnit.DAYS;
import static java.time.temporal.ChronoUnit.HOURS;
import static org.openhab.binding.awattar.internal.AwattarBindingConstants.CHANNEL_MARKET_NET; import static org.openhab.binding.awattar.internal.AwattarBindingConstants.CHANNEL_MARKET_NET;
import static org.openhab.binding.awattar.internal.AwattarBindingConstants.CHANNEL_TOTAL_NET; import static org.openhab.binding.awattar.internal.AwattarBindingConstants.CHANNEL_TOTAL_NET;
@ -186,11 +184,13 @@ public class AwattarBridgeHandler extends BaseBridgeHandler {
private boolean needRefresh() { private boolean needRefresh() {
// if the thing is offline, we need to refresh // if the thing is offline, we need to refresh
if (getThing().getStatus() != ThingStatus.ONLINE) { if (getThing().getStatus() != ThingStatus.ONLINE) {
lastRefresh = clock.instant();
return true; return true;
} }
// if the local cache is empty, we need to refresh // if the local cache is empty, we need to refresh
if (prices == null) { if (prices == null) {
lastRefresh = clock.instant();
return true; return true;
} }
@ -208,7 +208,7 @@ public class AwattarBridgeHandler extends BaseBridgeHandler {
// refresh at 15:00, 18:00 and 21:00 if the last refresh was more than an hour ago // refresh at 15:00, 18:00 and 21:00 if the last refresh was more than an hour ago
if (now.getHour() % 3 == 0 && lastRefresh.getEpochSecond() < now.minusHours(1).toEpochSecond()) { if (now.getHour() % 3 == 0 && lastRefresh.getEpochSecond() < now.minusHours(1).toEpochSecond()) {
// update the last refresh time // update the last refresh time
lastRefresh = Instant.now(); lastRefresh = clock.instant();
// return true to indicate an update is needed // return true to indicate an update is needed
return true; return true;

View File

@ -20,13 +20,19 @@ import static org.mockito.Mockito.when;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.time.Clock; import java.time.Clock;
import java.time.Instant;
import java.time.ZoneId;
import java.util.List; import java.util.List;
import java.util.stream.Stream;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.HttpClient;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.platform.commons.support.HierarchyTraversalMode; import org.junit.platform.commons.support.HierarchyTraversalMode;
import org.junit.platform.commons.support.ReflectionSupport; import org.junit.platform.commons.support.ReflectionSupport;
import org.mockito.Mock; import org.mockito.Mock;
@ -62,6 +68,7 @@ class AwattarBridgeHandlerRefreshTest extends JavaTest {
private @Mock @NonNullByDefault({}) ThingHandlerCallback bridgeCallbackMock; private @Mock @NonNullByDefault({}) ThingHandlerCallback bridgeCallbackMock;
private @Mock @NonNullByDefault({}) HttpClient httpClientMock; private @Mock @NonNullByDefault({}) HttpClient httpClientMock;
private @Mock @NonNullByDefault({}) Clock clockMock; private @Mock @NonNullByDefault({}) Clock clockMock;
private @Mock @NonNullByDefault({}) Clock fixedClock;
private @Mock @NonNullByDefault({}) AwattarApi awattarApiMock; private @Mock @NonNullByDefault({}) AwattarApi awattarApiMock;
// best price handler mocks // best price handler mocks
@ -151,4 +158,67 @@ class AwattarBridgeHandlerRefreshTest extends JavaTest {
assertThat(result, is(true)); assertThat(result, is(true));
} }
public static Stream<Arguments> testNeedRefreshTimes() {
return Stream.of(
// Update at 15:00 GMT+2
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T13:00:00Z"), true),
Arguments.of(Instant.parse("2021-01-01T12:00:00Z"), Instant.parse("2021-01-01T13:00:00Z"), false),
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T13:30:00Z"), true),
Arguments.of(Instant.parse("2021-01-01T12:00:00Z"), Instant.parse("2021-01-01T13:30:00Z"), true),
// Update at 16:00 GMT+2 and 17:00 GMT+2
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T14:00:00Z"), false),
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T15:00:00Z"), false),
// Update at 18:00 GMT+2
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T16:00:00Z"), true),
Arguments.of(Instant.parse("2021-01-01T15:00:00Z"), Instant.parse("2021-01-01T16:00:00Z"), false),
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T16:30:00Z"), true),
Arguments.of(Instant.parse("2021-01-01T15:00:00Z"), Instant.parse("2021-01-01T16:30:00Z"), true),
// Update at 19:00 GMT+2 and 20:00 GMT+2
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T17:00:00Z"), false),
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T18:00:00Z"), false),
// Update at 21:00 GMT+2
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T19:00:00Z"), true),
Arguments.of(Instant.parse("2021-01-01T18:00:00Z"), Instant.parse("2021-01-01T19:00:00Z"), false),
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T19:30:00Z"), true),
Arguments.of(Instant.parse("2021-01-01T18:00:00Z"), Instant.parse("2021-01-01T19:30:00Z"), true),
// Update at 22:00 GMT+2, 23:00 GMT+2 and 00:00 GMT+2
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T20:00:00Z"), false),
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T21:00:00Z"), false),
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T22:00:00Z"), false),
// Update before 15:00 GMT+2
Arguments.of(Instant.parse("2021-01-01T11:00:00Z"), Instant.parse("2021-01-01T14:00:00Z"), false),
Arguments.of(Instant.parse("2021-01-01T10:59:58Z"), Instant.parse("2021-01-01T11:59:59Z"), false),
Arguments.of(Instant.parse("2021-01-01T11:59:59Z"), Instant.parse("2021-01-01T11:59:59Z"), false),
Arguments.of(Instant.parse("2021-01-01T13:00:00Z"), Instant.parse("2021-01-01T13:00:00Z"), false));
}
@ParameterizedTest
@MethodSource
void testNeedRefreshTimes(Instant lastUpdate, Instant nowUpdate, Boolean expectedResult) {
when(bridgeMock.getStatus()).thenReturn(ThingStatus.ONLINE);
fixedClock = Clock.fixed(lastUpdate, ZoneId.of("GMT+2"));
when(clockMock.getZone()).thenReturn(fixedClock.getZone());
when(clockMock.instant()).thenReturn(fixedClock.instant());
bridgeHandler.refreshIfNeeded();
fixedClock = Clock.fixed(nowUpdate, ZoneId.of("GMT+2"));
when(clockMock.getZone()).thenReturn(fixedClock.getZone());
when(clockMock.instant()).thenReturn(fixedClock.instant());
// get private method via reflection
Method method = ReflectionSupport.findMethod(AwattarBridgeHandler.class, "needRefresh", "").get();
boolean result = (boolean) ReflectionSupport.invokeMethod(method, bridgeHandler);
assertThat(result, is(expectedResult));
}
} }