forked from github/wulkanowy-mirror
Fix no current student (#243)
This commit is contained in:
parent
297502056c
commit
ad9b6d42f0
@ -73,7 +73,7 @@ play {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||||
implementation "org.jetbrains.kotlin:kotlin-reflect:$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.legacy:legacy-support-v4:1.0.0"
|
||||||
implementation "androidx.appcompat:appcompat:1.0.2"
|
implementation "androidx.appcompat:appcompat:1.0.2"
|
||||||
|
@ -28,7 +28,7 @@ class StudentLocalTest {
|
|||||||
testDb = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java)
|
testDb = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java)
|
||||||
.build()
|
.build()
|
||||||
sharedHelper = SharedPrefHelper(context.getSharedPreferences("TEST", Context.MODE_PRIVATE))
|
sharedHelper = SharedPrefHelper(context.getSharedPreferences("TEST", Context.MODE_PRIVATE))
|
||||||
studentLocal = StudentLocal(testDb.studentDao, sharedHelper, context)
|
studentLocal = StudentLocal(testDb.studentDao, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
@ -40,7 +40,6 @@ class StudentLocalTest {
|
|||||||
fun saveAndReadTest() {
|
fun saveAndReadTest() {
|
||||||
studentLocal.saveStudent(Student(email = "test", password = "test123", schoolSymbol = "23", endpoint = "fakelog.cf", loginType = "AUTO", isCurrent = true))
|
studentLocal.saveStudent(Student(email = "test", password = "test123", schoolSymbol = "23", endpoint = "fakelog.cf", loginType = "AUTO", isCurrent = true))
|
||||||
.blockingGet()
|
.blockingGet()
|
||||||
assert(studentLocal.isStudentSaved)
|
|
||||||
|
|
||||||
val student = studentLocal.getCurrentStudent(true).blockingGet()
|
val student = studentLocal.getCurrentStudent(true).blockingGet()
|
||||||
assertEquals("23", student.schoolSymbol)
|
assertEquals("23", student.schoolSymbol)
|
||||||
|
@ -19,14 +19,6 @@ class SharedPrefHelper @Inject constructor(private val sharedPref: SharedPrefere
|
|||||||
return sharedPref.getLong(key, defaultValue)
|
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) {
|
fun delete(key: String) {
|
||||||
sharedPref.edit().remove(key).apply()
|
sharedPref.edit().remove(key).apply()
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package io.github.wulkanowy.data.db.dao
|
|||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Delete
|
import androidx.room.Delete
|
||||||
import androidx.room.Insert
|
import androidx.room.Insert
|
||||||
import androidx.room.OnConflictStrategy.FAIL
|
import androidx.room.OnConflictStrategy.ABORT
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.reactivex.Maybe
|
import io.reactivex.Maybe
|
||||||
@ -13,7 +13,7 @@ import javax.inject.Singleton
|
|||||||
@Dao
|
@Dao
|
||||||
interface StudentDao {
|
interface StudentDao {
|
||||||
|
|
||||||
@Insert(onConflict = FAIL)
|
@Insert(onConflict = ABORT)
|
||||||
fun insert(student: Student): Long
|
fun insert(student: Student): Long
|
||||||
|
|
||||||
@Delete
|
@Delete
|
||||||
|
@ -21,8 +21,7 @@ class StudentRepository @Inject constructor(
|
|||||||
private val apiHelper: ApiHelper
|
private val apiHelper: ApiHelper
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val isStudentSaved
|
fun isStudentSaved(): Single<Boolean> = local.getStudents(false).isEmpty.map { !it }
|
||||||
get() = local.isStudentSaved
|
|
||||||
|
|
||||||
fun getStudents(email: String, password: String, endpoint: String, symbol: String = ""): Single<List<Student>> {
|
fun getStudents(email: String, password: String, endpoint: String, symbol: String = ""): Single<List<Student>> {
|
||||||
return ReactiveNetwork.checkInternetConnectivity(settings)
|
return ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package io.github.wulkanowy.data.repositories.local
|
package io.github.wulkanowy.data.repositories.local
|
||||||
|
|
||||||
import android.content.Context
|
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.dao.StudentDao
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.utils.security.decrypt
|
import io.github.wulkanowy.utils.security.decrypt
|
||||||
@ -15,25 +14,17 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class StudentLocal @Inject constructor(
|
class StudentLocal @Inject constructor(
|
||||||
private val studentDb: StudentDao,
|
private val studentDb: StudentDao,
|
||||||
private val sharedPref: SharedPrefHelper,
|
|
||||||
private val context: Context
|
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> {
|
fun saveStudent(student: Student): Single<Long> {
|
||||||
return Single.fromCallable { studentDb.insert(student.copy(password = encrypt(student.password, context))) }
|
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>> {
|
fun getStudents(decryptPass: Boolean): Maybe<List<Student>> {
|
||||||
return studentDb.loadAll()
|
return studentDb.loadAll()
|
||||||
.map { list -> list.map { it.apply { if (decryptPass) password = decrypt(password) } } }
|
.map { list -> list.map { it.apply { if (decryptPass) password = decrypt(password) } } }
|
||||||
|
.filter { !it.isEmpty() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCurrentStudent(decryptPass: Boolean): Maybe<Student> {
|
fun getCurrentStudent(decryptPass: Boolean): Maybe<Student> {
|
||||||
@ -46,13 +37,10 @@ class StudentLocal @Inject constructor(
|
|||||||
resetCurrent()
|
resetCurrent()
|
||||||
updateCurrent(student.studentId)
|
updateCurrent(student.studentId)
|
||||||
}
|
}
|
||||||
}.doOnComplete { sharedPref.putBoolean(STUDENT_SAVED_KEY, true) }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun logoutStudent(student: Student): Completable {
|
fun logoutStudent(student: Student): Completable {
|
||||||
return Completable.fromCallable {
|
return Completable.fromCallable { studentDb.delete(student) }
|
||||||
studentDb.delete(student)
|
|
||||||
if (student.isCurrent) sharedPref.putBoolean(STUDENT_SAVED_KEY, false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ import io.github.wulkanowy.utils.friday
|
|||||||
import io.github.wulkanowy.utils.isHolidays
|
import io.github.wulkanowy.utils.isHolidays
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
|
import io.reactivex.Maybe
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
import org.threeten.bp.LocalDate
|
import org.threeten.bp.LocalDate
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -89,14 +90,14 @@ class SyncWorker : SimpleJobService() {
|
|||||||
val end = LocalDate.now().friday
|
val end = LocalDate.now().friday
|
||||||
|
|
||||||
if (start.isHolidays) return RESULT_FAIL_NORETRY
|
if (start.isHolidays) return RESULT_FAIL_NORETRY
|
||||||
if (!student.isStudentSaved) return RESULT_FAIL_RETRY
|
|
||||||
|
|
||||||
var error: Throwable? = null
|
var error: Throwable? = null
|
||||||
|
|
||||||
val notify = prefRepository.isNotificationsEnable
|
val notify = prefRepository.isNotificationsEnable
|
||||||
|
|
||||||
disposable.add(student.getCurrentStudent()
|
disposable.add(student.isStudentSaved()
|
||||||
.flatMap { semester.getCurrentSemester(it, true).map { semester -> semester to it } }
|
.flatMapMaybe { if (it) student.getCurrentStudent().toMaybe() else Maybe.empty() }
|
||||||
|
.flatMap { semester.getCurrentSemester(it, true).map { semester -> semester to it }.toMaybe() }
|
||||||
.flatMapCompletable {
|
.flatMapCompletable {
|
||||||
Completable.merge(
|
Completable.merge(
|
||||||
listOf(
|
listOf(
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package io.github.wulkanowy.ui.modules.splash
|
package io.github.wulkanowy.ui.modules.splash
|
||||||
|
|
||||||
import android.os.Bundle
|
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.base.BaseActivity
|
||||||
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
@ -26,6 +28,10 @@ class SplashActivity : BaseActivity(), SplashView {
|
|||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun showError(text: String, error: Throwable) {
|
||||||
|
Toast.makeText(this, text, LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
presenter.onDetachView()
|
presenter.onDetachView()
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
|
@ -3,18 +3,25 @@ package io.github.wulkanowy.ui.modules.splash
|
|||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class SplashPresenter @Inject constructor(
|
class SplashPresenter @Inject constructor(
|
||||||
private val studentRepository: StudentRepository,
|
private val studentRepository: StudentRepository,
|
||||||
errorHandler: ErrorHandler
|
private val errorHandler: ErrorHandler,
|
||||||
|
private val schedulers: SchedulersProvider
|
||||||
) : BasePresenter<SplashView>(errorHandler) {
|
) : BasePresenter<SplashView>(errorHandler) {
|
||||||
|
|
||||||
override fun onAttachView(view: SplashView) {
|
override fun onAttachView(view: SplashView) {
|
||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
view.run {
|
disposable.add(studentRepository.isStudentSaved()
|
||||||
if (studentRepository.isStudentSaved) openMainView()
|
.subscribeOn(schedulers.backgroundThread)
|
||||||
|
.observeOn(schedulers.mainThread)
|
||||||
|
.subscribe({
|
||||||
|
view.apply {
|
||||||
|
if (it) openMainView()
|
||||||
else openLoginView()
|
else openLoginView()
|
||||||
}
|
}
|
||||||
|
}, { errorHandler.dispatch(it) }))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import io.github.wulkanowy.data.repositories.SemesterRepository
|
|||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
import io.github.wulkanowy.data.repositories.TimetableRepository
|
import io.github.wulkanowy.data.repositories.TimetableRepository
|
||||||
import io.github.wulkanowy.utils.toFormattedString
|
import io.github.wulkanowy.utils.toFormattedString
|
||||||
|
import io.reactivex.Single
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
import org.threeten.bp.LocalDate
|
import org.threeten.bp.LocalDate
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -48,16 +49,17 @@ class TimetableWidgetFactory(
|
|||||||
override fun onDataSetChanged() {
|
override fun onDataSetChanged() {
|
||||||
intent?.action?.let { LocalDate.ofEpochDay(sharedPref.getLong(it, 0)) }
|
intent?.action?.let { LocalDate.ofEpochDay(sharedPref.getLong(it, 0)) }
|
||||||
?.let { date ->
|
?.let { date ->
|
||||||
if (studentRepository.isStudentSaved) {
|
disposable.add(studentRepository.isStudentSaved()
|
||||||
disposable.add(studentRepository.getCurrentStudent()
|
.flatMap {
|
||||||
.flatMap { semesterRepository.getCurrentSemester(it) }
|
if (it) studentRepository.getCurrentStudent()
|
||||||
|
else Single.error(IllegalArgumentException("No saved students"))
|
||||||
|
}.flatMap { semesterRepository.getCurrentSemester(it) }
|
||||||
.flatMap { timetableRepository.getTimetable(it, date, date) }
|
.flatMap { timetableRepository.getTimetable(it, date, date) }
|
||||||
.map { item -> item.sortedBy { it.number } }
|
.map { item -> item.sortedBy { it.number } }
|
||||||
.subscribe({ lessons = it })
|
.subscribe({ lessons = it })
|
||||||
{ Timber.e(it, "An error has occurred while downloading data for the widget") })
|
{ Timber.e(it, "An error has occurred while downloading data for the widget") })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun getViewAt(position: Int): RemoteViews? {
|
override fun getViewAt(position: Int): RemoteViews? {
|
||||||
if (position == INVALID_POSITION) return null
|
if (position == INVALID_POSITION) return null
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package io.github.wulkanowy.ui.modules.splash
|
package io.github.wulkanowy.ui.modules.splash
|
||||||
|
|
||||||
|
import io.github.wulkanowy.TestSchedulersProvider
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
|
import io.reactivex.Single
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
@ -25,19 +27,19 @@ class SplashPresenterTest {
|
|||||||
@Before
|
@Before
|
||||||
fun initPresenter() {
|
fun initPresenter() {
|
||||||
MockitoAnnotations.initMocks(this)
|
MockitoAnnotations.initMocks(this)
|
||||||
presenter = SplashPresenter(studentRepository, errorHandler)
|
presenter = SplashPresenter(studentRepository, errorHandler, TestSchedulersProvider())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testOpenLoginView() {
|
fun testOpenLoginView() {
|
||||||
doReturn(false).`when`(studentRepository).isStudentSaved
|
doReturn(Single.just(false)).`when`(studentRepository).isStudentSaved()
|
||||||
presenter.onAttachView(splashView)
|
presenter.onAttachView(splashView)
|
||||||
verify(splashView).openLoginView()
|
verify(splashView).openLoginView()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testMainMainView() {
|
fun testMainMainView() {
|
||||||
doReturn(true).`when`(studentRepository).isStudentSaved
|
doReturn(Single.just(true)).`when`(studentRepository).isStudentSaved()
|
||||||
presenter.onAttachView(splashView)
|
presenter.onAttachView(splashView)
|
||||||
verify(splashView).openMainView()
|
verify(splashView).openMainView()
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user