Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9641eb67 authored by Abhishek Aggarwal's avatar Abhishek Aggarwal
Browse files

fix(login): run okhttp cache eviction off main thread

parent de75a621
Loading
Loading
Loading
Loading
+19 −5
Original line number Diff line number Diff line
@@ -18,15 +18,29 @@
package foundation.e.apps.data.login.repository

import foundation.e.apps.domain.login.LoginCacheRepository
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.Cache
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class OkHttpLoginCacheRepository @Inject constructor(
    private val cache: Cache,
) : LoginCacheRepository {
    override fun clear() {
class OkHttpLoginCacheRepository : LoginCacheRepository {
    private val cache: Cache
    private val ioDispatcher: CoroutineDispatcher

    @Inject
    constructor(cache: Cache) : this(cache, Dispatchers.IO)

    constructor(cache: Cache, ioDispatcher: CoroutineDispatcher) {
        this.cache = cache
        this.ioDispatcher = ioDispatcher
    }

    override suspend fun clear() {
        withContext(ioDispatcher) {
            cache.evictAll()
        }
    }
}
+24 −2
Original line number Diff line number Diff line
package foundation.e.apps.data.login.repository

import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.runTest
import okhttp3.Cache
import org.junit.Test
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import org.mockito.kotlin.verifyNoInteractions

@OptIn(ExperimentalCoroutinesApi::class)
class OkHttpLoginCacheRepositoryTest {

    private val cache: Cache = mock()
    private val repository = OkHttpLoginCacheRepository(cache)

    @Test
    fun clear_evictsUnderlyingCache() {
    fun clear_evictsUnderlyingCache() = runTest {
        val repository = OkHttpLoginCacheRepository(cache, StandardTestDispatcher(testScheduler))

        repository.clear()

        verify(cache).evictAll()
    }

    @Test
    fun clear_dispatchesEvictionOffCallerThread() = runTest {
        val ioDispatcher = StandardTestDispatcher(testScheduler)
        val repository = OkHttpLoginCacheRepository(cache, ioDispatcher)

        val job = backgroundScope.launch { repository.clear() }

        // Eviction is queued on the IO dispatcher, not run inline on the caller.
        verifyNoInteractions(cache)

        testScheduler.advanceUntilIdle()
        job.join()
        verify(cache).evictAll()
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -18,5 +18,5 @@
package foundation.e.apps.domain.login

interface LoginCacheRepository {
    fun clear()
    suspend fun clear()
}
+1 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ class LogoutUseCaseTest {
    fun invoke_logsOutThroughRepository() = runTest {
        useCase()

        verify(exactly = 1) { loginCacheRepository.clear() }
        coVerify(exactly = 1) { loginCacheRepository.clear() }
        coVerify(exactly = 1) { authSessionRepository.clearSession() }
        verify(exactly = 1) {
            sourceSelectionRepository.saveSourceSelection(SourceSelection.DEFAULT)