Merge main into feat-unicode-search-casefold

This commit is contained in:
Jason Ross
2026-07-03 17:38:56 -05:00
committed by GitHub
9 changed files with 137 additions and 0 deletions
@@ -0,0 +1,45 @@
// SPDX-License-Identifier: GPL-3.0-or-later
package org.libremail.reporting
import androidx.work.ListenableWorker
import io.mockk.every
import io.mockk.mockk
import io.mockk.slot
import kotlinx.coroutines.test.runTest
import org.junit.Test
import java.util.concurrent.TimeUnit
import kotlin.math.abs
import kotlin.test.assertEquals
import kotlin.test.assertTrue
/**
* [ReportPurgeWorker] deletes locally-stored reports older than 30 days (issue #239). Pins the cutoff
* it computes and that a failure retries rather than silently dropping the housekeeping.
*/
class ReportPurgeWorkerTest {
private val store = mockk<ReportStore>()
private fun worker() = ReportPurgeWorker(mockk(relaxed = true), mockk(relaxed = true), store)
@Test
fun `purges reports older than 30 days and succeeds`() = runTest {
val cutoff = slot<Long>()
every { store.purgeOlderThan(capture(cutoff)) } returns 3
assertEquals(ListenableWorker.Result.success(), worker().doWork())
val expected = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(30)
assertTrue(
abs(cutoff.captured - expected) < TimeUnit.MINUTES.toMillis(1),
"cutoff should be ~30 days before now",
)
}
@Test
fun `retries when the purge fails`() = runTest {
every { store.purgeOlderThan(any()) } throws IllegalStateException("io error")
assertEquals(ListenableWorker.Result.retry(), worker().doWork())
}
}
@@ -99,4 +99,19 @@ class ReportStoreTest {
assertEquals(listOf("valid"), store.reports.value.map { it.id })
}
@Test
fun `purgeOlderThan deletes reports strictly older than the cutoff`() {
val store = ReportStore(tempFolder.root)
store.save(report("old", createdAt = 1_000L))
store.save(report("boundary", createdAt = 3_000L))
store.save(report("recent", createdAt = 5_000L))
val purged = store.purgeOlderThan(cutoffMillis = 3_000L)
assertEquals(1, purged)
assertNull(store.find("old"))
// A report exactly at the cutoff is kept (strictly-older purge); list stays newest-first.
assertEquals(listOf("recent", "boundary"), store.reports.value.map { it.id })
}
}