From ad9b6d42f0d2bf8f5972eb8bb7e3bd692fc4ff0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Borcz?= Date: Wed, 13 Feb 2019 20:49:19 +0100 Subject: [PATCH] Fix no current student (#243) --- app/build.gradle | 2 +- .../repositories/local/StudentLocalTest.kt | 3 +-- .../wulkanowy/data/db/SharedPrefHelper.kt | 8 -------- .../github/wulkanowy/data/db/dao/StudentDao.kt | 4 ++-- .../data/repositories/StudentRepository.kt | 3 +-- .../data/repositories/local/StudentLocal.kt | 18 +++--------------- .../wulkanowy/services/job/SyncWorker.kt | 7 ++++--- .../ui/modules/splash/SplashActivity.kt | 6 ++++++ .../ui/modules/splash/SplashPresenter.kt | 17 ++++++++++++----- .../timetable/TimetableWidgetFactory.kt | 18 ++++++++++-------- .../ui/modules/splash/SplashPresenterTest.kt | 8 +++++--- 11 files changed, 45 insertions(+), 49 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 6e3911fe..6e9b6ffa 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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" diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/local/StudentLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/local/StudentLocalTest.kt index 732dc5bc..3d442711 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/local/StudentLocalTest.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/local/StudentLocalTest.kt @@ -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) diff --git a/app/src/main/java/io/github/wulkanowy/data/db/SharedPrefHelper.kt b/app/src/main/java/io/github/wulkanowy/data/db/SharedPrefHelper.kt index 656b39d4..b3b6f5e3 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/SharedPrefHelper.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/SharedPrefHelper.kt @@ -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() } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/StudentDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/StudentDao.kt index 76e29539..c0c054c8 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/StudentDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/StudentDao.kt @@ -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 diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/StudentRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/StudentRepository.kt index 57f9a3cd..dc421d99 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/StudentRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/StudentRepository.kt @@ -21,8 +21,7 @@ class StudentRepository @Inject constructor( private val apiHelper: ApiHelper ) { - val isStudentSaved - get() = local.isStudentSaved + fun isStudentSaved(): Single = local.getStudents(false).isEmpty.map { !it } fun getStudents(email: String, password: String, endpoint: String, symbol: String = ""): Single> { return ReactiveNetwork.checkInternetConnectivity(settings) diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/local/StudentLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/local/StudentLocal.kt index 0e4e9cbd..29ca43fe 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/local/StudentLocal.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/local/StudentLocal.kt @@ -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 { return Single.fromCallable { studentDb.insert(student.copy(password = encrypt(student.password, context))) } - .doOnSuccess { sharedPref.putBoolean(STUDENT_SAVED_KEY, true) } } fun getStudents(decryptPass: Boolean): Maybe> { return studentDb.loadAll() .map { list -> list.map { it.apply { if (decryptPass) password = decrypt(password) } } } + .filter { !it.isEmpty() } } fun getCurrentStudent(decryptPass: Boolean): Maybe { @@ -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) } } } diff --git a/app/src/main/java/io/github/wulkanowy/services/job/SyncWorker.kt b/app/src/main/java/io/github/wulkanowy/services/job/SyncWorker.kt index a5fd754e..c3818560 100644 --- a/app/src/main/java/io/github/wulkanowy/services/job/SyncWorker.kt +++ b/app/src/main/java/io/github/wulkanowy/services/job/SyncWorker.kt @@ -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( diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashActivity.kt index 223d7abe..2bd62533 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashActivity.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashActivity.kt @@ -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() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashPresenter.kt index 5f8ba16e..4c3b240c 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashPresenter.kt @@ -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(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) })) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetFactory.kt b/app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetFactory.kt index fecdc42e..21b41c2e 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetFactory.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetFactory.kt @@ -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") }) } } diff --git a/app/src/test/java/io/github/wulkanowy/ui/modules/splash/SplashPresenterTest.kt b/app/src/test/java/io/github/wulkanowy/ui/modules/splash/SplashPresenterTest.kt index ee4b17cf..28ab5f43 100644 --- a/app/src/test/java/io/github/wulkanowy/ui/modules/splash/SplashPresenterTest.kt +++ b/app/src/test/java/io/github/wulkanowy/ui/modules/splash/SplashPresenterTest.kt @@ -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() }