Fix more than one current semester in database (#304)

This commit is contained in:
Rafał Borcz 2019-03-24 20:21:05 +01:00 committed by Mikołaj Pich
parent 3656d3161f
commit ed9458d9a5
13 changed files with 138 additions and 32 deletions

View File

@ -1,8 +1,8 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy.IGNORE
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Semester
import io.reactivex.Maybe
@ -12,15 +12,12 @@ import javax.inject.Singleton
@Dao
interface SemesterDao {
@Insert(onConflict = IGNORE)
@Insert
fun insertAll(semester: List<Semester>)
@Delete
fun deleteAll(semester: List<Semester>)
@Query("SELECT * FROM Semesters WHERE student_id = :studentId")
fun loadAll(studentId: Int): Maybe<List<Semester>>
@Query("UPDATE Semesters SET is_current = 1 WHERE semester_id = :semesterId AND diary_id = :diaryId")
fun updateCurrent(semesterId: Int, diaryId: Int)
@Query("UPDATE Semesters SET is_current = 0 WHERE student_id = :studentId")
fun resetCurrent(studentId: Int)
}

View File

@ -11,17 +11,14 @@ import javax.inject.Singleton
class SemesterLocal @Inject constructor(private val semesterDb: SemesterDao) {
fun saveSemesters(semesters: List<Semester>) {
return semesterDb.insertAll(semesters)
semesterDb.insertAll(semesters)
}
fun deleteSemesters(semesters: List<Semester>) {
semesterDb.deleteAll(semesters)
}
fun getSemesters(student: Student): Maybe<List<Semester>> {
return semesterDb.loadAll(student.studentId).filter { !it.isEmpty() }
}
fun setCurrentSemester(semester: Semester) {
semesterDb.run {
resetCurrent(semester.studentId)
updateCurrent(semester.semesterId, semester.diaryId)
}
}
}

View File

@ -7,6 +7,7 @@ import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.reactivex.Maybe
import io.reactivex.Single
import timber.log.Timber
import java.net.UnknownHostException
import javax.inject.Inject
import javax.inject.Singleton
@ -25,10 +26,17 @@ class SemesterRepository @Inject constructor(
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getSemesters(student) else Single.error(UnknownHostException())
}.map { newSemesters ->
local.apply {
saveSemesters(newSemesters)
setCurrentSemester(newSemesters.single { it.isCurrent })
}.flatMap { new ->
val currentSemesters = new.filter { it.isCurrent }
if (currentSemesters.size == 1) {
local.getSemesters(student).toSingle(emptyList())
.doOnSuccess { old ->
local.deleteSemesters(old - new)
local.saveSemesters(new - old)
}
} else {
Timber.i("Current semesters list:\n${currentSemesters.joinToString(separator = "\n")}")
throw IllegalArgumentException("Current semester can be only one.")
}
}.flatMap { local.getSemesters(student).toSingle(emptyList()) })
}

View File

@ -0,0 +1,19 @@
package io.github.wulkanowy.data.repositories
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingStrategy
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.error.ErrorHandler
import io.reactivex.Observable
import io.reactivex.Single
class UnitTestInternetObservingStrategy : InternetObservingStrategy {
override fun checkInternetConnectivity(host: String?, port: Int, timeoutInMs: Int, httpResponse: Int, errorHandler: ErrorHandler?): Single<Boolean> {
return Single.just(true)
}
override fun observeInternetConnectivity(initialIntervalInMs: Int, intervalInMs: Int, host: String?, port: Int, timeoutInMs: Int, httpResponse: Int, errorHandler: ErrorHandler?): Observable<Boolean> {
return Observable.just(true)
}
override fun getDefaultPingHost() = "localhost"
}

View File

@ -1,9 +1,8 @@
package io.github.wulkanowy.data.repositories.remote
package io.github.wulkanowy.data.repositories.attendance
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.api.attendance.Attendance
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.repositories.attendance.AttendanceRemote
import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.impl.annotations.MockK

