mirror of
https://github.com/wulkanowy/wulkanowy.git
synced 2025-01-31 11:48:20 +01:00
Wrap delete and save operations in database transactions (#2450)
This commit is contained in:
parent
fb240938ed
commit
333306e7ba
@ -2,24 +2,14 @@ package io.github.wulkanowy.data.db.dao
|
|||||||
|
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import androidx.room.Transaction
|
|
||||||
import io.github.wulkanowy.data.db.entities.AdminMessage
|
import io.github.wulkanowy.data.db.entities.AdminMessage
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@Dao
|
@Dao
|
||||||
abstract class AdminMessageDao : BaseDao<AdminMessage> {
|
interface AdminMessageDao : BaseDao<AdminMessage> {
|
||||||
|
|
||||||
@Query("SELECT * FROM AdminMessages")
|
@Query("SELECT * FROM AdminMessages")
|
||||||
abstract fun loadAll(): Flow<List<AdminMessage>>
|
fun loadAll(): Flow<List<AdminMessage>>
|
||||||
|
|
||||||
@Transaction
|
|
||||||
open suspend fun removeOldAndSaveNew(
|
|
||||||
oldMessages: List<AdminMessage>,
|
|
||||||
newMessages: List<AdminMessage>
|
|
||||||
) {
|
|
||||||
deleteAll(oldMessages)
|
|
||||||
insertAll(newMessages)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package io.github.wulkanowy.data.db.dao
|
|||||||
import androidx.room.Delete
|
import androidx.room.Delete
|
||||||
import androidx.room.Insert
|
import androidx.room.Insert
|
||||||
import androidx.room.OnConflictStrategy
|
import androidx.room.OnConflictStrategy
|
||||||
|
import androidx.room.Transaction
|
||||||
import androidx.room.Update
|
import androidx.room.Update
|
||||||
|
|
||||||
interface BaseDao<T> {
|
interface BaseDao<T> {
|
||||||
@ -15,4 +16,10 @@ interface BaseDao<T> {
|
|||||||
|
|
||||||
@Delete
|
@Delete
|
||||||
suspend fun deleteAll(items: List<T>)
|
suspend fun deleteAll(items: List<T>)
|
||||||
|
|
||||||
|
@Transaction
|
||||||
|
suspend fun removeOldAndSaveNew(oldItems: List<T>, newItems: List<T>) {
|
||||||
|
deleteAll(oldItems)
|
||||||
|
insertAll(newItems)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,12 +65,13 @@ class AttendanceRepository @Inject constructor(
|
|||||||
.mapToEntities(semester, lessons)
|
.mapToEntities(semester, lessons)
|
||||||
},
|
},
|
||||||
saveFetchResult = { old, new ->
|
saveFetchResult = { old, new ->
|
||||||
attendanceDb.deleteAll(old uniqueSubtract new)
|
|
||||||
val attendanceToAdd = (new uniqueSubtract old).map { newAttendance ->
|
val attendanceToAdd = (new uniqueSubtract old).map { newAttendance ->
|
||||||
newAttendance.apply { if (notify) isNotified = false }
|
newAttendance.apply { if (notify) isNotified = false }
|
||||||
}
|
}
|
||||||
attendanceDb.insertAll(attendanceToAdd)
|
attendanceDb.removeOldAndSaveNew(
|
||||||
|
oldItems = old uniqueSubtract new,
|
||||||
|
newItems = attendanceToAdd,
|
||||||
|
)
|
||||||
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester, start, end))
|
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester, start, end))
|
||||||
},
|
},
|
||||||
filterResult = { it.filter { item -> item.date in start..end } }
|
filterResult = { it.filter { item -> item.date in start..end } }
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package io.github.wulkanowy.data.repositories
|
package io.github.wulkanowy.data.repositories
|
||||||
|
|
||||||
|
import androidx.room.withTransaction
|
||||||
|
import io.github.wulkanowy.data.db.AppDatabase
|
||||||
import io.github.wulkanowy.data.db.dao.AttendanceSummaryDao
|
import io.github.wulkanowy.data.db.dao.AttendanceSummaryDao
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
@ -20,6 +22,7 @@ class AttendanceSummaryRepository @Inject constructor(
|
|||||||
private val attendanceDb: AttendanceSummaryDao,
|
private val attendanceDb: AttendanceSummaryDao,
|
||||||
private val sdk: Sdk,
|
private val sdk: Sdk,
|
||||||
private val refreshHelper: AutoRefreshHelper,
|
private val refreshHelper: AutoRefreshHelper,
|
||||||
|
private val appDatabase: AppDatabase,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val saveFetchResultMutex = Mutex()
|
private val saveFetchResultMutex = Mutex()
|
||||||
@ -46,8 +49,10 @@ class AttendanceSummaryRepository @Inject constructor(
|
|||||||
.mapToEntities(semester, subjectId)
|
.mapToEntities(semester, subjectId)
|
||||||
},
|
},
|
||||||
saveFetchResult = { old, new ->
|
saveFetchResult = { old, new ->
|
||||||
attendanceDb.deleteAll(old uniqueSubtract new)
|
appDatabase.withTransaction {
|
||||||
attendanceDb.insertAll(new uniqueSubtract old)
|
attendanceDb.deleteAll(old uniqueSubtract new)
|
||||||
|
attendanceDb.insertAll(new uniqueSubtract old)
|
||||||
|
}
|
||||||
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester))
|
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -6,7 +6,13 @@ import io.github.wulkanowy.data.db.entities.Student
|
|||||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||||
import io.github.wulkanowy.data.networkBoundResource
|
import io.github.wulkanowy.data.networkBoundResource
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.*
|
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||||
|
import io.github.wulkanowy.utils.getRefreshKey
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
|
import io.github.wulkanowy.utils.monday
|
||||||
|
import io.github.wulkanowy.utils.sunday
|
||||||
|
import io.github.wulkanowy.utils.switchSemester
|
||||||
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -53,8 +59,10 @@ class CompletedLessonsRepository @Inject constructor(
|
|||||||
.mapToEntities(semester)
|
.mapToEntities(semester)
|
||||||
},
|
},
|
||||||
saveFetchResult = { old, new ->
|
saveFetchResult = { old, new ->
|
||||||
completedLessonsDb.deleteAll(old uniqueSubtract new)
|
completedLessonsDb.removeOldAndSaveNew(
|
||||||
completedLessonsDb.insertAll(new uniqueSubtract old)
|
oldItems = old uniqueSubtract new,
|
||||||
|
newItems = new uniqueSubtract old,
|
||||||
|
)
|
||||||
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester, start, end))
|
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester, start, end))
|
||||||
},
|
},
|
||||||
filterResult = { it.filter { item -> item.date in start..end } }
|
filterResult = { it.filter { item -> item.date in start..end } }
|
||||||
|
@ -53,12 +53,12 @@ class ConferenceRepository @Inject constructor(
|
|||||||
.filter { it.date >= startDate }
|
.filter { it.date >= startDate }
|
||||||
},
|
},
|
||||||
saveFetchResult = { old, new ->
|
saveFetchResult = { old, new ->
|
||||||
val conferencesToSave = (new uniqueSubtract old).onEach {
|
conferenceDb.removeOldAndSaveNew(
|
||||||
if (notify) it.isNotified = false
|
oldItems = old uniqueSubtract new,
|
||||||
}
|
newItems = (new uniqueSubtract old).onEach {
|
||||||
|
if (notify) it.isNotified = false
|
||||||
conferenceDb.deleteAll(old uniqueSubtract new)
|
},
|
||||||
conferenceDb.insertAll(conferencesToSave)
|
)
|
||||||
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester))
|
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -62,12 +62,12 @@ class ExamRepository @Inject constructor(
|
|||||||
.mapToEntities(semester)
|
.mapToEntities(semester)
|
||||||
},
|
},
|
||||||
saveFetchResult = { old, new ->
|
saveFetchResult = { old, new ->
|
||||||
val examsToSave = (new uniqueSubtract old).onEach {
|
examDb.removeOldAndSaveNew(
|
||||||
if (notify) it.isNotified = false
|
oldItems = old uniqueSubtract new,
|
||||||
}
|
newItems = (new uniqueSubtract old).onEach {
|
||||||
|
if (notify) it.isNotified = false
|
||||||
examDb.deleteAll(old uniqueSubtract new)
|
},
|
||||||
examDb.insertAll(examsToSave)
|
)
|
||||||
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester, start, end))
|
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester, start, end))
|
||||||
},
|
},
|
||||||
filterResult = { it.filter { item -> item.date in start..end } }
|
filterResult = { it.filter { item -> item.date in start..end } }
|
||||||
|
@ -87,10 +87,12 @@ class GradeRepository @Inject constructor(
|
|||||||
new: List<GradeDescriptive>,
|
new: List<GradeDescriptive>,
|
||||||
notify: Boolean
|
notify: Boolean
|
||||||
) {
|
) {
|
||||||
gradeDescriptiveDb.deleteAll(old uniqueSubtract new)
|
gradeDescriptiveDb.removeOldAndSaveNew(
|
||||||
gradeDescriptiveDb.insertAll((new uniqueSubtract old).onEach {
|
oldItems = old uniqueSubtract new,
|
||||||
if (notify) it.isNotified = false
|
newItems = (new uniqueSubtract old).onEach {
|
||||||
})
|
if (notify) it.isNotified = false
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun refreshGradeDetails(
|
private suspend fun refreshGradeDetails(
|
||||||
@ -101,13 +103,16 @@ class GradeRepository @Inject constructor(
|
|||||||
) {
|
) {
|
||||||
val notifyBreakDate = oldGrades.maxByOrNull { it.date }?.date
|
val notifyBreakDate = oldGrades.maxByOrNull { it.date }?.date
|
||||||
?: student.registrationDate.toLocalDate()
|
?: student.registrationDate.toLocalDate()
|
||||||
gradeDb.deleteAll(oldGrades uniqueSubtract newDetails)
|
|
||||||
gradeDb.insertAll((newDetails uniqueSubtract oldGrades).onEach {
|
gradeDb.removeOldAndSaveNew(
|
||||||
if (it.date >= notifyBreakDate) it.apply {
|
oldItems = oldGrades uniqueSubtract newDetails,
|
||||||
isRead = false
|
newItems = (newDetails uniqueSubtract oldGrades).onEach {
|
||||||
if (notify) isNotified = false
|
if (it.date >= notifyBreakDate) it.apply {
|
||||||
}
|
isRead = false
|
||||||
})
|
if (notify) isNotified = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun refreshGradeSummaries(
|
private suspend fun refreshGradeSummaries(
|
||||||
@ -115,31 +120,43 @@ class GradeRepository @Inject constructor(
|
|||||||
newSummary: List<GradeSummary>,
|
newSummary: List<GradeSummary>,
|
||||||
notify: Boolean
|
notify: Boolean
|
||||||
) {
|
) {
|
||||||
gradeSummaryDb.deleteAll(oldSummaries uniqueSubtract newSummary)
|
gradeSummaryDb.removeOldAndSaveNew(
|
||||||
gradeSummaryDb.insertAll((newSummary uniqueSubtract oldSummaries).onEach { summary ->
|
oldItems = oldSummaries uniqueSubtract newSummary,
|
||||||
val oldSummary = oldSummaries.find { old -> old.subject == summary.subject }
|
newItems = (newSummary uniqueSubtract oldSummaries).onEach { summary ->
|
||||||
summary.isPredictedGradeNotified = when {
|
getGradeSummaryWithUpdatedNotificationState(
|
||||||
summary.predictedGrade.isEmpty() -> true
|
summary = summary,
|
||||||
notify && oldSummary?.predictedGrade != summary.predictedGrade -> false
|
oldSummary = oldSummaries.find { it.subject == summary.subject },
|
||||||
else -> true
|
notify = notify,
|
||||||
}
|
)
|
||||||
summary.isFinalGradeNotified = when {
|
},
|
||||||
summary.finalGrade.isEmpty() -> true
|
)
|
||||||
notify && oldSummary?.finalGrade != summary.finalGrade -> false
|
}
|
||||||
else -> true
|
|
||||||
}
|
|
||||||
|
|
||||||
summary.predictedGradeLastChange = when {
|
private fun getGradeSummaryWithUpdatedNotificationState(
|
||||||
oldSummary == null -> Instant.now()
|
summary: GradeSummary,
|
||||||
summary.predictedGrade != oldSummary.predictedGrade -> Instant.now()
|
oldSummary: GradeSummary?,
|
||||||
else -> oldSummary.predictedGradeLastChange
|
notify: Boolean,
|
||||||
}
|
) {
|
||||||
summary.finalGradeLastChange = when {
|
summary.isPredictedGradeNotified = when {
|
||||||
oldSummary == null -> Instant.now()
|
summary.predictedGrade.isEmpty() -> true
|
||||||
summary.finalGrade != oldSummary.finalGrade -> Instant.now()
|
notify && oldSummary?.predictedGrade != summary.predictedGrade -> false
|
||||||
else -> oldSummary.finalGradeLastChange
|
else -> true
|
||||||
}
|
}
|
||||||
})
|
summary.isFinalGradeNotified = when {
|
||||||
|
summary.finalGrade.isEmpty() -> true
|
||||||
|
notify && oldSummary?.finalGrade != summary.finalGrade -> false
|
||||||
|
else -> true
|
||||||
|
}
|
||||||
|
summary.predictedGradeLastChange = when {
|
||||||
|
oldSummary == null -> Instant.now()
|
||||||
|
summary.predictedGrade != oldSummary.predictedGrade -> Instant.now()
|
||||||
|
else -> oldSummary.predictedGradeLastChange
|
||||||
|
}
|
||||||
|
summary.finalGradeLastChange = when {
|
||||||
|
oldSummary == null -> Instant.now()
|
||||||
|
summary.finalGrade != oldSummary.finalGrade -> Instant.now()
|
||||||
|
else -> oldSummary.finalGradeLastChange
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getUnreadGrades(semester: Semester): Flow<List<Grade>> {
|
fun getUnreadGrades(semester: Semester): Flow<List<Grade>> {
|
||||||
|
@ -19,7 +19,7 @@ import io.github.wulkanowy.utils.init
|
|||||||
import io.github.wulkanowy.utils.switchSemester
|
import io.github.wulkanowy.utils.switchSemester
|
||||||
import io.github.wulkanowy.utils.uniqueSubtract
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import java.util.*
|
import java.util.Locale
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@ -62,8 +62,10 @@ class GradeStatisticsRepository @Inject constructor(
|
|||||||
.mapToEntities(semester)
|
.mapToEntities(semester)
|
||||||
},
|
},
|
||||||
saveFetchResult = { old, new ->
|
saveFetchResult = { old, new ->
|
||||||
gradePartialStatisticsDb.deleteAll(old uniqueSubtract new)
|
gradePartialStatisticsDb.removeOldAndSaveNew(
|
||||||
gradePartialStatisticsDb.insertAll(new uniqueSubtract old)
|
oldItems = old uniqueSubtract new,
|
||||||
|
newItems = new uniqueSubtract old,
|
||||||
|
)
|
||||||
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(partialCacheKey, semester))
|
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(partialCacheKey, semester))
|
||||||
},
|
},
|
||||||
mapResult = { items ->
|
mapResult = { items ->
|
||||||
@ -80,6 +82,7 @@ class GradeStatisticsRepository @Inject constructor(
|
|||||||
)
|
)
|
||||||
listOf(summaryItem) + items
|
listOf(summaryItem) + items
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> items.filter { it.subject == subjectName }
|
else -> items.filter { it.subject == subjectName }
|
||||||
}.mapPartialToStatisticItems()
|
}.mapPartialToStatisticItems()
|
||||||
}
|
}
|
||||||
@ -107,8 +110,10 @@ class GradeStatisticsRepository @Inject constructor(
|
|||||||
.mapToEntities(semester)
|
.mapToEntities(semester)
|
||||||
},
|
},
|
||||||
saveFetchResult = { old, new ->
|
saveFetchResult = { old, new ->
|
||||||
gradeSemesterStatisticsDb.deleteAll(old uniqueSubtract new)
|
gradeSemesterStatisticsDb.removeOldAndSaveNew(
|
||||||
gradeSemesterStatisticsDb.insertAll(new uniqueSubtract old)
|
oldItems = old uniqueSubtract new,
|
||||||
|
newItems = new uniqueSubtract old,
|
||||||
|
)
|
||||||
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(semesterCacheKey, semester))
|
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(semesterCacheKey, semester))
|
||||||
},
|
},
|
||||||
mapResult = { items ->
|
mapResult = { items ->
|
||||||
@ -138,6 +143,7 @@ class GradeStatisticsRepository @Inject constructor(
|
|||||||
}
|
}
|
||||||
listOf(summaryItem) + itemsWithAverage
|
listOf(summaryItem) + itemsWithAverage
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> itemsWithAverage.filter { it.subject == subjectName }
|
else -> itemsWithAverage.filter { it.subject == subjectName }
|
||||||
}.mapSemesterToStatisticItems()
|
}.mapSemesterToStatisticItems()
|
||||||
}
|
}
|
||||||
@ -163,8 +169,10 @@ class GradeStatisticsRepository @Inject constructor(
|
|||||||
.mapToEntities(semester)
|
.mapToEntities(semester)
|
||||||
},
|
},
|
||||||
saveFetchResult = { old, new ->
|
saveFetchResult = { old, new ->
|
||||||
gradePointsStatisticsDb.deleteAll(old uniqueSubtract new)
|
gradePointsStatisticsDb.removeOldAndSaveNew(
|
||||||
gradePointsStatisticsDb.insertAll(new uniqueSubtract old)
|
oldItems = old uniqueSubtract new,
|
||||||
|
newItems = new uniqueSubtract old,
|
||||||
|
)
|
||||||
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(pointsCacheKey, semester))
|
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(pointsCacheKey, semester))
|
||||||
},
|
},
|
||||||
mapResult = { items ->
|
mapResult = { items ->
|
||||||
|
@ -61,14 +61,14 @@ class HomeworkRepository @Inject constructor(
|
|||||||
.mapToEntities(semester)
|
.mapToEntities(semester)
|
||||||
},
|
},
|
||||||
saveFetchResult = { old, new ->
|
saveFetchResult = { old, new ->
|
||||||
val homeWorkToSave = (new uniqueSubtract old).onEach {
|
|
||||||
if (notify) it.isNotified = false
|
|
||||||
}
|
|
||||||
val filteredOld = old.filterNot { it.isAddedByUser }
|
val filteredOld = old.filterNot { it.isAddedByUser }
|
||||||
|
|
||||||
homeworkDb.deleteAll(filteredOld uniqueSubtract new)
|
homeworkDb.removeOldAndSaveNew(
|
||||||
homeworkDb.insertAll(homeWorkToSave)
|
oldItems = filteredOld uniqueSubtract new,
|
||||||
|
newItems = (new uniqueSubtract old).onEach {
|
||||||
|
if (notify) it.isNotified = false
|
||||||
|
},
|
||||||
|
)
|
||||||
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester, start, end))
|
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester, start, end))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -18,7 +18,7 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class LuckyNumberRepository @Inject constructor(
|
class LuckyNumberRepository @Inject constructor(
|
||||||
private val luckyNumberDb: LuckyNumberDao,
|
private val luckyNumberDb: LuckyNumberDao,
|
||||||
private val sdk: Sdk
|
private val sdk: Sdk,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val saveFetchResultMutex = Mutex()
|
private val saveFetchResultMutex = Mutex()
|
||||||
@ -39,11 +39,10 @@ class LuckyNumberRepository @Inject constructor(
|
|||||||
newLuckyNumber ?: return@networkBoundResource
|
newLuckyNumber ?: return@networkBoundResource
|
||||||
|
|
||||||
if (newLuckyNumber != oldLuckyNumber) {
|
if (newLuckyNumber != oldLuckyNumber) {
|
||||||
val updatedLuckNumberList =
|
luckyNumberDb.removeOldAndSaveNew(
|
||||||
listOf(newLuckyNumber.apply { if (notify) isNotified = false })
|
oldItems = listOfNotNull(oldLuckyNumber),
|
||||||
|
newItems = listOf(newLuckyNumber.apply { if (notify) isNotified = false }),
|
||||||
oldLuckyNumber?.let { luckyNumberDb.deleteAll(listOfNotNull(it)) }
|
)
|
||||||
luckyNumberDb.insertAll(updatedLuckNumberList)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -89,12 +89,13 @@ class MessageRepository @Inject constructor(
|
|||||||
},
|
},
|
||||||
saveFetchResult = { oldWithAuthors, new ->
|
saveFetchResult = { oldWithAuthors, new ->
|
||||||
val old = oldWithAuthors.map { it.message }
|
val old = oldWithAuthors.map { it.message }
|
||||||
messagesDb.deleteAll(old uniqueSubtract new)
|
messagesDb.removeOldAndSaveNew(
|
||||||
messagesDb.insertAll((new uniqueSubtract old).onEach {
|
oldItems = old uniqueSubtract new,
|
||||||
val muted = isMuted(it.correspondents)
|
newItems = (new uniqueSubtract old).onEach {
|
||||||
it.isNotified = !notify || muted
|
val muted = isMuted(it.correspondents)
|
||||||
})
|
it.isNotified = !notify || muted
|
||||||
|
},
|
||||||
|
)
|
||||||
refreshHelper.updateLastRefreshTimestamp(
|
refreshHelper.updateLastRefreshTimestamp(
|
||||||
getRefreshKey(messagesCacheKey, mailbox, folder)
|
getRefreshKey(messagesCacheKey, mailbox, folder)
|
||||||
)
|
)
|
||||||
|
@ -48,9 +48,10 @@ class MobileDeviceRepository @Inject constructor(
|
|||||||
.mapToEntities(student)
|
.mapToEntities(student)
|
||||||
},
|
},
|
||||||
saveFetchResult = { old, new ->
|
saveFetchResult = { old, new ->
|
||||||
mobileDb.deleteAll(old uniqueSubtract new)
|
mobileDb.removeOldAndSaveNew(
|
||||||
mobileDb.insertAll(new uniqueSubtract old)
|
oldItems = old uniqueSubtract new,
|
||||||
|
newItems = new uniqueSubtract old,
|
||||||
|
)
|
||||||
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, student))
|
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, student))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -7,7 +7,12 @@ import io.github.wulkanowy.data.db.entities.Student
|
|||||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||||
import io.github.wulkanowy.data.networkBoundResource
|
import io.github.wulkanowy.data.networkBoundResource
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.*
|
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||||
|
import io.github.wulkanowy.utils.getRefreshKey
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
|
import io.github.wulkanowy.utils.switchSemester
|
||||||
|
import io.github.wulkanowy.utils.toLocalDate
|
||||||
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -46,14 +51,16 @@ class NoteRepository @Inject constructor(
|
|||||||
.mapToEntities(semester)
|
.mapToEntities(semester)
|
||||||
},
|
},
|
||||||
saveFetchResult = { old, new ->
|
saveFetchResult = { old, new ->
|
||||||
noteDb.deleteAll(old uniqueSubtract new)
|
val notesToAdd = (new uniqueSubtract old).onEach {
|
||||||
noteDb.insertAll((new uniqueSubtract old).onEach {
|
|
||||||
if (it.date >= student.registrationDate.toLocalDate()) it.apply {
|
if (it.date >= student.registrationDate.toLocalDate()) it.apply {
|
||||||
isRead = false
|
isRead = false
|
||||||
if (notify) isNotified = false
|
if (notify) isNotified = false
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
noteDb.removeOldAndSaveNew(
|
||||||
|
oldItems = old uniqueSubtract new,
|
||||||
|
newItems = notesToAdd,
|
||||||
|
)
|
||||||
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester))
|
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
package io.github.wulkanowy.data.repositories
|
package io.github.wulkanowy.data.repositories
|
||||||
|
|
||||||
import io.github.wulkanowy.data.db.dao.RecipientDao
|
import io.github.wulkanowy.data.db.dao.RecipientDao
|
||||||
import io.github.wulkanowy.data.db.entities.*
|
import io.github.wulkanowy.data.db.entities.Mailbox
|
||||||
|
import io.github.wulkanowy.data.db.entities.MailboxType
|
||||||
|
import io.github.wulkanowy.data.db.entities.Message
|
||||||
|
import io.github.wulkanowy.data.db.entities.Recipient
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||||
@ -25,8 +29,10 @@ class RecipientRepository @Inject constructor(
|
|||||||
.mapToEntities(mailbox.globalKey)
|
.mapToEntities(mailbox.globalKey)
|
||||||
val old = recipientDb.loadAll(type, mailbox.globalKey)
|
val old = recipientDb.loadAll(type, mailbox.globalKey)
|
||||||
|
|
||||||
recipientDb.deleteAll(old uniqueSubtract new)
|
recipientDb.removeOldAndSaveNew(
|
||||||
recipientDb.insertAll(new uniqueSubtract old)
|
oldItems = old uniqueSubtract new,
|
||||||
|
newItems = new uniqueSubtract old,
|
||||||
|
)
|
||||||
|
|
||||||
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, student))
|
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, student))
|
||||||
}
|
}
|
||||||
|
@ -47,12 +47,12 @@ class SchoolAnnouncementRepository @Inject constructor(
|
|||||||
lastAnnouncements + directorInformation
|
lastAnnouncements + directorInformation
|
||||||
},
|
},
|
||||||
saveFetchResult = { old, new ->
|
saveFetchResult = { old, new ->
|
||||||
val schoolAnnouncementsToSave = (new uniqueSubtract old).onEach {
|
schoolAnnouncementDb.removeOldAndSaveNew(
|
||||||
if (notify) it.isNotified = false
|
oldItems = old uniqueSubtract new,
|
||||||
}
|
newItems = (new uniqueSubtract old).onEach {
|
||||||
|
if (notify) it.isNotified = false
|
||||||
schoolAnnouncementDb.deleteAll(old uniqueSubtract new)
|
},
|
||||||
schoolAnnouncementDb.insertAll(schoolAnnouncementsToSave)
|
)
|
||||||
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, student))
|
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, student))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -47,10 +47,10 @@ class SchoolRepository @Inject constructor(
|
|||||||
},
|
},
|
||||||
saveFetchResult = { old, new ->
|
saveFetchResult = { old, new ->
|
||||||
if (old != null && new != old) {
|
if (old != null && new != old) {
|
||||||
with(schoolDb) {
|
schoolDb.removeOldAndSaveNew(
|
||||||
deleteAll(listOf(old))
|
oldItems = listOf(old),
|
||||||
insertAll(listOf(new))
|
newItems = listOf(new)
|
||||||
}
|
)
|
||||||
} else if (old == null) {
|
} else if (old == null) {
|
||||||
schoolDb.insertAll(listOf(new))
|
schoolDb.insertAll(listOf(new))
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,11 @@ import io.github.wulkanowy.data.db.entities.Semester
|
|||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.*
|
import io.github.wulkanowy.utils.DispatchersProvider
|
||||||
|
import io.github.wulkanowy.utils.getCurrentOrLast
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
|
import io.github.wulkanowy.utils.isCurrent
|
||||||
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -15,7 +19,7 @@ import javax.inject.Singleton
|
|||||||
class SemesterRepository @Inject constructor(
|
class SemesterRepository @Inject constructor(
|
||||||
private val semesterDb: SemesterDao,
|
private val semesterDb: SemesterDao,
|
||||||
private val sdk: Sdk,
|
private val sdk: Sdk,
|
||||||
private val dispatchers: DispatchersProvider
|
private val dispatchers: DispatchersProvider,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun getSemesters(
|
suspend fun getSemesters(
|
||||||
@ -45,6 +49,7 @@ class SemesterRepository @Inject constructor(
|
|||||||
0 == it.diaryId && 0 == it.kindergartenDiaryId
|
0 == it.diaryId && 0 == it.kindergartenDiaryId
|
||||||
} == true
|
} == true
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,8 +64,10 @@ class SemesterRepository @Inject constructor(
|
|||||||
if (new.isEmpty()) return Timber.i("Empty semester list!")
|
if (new.isEmpty()) return Timber.i("Empty semester list!")
|
||||||
|
|
||||||
val old = semesterDb.loadAll(student.studentId, student.classId)
|
val old = semesterDb.loadAll(student.studentId, student.classId)
|
||||||
semesterDb.deleteAll(old.uniqueSubtract(new))
|
semesterDb.removeOldAndSaveNew(
|
||||||
semesterDb.insertSemesters(new.uniqueSubtract(old))
|
oldItems = old uniqueSubtract new,
|
||||||
|
newItems = new uniqueSubtract old,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getCurrentSemester(student: Student, forceRefresh: Boolean = false) =
|
suspend fun getCurrentSemester(student: Student, forceRefresh: Boolean = false) =
|
||||||
|
@ -15,7 +15,7 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class StudentInfoRepository @Inject constructor(
|
class StudentInfoRepository @Inject constructor(
|
||||||
private val studentInfoDao: StudentInfoDao,
|
private val studentInfoDao: StudentInfoDao,
|
||||||
private val sdk: Sdk
|
private val sdk: Sdk,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val saveFetchResultMutex = Mutex()
|
private val saveFetchResultMutex = Mutex()
|
||||||
@ -36,10 +36,10 @@ class StudentInfoRepository @Inject constructor(
|
|||||||
},
|
},
|
||||||
saveFetchResult = { old, new ->
|
saveFetchResult = { old, new ->
|
||||||
if (old != null && new != old) {
|
if (old != null && new != old) {
|
||||||
with(studentInfoDao) {
|
studentInfoDao.removeOldAndSaveNew(
|
||||||
deleteAll(listOf(old))
|
oldItems = listOf(old),
|
||||||
insertAll(listOf(new))
|
newItems = listOf(new),
|
||||||
}
|
)
|
||||||
} else if (old == null) {
|
} else if (old == null) {
|
||||||
studentInfoDao.insertAll(listOf(new))
|
studentInfoDao.insertAll(listOf(new))
|
||||||
}
|
}
|
||||||
|
@ -45,9 +45,10 @@ class SubjectRepository @Inject constructor(
|
|||||||
.mapToEntities(semester)
|
.mapToEntities(semester)
|
||||||
},
|
},
|
||||||
saveFetchResult = { old, new ->
|
saveFetchResult = { old, new ->
|
||||||
subjectDao.deleteAll(old uniqueSubtract new)
|
subjectDao.removeOldAndSaveNew(
|
||||||
subjectDao.insertAll(new uniqueSubtract old)
|
oldItems = old uniqueSubtract new,
|
||||||
|
newItems = new uniqueSubtract old
|
||||||
|
)
|
||||||
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester))
|
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -45,9 +45,10 @@ class TeacherRepository @Inject constructor(
|
|||||||
.mapToEntities(semester)
|
.mapToEntities(semester)
|
||||||
},
|
},
|
||||||
saveFetchResult = { old, new ->
|
saveFetchResult = { old, new ->
|
||||||
teacherDb.deleteAll(old uniqueSubtract new)
|
teacherDb.removeOldAndSaveNew(
|
||||||
teacherDb.insertAll(new uniqueSubtract old)
|
oldItems = old uniqueSubtract new,
|
||||||
|
newItems = new uniqueSubtract old,
|
||||||
|
)
|
||||||
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester))
|
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -154,8 +154,10 @@ class TimetableRepository @Inject constructor(
|
|||||||
new.apply { if (notify) isNotified = false }
|
new.apply { if (notify) isNotified = false }
|
||||||
}
|
}
|
||||||
|
|
||||||
timetableDb.deleteAll(lessonsToRemove)
|
timetableDb.removeOldAndSaveNew(
|
||||||
timetableDb.insertAll(lessonsToAdd)
|
oldItems = lessonsToRemove,
|
||||||
|
newItems = lessonsToAdd,
|
||||||
|
)
|
||||||
|
|
||||||
schedulerHelper.cancelScheduled(lessonsToRemove, student)
|
schedulerHelper.cancelScheduled(lessonsToRemove, student)
|
||||||
schedulerHelper.scheduleNotifications(lessonsToAdd, student)
|
schedulerHelper.scheduleNotifications(lessonsToAdd, student)
|
||||||
@ -166,13 +168,17 @@ class TimetableRepository @Inject constructor(
|
|||||||
new: List<TimetableAdditional>
|
new: List<TimetableAdditional>
|
||||||
) {
|
) {
|
||||||
val oldFiltered = old.filter { !it.isAddedByUser }
|
val oldFiltered = old.filter { !it.isAddedByUser }
|
||||||
timetableAdditionalDb.deleteAll(oldFiltered uniqueSubtract new)
|
timetableAdditionalDb.removeOldAndSaveNew(
|
||||||
timetableAdditionalDb.insertAll(new uniqueSubtract old)
|
oldItems = oldFiltered uniqueSubtract new,
|
||||||
|
newItems = new uniqueSubtract old,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun refreshDayHeaders(old: List<TimetableHeader>, new: List<TimetableHeader>) {
|
private suspend fun refreshDayHeaders(old: List<TimetableHeader>, new: List<TimetableHeader>) {
|
||||||
timetableHeaderDb.deleteAll(old uniqueSubtract new)
|
timetableHeaderDb.removeOldAndSaveNew(
|
||||||
timetableHeaderDb.insertAll(new uniqueSubtract old)
|
oldItems = old uniqueSubtract new,
|
||||||
|
newItems = new uniqueSubtract old,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getLastRefreshTimestamp(semester: Semester, start: LocalDate, end: LocalDate): Instant {
|
fun getLastRefreshTimestamp(semester: Semester, start: LocalDate, end: LocalDate): Instant {
|
||||||
|
@ -10,11 +10,17 @@ import io.github.wulkanowy.getSemesterEntity
|
|||||||
import io.github.wulkanowy.getStudentEntity
|
import io.github.wulkanowy.getStudentEntity
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||||
import io.mockk.*
|
import io.mockk.MockKAnnotations
|
||||||
|
import io.mockk.Runs
|
||||||
|
import io.mockk.coEvery
|
||||||
|
import io.mockk.coVerify
|
||||||
|
import io.mockk.every
|
||||||
import io.mockk.impl.annotations.MockK
|
import io.mockk.impl.annotations.MockK
|
||||||
import io.mockk.impl.annotations.SpyK
|
import io.mockk.impl.annotations.SpyK
|
||||||
|
import io.mockk.just
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@ -61,26 +67,36 @@ class AttendanceRepositoryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `force refresh without difference`() {
|
fun `force refresh without difference`() = runTest {
|
||||||
// prepare
|
// prepare
|
||||||
coEvery { sdk.getAttendance(startDate, endDate) } returns remoteList
|
coEvery { sdk.getAttendance(startDate, endDate) } returns remoteList
|
||||||
coEvery { attendanceDb.loadAll(1, 1, startDate, endDate) } returnsMany listOf(
|
coEvery { attendanceDb.loadAll(1, 1, startDate, endDate) } returnsMany listOf(
|
||||||
flowOf(remoteList.mapToEntities(semester, emptyList())),
|
flowOf(remoteList.mapToEntities(semester, emptyList())),
|
||||||
flowOf(remoteList.mapToEntities(semester, emptyList()))
|
flowOf(remoteList.mapToEntities(semester, emptyList()))
|
||||||
)
|
)
|
||||||
coEvery { attendanceDb.insertAll(any()) } returns listOf(1, 2, 3)
|
coEvery { attendanceDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { attendanceDb.deleteAll(any()) } just Runs
|
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
val res = runBlocking { attendanceRepository.getAttendance(student, semester, startDate, endDate, true).toFirstResult() }
|
val res = attendanceRepository.getAttendance(
|
||||||
|
student = student,
|
||||||
|
semester = semester,
|
||||||
|
start = startDate,
|
||||||
|
end = endDate,
|
||||||
|
forceRefresh = true,
|
||||||
|
).toFirstResult()
|
||||||
|
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
assertEquals(null, res.errorOrNull)
|
assertEquals(null, res.errorOrNull)
|
||||||
assertEquals(2, res.dataOrNull?.size)
|
assertEquals(2, res.dataOrNull?.size)
|
||||||
coVerify { sdk.getAttendance(startDate, endDate) }
|
coVerify { sdk.getAttendance(startDate, endDate) }
|
||||||
coVerify { attendanceDb.loadAll(1, 1, startDate, endDate) }
|
coVerify { attendanceDb.loadAll(1, 1, startDate, endDate) }
|
||||||
coVerify { attendanceDb.insertAll(match { it.isEmpty() }) }
|
coVerify {
|
||||||
coVerify { attendanceDb.deleteAll(match { it.isEmpty() }) }
|
attendanceDb.removeOldAndSaveNew(
|
||||||
|
oldItems = match { it.isEmpty() },
|
||||||
|
newItems = match { it.isEmpty() },
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -89,14 +105,23 @@ class AttendanceRepositoryTest {
|
|||||||
coEvery { sdk.getAttendance(startDate, endDate) } returns remoteList
|
coEvery { sdk.getAttendance(startDate, endDate) } returns remoteList
|
||||||
coEvery { attendanceDb.loadAll(1, 1, startDate, endDate) } returnsMany listOf(
|
coEvery { attendanceDb.loadAll(1, 1, startDate, endDate) } returnsMany listOf(
|
||||||
flowOf(remoteList.dropLast(1).mapToEntities(semester, emptyList())),
|
flowOf(remoteList.dropLast(1).mapToEntities(semester, emptyList())),
|
||||||
flowOf(remoteList.dropLast(1).mapToEntities(semester, emptyList())), // after fetch end before save result
|
flowOf(
|
||||||
|
remoteList.dropLast(1).mapToEntities(semester, emptyList())
|
||||||
|
), // after fetch end before save result
|
||||||
flowOf(remoteList.mapToEntities(semester, emptyList()))
|
flowOf(remoteList.mapToEntities(semester, emptyList()))
|
||||||
)
|
)
|
||||||
coEvery { attendanceDb.insertAll(any()) } returns listOf(1, 2, 3)
|
coEvery { attendanceDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { attendanceDb.deleteAll(any()) } just Runs
|
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
val res = runBlocking { attendanceRepository.getAttendance(student, semester, startDate, endDate, true).toFirstResult() }
|
val res = runBlocking {
|
||||||
|
attendanceRepository.getAttendance(
|
||||||
|
student,
|
||||||
|
semester,
|
||||||
|
startDate,
|
||||||
|
endDate,
|
||||||
|
true
|
||||||
|
).toFirstResult()
|
||||||
|
}
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
assertEquals(null, res.errorOrNull)
|
assertEquals(null, res.errorOrNull)
|
||||||
@ -104,11 +129,13 @@ class AttendanceRepositoryTest {
|
|||||||
coVerify { sdk.getAttendance(startDate, endDate) }
|
coVerify { sdk.getAttendance(startDate, endDate) }
|
||||||
coVerify { attendanceDb.loadAll(1, 1, startDate, endDate) }
|
coVerify { attendanceDb.loadAll(1, 1, startDate, endDate) }
|
||||||
coVerify {
|
coVerify {
|
||||||
attendanceDb.insertAll(match {
|
attendanceDb.removeOldAndSaveNew(
|
||||||
it.size == 1 && it[0] == remoteList.mapToEntities(semester, emptyList())[1]
|
oldItems = match { it.isEmpty() },
|
||||||
})
|
newItems = match {
|
||||||
|
it.size == 1 && it[0] == remoteList.mapToEntities(semester, emptyList())[1]
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
coVerify { attendanceDb.deleteAll(match { it.isEmpty() }) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -117,25 +144,39 @@ class AttendanceRepositoryTest {
|
|||||||
coEvery { sdk.getAttendance(startDate, endDate) } returns remoteList.dropLast(1)
|
coEvery { sdk.getAttendance(startDate, endDate) } returns remoteList.dropLast(1)
|
||||||
coEvery { attendanceDb.loadAll(1, 1, startDate, endDate) } returnsMany listOf(
|
coEvery { attendanceDb.loadAll(1, 1, startDate, endDate) } returnsMany listOf(
|
||||||
flowOf(remoteList.mapToEntities(semester, emptyList())),
|
flowOf(remoteList.mapToEntities(semester, emptyList())),
|
||||||
flowOf(remoteList.mapToEntities(semester, emptyList())), // after fetch end before save result
|
flowOf(
|
||||||
|
remoteList.mapToEntities(
|
||||||
|
semester,
|
||||||
|
emptyList()
|
||||||
|
)
|
||||||
|
), // after fetch end before save result
|
||||||
flowOf(remoteList.dropLast(1).mapToEntities(semester, emptyList()))
|
flowOf(remoteList.dropLast(1).mapToEntities(semester, emptyList()))
|
||||||
)
|
)
|
||||||
coEvery { attendanceDb.insertAll(any()) } returns listOf(1, 2, 3)
|
coEvery { attendanceDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { attendanceDb.deleteAll(any()) } just Runs
|
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
val res = runBlocking { attendanceRepository.getAttendance(student, semester, startDate, endDate, true).toFirstResult() }
|
val res = runBlocking {
|
||||||
|
attendanceRepository.getAttendance(
|
||||||
|
student,
|
||||||
|
semester,
|
||||||
|
startDate,
|
||||||
|
endDate,
|
||||||
|
true
|
||||||
|
).toFirstResult()
|
||||||
|
}
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
assertEquals(null, res.errorOrNull)
|
assertEquals(null, res.errorOrNull)
|
||||||
assertEquals(1, res.dataOrNull?.size)
|
assertEquals(1, res.dataOrNull?.size)
|
||||||
coVerify { sdk.getAttendance(startDate, endDate) }
|
coVerify { sdk.getAttendance(startDate, endDate) }
|
||||||
coVerify { attendanceDb.loadAll(1, 1, startDate, endDate) }
|
coVerify { attendanceDb.loadAll(1, 1, startDate, endDate) }
|
||||||
coVerify { attendanceDb.insertAll(match { it.isEmpty() }) }
|
|
||||||
coVerify {
|
coVerify {
|
||||||
attendanceDb.deleteAll(match {
|
attendanceDb.removeOldAndSaveNew(
|
||||||
it.size == 1 && it[0] == remoteList.mapToEntities(semester, emptyList())[1]
|
oldItems = match {
|
||||||
})
|
it.size == 1 && it[0] == remoteList.mapToEntities(semester, emptyList())[1]
|
||||||
|
},
|
||||||
|
newItems = emptyList(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,11 +9,16 @@ import io.github.wulkanowy.getSemesterEntity
|
|||||||
import io.github.wulkanowy.getStudentEntity
|
import io.github.wulkanowy.getStudentEntity
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||||
import io.mockk.*
|
import io.mockk.MockKAnnotations
|
||||||
|
import io.mockk.Runs
|
||||||
|
import io.mockk.coEvery
|
||||||
|
import io.mockk.coVerify
|
||||||
|
import io.mockk.every
|
||||||
import io.mockk.impl.annotations.MockK
|
import io.mockk.impl.annotations.MockK
|
||||||
import io.mockk.impl.annotations.SpyK
|
import io.mockk.impl.annotations.SpyK
|
||||||
|
import io.mockk.just
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@ -52,46 +57,28 @@ class CompletedLessonsRepositoryTest {
|
|||||||
MockKAnnotations.init(this)
|
MockKAnnotations.init(this)
|
||||||
every { refreshHelper.shouldBeRefreshed(any()) } returns false
|
every { refreshHelper.shouldBeRefreshed(any()) } returns false
|
||||||
|
|
||||||
completedLessonRepository = CompletedLessonsRepository(completedLessonDb, sdk, refreshHelper)
|
completedLessonRepository =
|
||||||
|
CompletedLessonsRepository(completedLessonDb, sdk, refreshHelper)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `force refresh without difference`() {
|
fun `force refresh without difference`() = runTest {
|
||||||
// prepare
|
// prepare
|
||||||
coEvery { sdk.getCompletedLessons(startDate, endDate) } returns remoteList
|
coEvery { sdk.getCompletedLessons(startDate, endDate) } returns remoteList
|
||||||
coEvery { completedLessonDb.loadAll(1, 1, startDate, endDate) } returnsMany listOf(
|
coEvery { completedLessonDb.loadAll(1, 1, startDate, endDate) } returnsMany listOf(
|
||||||
flowOf(remoteList.mapToEntities(semester)),
|
flowOf(remoteList.mapToEntities(semester)),
|
||||||
flowOf(remoteList.mapToEntities(semester))
|
flowOf(remoteList.mapToEntities(semester))
|
||||||
)
|
)
|
||||||
coEvery { completedLessonDb.insertAll(any()) } returns listOf(1, 2, 3)
|
coEvery { completedLessonDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { completedLessonDb.deleteAll(any()) } just Runs
|
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
val res = runBlocking { completedLessonRepository.getCompletedLessons(student, semester, startDate, endDate, true).toFirstResult() }
|
val res = completedLessonRepository.getCompletedLessons(
|
||||||
|
student = student,
|
||||||
// verify
|
semester = semester,
|
||||||
assertEquals(null, res.errorOrNull)
|
start = startDate,
|
||||||
assertEquals(2, res.dataOrNull?.size)
|
end = endDate,
|
||||||
coVerify { sdk.getCompletedLessons(startDate, endDate) }
|
forceRefresh = true,
|
||||||
coVerify { completedLessonDb.loadAll(1, 1, startDate, endDate) }
|
).toFirstResult()
|
||||||
coVerify { completedLessonDb.insertAll(match { it.isEmpty() }) }
|
|
||||||
coVerify { completedLessonDb.deleteAll(match { it.isEmpty() }) }
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `force refresh with more items in remote`() {
|
|
||||||
// prepare
|
|
||||||
coEvery { sdk.getCompletedLessons(startDate, endDate) } returns remoteList
|
|
||||||
coEvery { completedLessonDb.loadAll(1, 1, startDate, endDate) } returnsMany listOf(
|
|
||||||
flowOf(remoteList.dropLast(1).mapToEntities(semester)),
|
|
||||||
flowOf(remoteList.dropLast(1).mapToEntities(semester)), // after fetch end before save result
|
|
||||||
flowOf(remoteList.mapToEntities(semester))
|
|
||||||
)
|
|
||||||
coEvery { completedLessonDb.insertAll(any()) } returns listOf(1, 2, 3)
|
|
||||||
coEvery { completedLessonDb.deleteAll(any()) } just Runs
|
|
||||||
|
|
||||||
// execute
|
|
||||||
val res = runBlocking { completedLessonRepository.getCompletedLessons(student, semester, startDate, endDate, true).toFirstResult() }
|
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
assertEquals(null, res.errorOrNull)
|
assertEquals(null, res.errorOrNull)
|
||||||
@ -99,15 +86,52 @@ class CompletedLessonsRepositoryTest {
|
|||||||
coVerify { sdk.getCompletedLessons(startDate, endDate) }
|
coVerify { sdk.getCompletedLessons(startDate, endDate) }
|
||||||
coVerify { completedLessonDb.loadAll(1, 1, startDate, endDate) }
|
coVerify { completedLessonDb.loadAll(1, 1, startDate, endDate) }
|
||||||
coVerify {
|
coVerify {
|
||||||
completedLessonDb.insertAll(match {
|
completedLessonDb.removeOldAndSaveNew(
|
||||||
it.size == 1 && it[0] == remoteList.mapToEntities(semester)[1]
|
oldItems = match { it.isEmpty() },
|
||||||
})
|
newItems = match { it.isEmpty() },
|
||||||
|
)
|
||||||
}
|
}
|
||||||
coVerify { completedLessonDb.deleteAll(match { it.isEmpty() }) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `force refresh with more items in local`() {
|
fun `force refresh with more items in remote`() = runTest {
|
||||||
|
// prepare
|
||||||
|
coEvery { sdk.getCompletedLessons(startDate, endDate) } returns remoteList
|
||||||
|
coEvery { completedLessonDb.loadAll(1, 1, startDate, endDate) } returnsMany listOf(
|
||||||
|
flowOf(remoteList.dropLast(1).mapToEntities(semester)),
|
||||||
|
flowOf(
|
||||||
|
remoteList.dropLast(1).mapToEntities(semester)
|
||||||
|
), // after fetch end before save result
|
||||||
|
flowOf(remoteList.mapToEntities(semester))
|
||||||
|
)
|
||||||
|
coEvery { completedLessonDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
|
|
||||||
|
// execute
|
||||||
|
val res = completedLessonRepository.getCompletedLessons(
|
||||||
|
student = student,
|
||||||
|
semester = semester,
|
||||||
|
start = startDate,
|
||||||
|
end = endDate,
|
||||||
|
forceRefresh = true
|
||||||
|
).toFirstResult()
|
||||||
|
|
||||||
|
// verify
|
||||||
|
assertEquals(null, res.errorOrNull)
|
||||||
|
assertEquals(2, res.dataOrNull?.size)
|
||||||
|
coVerify { sdk.getCompletedLessons(startDate, endDate) }
|
||||||
|
coVerify { completedLessonDb.loadAll(1, 1, startDate, endDate) }
|
||||||
|
coVerify {
|
||||||
|
completedLessonDb.removeOldAndSaveNew(
|
||||||
|
oldItems = match { it.isEmpty() },
|
||||||
|
newItems = match {
|
||||||
|
it.size == 1 && it[0] == remoteList.mapToEntities(semester)[1]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `force refresh with more items in local`() = runTest {
|
||||||
// prepare
|
// prepare
|
||||||
coEvery { sdk.getCompletedLessons(startDate, endDate) } returns remoteList.dropLast(1)
|
coEvery { sdk.getCompletedLessons(startDate, endDate) } returns remoteList.dropLast(1)
|
||||||
coEvery { completedLessonDb.loadAll(1, 1, startDate, endDate) } returnsMany listOf(
|
coEvery { completedLessonDb.loadAll(1, 1, startDate, endDate) } returnsMany listOf(
|
||||||
@ -115,22 +139,29 @@ class CompletedLessonsRepositoryTest {
|
|||||||
flowOf(remoteList.mapToEntities(semester)), // after fetch end before save result
|
flowOf(remoteList.mapToEntities(semester)), // after fetch end before save result
|
||||||
flowOf(remoteList.dropLast(1).mapToEntities(semester))
|
flowOf(remoteList.dropLast(1).mapToEntities(semester))
|
||||||
)
|
)
|
||||||
coEvery { completedLessonDb.insertAll(any()) } returns listOf(1, 2, 3)
|
coEvery { completedLessonDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { completedLessonDb.deleteAll(any()) } just Runs
|
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
val res = runBlocking { completedLessonRepository.getCompletedLessons(student, semester, startDate, endDate, true).toFirstResult() }
|
val res = completedLessonRepository.getCompletedLessons(
|
||||||
|
student = student,
|
||||||
|
semester = semester,
|
||||||
|
start = startDate,
|
||||||
|
end = endDate,
|
||||||
|
forceRefresh = true,
|
||||||
|
).toFirstResult()
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
assertEquals(null, res.errorOrNull)
|
assertEquals(null, res.errorOrNull)
|
||||||
assertEquals(1, res.dataOrNull?.size)
|
assertEquals(1, res.dataOrNull?.size)
|
||||||
coVerify { sdk.getCompletedLessons(startDate, endDate) }
|
coVerify { sdk.getCompletedLessons(startDate, endDate) }
|
||||||
coVerify { completedLessonDb.loadAll(1, 1, startDate, endDate) }
|
coVerify { completedLessonDb.loadAll(1, 1, startDate, endDate) }
|
||||||
coVerify { completedLessonDb.insertAll(match { it.isEmpty() }) }
|
|
||||||
coVerify {
|
coVerify {
|
||||||
completedLessonDb.deleteAll(match {
|
completedLessonDb.removeOldAndSaveNew(
|
||||||
it.size == 1 && it[0] == remoteList.mapToEntities(semester)[1]
|
oldItems = match {
|
||||||
})
|
it.size == 1 && it[0] == remoteList.mapToEntities(semester)[1]
|
||||||
|
},
|
||||||
|
newItems = match { it.isEmpty() },
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,11 +9,17 @@ import io.github.wulkanowy.getSemesterEntity
|
|||||||
import io.github.wulkanowy.getStudentEntity
|
import io.github.wulkanowy.getStudentEntity
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||||
import io.mockk.*
|
import io.mockk.MockKAnnotations
|
||||||
|
import io.mockk.Runs
|
||||||
|
import io.mockk.coEvery
|
||||||
|
import io.mockk.coVerify
|
||||||
|
import io.mockk.every
|
||||||
import io.mockk.impl.annotations.MockK
|
import io.mockk.impl.annotations.MockK
|
||||||
import io.mockk.impl.annotations.SpyK
|
import io.mockk.impl.annotations.SpyK
|
||||||
|
import io.mockk.just
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@ -64,35 +70,42 @@ class ExamRemoteTest {
|
|||||||
flowOf(remoteList.mapToEntities(semester)),
|
flowOf(remoteList.mapToEntities(semester)),
|
||||||
flowOf(remoteList.mapToEntities(semester))
|
flowOf(remoteList.mapToEntities(semester))
|
||||||
)
|
)
|
||||||
coEvery { examDb.insertAll(any()) } returns listOf(1, 2, 3)
|
coEvery { examDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { examDb.deleteAll(any()) } just Runs
|
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
val res = runBlocking { examRepository.getExams(student, semester, startDate, endDate, true).toFirstResult() }
|
val res = runBlocking {
|
||||||
|
examRepository.getExams(student, semester, startDate, endDate, true).toFirstResult()
|
||||||
|
}
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
assertEquals(null, res.errorOrNull)
|
assertEquals(null, res.errorOrNull)
|
||||||
assertEquals(2, res.dataOrNull?.size)
|
assertEquals(2, res.dataOrNull?.size)
|
||||||
coVerify { sdk.getExams(startDate, realEndDate) }
|
coVerify { sdk.getExams(startDate, realEndDate) }
|
||||||
coVerify { examDb.loadAll(1, 1, startDate, realEndDate) }
|
coVerify { examDb.loadAll(1, 1, startDate, realEndDate) }
|
||||||
coVerify { examDb.insertAll(match { it.isEmpty() }) }
|
coVerify { examDb.removeOldAndSaveNew(emptyList(), emptyList()) }
|
||||||
coVerify { examDb.deleteAll(match { it.isEmpty() }) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `force refresh with more items in remote`() {
|
fun `force refresh with more items in remote`() = runTest {
|
||||||
// prepare
|
// prepare
|
||||||
coEvery { sdk.getExams(startDate, realEndDate) } returns remoteList
|
coEvery { sdk.getExams(startDate, realEndDate) } returns remoteList
|
||||||
coEvery { examDb.loadAll(1, 1, startDate, realEndDate) } returnsMany listOf(
|
coEvery { examDb.loadAll(1, 1, startDate, realEndDate) } returnsMany listOf(
|
||||||
flowOf(remoteList.dropLast(1).mapToEntities(semester)),
|
flowOf(remoteList.dropLast(1).mapToEntities(semester)),
|
||||||
flowOf(remoteList.dropLast(1).mapToEntities(semester)), // after fetch end before save result
|
flowOf(
|
||||||
|
remoteList.dropLast(1).mapToEntities(semester)
|
||||||
|
), // after fetch end before save result
|
||||||
flowOf(remoteList.mapToEntities(semester))
|
flowOf(remoteList.mapToEntities(semester))
|
||||||
)
|
)
|
||||||
coEvery { examDb.insertAll(any()) } returns listOf(1, 2, 3)
|
coEvery { examDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { examDb.deleteAll(any()) } just Runs
|
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
val res = runBlocking { examRepository.getExams(student, semester, startDate, endDate, true).toFirstResult() }
|
val res = examRepository.getExams(
|
||||||
|
student = student,
|
||||||
|
semester = semester,
|
||||||
|
start = startDate,
|
||||||
|
end = endDate,
|
||||||
|
forceRefresh = true,
|
||||||
|
).toFirstResult()
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
assertEquals(null, res.errorOrNull)
|
assertEquals(null, res.errorOrNull)
|
||||||
@ -100,15 +113,17 @@ class ExamRemoteTest {
|
|||||||
coVerify { sdk.getExams(startDate, realEndDate) }
|
coVerify { sdk.getExams(startDate, realEndDate) }
|
||||||
coVerify { examDb.loadAll(1, 1, startDate, realEndDate) }
|
coVerify { examDb.loadAll(1, 1, startDate, realEndDate) }
|
||||||
coVerify {
|
coVerify {
|
||||||
examDb.insertAll(match {
|
examDb.removeOldAndSaveNew(
|
||||||
it.size == 1 && it[0] == remoteList.mapToEntities(semester)[1]
|
oldItems = emptyList(),
|
||||||
})
|
newItems = match {
|
||||||
|
it.size == 1 && it[0] == remoteList.mapToEntities(semester)[1]
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
coVerify { examDb.deleteAll(match { it.isEmpty() }) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `force refresh with more items in local`() {
|
fun `force refresh with more items in local`() = runTest {
|
||||||
// prepare
|
// prepare
|
||||||
coEvery { sdk.getExams(startDate, realEndDate) } returns remoteList.dropLast(1)
|
coEvery { sdk.getExams(startDate, realEndDate) } returns remoteList.dropLast(1)
|
||||||
coEvery { examDb.loadAll(1, 1, startDate, realEndDate) } returnsMany listOf(
|
coEvery { examDb.loadAll(1, 1, startDate, realEndDate) } returnsMany listOf(
|
||||||
@ -116,22 +131,27 @@ class ExamRemoteTest {
|
|||||||
flowOf(remoteList.mapToEntities(semester)), // after fetch end before save result
|
flowOf(remoteList.mapToEntities(semester)), // after fetch end before save result
|
||||||
flowOf(remoteList.dropLast(1).mapToEntities(semester))
|
flowOf(remoteList.dropLast(1).mapToEntities(semester))
|
||||||
)
|
)
|
||||||
coEvery { examDb.insertAll(any()) } returns listOf(1, 2, 3)
|
coEvery { examDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { examDb.deleteAll(any()) } just Runs
|
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
val res = runBlocking { examRepository.getExams(student, semester, startDate, endDate, true).toFirstResult() }
|
val res = examRepository.getExams(
|
||||||
|
student = student,
|
||||||
|
semester = semester,
|
||||||
|
start = startDate,
|
||||||
|
end = endDate,
|
||||||
|
forceRefresh = true,
|
||||||
|
).toFirstResult()
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
assertEquals(null, res.errorOrNull)
|
assertEquals(null, res.errorOrNull)
|
||||||
assertEquals(1, res.dataOrNull?.size)
|
assertEquals(1, res.dataOrNull?.size)
|
||||||
coVerify { sdk.getExams(startDate, realEndDate) }
|
coVerify { sdk.getExams(startDate, realEndDate) }
|
||||||
coVerify { examDb.loadAll(1, 1, startDate, realEndDate) }
|
coVerify { examDb.loadAll(1, 1, startDate, realEndDate) }
|
||||||
coVerify { examDb.insertAll(match { it.isEmpty() }) }
|
|
||||||
coVerify {
|
coVerify {
|
||||||
examDb.deleteAll(match {
|
examDb.removeOldAndSaveNew(
|
||||||
it.size == 1 && it[0] == remoteList.mapToEntities(semester)[1]
|
oldItems = match { it.size == 1 && it[0] == remoteList.mapToEntities(semester)[1] },
|
||||||
})
|
newItems = emptyList()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ import io.mockk.impl.annotations.SpyK
|
|||||||
import io.mockk.just
|
import io.mockk.just
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Assert.assertFalse
|
import org.junit.Assert.assertFalse
|
||||||
import org.junit.Assert.assertTrue
|
import org.junit.Assert.assertTrue
|
||||||
@ -60,26 +61,27 @@ class GradeRepositoryTest {
|
|||||||
MockKAnnotations.init(this)
|
MockKAnnotations.init(this)
|
||||||
every { refreshHelper.shouldBeRefreshed(any()) } returns false
|
every { refreshHelper.shouldBeRefreshed(any()) } returns false
|
||||||
|
|
||||||
gradeRepository =
|
gradeRepository = GradeRepository(
|
||||||
GradeRepository(gradeDb, gradeSummaryDb, gradeDescriptiveDb, sdk, refreshHelper)
|
gradeDb = gradeDb,
|
||||||
|
gradeSummaryDb = gradeSummaryDb,
|
||||||
|
gradeDescriptiveDb = gradeDescriptiveDb,
|
||||||
|
sdk = sdk,
|
||||||
|
refreshHelper = refreshHelper,
|
||||||
|
)
|
||||||
|
|
||||||
coEvery { gradeDb.deleteAll(any()) } just Runs
|
coEvery { gradeDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { gradeDb.insertAll(any()) } returns listOf()
|
|
||||||
|
|
||||||
|
coEvery { gradeSummaryDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { gradeSummaryDb.loadAll(1, 1) } returnsMany listOf(
|
coEvery { gradeSummaryDb.loadAll(1, 1) } returnsMany listOf(
|
||||||
flowOf(listOf()),
|
flowOf(listOf()),
|
||||||
flowOf(listOf()),
|
flowOf(listOf()),
|
||||||
flowOf(listOf())
|
flowOf(listOf())
|
||||||
)
|
)
|
||||||
coEvery { gradeSummaryDb.deleteAll(any()) } just Runs
|
|
||||||
coEvery { gradeSummaryDb.insertAll(any()) } returns listOf()
|
|
||||||
|
|
||||||
|
coEvery { gradeDescriptiveDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { gradeDescriptiveDb.loadAll(any(), any()) } returnsMany listOf(
|
coEvery { gradeDescriptiveDb.loadAll(any(), any()) } returnsMany listOf(
|
||||||
flowOf(listOf()),
|
flowOf(listOf()),
|
||||||
)
|
)
|
||||||
|
|
||||||
coEvery { gradeDescriptiveDb.deleteAll(any()) } just Runs
|
|
||||||
coEvery { gradeDescriptiveDb.insertAll(any()) } returns listOf()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -113,13 +115,16 @@ class GradeRepositoryTest {
|
|||||||
assertEquals(null, res.errorOrNull)
|
assertEquals(null, res.errorOrNull)
|
||||||
assertEquals(4, res.dataOrNull?.first?.size)
|
assertEquals(4, res.dataOrNull?.first?.size)
|
||||||
coVerify {
|
coVerify {
|
||||||
gradeDb.insertAll(withArg {
|
gradeDb.removeOldAndSaveNew(
|
||||||
assertEquals(4, it.size)
|
oldItems = emptyList(),
|
||||||
assertTrue(it[0].isRead)
|
newItems = withArg {
|
||||||
assertTrue(it[1].isRead)
|
assertEquals(4, it.size)
|
||||||
assertFalse(it[2].isRead)
|
assertTrue(it[0].isRead)
|
||||||
assertFalse(it[3].isRead)
|
assertTrue(it[1].isRead)
|
||||||
})
|
assertFalse(it[2].isRead)
|
||||||
|
assertFalse(it[3].isRead)
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,23 +172,23 @@ class GradeRepositoryTest {
|
|||||||
assertEquals(null, res.errorOrNull)
|
assertEquals(null, res.errorOrNull)
|
||||||
assertEquals(4, res.dataOrNull?.first?.size)
|
assertEquals(4, res.dataOrNull?.first?.size)
|
||||||
coVerify {
|
coVerify {
|
||||||
gradeDb.insertAll(withArg {
|
gradeDb.removeOldAndSaveNew(
|
||||||
assertEquals(3, it.size)
|
oldItems = withArg {
|
||||||
assertTrue(it[0].isRead)
|
assertEquals(2, it.size)
|
||||||
assertTrue(it[1].isRead)
|
},
|
||||||
assertFalse(it[2].isRead)
|
newItems = withArg {
|
||||||
assertEquals(remoteList.mapToEntities(semester).last(), it[2])
|
assertEquals(3, it.size)
|
||||||
})
|
assertTrue(it[0].isRead)
|
||||||
}
|
assertTrue(it[1].isRead)
|
||||||
coVerify {
|
assertFalse(it[2].isRead)
|
||||||
gradeDb.deleteAll(withArg {
|
assertEquals(remoteList.mapToEntities(semester).last(), it[2])
|
||||||
assertEquals(2, it.size)
|
}
|
||||||
})
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `force refresh when local contains duplicated grades`() {
|
fun `force refresh when local contains duplicated grades`() = runTest {
|
||||||
// prepare
|
// prepare
|
||||||
val remoteList = listOf(
|
val remoteList = listOf(
|
||||||
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
|
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
|
||||||
@ -203,13 +208,17 @@ class GradeRepositoryTest {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
val res = runBlocking { gradeRepository.getGrades(student, semester, true).toFirstResult() }
|
val res = gradeRepository.getGrades(student, semester, true).toFirstResult()
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
assertEquals(null, res.errorOrNull)
|
assertEquals(null, res.errorOrNull)
|
||||||
assertEquals(2, res.dataOrNull?.first?.size)
|
assertEquals(2, res.dataOrNull?.first?.size)
|
||||||
coVerify { gradeDb.insertAll(match { it.isEmpty() }) }
|
coVerify {
|
||||||
coVerify { gradeDb.deleteAll(match { it.size == 1 }) } // ... here
|
gradeDb.removeOldAndSaveNew(
|
||||||
|
oldItems = match { it.size == 1 }, // ... here
|
||||||
|
newItems = emptyList()
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -238,8 +247,12 @@ class GradeRepositoryTest {
|
|||||||
// verify
|
// verify
|
||||||
assertEquals(null, res.errorOrNull)
|
assertEquals(null, res.errorOrNull)
|
||||||
assertEquals(3, res.dataOrNull?.first?.size)
|
assertEquals(3, res.dataOrNull?.first?.size)
|
||||||
coVerify { gradeDb.insertAll(match { it.size == 1 }) } // ... here
|
coVerify {
|
||||||
coVerify { gradeDb.deleteAll(match { it.isEmpty() }) }
|
gradeDb.removeOldAndSaveNew(
|
||||||
|
oldItems = emptyList(),
|
||||||
|
newItems = match { it.size == 1 }, // ... here
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -71,8 +71,7 @@ class GradeStatisticsRepositoryTest {
|
|||||||
flowOf(remotePartialList.mapToEntities(semester)),
|
flowOf(remotePartialList.mapToEntities(semester)),
|
||||||
flowOf(remotePartialList.mapToEntities(semester))
|
flowOf(remotePartialList.mapToEntities(semester))
|
||||||
)
|
)
|
||||||
coEvery { gradePartialStatisticsDb.insertAll(any()) } returns listOf(1, 2, 3)
|
coEvery { gradePartialStatisticsDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { gradePartialStatisticsDb.deleteAll(any()) } just Runs
|
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
val res = runBlocking {
|
val res = runBlocking {
|
||||||
@ -93,8 +92,7 @@ class GradeStatisticsRepositoryTest {
|
|||||||
assertEquals("", items[2].partial?.studentAverage)
|
assertEquals("", items[2].partial?.studentAverage)
|
||||||
coVerify { sdk.getGradesPartialStatistics(1) }
|
coVerify { sdk.getGradesPartialStatistics(1) }
|
||||||
coVerify { gradePartialStatisticsDb.loadAll(1, 1) }
|
coVerify { gradePartialStatisticsDb.loadAll(1, 1) }
|
||||||
coVerify { gradePartialStatisticsDb.insertAll(match { it.isEmpty() }) }
|
coVerify { gradePartialStatisticsDb.removeOldAndSaveNew(emptyList(), emptyList()) }
|
||||||
coVerify { gradePartialStatisticsDb.deleteAll(match { it.isEmpty() }) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -109,8 +107,7 @@ class GradeStatisticsRepositoryTest {
|
|||||||
flowOf(remotePartialList.mapToEntities(semester)),
|
flowOf(remotePartialList.mapToEntities(semester)),
|
||||||
flowOf(remotePartialList.mapToEntities(semester))
|
flowOf(remotePartialList.mapToEntities(semester))
|
||||||
)
|
)
|
||||||
coEvery { gradePartialStatisticsDb.insertAll(any()) } returns listOf(1, 2, 3)
|
coEvery { gradePartialStatisticsDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { gradePartialStatisticsDb.deleteAll(any()) } just Runs
|
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
val res = runBlocking {
|
val res = runBlocking {
|
||||||
@ -131,8 +128,7 @@ class GradeStatisticsRepositoryTest {
|
|||||||
assertEquals("5.0", items[2].partial?.studentAverage)
|
assertEquals("5.0", items[2].partial?.studentAverage)
|
||||||
coVerify { sdk.getGradesPartialStatistics(1) }
|
coVerify { sdk.getGradesPartialStatistics(1) }
|
||||||
coVerify { gradePartialStatisticsDb.loadAll(1, 1) }
|
coVerify { gradePartialStatisticsDb.loadAll(1, 1) }
|
||||||
coVerify { gradePartialStatisticsDb.insertAll(match { it.isEmpty() }) }
|
coVerify { gradePartialStatisticsDb.removeOldAndSaveNew(emptyList(), emptyList()) }
|
||||||
coVerify { gradePartialStatisticsDb.deleteAll(match { it.isEmpty() }) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getGradeStatisticsPartialSubject(
|
private fun getGradeStatisticsPartialSubject(
|
||||||
|
@ -7,11 +7,16 @@ import io.github.wulkanowy.data.mappers.mapToEntity
|
|||||||
import io.github.wulkanowy.data.toFirstResult
|
import io.github.wulkanowy.data.toFirstResult
|
||||||
import io.github.wulkanowy.getStudentEntity
|
import io.github.wulkanowy.getStudentEntity
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.mockk.*
|
import io.mockk.MockKAnnotations
|
||||||
|
import io.mockk.Runs
|
||||||
|
import io.mockk.coEvery
|
||||||
|
import io.mockk.coVerify
|
||||||
import io.mockk.impl.annotations.MockK
|
import io.mockk.impl.annotations.MockK
|
||||||
import io.mockk.impl.annotations.SpyK
|
import io.mockk.impl.annotations.SpyK
|
||||||
|
import io.mockk.just
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@ -53,7 +58,8 @@ class LuckyNumberRemoteTest {
|
|||||||
coEvery { luckyNumberDb.deleteAll(any()) } just Runs
|
coEvery { luckyNumberDb.deleteAll(any()) } just Runs
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
val res = runBlocking { luckyNumberRepository.getLuckyNumber(student, true).toFirstResult() }
|
val res =
|
||||||
|
runBlocking { luckyNumberRepository.getLuckyNumber(student, true).toFirstResult() }
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
assertEquals(null, res.errorOrNull)
|
assertEquals(null, res.errorOrNull)
|
||||||
@ -65,19 +71,19 @@ class LuckyNumberRemoteTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `force refresh with different item on remote`() {
|
fun `force refresh with different item on remote`() = runTest {
|
||||||
// prepare
|
// prepare
|
||||||
coEvery { sdk.getLuckyNumber(student.schoolShortName) } returns luckyNumber
|
coEvery { sdk.getLuckyNumber(student.schoolShortName) } returns luckyNumber
|
||||||
coEvery { luckyNumberDb.load(1, date) } returnsMany listOf(
|
coEvery { luckyNumberDb.load(1, date) } returnsMany listOf(
|
||||||
flowOf(luckyNumber.mapToEntity(student).copy(luckyNumber = 6666)),
|
flowOf(luckyNumber.mapToEntity(student).copy(luckyNumber = 6666)),
|
||||||
flowOf(luckyNumber.mapToEntity(student).copy(luckyNumber = 6666)), // after fetch end before save result
|
// after fetch end before save result
|
||||||
|
flowOf(luckyNumber.mapToEntity(student).copy(luckyNumber = 6666)),
|
||||||
flowOf(luckyNumber.mapToEntity(student))
|
flowOf(luckyNumber.mapToEntity(student))
|
||||||
)
|
)
|
||||||
coEvery { luckyNumberDb.insertAll(any()) } returns listOf(1, 2, 3)
|
coEvery { luckyNumberDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { luckyNumberDb.deleteAll(any()) } just Runs
|
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
val res = runBlocking { luckyNumberRepository.getLuckyNumber(student, true).toFirstResult() }
|
val res = luckyNumberRepository.getLuckyNumber(student, true).toFirstResult()
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
assertEquals(null, res.errorOrNull)
|
assertEquals(null, res.errorOrNull)
|
||||||
@ -85,13 +91,16 @@ class LuckyNumberRemoteTest {
|
|||||||
coVerify { sdk.getLuckyNumber(student.schoolShortName) }
|
coVerify { sdk.getLuckyNumber(student.schoolShortName) }
|
||||||
coVerify { luckyNumberDb.load(1, date) }
|
coVerify { luckyNumberDb.load(1, date) }
|
||||||
coVerify {
|
coVerify {
|
||||||
luckyNumberDb.insertAll(match {
|
luckyNumberDb.removeOldAndSaveNew(
|
||||||
it.size == 1 && it[0] == luckyNumber.mapToEntity(student)
|
oldItems = match {
|
||||||
})
|
it.size == 1 && it[0] == luckyNumber.mapToEntity(student)
|
||||||
|
.copy(luckyNumber = 6666)
|
||||||
|
},
|
||||||
|
newItems = match {
|
||||||
|
it.size == 1 && it[0] == luckyNumber.mapToEntity(student)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
coVerify { luckyNumberDb.deleteAll(match {
|
|
||||||
it.size == 1 && it[0] == luckyNumber.mapToEntity(student).copy(luckyNumber = 6666)
|
|
||||||
}) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -103,11 +112,11 @@ class LuckyNumberRemoteTest {
|
|||||||
flowOf(null), // after fetch end before save result
|
flowOf(null), // after fetch end before save result
|
||||||
flowOf(luckyNumber.mapToEntity(student))
|
flowOf(luckyNumber.mapToEntity(student))
|
||||||
)
|
)
|
||||||
coEvery { luckyNumberDb.insertAll(any()) } returns listOf(1, 2, 3)
|
coEvery { luckyNumberDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { luckyNumberDb.deleteAll(any()) } just Runs
|
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
val res = runBlocking { luckyNumberRepository.getLuckyNumber(student, true).toFirstResult() }
|
val res =
|
||||||
|
runBlocking { luckyNumberRepository.getLuckyNumber(student, true).toFirstResult() }
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
assertEquals(null, res.errorOrNull)
|
assertEquals(null, res.errorOrNull)
|
||||||
@ -115,10 +124,12 @@ class LuckyNumberRemoteTest {
|
|||||||
coVerify { sdk.getLuckyNumber(student.schoolShortName) }
|
coVerify { sdk.getLuckyNumber(student.schoolShortName) }
|
||||||
coVerify { luckyNumberDb.load(1, date) }
|
coVerify { luckyNumberDb.load(1, date) }
|
||||||
coVerify {
|
coVerify {
|
||||||
luckyNumberDb.insertAll(match {
|
luckyNumberDb.removeOldAndSaveNew(
|
||||||
it.size == 1 && it[0] == luckyNumber.mapToEntity(student)
|
oldItems = emptyList(),
|
||||||
})
|
newItems = match {
|
||||||
|
it.size == 1 && it[0] == luckyNumber.mapToEntity(student)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
coVerify(exactly = 0) { luckyNumberDb.deleteAll(any()) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ class MessageRepositoryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `get messages when fetched completely new message without notify`() = runBlocking {
|
fun `get messages when fetched completely new message without notify`() = runTest {
|
||||||
coEvery { mailboxDao.loadAll(any()) } returns listOf(mailbox)
|
coEvery { mailboxDao.loadAll(any()) } returns listOf(mailbox)
|
||||||
every { messageDb.loadAll(mailbox.globalKey, any()) } returns flowOf(emptyList())
|
every { messageDb.loadAll(mailbox.globalKey, any()) } returns flowOf(emptyList())
|
||||||
coEvery { sdk.getMessages(Folder.RECEIVED, any()) } returns listOf(
|
coEvery { sdk.getMessages(Folder.RECEIVED, any()) } returns listOf(
|
||||||
@ -122,8 +122,7 @@ class MessageRepositoryTest {
|
|||||||
readBy = 10,
|
readBy = 10,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
coEvery { messageDb.deleteAll(any()) } just Runs
|
coEvery { messageDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { messageDb.insertAll(any()) } returns listOf()
|
|
||||||
|
|
||||||
val res = repository.getMessages(
|
val res = repository.getMessages(
|
||||||
student = student,
|
student = student,
|
||||||
@ -134,12 +133,14 @@ class MessageRepositoryTest {
|
|||||||
).toFirstResult()
|
).toFirstResult()
|
||||||
|
|
||||||
assertEquals(null, res.errorOrNull)
|
assertEquals(null, res.errorOrNull)
|
||||||
coVerify(exactly = 1) { messageDb.deleteAll(withArg { checkEquals(emptyList<Message>()) }) }
|
|
||||||
coVerify {
|
coVerify {
|
||||||
messageDb.insertAll(withArg {
|
messageDb.removeOldAndSaveNew(
|
||||||
assertEquals(4, it.single().messageId)
|
oldItems = withArg { checkEquals(emptyList<Message>()) },
|
||||||
assertTrue(it.single().isNotified)
|
newItems = withArg {
|
||||||
})
|
assertEquals(4, it.single().messageId)
|
||||||
|
assertTrue(it.single().isNotified)
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ import io.mockk.impl.annotations.MockK
|
|||||||
import io.mockk.impl.annotations.SpyK
|
import io.mockk.impl.annotations.SpyK
|
||||||
import io.mockk.just
|
import io.mockk.just
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@ -57,42 +57,21 @@ class MobileDeviceRepositoryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `force refresh without difference`() {
|
fun `force refresh without difference`() = runTest {
|
||||||
// prepare
|
// prepare
|
||||||
coEvery { sdk.getRegisteredDevices() } returns remoteList
|
coEvery { sdk.getRegisteredDevices() } returns remoteList
|
||||||
coEvery { mobileDeviceDb.loadAll(student.studentId) } returnsMany listOf(
|
coEvery { mobileDeviceDb.loadAll(student.studentId) } returnsMany listOf(
|
||||||
flowOf(remoteList.mapToEntities(student)),
|
flowOf(remoteList.mapToEntities(student)),
|
||||||
flowOf(remoteList.mapToEntities(student))
|
flowOf(remoteList.mapToEntities(student))
|
||||||
)
|
)
|
||||||
coEvery { mobileDeviceDb.insertAll(any()) } returns listOf(1, 2, 3)
|
coEvery { mobileDeviceDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { mobileDeviceDb.deleteAll(any()) } just Runs
|
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
val res = runBlocking { mobileDeviceRepository.getDevices(student, semester, true).toFirstResult() }
|
val res = mobileDeviceRepository.getDevices(
|
||||||
|
student = student,
|
||||||
// verify
|
semester = semester,
|
||||||
Assert.assertEquals(null, res.errorOrNull)
|
forceRefresh = true,
|
||||||
Assert.assertEquals(2, res.dataOrNull?.size)
|
).toFirstResult()
|
||||||
coVerify { sdk.getRegisteredDevices() }
|
|
||||||
coVerify { mobileDeviceDb.loadAll(1) }
|
|
||||||
coVerify { mobileDeviceDb.insertAll(match { it.isEmpty() }) }
|
|
||||||
coVerify { mobileDeviceDb.deleteAll(match { it.isEmpty() }) }
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `force refresh with more items in remote`() {
|
|
||||||
// prepare
|
|
||||||
coEvery { sdk.getRegisteredDevices() } returns remoteList
|
|
||||||
coEvery { mobileDeviceDb.loadAll(1) } returnsMany listOf(
|
|
||||||
flowOf(remoteList.dropLast(1).mapToEntities(student)),
|
|
||||||
flowOf(remoteList.dropLast(1).mapToEntities(student)), // after fetch end before save result
|
|
||||||
flowOf(remoteList.mapToEntities(student))
|
|
||||||
)
|
|
||||||
coEvery { mobileDeviceDb.insertAll(any()) } returns listOf(1, 2, 3)
|
|
||||||
coEvery { mobileDeviceDb.deleteAll(any()) } just Runs
|
|
||||||
|
|
||||||
// execute
|
|
||||||
val res = runBlocking { mobileDeviceRepository.getDevices(student, semester, true).toFirstResult() }
|
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
Assert.assertEquals(null, res.errorOrNull)
|
Assert.assertEquals(null, res.errorOrNull)
|
||||||
@ -100,15 +79,50 @@ class MobileDeviceRepositoryTest {
|
|||||||
coVerify { sdk.getRegisteredDevices() }
|
coVerify { sdk.getRegisteredDevices() }
|
||||||
coVerify { mobileDeviceDb.loadAll(1) }
|
coVerify { mobileDeviceDb.loadAll(1) }
|
||||||
coVerify {
|
coVerify {
|
||||||
mobileDeviceDb.insertAll(match {
|
mobileDeviceDb.removeOldAndSaveNew(
|
||||||
it.size == 1 && it[0] == remoteList.mapToEntities(student)[1]
|
oldItems = match { it.isEmpty() },
|
||||||
})
|
newItems = match { it.isEmpty() },
|
||||||
|
)
|
||||||
}
|
}
|
||||||
coVerify { mobileDeviceDb.deleteAll(match { it.isEmpty() }) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `force refresh with more items in local`() {
|
fun `force refresh with more items in remote`() = runTest {
|
||||||
|
// prepare
|
||||||
|
coEvery { sdk.getRegisteredDevices() } returns remoteList
|
||||||
|
coEvery { mobileDeviceDb.loadAll(1) } returnsMany listOf(
|
||||||
|
flowOf(remoteList.dropLast(1).mapToEntities(student)),
|
||||||
|
flowOf(
|
||||||
|
remoteList.dropLast(1).mapToEntities(student)
|
||||||
|
), // after fetch end before save result
|
||||||
|
flowOf(remoteList.mapToEntities(student))
|
||||||
|
)
|
||||||
|
coEvery { mobileDeviceDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
|
|
||||||
|
// execute
|
||||||
|
val res = mobileDeviceRepository.getDevices(
|
||||||
|
student = student,
|
||||||
|
semester = semester,
|
||||||
|
forceRefresh = true,
|
||||||
|
).toFirstResult()
|
||||||
|
|
||||||
|
// verify
|
||||||
|
Assert.assertEquals(null, res.errorOrNull)
|
||||||
|
Assert.assertEquals(2, res.dataOrNull?.size)
|
||||||
|
coVerify { sdk.getRegisteredDevices() }
|
||||||
|
coVerify { mobileDeviceDb.loadAll(1) }
|
||||||
|
coVerify {
|
||||||
|
mobileDeviceDb.removeOldAndSaveNew(
|
||||||
|
oldItems = match { it.isEmpty() },
|
||||||
|
newItems = match {
|
||||||
|
it.size == 1 && it[0] == remoteList.mapToEntities(student)[1]
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `force refresh with more items in local`() = runTest {
|
||||||
// prepare
|
// prepare
|
||||||
coEvery { sdk.getRegisteredDevices() } returns remoteList.dropLast(1)
|
coEvery { sdk.getRegisteredDevices() } returns remoteList.dropLast(1)
|
||||||
coEvery { mobileDeviceDb.loadAll(1) } returnsMany listOf(
|
coEvery { mobileDeviceDb.loadAll(1) } returnsMany listOf(
|
||||||
@ -116,22 +130,27 @@ class MobileDeviceRepositoryTest {
|
|||||||
flowOf(remoteList.mapToEntities(student)), // after fetch end before save result
|
flowOf(remoteList.mapToEntities(student)), // after fetch end before save result
|
||||||
flowOf(remoteList.dropLast(1).mapToEntities(student))
|
flowOf(remoteList.dropLast(1).mapToEntities(student))
|
||||||
)
|
)
|
||||||
coEvery { mobileDeviceDb.insertAll(any()) } returns listOf(1, 2, 3)
|
coEvery { mobileDeviceDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { mobileDeviceDb.deleteAll(any()) } just Runs
|
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
val res = runBlocking { mobileDeviceRepository.getDevices(student, semester, true).toFirstResult() }
|
val res = mobileDeviceRepository.getDevices(
|
||||||
|
student = student,
|
||||||
|
semester = semester,
|
||||||
|
forceRefresh = true,
|
||||||
|
).toFirstResult()
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
Assert.assertEquals(null, res.errorOrNull)
|
Assert.assertEquals(null, res.errorOrNull)
|
||||||
Assert.assertEquals(1, res.dataOrNull?.size)
|
Assert.assertEquals(1, res.dataOrNull?.size)
|
||||||
coVerify { sdk.getRegisteredDevices() }
|
coVerify { sdk.getRegisteredDevices() }
|
||||||
coVerify { mobileDeviceDb.loadAll(1) }
|
coVerify { mobileDeviceDb.loadAll(1) }
|
||||||
coVerify { mobileDeviceDb.insertAll(match { it.isEmpty() }) }
|
|
||||||
coVerify {
|
coVerify {
|
||||||
mobileDeviceDb.deleteAll(match {
|
mobileDeviceDb.removeOldAndSaveNew(
|
||||||
it.size == 1 && it[0] == remoteList.mapToEntities(student)[1]
|
oldItems = match {
|
||||||
})
|
it.size == 1 && it[0] == remoteList.mapToEntities(student)[1]
|
||||||
|
},
|
||||||
|
newItems = match { it.isEmpty() },
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,12 @@ class RecipientLocalTest {
|
|||||||
@Test
|
@Test
|
||||||
fun `load recipients when items already in database`() {
|
fun `load recipients when items already in database`() {
|
||||||
// prepare
|
// prepare
|
||||||
coEvery { recipientDb.loadAll(io.github.wulkanowy.data.db.entities.MailboxType.UNKNOWN, "v4") } returnsMany listOf(
|
coEvery {
|
||||||
|
recipientDb.loadAll(
|
||||||
|
io.github.wulkanowy.data.db.entities.MailboxType.UNKNOWN,
|
||||||
|
"v4"
|
||||||
|
)
|
||||||
|
} returnsMany listOf(
|
||||||
remoteList.mapToEntities("v4"),
|
remoteList.mapToEntities("v4"),
|
||||||
remoteList.mapToEntities("v4")
|
remoteList.mapToEntities("v4")
|
||||||
)
|
)
|
||||||
@ -108,8 +113,7 @@ class RecipientLocalTest {
|
|||||||
emptyList(),
|
emptyList(),
|
||||||
remoteList.mapToEntities("v4")
|
remoteList.mapToEntities("v4")
|
||||||
)
|
)
|
||||||
coEvery { recipientDb.insertAll(any()) } returns listOf(1, 2, 3)
|
coEvery { recipientDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { recipientDb.deleteAll(any()) } just Runs
|
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
val res = runBlocking {
|
val res = runBlocking {
|
||||||
@ -123,8 +127,12 @@ class RecipientLocalTest {
|
|||||||
// verify
|
// verify
|
||||||
assertEquals(3, res.size)
|
assertEquals(3, res.size)
|
||||||
coVerify { sdk.getRecipients("v4") }
|
coVerify { sdk.getRecipients("v4") }
|
||||||
coVerify { recipientDb.loadAll(io.github.wulkanowy.data.db.entities.MailboxType.UNKNOWN, "v4") }
|
coVerify {
|
||||||
coVerify { recipientDb.insertAll(match { it.isEmpty() }) }
|
recipientDb.loadAll(
|
||||||
coVerify { recipientDb.deleteAll(match { it.isEmpty() }) }
|
io.github.wulkanowy.data.db.entities.MailboxType.UNKNOWN,
|
||||||
|
"v4"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
coVerify { recipientDb.removeOldAndSaveNew(match { it.isEmpty() }, match { it.isEmpty() }) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,13 +50,16 @@ class SemesterRepositoryTest {
|
|||||||
|
|
||||||
coEvery { semesterDb.loadAll(student.studentId, student.classId) } returns emptyList()
|
coEvery { semesterDb.loadAll(student.studentId, student.classId) } returns emptyList()
|
||||||
coEvery { sdk.getSemesters() } returns semesters
|
coEvery { sdk.getSemesters() } returns semesters
|
||||||
coEvery { semesterDb.deleteAll(any()) } just Runs
|
coEvery { semesterDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { semesterDb.insertSemesters(any()) } returns emptyList()
|
|
||||||
|
|
||||||
runBlocking { semesterRepository.getSemesters(student) }
|
runBlocking { semesterRepository.getSemesters(student) }
|
||||||
|
|
||||||
coVerify { semesterDb.insertSemesters(semesters.mapToEntities(student.studentId)) }
|
coVerify {
|
||||||
coVerify { semesterDb.deleteAll(emptyList()) }
|
semesterDb.removeOldAndSaveNew(
|
||||||
|
oldItems = emptyList(),
|
||||||
|
newItems = semesters.mapToEntities(student.studentId),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -71,12 +74,17 @@ class SemesterRepositoryTest {
|
|||||||
getSemesterPojo(123, 2, now().minusMonths(3), now())
|
getSemesterPojo(123, 2, now().minusMonths(3), now())
|
||||||
)
|
)
|
||||||
|
|
||||||
coEvery { semesterDb.loadAll(student.studentId, student.classId) } returns badSemesters.mapToEntities(student.studentId)
|
coEvery {
|
||||||
|
semesterDb.loadAll(
|
||||||
|
student.studentId,
|
||||||
|
student.classId
|
||||||
|
)
|
||||||
|
} returns badSemesters.mapToEntities(student.studentId)
|
||||||
coEvery { sdk.getSemesters() } returns goodSemesters
|
coEvery { sdk.getSemesters() } returns goodSemesters
|
||||||
coEvery { semesterDb.deleteAll(any()) } just Runs
|
coEvery { semesterDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { semesterDb.insertSemesters(any()) } returns listOf()
|
|
||||||
|
|
||||||
val items = runBlocking { semesterRepository.getSemesters(student.copy(loginMode = Sdk.Mode.HEBE.name)) }
|
val items =
|
||||||
|
runBlocking { semesterRepository.getSemesters(student.copy(loginMode = Sdk.Mode.HEBE.name)) }
|
||||||
assertEquals(2, items.size)
|
assertEquals(2, items.size)
|
||||||
assertEquals(0, items[0].diaryId)
|
assertEquals(0, items[0].diaryId)
|
||||||
}
|
}
|
||||||
@ -99,8 +107,7 @@ class SemesterRepositoryTest {
|
|||||||
goodSemesters.mapToEntities(student.studentId)
|
goodSemesters.mapToEntities(student.studentId)
|
||||||
)
|
)
|
||||||
coEvery { sdk.getSemesters() } returns goodSemesters
|
coEvery { sdk.getSemesters() } returns goodSemesters
|
||||||
coEvery { semesterDb.deleteAll(any()) } just Runs
|
coEvery { semesterDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { semesterDb.insertSemesters(any()) } returns listOf()
|
|
||||||
|
|
||||||
val items = semesterRepository.getSemesters(
|
val items = semesterRepository.getSemesters(
|
||||||
student = student.copy(loginMode = Sdk.Mode.SCRAPPER.name)
|
student = student.copy(loginMode = Sdk.Mode.SCRAPPER.name)
|
||||||
@ -157,13 +164,16 @@ class SemesterRepositoryTest {
|
|||||||
|
|
||||||
coEvery { semesterDb.loadAll(student.studentId, student.classId) } returns emptyList()
|
coEvery { semesterDb.loadAll(student.studentId, student.classId) } returns emptyList()
|
||||||
coEvery { sdk.getSemesters() } returns semesters
|
coEvery { sdk.getSemesters() } returns semesters
|
||||||
coEvery { semesterDb.deleteAll(any()) } just Runs
|
coEvery { semesterDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { semesterDb.insertSemesters(any()) } returns listOf()
|
|
||||||
|
|
||||||
runBlocking { semesterRepository.getSemesters(student, refreshOnNoCurrent = true) }
|
runBlocking { semesterRepository.getSemesters(student, refreshOnNoCurrent = true) }
|
||||||
|
|
||||||
coVerify { semesterDb.deleteAll(emptyList()) }
|
coVerify {
|
||||||
coVerify { semesterDb.insertSemesters(semesters.mapToEntities(student.studentId)) }
|
semesterDb.removeOldAndSaveNew(
|
||||||
|
oldItems = emptyList(),
|
||||||
|
newItems = semesters.mapToEntities(student.studentId),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -181,12 +191,17 @@ class SemesterRepositoryTest {
|
|||||||
getSemesterPojo(2, 2, now().plusMonths(5), now().plusMonths(11)),
|
getSemesterPojo(2, 2, now().plusMonths(5), now().plusMonths(11)),
|
||||||
)
|
)
|
||||||
|
|
||||||
coEvery { semesterDb.loadAll(student.studentId, student.classId) } returns semestersWithNoCurrent
|
coEvery {
|
||||||
|
semesterDb.loadAll(
|
||||||
|
student.studentId,
|
||||||
|
student.classId
|
||||||
|
)
|
||||||
|
} returns semestersWithNoCurrent
|
||||||
coEvery { sdk.getSemesters() } returns newSemesters
|
coEvery { sdk.getSemesters() } returns newSemesters
|
||||||
coEvery { semesterDb.deleteAll(any()) } just Runs
|
coEvery { semesterDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { semesterDb.insertSemesters(any()) } returns listOf()
|
|
||||||
|
|
||||||
val items = runBlocking { semesterRepository.getSemesters(student, refreshOnNoCurrent = true) }
|
val items =
|
||||||
|
runBlocking { semesterRepository.getSemesters(student, refreshOnNoCurrent = true) }
|
||||||
assertEquals(2, items.size)
|
assertEquals(2, items.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,8 +108,7 @@ class TimetableRepositoryTest {
|
|||||||
flowOf(remoteList.mapToEntities(semester)),
|
flowOf(remoteList.mapToEntities(semester)),
|
||||||
flowOf(remoteList.mapToEntities(semester))
|
flowOf(remoteList.mapToEntities(semester))
|
||||||
)
|
)
|
||||||
coEvery { timetableDb.insertAll(any()) } returns listOf(1, 2, 3)
|
coEvery { timetableDb.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { timetableDb.deleteAll(any()) } just Runs
|
|
||||||
|
|
||||||
coEvery {
|
coEvery {
|
||||||
timetableAdditionalDao.loadAll(
|
timetableAdditionalDao.loadAll(
|
||||||
@ -119,12 +118,10 @@ class TimetableRepositoryTest {
|
|||||||
end = endDate
|
end = endDate
|
||||||
)
|
)
|
||||||
} returns flowOf(listOf())
|
} returns flowOf(listOf())
|
||||||
coEvery { timetableAdditionalDao.deleteAll(emptyList()) } just Runs
|
coEvery { timetableAdditionalDao.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { timetableAdditionalDao.insertAll(emptyList()) } returns listOf(1, 2, 3)
|
|
||||||
|
|
||||||
coEvery { timetableHeaderDao.loadAll(1, 1, startDate, endDate) } returns flowOf(listOf())
|
coEvery { timetableHeaderDao.loadAll(1, 1, startDate, endDate) } returns flowOf(listOf())
|
||||||
coEvery { timetableHeaderDao.insertAll(emptyList()) } returns listOf(1, 2, 3)
|
coEvery { timetableHeaderDao.removeOldAndSaveNew(any(), any()) } just Runs
|
||||||
coEvery { timetableHeaderDao.deleteAll(emptyList()) } just Runs
|
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
val res = runBlocking {
|
val res = runBlocking {
|
||||||
@ -142,8 +139,12 @@ class TimetableRepositoryTest {
|
|||||||
assertEquals(2, res.dataOrNull!!.lessons.size)
|
assertEquals(2, res.dataOrNull!!.lessons.size)
|
||||||
coVerify { sdk.getTimetable(startDate, endDate) }
|
coVerify { sdk.getTimetable(startDate, endDate) }
|
||||||
coVerify { timetableDb.loadAll(1, 1, startDate, endDate) }
|
coVerify { timetableDb.loadAll(1, 1, startDate, endDate) }
|
||||||
coVerify { timetableDb.insertAll(match { it.isEmpty() }) }
|
coVerify {
|
||||||
coVerify { timetableDb.deleteAll(match { it.isEmpty() }) }
|
timetableDb.removeOldAndSaveNew(
|
||||||
|
oldItems = match { it.isEmpty() },
|
||||||
|
newItems = match { it.isEmpty() },
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createTimetableRemote(
|
private fun createTimetableRemote(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user