Merge branch 'release/0.17.2'

This commit is contained in:
Mikołaj Pich 2020-04-19 23:41:53 +02:00
commit 7fa333cff2
21 changed files with 228 additions and 88 deletions

View File

@ -14,7 +14,7 @@ cache:
branches:
only:
- develop
- 0.17.1
- 0.17.2
android:
licenses:

View File

@ -18,8 +18,8 @@ android {
testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 17
targetSdkVersion 29
versionCode 55
versionName "0.17.1"
versionCode 56
versionName "0.17.2"
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
@ -128,7 +128,7 @@ configurations.all {
}
dependencies {
implementation "io.github.wulkanowy:sdk:0.17.1"
implementation "io.github.wulkanowy:sdk:0.17.2"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "androidx.core:core-ktx:1.2.0"
@ -139,10 +139,10 @@ dependencies {
implementation "androidx.annotation:annotation:1.1.0"
implementation "androidx.multidex:multidex:2.0.1"
implementation "androidx.preference:preference-ktx:1.1.0"
implementation "androidx.preference:preference-ktx:1.1.1"
implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation "androidx.viewpager:viewpager:1.0.0"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-beta01"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-rc01"
implementation "androidx.constraintlayout:constraintlayout:1.1.3"
implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
implementation "com.google.android.material:material:1.1.0"

View File

@ -4,6 +4,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.getCurrentOrLast
import io.github.wulkanowy.utils.isCurrent
import io.github.wulkanowy.utils.uniqueSubtract
@ -20,10 +21,12 @@ class SemesterRepository @Inject constructor(
) {
fun getSemesters(student: Student, forceRefresh: Boolean = false, refreshOnNoCurrent: Boolean = false): Single<List<Semester>> {
return local.getSemesters(student).filter { !forceRefresh }.filter {
if (refreshOnNoCurrent) {
it.any { semester -> semester.isCurrent }
} else true
return local.getSemesters(student).filter { !forceRefresh }.filter { semesters ->
when {
Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.API -> semesters.firstOrNull { it.isCurrent }?.diaryId != 0
refreshOnNoCurrent -> semesters.any { semester -> semester.isCurrent }
else -> true
}
}.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getSemesters(student)

View File

@ -29,7 +29,7 @@ class StudentLocal @Inject constructor(
fun getStudents(decryptPass: Boolean): Maybe<List<Student>> {
return studentDb.loadAll()
.map { list -> list.map { it.apply { if (decryptPass) password = decrypt(password) } } }
.map { list -> list.map { it.apply { if (decryptPass && Sdk.Mode.valueOf(loginMode) != Sdk.Mode.API) password = decrypt(password) } } }
.filter { it.isNotEmpty() }
}

View File

@ -1,7 +1,6 @@
package io.github.wulkanowy.services.sync
import android.content.Context
import android.os.Build.VERSION_CODES.LOLLIPOP
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationCompat.BigTextStyle
import androidx.core.app.NotificationCompat.PRIORITY_DEFAULT
@ -17,9 +16,9 @@ import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.sdk.exception.FeatureDisabledException
import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException
import io.github.wulkanowy.services.sync.channels.DebugChannel
import io.github.wulkanowy.services.sync.works.Work
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.getCompatColor
import io.reactivex.Completable
import io.reactivex.Single
@ -33,8 +32,7 @@ class SyncWorker @AssistedInject constructor(
private val semesterRepository: SemesterRepository,
private val works: Set<@JvmSuppressWildcards Work>,
private val preferencesRepository: PreferencesRepository,
private val notificationManager: NotificationManagerCompat,
private val appInfo: AppInfo
private val notificationManager: NotificationManagerCompat
) : RxWorker(appContext, workerParameters) {
override fun createWork(): Single<Result> {
@ -47,6 +45,10 @@ class SyncWorker @AssistedInject constructor(
.flatMapCompletable { semester ->
Completable.mergeDelayError(works.map { work ->
work.create(student, semester)
.onErrorResumeNext {
if (it is FeatureDisabledException || it is FeatureNotAvailableException) Completable.complete()
else Completable.error(it)
}
.doOnSubscribe { Timber.i("${work::class.java.simpleName} is starting") }
.doOnError { Timber.i("${work::class.java.simpleName} result: An exception occurred") }
.doOnComplete { Timber.i("${work::class.java.simpleName} result: Success") }
@ -57,11 +59,11 @@ class SyncWorker @AssistedInject constructor(
.onErrorReturn {
Timber.e(it, "There was an error during synchronization")
when {
it is FeatureDisabledException -> Result.success()
inputData.getBoolean("one_time", false) -> {
Result.failure(Data.Builder()
.putString("error", it.toString())
.build())
.build()
)
}
else -> Result.retry()
}

View File

@ -6,19 +6,32 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.HorizontalScrollView
import android.widget.Toast
import android.widget.Toast.LENGTH_LONG
import androidx.core.content.getSystemService
import androidx.fragment.app.DialogFragment
import io.github.wulkanowy.R
import io.github.wulkanowy.sdk.exception.FeatureDisabledException
import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException
import io.github.wulkanowy.sdk.exception.ServiceUnavailableException
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.getString
import io.github.wulkanowy.utils.openEmailClient
import io.github.wulkanowy.utils.openInternetBrowser
import kotlinx.android.synthetic.main.dialog_error.*
import java.io.PrintWriter
import java.io.StringWriter
import java.net.SocketTimeoutException
import java.net.UnknownHostException
import javax.inject.Inject
class ErrorDialog : DialogFragment() {
class ErrorDialog : BaseDialogFragment() {
private lateinit var error: Throwable
@Inject
lateinit var appInfo: AppInfo
companion object {
private const val ARGUMENT_KEY = "Data"
@ -49,6 +62,9 @@ class ErrorDialog : DialogFragment() {
}
errorDialogContent.text = stringWriter.toString()
with(errorDialogHorizontalScroll) {
post { fullScroll(HorizontalScrollView.FOCUS_LEFT) }
}
errorDialogCopy.setOnClickListener {
val clip = ClipData.newPlainText("wulkanowy", stringWriter.toString())
activity?.getSystemService<ClipboardManager>()?.setPrimaryClip(clip)
@ -56,6 +72,29 @@ class ErrorDialog : DialogFragment() {
Toast.makeText(context, R.string.all_copied, LENGTH_LONG).show()
}
errorDialogCancel.setOnClickListener { dismiss() }
errorDialogReport.setOnClickListener { openEmailClient(stringWriter.toString()) }
errorDialogMessage.text = resources.getString(error)
errorDialogReport.isEnabled = when (error) {
is UnknownHostException,
is SocketTimeoutException,
is ServiceUnavailableException,
is FeatureDisabledException,
is FeatureNotAvailableException -> false
else -> true
}
}
private fun openEmailClient(content: String) {
requireContext().openEmailClient(
chooserTitle = getString(R.string.about_feedback),
email = "wulkanowyinc@gmail.com",
subject = "Zgłoszenie błędu",
body = requireContext().getString(R.string.about_feedback_template,
"${appInfo.systemManufacturer} ${appInfo.systemModel}", appInfo.systemVersion.toString(), appInfo.versionName
) + "\n" + content,
onActivityNotFound = {
requireContext().openInternetBrowser("https://github.com/wulkanowy/wulkanowy/issues", ::showMessage)
}
)
}
}

View File

@ -2,17 +2,11 @@ package io.github.wulkanowy.ui.base
import android.content.res.Resources
import com.chuckerteam.chucker.api.ChuckerCollector
import io.github.wulkanowy.R
import io.github.wulkanowy.data.exceptions.NoCurrentStudentException
import io.github.wulkanowy.sdk.exception.BadCredentialsException
import io.github.wulkanowy.sdk.exception.FeatureDisabledException
import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException
import io.github.wulkanowy.sdk.exception.NotLoggedInException
import io.github.wulkanowy.sdk.exception.ServiceUnavailableException
import io.github.wulkanowy.utils.getString
import io.github.wulkanowy.utils.security.ScramblerException
import timber.log.Timber
import java.net.SocketTimeoutException
import java.net.UnknownHostException
import javax.inject.Inject
open class ErrorHandler @Inject constructor(protected val resources: Resources, private val chuckerCollector: ChuckerCollector) {
@ -30,18 +24,10 @@ open class ErrorHandler @Inject constructor(protected val resources: Resources,
}
protected open fun proceed(error: Throwable) {
resources.run {
when (error) {
is UnknownHostException -> showErrorMessage(getString(R.string.error_no_internet), error)
is SocketTimeoutException -> showErrorMessage(getString(R.string.error_timeout), error)
is NotLoggedInException -> showErrorMessage(getString(R.string.error_login_failed), error)
is ServiceUnavailableException -> showErrorMessage(getString(R.string.error_service_unavailable), error)
is FeatureDisabledException -> showErrorMessage(getString(R.string.error_feature_disabled), error)
is ScramblerException, is BadCredentialsException -> onSessionExpired()
is NoCurrentStudentException -> onNoCurrentStudent()
is FeatureNotAvailableException -> showErrorMessage(getString(R.string.error_feature_not_available), error)
else -> showErrorMessage(getString(R.string.error_unknown), error)
}
when (error) {
is ScramblerException, is BadCredentialsException -> onSessionExpired()
is NoCurrentStudentException -> onNoCurrentStudent()
else -> showErrorMessage(resources.getString(error), error)
}
}

View File

@ -133,7 +133,7 @@ class GradeStatisticsPresenter @Inject constructor(
showSubjects(true)
}
}, {
Timber.e("Loading grade stats subjects result: An exception occurred")
Timber.i("Loading grade stats subjects result: An exception occurred")
errorHandler.dispatch(it)
})
)
@ -179,7 +179,7 @@ class GradeStatisticsPresenter @Inject constructor(
}
analytics.logEvent("load_grade_statistics", "items" to it.size, "force_refresh" to forceRefresh)
}) {
Timber.e("Loading grade stats result: An exception occurred")
Timber.i("Loading grade stats result: An exception occurred")
errorHandler.dispatch(it)
})
}

View File

@ -70,7 +70,7 @@ class LoginRecoverPresenter @Inject constructor(
.subscribe({ (resetUrl, siteKey) ->
view?.loadReCaptcha(siteKey, resetUrl)
}) {
Timber.e("Obtain captcha site key result: An exception occurred")
Timber.i("Obtain captcha site key result: An exception occurred")
errorHandler.dispatch(it)
})
}
@ -120,7 +120,7 @@ class LoginRecoverPresenter @Inject constructor(
analytics.logEvent("account_recover", "register" to host, "symbol" to symbol, "success" to true)
}) {
Timber.e("Send recover request result: An exception occurred")
Timber.i("Send recover request result: An exception occurred")
errorHandler.dispatch(it)
analytics.logEvent("account_recover", "register" to host, "symbol" to symbol, "success" to false)
})

View File

@ -7,6 +7,7 @@ import dagger.Provides
import dagger.android.ContributesAndroidInjector
import io.github.wulkanowy.R
import io.github.wulkanowy.di.scopes.PerFragment
import io.github.wulkanowy.ui.base.ErrorDialog
import io.github.wulkanowy.ui.modules.about.AboutFragment
import io.github.wulkanowy.ui.modules.about.contributor.ContributorFragment
import io.github.wulkanowy.ui.modules.about.license.LicenseFragment
@ -115,6 +116,10 @@ abstract class MainModule {
@ContributesAndroidInjector
abstract fun bindAccountDialog(): AccountDialog
@PerFragment
@ContributesAndroidInjector
abstract fun bindErrorDialog(): ErrorDialog
@PerFragment
@ContributesAndroidInjector(modules = [MobileDeviceModule::class])
abstract fun bindMobileDevices(): MobileDeviceFragment
@ -132,7 +137,7 @@ abstract class MainModule {
abstract fun bindLogViewerFragment(): LogViewerFragment
@PerFragment
@ContributesAndroidInjector()
@ContributesAndroidInjector
abstract fun bindContributorFragment(): ContributorFragment
@PerFragment

View File

@ -147,7 +147,7 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter>(), SendMessageVie
}
override fun popView() {
onBackPressed()
finish()
}
private fun setUpExtendedHitArea() {

View File

@ -135,12 +135,12 @@ class SendMessagePresenter @Inject constructor(
if (selectedRecipientChips.isNotEmpty()) setSelectedRecipients(selectedRecipientChips)
showContent(true)
} else {
Timber.e("Loading recipients result: Can't find the reporting unit")
Timber.i("Loading recipients result: Can't find the reporting unit")
view?.showEmpty(true)
}
}
}, {
Timber.e("Loading recipients result: An exception occurred")
Timber.i("Loading recipients result: An exception occurred")
view?.showContent(true)
errorHandler.dispatch(it)
}))

View File

@ -0,0 +1,20 @@
package io.github.wulkanowy.utils
import android.content.res.Resources
import io.github.wulkanowy.R
import io.github.wulkanowy.sdk.exception.FeatureDisabledException
import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException
import io.github.wulkanowy.sdk.exception.NotLoggedInException
import io.github.wulkanowy.sdk.exception.ServiceUnavailableException
import java.net.SocketTimeoutException
import java.net.UnknownHostException
fun Resources.getString(error: Throwable) = when (error) {
is UnknownHostException -> getString(R.string.error_no_internet)
is SocketTimeoutException -> getString(R.string.error_timeout)
is NotLoggedInException -> getString(R.string.error_login_failed)
is ServiceUnavailableException -> getString(R.string.error_service_unavailable)
is FeatureDisabledException -> getString(R.string.error_feature_disabled)
is FeatureNotAvailableException -> getString(R.string.error_feature_not_available)
else -> getString(R.string.error_unknown)
}

View File

@ -1,9 +1,8 @@
Wersja 0.17.1
Wersja 0.17.2
- naprawiliśmy problemy ze stabilnością w szczegółach zadania domowego i podglądzie wiadomości
- naprawiliśmy odświeżanie danych w określonych przypadkach
- naprawiliśmy odświeżanie listy urządzeń
- w trybie hybrydowym lista przedmiotów w zakładckach Klasa i Podsumowanie frekwencji powinna teraz zawierać tylko przedmioty ucznia
- na liście dzienników pokazują się teraz również te niestandardowe
- naprawiliśmy wyświetlanie przycisku oznaczania zadania domowego jako wykonanego
- naprawiliśmy rzadki błąd ze stabilnością przy wysyłaniu wiadomości
- naprawiliśmy błąd po logowaniu w domyślnym trybie, jeśli wcześniej użytkownik zalogowany był w trybie Mobilnego API
- ulepszyliśmy wygląd okienka ze szczegółami błędu
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases

View File

@ -1,26 +1,49 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minWidth="300dp"
android:orientation="vertical">
<LinearLayout
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="20dp"
android:paddingTop="20dp"
android:text="@string/all_details"
android:textSize="20sp" />
<TextView
android:id="@+id/errorDialogMessage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="20dp"
android:paddingVertical="10dp"
android:textSize="21sp"
tools:text="@tools:sample/lorem" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical">
<androidx.core.widget.NestedScrollView
android:id="@+id/errorDialogNestedScroll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:overScrollMode="ifContentScrolls">
android:overScrollMode="ifContentScrolls"
app:layout_constrainedHeight="true"
app:layout_constraintHeight_max="300dp"
app:layout_constraintHeight_min="200dp"
app:layout_constraintTop_toTopOf="parent">
<HorizontalScrollView
android:id="@+id/errorDialogHorizontalScroll"
android:layout_width="350dp"
android:layout_height="wrap_content"
android:paddingLeft="24dp"
android:paddingTop="24dp"
android:paddingRight="24dp">
<TextView
@ -33,16 +56,31 @@
tools:text="@tools:sample/lorem/random" />
</HorizontalScrollView>
</androidx.core.widget.NestedScrollView>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:background="@drawable/ic_all_divider"
android:gravity="end"
android:minHeight="52dp"
android:orientation="horizontal">
<com.google.android.material.button.MaterialButton
android:id="@+id/errorDialogReport"
style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:text="@string/about_feedback" />
<Space
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.google.android.material.button.MaterialButton
android:id="@+id/errorDialogCancel"
style="@style/Widget.MaterialComponents.Button.TextButton"
@ -50,7 +88,6 @@
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:text="@android:string/cancel" />
<com.google.android.material.button.MaterialButton
@ -60,7 +97,6 @@
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:text="@android:string/copy" />
</LinearLayout>
</LinearLayout>
</LinearLayout>

View File

@ -9,14 +9,18 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/homeworkDialogRecycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:minWidth="300dp"
tools:itemCount="1"
tools:listitem="@layout/item_homework_dialog_details" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:background="@drawable/ic_all_divider"
android:paddingHorizontal="10dp"
android:paddingVertical="5dp">
<com.google.android.material.button.MaterialButton
android:id="@+id/homeworkDialogRead"
@ -25,8 +29,6 @@
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:layout_marginStart="10dp"
android:layout_marginBottom="10dp"
android:text="@string/homework_mark_as_done"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
@ -38,8 +40,6 @@
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_marginEnd="10dp"
android:layout_marginBottom="10dp"
android:text="@string/all_close"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />

View File

@ -1,4 +1,5 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
@ -93,6 +94,7 @@
android:lineSpacingMultiplier="1.2"
android:text="@string/all_no_data"
android:textIsSelectable="true"
android:textSize="12sp" />
android:textSize="12sp"
tools:text="@tools:sample/lorem/random" />
</LinearLayout>

View File

@ -421,5 +421,5 @@
<string name="error_service_unavailable">Trwa przerwa techniczna dziennika UONET+. Spróbuj ponownie później</string>
<string name="error_unknown">Wystąpił nieoczekiwany błąd</string>
<string name="error_feature_disabled">Funkcja wyłączona przez szkołę</string>
<string name="error_feature_not_available">Funkcja niedostępna. Zaloguj się w innym trybie niż Mobilne API</string>
<string name="error_feature_not_available">Funkcja niedostępna. Zaloguj się w trybie innym niż Mobilne API</string>
</resources>

View File

@ -7,6 +7,9 @@ import com.crashlytics.android.core.CrashlyticsCore
import fr.bipi.tressence.crash.CrashlyticsLogExceptionTree
import fr.bipi.tressence.crash.CrashlyticsLogTree
import io.fabric.sdk.android.Fabric
import io.github.wulkanowy.sdk.exception.FeatureDisabledException
import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException
import java.net.UnknownHostException
fun initCrashlytics(context: Context, appInfo: AppInfo) {
Fabric.with(Fabric.Builder(context)
@ -21,6 +24,13 @@ fun initCrashlytics(context: Context, appInfo: AppInfo) {
.build())
}
class CrashlyticsTree : CrashlyticsLogTree(Log.VERBOSE)
class CrashlyticsTree : CrashlyticsLogTree(Log.VERBOSE) {
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
if (t is FeatureDisabledException || t is FeatureNotAvailableException || t is UnknownHostException) return
super.log(priority, tag, message, t)
}
}
class CrashlyticsExceptionTree : CrashlyticsLogExceptionTree()

View File

@ -8,6 +8,7 @@ import io.github.wulkanowy.data.repositories.createSemesterEntity
import io.reactivex.Maybe
import io.reactivex.Single
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotEquals
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
@ -37,13 +38,14 @@ class SemesterRepositoryTest {
fun initTest() {
MockitoAnnotations.initMocks(this)
semesterRepository = SemesterRepository(semesterRemote, semesterLocal, settings)
doReturn("SCRAPPER").`when`(student).loginMode
}
@Test
fun getSemesters_noSemesters() {
val semesters = listOf(
createSemesterEntity(0, 0, now().minusMonths(6), now().minusMonths(3)),
createSemesterEntity(0, 0, now().minusMonths(3), now())
createSemesterEntity(1, 1, now().minusMonths(6), now().minusMonths(3)),
createSemesterEntity(1, 2, now().minusMonths(3), now())
)
doReturn(Maybe.empty<Semester>()).`when`(semesterLocal).getSemesters(student)
@ -55,11 +57,47 @@ class SemesterRepositoryTest {
verify(semesterLocal).saveSemesters(semesters)
}
@Test
fun getSemesters_invalidDiary_api() {
doReturn("API").`when`(student).loginMode
val badSemesters = listOf(
createSemesterEntity(0, 1, now().minusMonths(6), now().minusMonths(3)),
createSemesterEntity(0, 2, now().minusMonths(3), now())
)
doReturn(Maybe.just(badSemesters)).`when`(semesterLocal).getSemesters(student)
val items = semesterRepository.getSemesters(student).blockingGet()
assertEquals(2, items.size)
assertEquals(0, items[0].diaryId)
}
@Test
fun getSemesters_invalidDiary_scrapper() {
doReturn("SCRAPPER").`when`(student).loginMode
val badSemesters = listOf(
createSemesterEntity(0, 1, now().minusMonths(6), now().minusMonths(3)),
createSemesterEntity(0, 2, now().minusMonths(3), now())
)
val goodSemesters = listOf(
createSemesterEntity(1, 1, now().minusMonths(6), now().minusMonths(3)),
createSemesterEntity(1, 2, now().minusMonths(3), now())
)
doReturn(Maybe.just(badSemesters), Maybe.just(badSemesters), Maybe.just(goodSemesters)).`when`(semesterLocal).getSemesters(student)
doReturn(Single.just(goodSemesters)).`when`(semesterRemote).getSemesters(student)
val items = semesterRepository.getSemesters(student).blockingGet()
assertEquals(2, items.size)
assertNotEquals(0, items[0].diaryId)
}
@Test
fun getSemesters_noCurrent() {
val semesters = listOf(
createSemesterEntity(0, 0, now().minusMonths(12), now().minusMonths(6)),
createSemesterEntity(0, 0, now().minusMonths(6), now().minusMonths(1))
createSemesterEntity(1, 1, now().minusMonths(12), now().minusMonths(6)),
createSemesterEntity(1, 2, now().minusMonths(6), now().minusMonths(1))
)
doReturn(Maybe.just(semesters)).`when`(semesterLocal).getSemesters(student)
@ -71,8 +109,8 @@ class SemesterRepositoryTest {
@Test
fun getSemesters_oneCurrent() {
val semesters = listOf(
createSemesterEntity(0, 0, now().minusMonths(6), now().minusMonths(3)),
createSemesterEntity(0, 0, now().minusMonths(3), now())
createSemesterEntity(1, 1, now().minusMonths(6), now().minusMonths(3)),
createSemesterEntity(1, 2, now().minusMonths(3), now())
)
doReturn(Maybe.just(semesters)).`when`(semesterLocal).getSemesters(student)
@ -84,8 +122,8 @@ class SemesterRepositoryTest {
@Test
fun getSemesters_doubleCurrent() {
val semesters = listOf(
createSemesterEntity(0, 0, now(), now()),
createSemesterEntity(0, 0, now(), now())
createSemesterEntity(1, 1, now(), now()),
createSemesterEntity(1, 2, now(), now())
)
doReturn(Maybe.just(semesters)).`when`(semesterLocal).getSemesters(student)
@ -97,8 +135,8 @@ class SemesterRepositoryTest {
@Test
fun getSemesters_noSemesters_refreshOnNoCurrent() {
val semesters = listOf(
createSemesterEntity(0, 0, now().minusMonths(6), now().minusMonths(3)),
createSemesterEntity(0, 0, now().minusMonths(3), now())
createSemesterEntity(1, 1, now().minusMonths(6), now().minusMonths(3)),
createSemesterEntity(1, 2, now().minusMonths(3), now())
)
doReturn(Maybe.empty<Semester>()).`when`(semesterLocal).getSemesters(student)
@ -113,8 +151,8 @@ class SemesterRepositoryTest {
@Test
fun getSemesters_noCurrent_refreshOnNoCurrent() {
val semesters = listOf(
createSemesterEntity(0, 0, now().minusMonths(12), now().minusMonths(6)),
createSemesterEntity(0, 0, now().minusMonths(6), now().minusMonths(1))
createSemesterEntity(1, 1, now().minusMonths(12), now().minusMonths(6)),
createSemesterEntity(1, 2, now().minusMonths(6), now().minusMonths(1))
)
doReturn(Maybe.just(semesters)).`when`(semesterLocal).getSemesters(student)
@ -127,8 +165,8 @@ class SemesterRepositoryTest {
@Test
fun getSemesters_doubleCurrent_refreshOnNoCurrent() {
val semesters = listOf(
createSemesterEntity(0, 0, now(), now()),
createSemesterEntity(0, 0, now(), now())
createSemesterEntity(1, 1, now(), now()),
createSemesterEntity(1, 2, now(), now())
)
doReturn(Maybe.just(semesters)).`when`(semesterLocal).getSemesters(student)
@ -140,8 +178,8 @@ class SemesterRepositoryTest {
@Test(expected = IllegalArgumentException::class)
fun getCurrentSemester_doubleCurrent() {
val semesters = listOf(
createSemesterEntity(0, 0, now(), now()),
createSemesterEntity(0, 0, now(), now())
createSemesterEntity(1, 1, now(), now()),
createSemesterEntity(1, 1, now(), now())
)
doReturn(Maybe.just(semesters)).`when`(semesterLocal).getSemesters(student)

View File

@ -1,5 +1,5 @@
buildscript {
ext.kotlin_version = '1.3.71'
ext.kotlin_version = '1.3.72'
ext.about_libraries = '8.1.1'
repositories {
mavenCentral()
@ -10,7 +10,7 @@ buildscript {
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.android.tools.build:gradle:3.6.2'
classpath 'com.android.tools.build:gradle:3.6.3'
classpath 'com.google.gms:google-services:4.3.3'
//noinspection GradleDependency https://github.com/firebase/firebase-android-sdk/issues/1276#issuecomment-592098283
classpath "io.fabric.tools:gradle:1.31.0"