View File

@ -1,9 +1,8 @@
package io.github.wulkanowy.data.repositories.remote
package io.github.wulkanowy.data.repositories.completedlessons
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.api.timetable.CompletedLesson
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.repositories.completedlessons.CompletedLessonsRemote
import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.impl.annotations.MockK

View File

@ -1,9 +1,8 @@
package io.github.wulkanowy.data.repositories.remote
package io.github.wulkanowy.data.repositories.exam
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.api.exams.Exam
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.repositories.exam.ExamRemote
import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.impl.annotations.MockK

View File

@ -1,9 +1,8 @@
package io.github.wulkanowy.data.repositories.remote
package io.github.wulkanowy.data.repositories.gradestatistics
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.api.grades.GradeStatistics
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.repositories.gradestatistics.GradeStatisticsRemote
import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.impl.annotations.MockK

View File

@ -1,4 +1,4 @@
package io.github.wulkanowy.data.repositories.remote
package io.github.wulkanowy.data.repositories.luckynumber
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.entities.Semester

View File

@ -0,0 +1,74 @@
package io.github.wulkanowy.data.repositories.semester
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.ApiHelper
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.UnitTestInternetObservingStrategy
import io.reactivex.Maybe
import io.reactivex.Single
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
import org.mockito.Mockito.doNothing
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
class SemesterRepositoryTest {
@Mock
private lateinit var semesterRemote: SemesterRemote
@Mock
private lateinit var semesterLocal: SemesterLocal
@Mock
private lateinit var apiHelper: ApiHelper
@Mock
private lateinit var student: Student
private lateinit var semesterRepository: SemesterRepository
private val settings = InternetObservingSettings.builder()
.strategy(UnitTestInternetObservingStrategy())
.build()
@Before
fun initTest() {
MockitoAnnotations.initMocks(this)
semesterRepository = SemesterRepository(semesterRemote, semesterLocal, settings, apiHelper)
}
@Test
fun singleCurrentSemesterTest() {
val semesters = listOf(
createSemesterEntity(false),
createSemesterEntity(true)
)
doNothing().`when`(apiHelper).initApi(student)
doReturn(Maybe.empty<Semester>()).`when`(semesterLocal).getSemesters(student)
doReturn(Single.just(semesters)).`when`(semesterRemote).getSemesters(student)
semesterRepository.getSemesters(student).blockingGet()
verify(semesterLocal).deleteSemesters(emptyList())
verify(semesterLocal).saveSemesters(semesters)
}
@Test(expected = IllegalArgumentException::class)
fun twoCurrentSemesterTest() {
val semesters = listOf(
createSemesterEntity(true),
createSemesterEntity(true)
)
doNothing().`when`(apiHelper).initApi(student)
doReturn(Maybe.empty<Semester>()).`when`(semesterLocal).getSemesters(student)
doReturn(Single.just(semesters)).`when`(semesterRemote).getSemesters(student)
semesterRepository.getSemesters(student).blockingGet()
}
}

View File

@ -0,0 +1,16 @@
package io.github.wulkanowy.data.repositories.semester
import io.github.wulkanowy.data.db.entities.Semester
fun createSemesterEntity(current: Boolean): Semester {
return Semester(
studentId = 0,
diaryId = 0,
semesterId = 0,
diaryName = "",
classId = 0,
isCurrent = current,
semesterName = 0,
unitId = 0
)
}

View File

@ -1,8 +1,7 @@
package io.github.wulkanowy.data.repositories.remote
package io.github.wulkanowy.data.repositories.student
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.api.register.Student
import io.github.wulkanowy.data.repositories.student.StudentRemote
import io.reactivex.Single
import org.junit.Assert.assertEquals
import org.junit.Before

View File

@ -1,4 +1,4 @@
package io.github.wulkanowy.data.repositories.remote
package io.github.wulkanowy.data.repositories.timetable
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.api.timetable.Timetable