Fix no current student (#243)

This commit is contained in:
Rafał Borcz 2019-02-13 20:49:19 +01:00 committed by Mikołaj Pich
parent 297502056c
commit ad9b6d42f0
11 changed files with 45 additions and 49 deletions

View File

@ -73,7 +73,7 @@ play {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
implementation('com.github.wulkanowy:api:0bbd246778') { exclude module: "threetenbp" }
implementation('com.github.wulkanowy:api:0a4317f651') { exclude module: "threetenbp" }
implementation "androidx.legacy:legacy-support-v4:1.0.0"
implementation "androidx.appcompat:appcompat:1.0.2"

View File

@ -28,7 +28,7 @@ class StudentLocalTest {
testDb = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java)
.build()
sharedHelper = SharedPrefHelper(context.getSharedPreferences("TEST", Context.MODE_PRIVATE))
studentLocal = StudentLocal(testDb.studentDao, sharedHelper, context)
studentLocal = StudentLocal(testDb.studentDao, context)
}
@After
@ -40,7 +40,6 @@ class StudentLocalTest {
fun saveAndReadTest() {
studentLocal.saveStudent(Student(email = "test", password = "test123", schoolSymbol = "23", endpoint = "fakelog.cf", loginType = "AUTO", isCurrent = true))
.blockingGet()
assert(studentLocal.isStudentSaved)
val student = studentLocal.getCurrentStudent(true).blockingGet()
assertEquals("23", student.schoolSymbol)

View File

@ -19,14 +19,6 @@ class SharedPrefHelper @Inject constructor(private val sharedPref: SharedPrefere
return sharedPref.getLong(key, defaultValue)
}
fun putBoolean(key: String, value: Boolean) {
sharedPref.edit().putBoolean(key, value).apply()
}
fun getBoolean(key: String, defaultValue: Boolean): Boolean {
return sharedPref.getBoolean(key, defaultValue)
}
fun delete(key: String) {
sharedPref.edit().remove(key).apply()
}

View File

@ -3,7 +3,7 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy.FAIL
import androidx.room.OnConflictStrategy.ABORT
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Student
import io.reactivex.Maybe
@ -13,7 +13,7 @@ import javax.inject.Singleton
@Dao
interface StudentDao {
@Insert(onConflict = FAIL)
@Insert(onConflict = ABORT)
fun insert(student: Student): Long
@Delete

View File

@ -21,8 +21,7 @@ class StudentRepository @Inject constructor(
private val apiHelper: ApiHelper
) {
val isStudentSaved
get() = local.isStudentSaved
fun isStudentSaved(): Single<Boolean> = local.getStudents(false).isEmpty.map { !it }
fun getStudents(email: String, password: String, endpoint: String, symbol: String = ""): Single<List<Student>> {
return ReactiveNetwork.checkInternetConnectivity(settings)

View File

@ -1,7 +1,6 @@
package io.github.wulkanowy.data.repositories.local
import android.content.Context
import io.github.wulkanowy.data.db.SharedPrefHelper
import io.github.wulkanowy.data.db.dao.StudentDao
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.utils.security.decrypt
@ -15,25 +14,17 @@ import javax.inject.Singleton
@Singleton
class StudentLocal @Inject constructor(
private val studentDb: StudentDao,
private val sharedPref: SharedPrefHelper,
private val context: Context
) {
companion object {
const val STUDENT_SAVED_KEY: String = "is_student_saved"
}
val isStudentSaved
get() = sharedPref.getBoolean(STUDENT_SAVED_KEY, false)
fun saveStudent(student: Student): Single<Long> {
return Single.fromCallable { studentDb.insert(student.copy(password = encrypt(student.password, context))) }
.doOnSuccess { sharedPref.putBoolean(STUDENT_SAVED_KEY, true) }
}
fun getStudents(decryptPass: Boolean): Maybe<List<Student>> {
return studentDb.loadAll()
.map { list -> list.map { it.apply { if (decryptPass) password = decrypt(password) } } }
.filter { !it.isEmpty() }
}
fun getCurrentStudent(decryptPass: Boolean): Maybe<Student> {
@ -46,13 +37,10 @@ class StudentLocal @Inject constructor(
resetCurrent()
updateCurrent(student.studentId)
}
}.doOnComplete { sharedPref.putBoolean(STUDENT_SAVED_KEY, true) }
}
}
fun logoutStudent(student: Student): Completable {
return Completable.fromCallable {
studentDb.delete(student)
if (student.isCurrent) sharedPref.putBoolean(STUDENT_SAVED_KEY, false)
}
return Completable.fromCallable { studentDb.delete(student) }
}
}

View File

@ -25,6 +25,7 @@ import io.github.wulkanowy.utils.friday
import io.github.wulkanowy.utils.isHolidays
import io.github.wulkanowy.utils.monday
import io.reactivex.Completable
import io.reactivex.Maybe
import io.reactivex.disposables.CompositeDisposable
import org.threeten.bp.LocalDate
import timber.log.Timber
@ -89,14 +90,14 @@ class SyncWorker : SimpleJobService() {
val end = LocalDate.now().friday
if (start.isHolidays) return RESULT_FAIL_NORETRY
if (!student.isStudentSaved) return RESULT_FAIL_RETRY
var error: Throwable? = null
val notify = prefRepository.isNotificationsEnable
disposable.add(student.getCurrentStudent()
.flatMap { semester.getCurrentSemester(it, true).map { semester -> semester to it } }
disposable.add(student.isStudentSaved()
.flatMapMaybe { if (it) student.getCurrentStudent().toMaybe() else Maybe.empty() }
.flatMap { semester.getCurrentSemester(it, true).map { semester -> semester to it }.toMaybe() }
.flatMapCompletable {
Completable.merge(
listOf(

View File

@ -1,6 +1,8 @@
package io.github.wulkanowy.ui.modules.splash
import android.os.Bundle
import android.widget.Toast
import android.widget.Toast.LENGTH_LONG
import io.github.wulkanowy.ui.base.BaseActivity
import io.github.wulkanowy.ui.modules.login.LoginActivity
import io.github.wulkanowy.ui.modules.main.MainActivity
@ -26,6 +28,10 @@ class SplashActivity : BaseActivity(), SplashView {
finish()
}
override fun showError(text: String, error: Throwable) {
Toast.makeText(this, text, LENGTH_LONG).show()
}
override fun onDestroy() {
presenter.onDetachView()
super.onDestroy()

View File

@ -3,18 +3,25 @@ package io.github.wulkanowy.ui.modules.splash
import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.utils.SchedulersProvider
import javax.inject.Inject
class SplashPresenter @Inject constructor(
private val studentRepository: StudentRepository,
errorHandler: ErrorHandler
private val errorHandler: ErrorHandler,
private val schedulers: SchedulersProvider
) : BasePresenter<SplashView>(errorHandler) {
override fun onAttachView(view: SplashView) {
super.onAttachView(view)
view.run {
if (studentRepository.isStudentSaved) openMainView()
else openLoginView()
}
disposable.add(studentRepository.isStudentSaved()
.subscribeOn(schedulers.backgroundThread)
.observeOn(schedulers.mainThread)
.subscribe({
view.apply {
if (it) openMainView()
else openLoginView()
}
}, { errorHandler.dispatch(it) }))
}
}

View File

@ -16,6 +16,7 @@ import io.github.wulkanowy.data.repositories.SemesterRepository
import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.data.repositories.TimetableRepository
import io.github.wulkanowy.utils.toFormattedString
import io.reactivex.Single
import io.reactivex.disposables.CompositeDisposable
import org.threeten.bp.LocalDate
import timber.log.Timber
@ -48,14 +49,15 @@ class TimetableWidgetFactory(
override fun onDataSetChanged() {
intent?.action?.let { LocalDate.ofEpochDay(sharedPref.getLong(it, 0)) }
?.let { date ->
if (studentRepository.isStudentSaved) {
disposable.add(studentRepository.getCurrentStudent()
.flatMap { semesterRepository.getCurrentSemester(it) }
.flatMap { timetableRepository.getTimetable(it, date, date) }
.map { item -> item.sortedBy { it.number } }
.subscribe({ lessons = it })
{ Timber.e(it, "An error has occurred while downloading data for the widget") })
}
disposable.add(studentRepository.isStudentSaved()
.flatMap {
if (it) studentRepository.getCurrentStudent()
else Single.error(IllegalArgumentException("No saved students"))
}.flatMap { semesterRepository.getCurrentSemester(it) }
.flatMap { timetableRepository.getTimetable(it, date, date) }
.map { item -> item.sortedBy { it.number } }
.subscribe({ lessons = it })
{ Timber.e(it, "An error has occurred while downloading data for the widget") })
}
}

View File

@ -1,7 +1,9 @@
package io.github.wulkanowy.ui.modules.splash
import io.github.wulkanowy.TestSchedulersProvider
import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.ui.base.ErrorHandler
import io.reactivex.Single
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
@ -25,19 +27,19 @@ class SplashPresenterTest {
@Before
fun initPresenter() {
MockitoAnnotations.initMocks(this)
presenter = SplashPresenter(studentRepository, errorHandler)
presenter = SplashPresenter(studentRepository, errorHandler, TestSchedulersProvider())
}
@Test
fun testOpenLoginView() {
doReturn(false).`when`(studentRepository).isStudentSaved
doReturn(Single.just(false)).`when`(studentRepository).isStudentSaved()
presenter.onAttachView(splashView)
verify(splashView).openLoginView()
}
@Test
fun testMainMainView() {
doReturn(true).`when`(studentRepository).isStudentSaved
doReturn(Single.just(true)).`when`(studentRepository).isStudentSaved()
presenter.onAttachView(splashView)
verify(splashView).openMainView()
}