Fix login process after was interrupted (#1505)

This commit is contained in:
Rafał Borcz 2021-09-13 14:36:31 +02:00 committed by GitHub
parent 19c96ee83f
commit 827fb33eeb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 76 additions and 76 deletions

View File

@ -14,33 +14,39 @@ import javax.inject.Singleton
@Singleton @Singleton
@Dao @Dao
interface StudentDao { abstract class StudentDao {
@Insert(onConflict = ABORT) @Insert(onConflict = ABORT)
suspend fun insertAll(student: List<Student>): List<Long> abstract suspend fun insertAll(student: List<Student>): List<Long>
@Delete @Delete
suspend fun delete(student: Student) abstract suspend fun delete(student: Student)
@Update(entity = Student::class) @Update(entity = Student::class)
suspend fun update(studentNickAndAvatar: StudentNickAndAvatar) abstract suspend fun update(studentNickAndAvatar: StudentNickAndAvatar)
@Query("SELECT * FROM Students WHERE is_current = 1") @Query("SELECT * FROM Students WHERE is_current = 1")
suspend fun loadCurrent(): Student? abstract suspend fun loadCurrent(): Student?
@Query("SELECT * FROM Students WHERE id = :id") @Query("SELECT * FROM Students WHERE id = :id")
suspend fun loadById(id: Long): Student? abstract suspend fun loadById(id: Long): Student?
@Query("SELECT * FROM Students") @Query("SELECT * FROM Students")
suspend fun loadAll(): List<Student> abstract suspend fun loadAll(): List<Student>
@Transaction @Transaction
@Query("SELECT * FROM Students") @Query("SELECT * FROM Students")
suspend fun loadStudentsWithSemesters(): List<StudentWithSemesters> abstract suspend fun loadStudentsWithSemesters(): List<StudentWithSemesters>
@Query("UPDATE Students SET is_current = 1 WHERE id = :id") @Query("UPDATE Students SET is_current = 1 WHERE id = :id")
suspend fun updateCurrent(id: Long) abstract suspend fun updateCurrent(id: Long)
@Query("UPDATE Students SET is_current = 0") @Query("UPDATE Students SET is_current = 0")
suspend fun resetCurrent() abstract suspend fun resetCurrent()
@Transaction
open suspend fun switchCurrent(id: Long) {
resetCurrent()
updateCurrent(id)
}
} }

View File

@ -1,7 +1,9 @@
package io.github.wulkanowy.data.repositories package io.github.wulkanowy.data.repositories
import android.content.Context import android.content.Context
import androidx.room.withTransaction
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.dao.SemesterDao import io.github.wulkanowy.data.db.dao.SemesterDao
import io.github.wulkanowy.data.db.dao.StudentDao import io.github.wulkanowy.data.db.dao.StudentDao
import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Student
@ -25,7 +27,8 @@ class StudentRepository @Inject constructor(
private val studentDb: StudentDao, private val studentDb: StudentDao,
private val semesterDb: SemesterDao, private val semesterDb: SemesterDao,
private val sdk: Sdk, private val sdk: Sdk,
private val appInfo: AppInfo private val appInfo: AppInfo,
private val appDatabase: AppDatabase
) { ) {
suspend fun isStudentSaved() = getSavedStudents(false).isNotEmpty() suspend fun isStudentSaved() = getSavedStudents(false).isNotEmpty()
@ -92,7 +95,7 @@ class StudentRepository @Inject constructor(
return student return student
} }
suspend fun saveStudents(studentsWithSemesters: List<StudentWithSemesters>): List<Long> { suspend fun saveStudents(studentsWithSemesters: List<StudentWithSemesters>) {
val semesters = studentsWithSemesters.flatMap { it.semesters } val semesters = studentsWithSemesters.flatMap { it.semesters }
val students = studentsWithSemesters.map { it.student } val students = studentsWithSemesters.map { it.student }
.map { .map {
@ -104,16 +107,21 @@ class StudentRepository @Inject constructor(
} }
} }
} }
.mapIndexed { index, student ->
if (index == 0) {
student.copy(isCurrent = true).apply { avatarColor = student.avatarColor }
} else student
}
semesterDb.insertSemesters(semesters) appDatabase.withTransaction {
return studentDb.insertAll(students) studentDb.resetCurrent()
semesterDb.insertSemesters(semesters)
studentDb.insertAll(students)
}
} }
suspend fun switchStudent(studentWithSemesters: StudentWithSemesters) { suspend fun switchStudent(studentWithSemesters: StudentWithSemesters) {
with(studentDb) { studentDb.switchCurrent(studentWithSemesters.student.id)
resetCurrent()
updateCurrent(studentWithSemesters.student.id)
}
} }
suspend fun logoutStudent(student: Student) = studentDb.delete(student) suspend fun logoutStudent(student: Student) = studentDb.delete(student)

View File

