diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/semester/SemesterRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/semester/SemesterRepository.kt index 28d37ed85..7a76503f2 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/semester/SemesterRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/semester/SemesterRepository.kt @@ -1,5 +1,6 @@ package io.github.wulkanowy.data.repositories.semester +import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.sdk.Sdk import io.github.wulkanowy.utils.DispatchersProvider @@ -18,24 +19,33 @@ class SemesterRepository @Inject constructor( ) { suspend fun getSemesters(student: Student, forceRefresh: Boolean = false, refreshOnNoCurrent: Boolean = false) = withContext(dispatchers.backgroundThread) { - local.getSemesters(student).let { semesters -> - semesters.filter { - !forceRefresh && when { - Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.API -> semesters.firstOrNull { it.isCurrent }?.diaryId != 0 - refreshOnNoCurrent -> semesters.any { semester -> semester.isCurrent } - else -> true - } - } - }.ifEmpty { - val new = remote.getSemesters(student) - if (new.isEmpty()) throw IllegalArgumentException("Empty semester list!") - - val old = local.getSemesters(student) - local.deleteSemesters(old.uniqueSubtract(new)) - local.saveSemesters(new.uniqueSubtract(old)) + val semesters = local.getSemesters(student) + if (isShouldFetch(student, semesters, forceRefresh, refreshOnNoCurrent)) { + refreshSemesters(student) local.getSemesters(student) - } + } else semesters + } + + private fun isShouldFetch(student: Student, semesters: List, forceRefresh: Boolean, refreshOnNoCurrent: Boolean): Boolean { + val isNoSemesters = semesters.isEmpty() + + val isRefreshOnModeChangeRequired = if (Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.API) { + semesters.firstOrNull { it.isCurrent }?.diaryId == 0 + } else false + + val isRefreshOnNoCurrentAppropriate = refreshOnNoCurrent && !semesters.any { semester -> semester.isCurrent } + + return forceRefresh || isNoSemesters || isRefreshOnModeChangeRequired || isRefreshOnNoCurrentAppropriate + } + + private suspend fun refreshSemesters(student: Student) { + val new = remote.getSemesters(student) + if (new.isEmpty()) throw IllegalArgumentException("Empty semester list!") + + val old = local.getSemesters(student) + local.deleteSemesters(old.uniqueSubtract(new)) + local.saveSemesters(new.uniqueSubtract(old)) } suspend fun getCurrentSemester(student: Student, forceRefresh: Boolean = false) = withContext(dispatchers.backgroundThread) { diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/semester/SemesterRepositoryTest.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/semester/SemesterRepositoryTest.kt index 866c2af4d..5a2388ff7 100644 --- a/app/src/test/java/io/github/wulkanowy/data/repositories/semester/SemesterRepositoryTest.kt +++ b/app/src/test/java/io/github/wulkanowy/data/repositories/semester/SemesterRepositoryTest.kt @@ -63,7 +63,15 @@ class SemesterRepositoryTest { createSemesterEntity(0, 2, now().minusMonths(3), now()) ) + val goodSemesters = listOf( + createSemesterEntity(122, 1, now().minusMonths(6), now().minusMonths(3)), + createSemesterEntity(123, 2, now().minusMonths(3), now()) + ) + coEvery { semesterLocal.getSemesters(student) } returns badSemesters + coEvery { semesterRemote.getSemesters(student) } returns goodSemesters + coEvery { semesterLocal.deleteSemesters(any()) } just Runs + coEvery { semesterLocal.saveSemesters(any()) } just Runs val items = runBlocking { semesterRepository.getSemesters(student) } assertEquals(2, items.size) @@ -152,12 +160,23 @@ class SemesterRepositoryTest { @Test fun getSemesters_noCurrent_refreshOnNoCurrent() { - val semesters = listOf( + val semestersWithNoCurrent = listOf( createSemesterEntity(1, 1, now().minusMonths(12), now().minusMonths(6)), createSemesterEntity(1, 2, now().minusMonths(6), now().minusMonths(1)) ) - coEvery { semesterLocal.getSemesters(student) } returns semesters + val newSemesters = listOf( + createSemesterEntity(1, 1, now().minusMonths(12), now().minusMonths(6)), + createSemesterEntity(1, 2, now().minusMonths(6), now().minusMonths(1)), + + createSemesterEntity(2, 1, now().minusMonths(1), now().plusMonths(5)), + createSemesterEntity(2, 2, now().plusMonths(5), now().plusMonths(11)), + ) + + coEvery { semesterLocal.getSemesters(student) } returns semestersWithNoCurrent + coEvery { semesterRemote.getSemesters(student) } returns newSemesters + coEvery { semesterLocal.deleteSemesters(any()) } just Runs + coEvery { semesterLocal.saveSemesters(any()) } just Runs val items = runBlocking { semesterRepository.getSemesters(student, refreshOnNoCurrent = true) } assertEquals(2, items.size)