diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/utils/MidnightTimer.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/utils/MidnightTimer.kt index e0661ba77..3dbba72c5 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/utils/MidnightTimer.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/utils/MidnightTimer.kt @@ -39,11 +39,11 @@ open class MidnightTimer @Inject constructor() { @Synchronized fun onPause(): MutableList? = executor.shutdownNow() - @Synchronized fun onResume() { - executor = Executors.newSingleThreadScheduledExecutor() + @Synchronized fun onResume(delayOffsetInMillis: Long = DateUtils.MINUTE_LENGTH, testExecutor: ScheduledExecutorService? = null) { + executor = testExecutor ?: Executors.newSingleThreadScheduledExecutor() executor.scheduleAtFixedRate( { notifyListeners() }, - DateUtils.millisecondsUntilTomorrowWithOffset() + 1000, + DateUtils.millisecondsUntilTomorrowWithOffset() + delayOffsetInMillis, DateUtils.DAY_LENGTH, TimeUnit.MILLISECONDS ) diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/BaseUnitTest.kt b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/BaseUnitTest.kt index f97991b6d..4079600ab 100644 --- a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/BaseUnitTest.kt +++ b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/BaseUnitTest.kt @@ -95,15 +95,13 @@ open class BaseUnitTest { } fun unixTime(year: Int, month: Int, day: Int): Long { - val cal = getStartOfTodayCalendar() - cal.set(year, month, day, 0, 0, 0) - return cal.timeInMillis + return unixTime(year, month, day, 0, 0) } - open fun unixTime(year: Int, month: Int, day: Int, hour: Int, minute: Int): Long { + open fun unixTime(year: Int, month: Int, day: Int, hour: Int, minute: Int, milliseconds: Long = 0): Long { val cal = getStartOfTodayCalendar() cal.set(year, month, day, hour, minute) - return cal.timeInMillis + return cal.timeInMillis + milliseconds } fun timestamp(year: Int, month: Int, day: Int): Timestamp { diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/reminders/ReminderSchedulerTest.kt b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/reminders/ReminderSchedulerTest.kt index d354e81f0..cf81fbe9a 100644 --- a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/reminders/ReminderSchedulerTest.kt +++ b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/reminders/ReminderSchedulerTest.kt @@ -138,7 +138,7 @@ class ReminderSchedulerTest : BaseUnitTest() { reminderScheduler.schedule(habit) } - override fun unixTime(year: Int, month: Int, day: Int, hour: Int, minute: Int): Long { + override fun unixTime(year: Int, month: Int, day: Int, hour: Int, minute: Int, milliseconds: Long): Long { val cal: Calendar = getStartOfTodayCalendar() cal[year, month, day, hour] = minute return cal.timeInMillis diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/utils/MidnightTimerTest.kt b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/utils/MidnightTimerTest.kt new file mode 100644 index 000000000..80a90edb9 --- /dev/null +++ b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/utils/MidnightTimerTest.kt @@ -0,0 +1,45 @@ +package org.isoron.uhabits.core.utils + +import kotlinx.coroutines.asCoroutineDispatcher +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withContext +import org.isoron.uhabits.core.BaseUnitTest +import org.junit.Test +import java.util.Calendar +import java.util.TimeZone +import java.util.concurrent.Executors +import kotlin.coroutines.resume +import kotlin.coroutines.suspendCoroutine +import kotlin.test.assertEquals + +class MidnightTimerTest : BaseUnitTest() { + + @Test + fun testMidnightTimer_notifyListener_atMidnight() = runBlocking { + // Given + val executor = Executors.newSingleThreadScheduledExecutor() + val dispatcher = executor.asCoroutineDispatcher() + + withContext(dispatcher) { + DateUtils.setFixedTimeZone(TimeZone.getTimeZone("GMT")) + DateUtils.setFixedLocalTime(unixTime(2017, Calendar.JANUARY, 1, 23, 59, DateUtils.MINUTE_LENGTH - 1)) + + val suspendedListener = suspendCoroutine { continuation -> + val listener = object : MidnightTimer.MidnightListener { + override fun atMidnight() { + continuation.resume(true) + } + } + + MidnightTimer().apply { + addListener(listener) + // When + onResume(1, executor) + } + } + + // Then + assertEquals(true, suspendedListener) + } + } +}