@ -90,10 +90,10 @@ class LoginFormPresenter @Inject constructor(
flowWithResource { flowWithResource {
studentRepository.getStudentsScrapper( studentRepository.getStudentsScrapper(
email, email = email,
password, password = password,
host, scrapperBaseUrl = host,
symbol symbol = symbol
) )
}.onEach { }.onEach {
when (it.status) { when (it.status) {

View File

@ -78,7 +78,9 @@ class LoginStudentSelectPresenter @Inject constructor(
when (it.status) { when (it.status) {
Status.LOADING -> Timber.d("Login student select students load started") Status.LOADING -> Timber.d("Login student select students load started")
Status.SUCCESS -> view?.updateData(studentsWithSemesters.map { studentWithSemesters -> Status.SUCCESS -> view?.updateData(studentsWithSemesters.map { studentWithSemesters ->
studentWithSemesters to it.data!!.any { item -> compareStudents(studentWithSemesters.student, item.student) } studentWithSemesters to it.data!!.any { item ->
compareStudents(studentWithSemesters.student, item.student)
}
}) })
Status.ERROR -> { Status.ERROR -> {
errorHandler.dispatch(it.error!!) errorHandler.dispatch(it.error!!)
@ -95,35 +97,32 @@ class LoginStudentSelectPresenter @Inject constructor(
} }
private fun registerStudents(studentsWithSemesters: List<StudentWithSemesters>) { private fun registerStudents(studentsWithSemesters: List<StudentWithSemesters>) {
flowWithResource { flowWithResource { studentRepository.saveStudents(studentsWithSemesters) }
val savedStudents = studentRepository.saveStudents(studentsWithSemesters) .onEach {
val firstRegistered = studentsWithSemesters.first().apply { student.id = savedStudents.first() } when (it.status) {
studentRepository.switchStudent(firstRegistered) Status.LOADING -> view?.run {
}.onEach { Timber.i("Registration started")
when (it.status) { showProgress(true)
Status.LOADING -> view?.run { showContent(false)
Timber.i("Registration started") }
showProgress(true) Status.SUCCESS -> {
showContent(false) Timber.i("Registration result: Success")
} view?.openMainView()
Status.SUCCESS -> { logRegisterEvent(studentsWithSemesters)
Timber.i("Registration result: Success") }
view?.openMainView() Status.ERROR -> {
logRegisterEvent(studentsWithSemesters) Timber.i("Registration result: An exception occurred ")
} view?.apply {
Status.ERROR -> { showProgress(false)
Timber.i("Registration result: An exception occurred ") showContent(true)
view?.apply { showContact(true)
showProgress(false) }
showContent(true) lastError = it.error
showContact(true) loginErrorHandler.dispatch(it.error!!)
logRegisterEvent(studentsWithSemesters, it.error)
} }
lastError = it.error
loginErrorHandler.dispatch(it.error!!)
logRegisterEvent(studentsWithSemesters, it.error)
} }
} }.launch("register")
}.launch("register")
} }
fun onDiscordClick() { fun onDiscordClick() {
@ -134,7 +133,10 @@ class LoginStudentSelectPresenter @Inject constructor(
view?.openEmail(lastError?.message.ifNullOrBlank { "empty" }) view?.openEmail(lastError?.message.ifNullOrBlank { "empty" })
} }
private fun logRegisterEvent(studentsWithSemesters: List<StudentWithSemesters>, error: Throwable? = null) { private fun logRegisterEvent(
studentsWithSemesters: List<StudentWithSemesters>,
error: Throwable? = null
) {
studentsWithSemesters.forEach { student -> studentsWithSemesters.forEach { student ->
analytics.logEvent( analytics.logEvent(
"registration_student_select", "registration_student_select",

View File

@ -37,7 +37,8 @@ class StudentTest {
studentDb, studentDb,
semesterDb, semesterDb,
mockSdk, mockSdk,
AppInfo() AppInfo(),
mockk()
) )
} }

View File

@ -89,24 +89,11 @@ class LoginStudentSelectPresenterTest {
@Test @Test
fun onSelectedStudentTest() { fun onSelectedStudentTest() {
coEvery { coEvery {
studentRepository.saveStudents( studentRepository.saveStudents(listOf(StudentWithSemesters(testStudent, emptyList())))
listOf(
StudentWithSemesters(
testStudent,
emptyList()
)
)
)
} returns listOf(1L)
coEvery {
studentRepository.switchStudent(
StudentWithSemesters(
testStudent,
emptyList()
)
)
} just Runs } just Runs
every { loginStudentSelectView.openMainView() } just Runs every { loginStudentSelectView.openMainView() } just Runs
presenter.onItemSelected(StudentWithSemesters(testStudent, emptyList()), false) presenter.onItemSelected(StudentWithSemesters(testStudent, emptyList()), false)
presenter.onSignIn() presenter.onSignIn()
@ -118,18 +105,14 @@ class LoginStudentSelectPresenterTest {
@Test @Test
fun onSelectedStudentErrorTest() { fun onSelectedStudentErrorTest() {
coEvery { coEvery {
studentRepository.saveStudents( studentRepository.saveStudents(listOf(StudentWithSemesters(testStudent, emptyList())))
listOf(
StudentWithSemesters(
testStudent,
emptyList()
)
)
)
} throws testException } throws testException
coEvery { studentRepository.logoutStudent(testStudent) } just Runs coEvery { studentRepository.logoutStudent(testStudent) } just Runs
presenter.onItemSelected(StudentWithSemesters(testStudent, emptyList()), false) presenter.onItemSelected(StudentWithSemesters(testStudent, emptyList()), false)
presenter.onSignIn() presenter.onSignIn()
verify { loginStudentSelectView.showContent(false) } verify { loginStudentSelectView.showContent(false) }
verify { loginStudentSelectView.showProgress(true) } verify { loginStudentSelectView.showProgress(true) }
verify { errorHandler.dispatch(match { testException.message == it.message }) } verify { errorHandler.dispatch(match { testException.message == it.message }) }