Automatically switch semesters without sync (#681)

This commit is contained in:
Mikołaj Pich 2020-02-24 00:24:40 +01:00 committed by GitHub
parent 00f5b9431e
commit 96c1bb4c69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 246 additions and 153 deletions

View File

@ -122,10 +122,10 @@ configurations.all {
}
dependencies {
implementation "io.github.wulkanowy:sdk:0.15.0"
implementation "io.github.wulkanowy:sdk:7e89883"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "androidx.core:core-ktx:1.2.0-rc01"
implementation "androidx.core:core-ktx:1.2.0"
implementation "androidx.activity:activity-ktx:1.1.0"
implementation "androidx.appcompat:appcompat:1.1.0"
implementation "androidx.appcompat:appcompat-resources:1.1.0"

View File

@ -8,7 +8,6 @@ import io.github.wulkanowy.data.db.entities.Semester
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import org.threeten.bp.LocalDate.now
import org.threeten.bp.LocalDate.of
import kotlin.test.assertFalse
import kotlin.test.assertTrue
@ -104,45 +103,45 @@ class Migration13Test : AbstractMigrationTest() {
val db = helper.runMigrationsAndValidate(dbName, 13, true, Migration13())
val semesters1 = getSemesters(db, "SELECT * FROM Semesters WHERE student_id = 1 AND class_id = 5")
assertTrue { semesters1.single { it.isCurrent }.isCurrent }
assertTrue { semesters1.single { it.second }.second }
semesters1[0].run {
assertFalse(isCurrent)
assertEquals(1, semesterId)
assertEquals(1, diaryId)
assertFalse(second)
assertEquals(1, first.semesterId)
assertEquals(1, first.diaryId)
}
semesters1[2].run {
assertFalse(isCurrent)
assertEquals(3, semesterId)
assertEquals(2, diaryId)
assertFalse(second)
assertEquals(3, first.semesterId)
assertEquals(2, first.diaryId)
}
semesters1[3].run {
assertTrue(isCurrent)
assertEquals(4, semesterId)
assertEquals(2, diaryId)
assertTrue(second)
assertEquals(4, first.semesterId)
assertEquals(2, first.diaryId)
}
getSemesters(db, "SELECT * FROM Semesters WHERE student_id = 2 AND class_id = 5").let {
assertTrue { it.single { it.isCurrent }.isCurrent }
assertEquals(1970, it[0].schoolYear)
assertEquals(of(1970, 1, 1), it[0].end)
assertEquals(of(1970, 1, 1), it[0].start)
assertFalse(it[0].isCurrent)
assertFalse(it[1].isCurrent)
assertFalse(it[2].isCurrent)
assertTrue(it[3].isCurrent)
assertTrue { it.single { it.second }.second }
assertEquals(1970, it[0].first.schoolYear)
assertEquals(of(1970, 1, 1), it[0].first.end)
assertEquals(of(1970, 1, 1), it[0].first.start)
assertFalse(it[0].second)
assertFalse(it[1].second)
assertFalse(it[2].second)
assertTrue(it[3].second)
}
getSemesters(db, "SELECT * FROM Semesters WHERE student_id = 2 AND class_id = 5").let {
assertTrue { it.single { it.isCurrent }.isCurrent }
assertFalse(it[0].isCurrent)
assertFalse(it[1].isCurrent)
assertFalse(it[2].isCurrent)
assertTrue(it[3].isCurrent)
assertTrue { it.single { it.second }.second }
assertFalse(it[0].second)
assertFalse(it[1].second)
assertFalse(it[2].second)
assertTrue(it[3].second)
}
}
private fun getSemesters(db: SupportSQLiteDatabase, query: String): List<Semester> {
val semesters = mutableListOf<Semester>()
private fun getSemesters(db: SupportSQLiteDatabase, query: String): List<Pair<Semester, Boolean>> {
val semesters = mutableListOf<Pair<Semester, Boolean>>()
val cursor = db.query(query)
if (cursor.moveToFirst()) {
@ -153,13 +152,12 @@ class Migration13Test : AbstractMigrationTest() {
diaryName = cursor.getString(3),
semesterId = cursor.getInt(4),
semesterName = cursor.getInt(5),
isCurrent = cursor.getInt(6) == 1,
classId = cursor.getInt(7),
unitId = cursor.getInt(8),
schoolYear = cursor.getInt(9),
start = Converters().timestampToDate(cursor.getLong(10))!!,
end = Converters().timestampToDate(cursor.getLong(11))!!
))
) to (cursor.getInt(6) == 1))
} while (cursor.moveToNext())
}
return semesters.toList()

View File

@ -10,8 +10,8 @@ import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDate.now
import org.threeten.bp.LocalDate.of
import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
@ -35,19 +35,19 @@ class AttendanceLocalTest {
@Test
fun saveAndReadTest() {
attendanceLocal.saveAttendance(listOf(
Attendance(1, 2, 3, LocalDate.of(2018, 9, 10), 0, "", "", false, false, false, false, false, false, false, SentExcuseStatus.ACCEPTED.name),
Attendance(1, 2, 3, LocalDate.of(2018, 9, 14), 0, "", "", false, false, false, false, false, false, false, SentExcuseStatus.WAITING.name),
Attendance(1, 2, 3, LocalDate.of(2018, 9, 17), 0, "", "", false, false, false, false, false, false, false, SentExcuseStatus.ACCEPTED.name)
Attendance(1, 2, 3, of(2018, 9, 10), 0, "", "", false, false, false, false, false, false, false, SentExcuseStatus.ACCEPTED.name),
Attendance(1, 2, 3, of(2018, 9, 14), 0, "", "", false, false, false, false, false, false, false, SentExcuseStatus.WAITING.name),
Attendance(1, 2, 3, of(2018, 9, 17), 0, "", "", false, false, false, false, false, false, false, SentExcuseStatus.ACCEPTED.name)
))
val attendance = attendanceLocal
.getAttendance(Semester(1, 2, "", 1, 3, 2019, true, now(), now(), 1, 1),
LocalDate.of(2018, 9, 10),
LocalDate.of(2018, 9, 14)
)
.blockingGet()
.getAttendance(Semester(1, 2, "", 1, 3, 2019, now(), now(), 1, 1),
of(2018, 9, 10),
of(2018, 9, 14)
)
.blockingGet()
assertEquals(2, attendance.size)
assertEquals(attendance[0].date, LocalDate.of(2018, 9, 10))
assertEquals(attendance[1].date, LocalDate.of(2018, 9, 14))
assertEquals(attendance[0].date, of(2018, 9, 10))
assertEquals(attendance[1].date, of(2018, 9, 14))
}
}

View File

@ -11,6 +11,8 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDate.now
import org.threeten.bp.LocalDate.of
import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
@ -35,20 +37,20 @@ class CompletedLessonsLocalTest {
@Test
fun saveAndReadTest() {
completedLessonsLocal.saveCompletedLessons(listOf(
getCompletedLesson(LocalDate.of(2018, 9, 10), 1),
getCompletedLesson(LocalDate.of(2018, 9, 14), 2),
getCompletedLesson(LocalDate.of(2018, 9, 17), 3)
getCompletedLesson(of(2018, 9, 10), 1),
getCompletedLesson(of(2018, 9, 14), 2),
getCompletedLesson(of(2018, 9, 17), 3)
))
val completed = completedLessonsLocal
.getCompletedLessons(Semester(1, 2, "", 1, 3, 2019, true, LocalDate.now(), LocalDate.now(), 1, 1),
LocalDate.of(2018, 9, 10),
LocalDate.of(2018, 9, 14)
.getCompletedLessons(Semester(1, 2, "", 1, 3, 2019, now(), now(), 1, 1),
of(2018, 9, 10),
of(2018, 9, 14)
)
.blockingGet()
assertEquals(2, completed.size)
assertEquals(completed[0].date, LocalDate.of(2018, 9, 10))
assertEquals(completed[1].date, LocalDate.of(2018, 9, 14))
assertEquals(completed[0].date, of(2018, 9, 10))
assertEquals(completed[1].date, of(2018, 9, 14))
}
private fun getCompletedLesson(date: LocalDate, number: Int): CompletedLesson {

View File

@ -10,7 +10,8 @@ import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDate.now
import org.threeten.bp.LocalDate.of
import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
@ -34,19 +35,19 @@ class ExamLocalTest {
@Test
fun saveAndReadTest() {
examLocal.saveExams(listOf(
Exam(1, 2, LocalDate.of(2018, 9, 10), LocalDate.now(), "", "", "", "", "", ""),
Exam(1, 2, LocalDate.of(2018, 9, 14), LocalDate.now(), "", "", "", "", "", ""),
Exam(1, 2, LocalDate.of(2018, 9, 17), LocalDate.now(), "", "", "", "", "", "")
Exam(1, 2, of(2018, 9, 10), now(), "", "", "", "", "", ""),
Exam(1, 2, of(2018, 9, 14), now(), "", "", "", "", "", ""),
Exam(1, 2, of(2018, 9, 17), now(), "", "", "", "", "", "")
))
val exams = examLocal
.getExams(Semester(1, 2, "", 1, 3, 2019, true, LocalDate.now(), LocalDate.now(), 1, 1),
LocalDate.of(2018, 9, 10),
LocalDate.of(2018, 9, 14)
)
.blockingGet()
.getExams(Semester(1, 2, "", 1, 3, 2019, now(), now(), 1, 1),
of(2018, 9, 10),
of(2018, 9, 14)
)
.blockingGet()
assertEquals(2, exams.size)
assertEquals(exams[0].date, LocalDate.of(2018, 9, 10))
assertEquals(exams[1].date, LocalDate.of(2018, 9, 14))
assertEquals(exams[0].date, of(2018, 9, 10))
assertEquals(exams[1].date, of(2018, 9, 14))
}
}

View File

@ -40,7 +40,7 @@ class GradeLocalTest {
createGradeLocal(3, 5.0, LocalDate.of(2019, 2, 28), "", 2)
))
val semester = Semester(1, 2, "", 2019, 2, 1, true, now(), now(), 1, 1)
val semester = Semester(1, 2, "", 2019, 2, 1, now(), now(), 1, 1)
val grades = gradeLocal
.getGrades(semester)

View File

@ -11,7 +11,7 @@ import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDate.now
import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
@ -40,10 +40,7 @@ class GradeStatisticsLocalTest {
getGradeStatistics("Fizyka", 1, 2)
))
val stats = gradeStatisticsLocal.getGradesStatistics(
Semester(2, 2, "", 2019, 1, 2, true, LocalDate.now(), LocalDate.now(), 1, 1), false,
"Matematyka"
).blockingGet()
val stats = gradeStatisticsLocal.getGradesStatistics(getSemester(), false, "Matematyka").blockingGet()
assertEquals(1, stats.size)
assertEquals(stats[0].subject, "Matematyka")
}
@ -56,10 +53,7 @@ class GradeStatisticsLocalTest {
getGradeStatistics("Fizyka", 1, 2)
))
val stats = gradeStatisticsLocal.getGradesStatistics(
Semester(2, 2, "", 2019, 1, 2, true, LocalDate.now(), LocalDate.now(), 1, 1), false,
"Wszystkie"
).blockingGet()
val stats = gradeStatisticsLocal.getGradesStatistics(getSemester(), false, "Wszystkie").blockingGet()
assertEquals(1, stats.size)
assertEquals(stats[0].subject, "Wszystkie")
}
@ -72,10 +66,7 @@ class GradeStatisticsLocalTest {
getGradePointsStatistics("Fizyka", 1, 2)
))
val stats = gradeStatisticsLocal.getGradesPointsStatistics(
Semester(2, 2, "", 2019, 1, 2, true, LocalDate.now(), LocalDate.now(), 1, 1),
"Matematyka"
).blockingGet()
val stats = gradeStatisticsLocal.getGradesPointsStatistics(getSemester(), "Matematyka").blockingGet()
with(stats) {
assertEquals(subject, "Matematyka")
assertEquals(others, 5.0)
@ -87,10 +78,7 @@ class GradeStatisticsLocalTest {
fun saveAndRead_subjectEmpty() {
gradeStatisticsLocal.saveGradesPointsStatistics(listOf())
val stats = gradeStatisticsLocal.getGradesPointsStatistics(
Semester(2, 2, "", 2019, 1, 2, true, LocalDate.now(), LocalDate.now(), 1, 1),
"Matematyka"
).blockingGet()
val stats = gradeStatisticsLocal.getGradesPointsStatistics(getSemester(), "Matematyka").blockingGet()
assertEquals(null, stats)
}
@ -98,13 +86,14 @@ class GradeStatisticsLocalTest {
fun saveAndRead_allEmpty() {
gradeStatisticsLocal.saveGradesPointsStatistics(listOf())
val stats = gradeStatisticsLocal.getGradesPointsStatistics(
Semester(2, 2, "", 2019, 1, 2, true, LocalDate.now(), LocalDate.now(), 1, 1),
"Wszystkie"
).blockingGet()
val stats = gradeStatisticsLocal.getGradesPointsStatistics(getSemester(), "Wszystkie").blockingGet()
assertEquals(null, stats)
}
private fun getSemester(): Semester {
return Semester(2, 2, "", 2019, 1, 2, now(), now(), 1, 1)
}
private fun getGradeStatistics(subject: String, studentId: Int, semesterId: Int): GradeStatistics {
return GradeStatistics(studentId, semesterId, subject, 5, 5, false)
}

View File

@ -36,7 +36,7 @@ class LuckyNumberLocalTest {
fun saveAndReadTest() {
luckyNumberLocal.saveLuckyNumber(LuckyNumber(1, LocalDate.of(2019, 1, 20), 14))
val luckyNumber = luckyNumberLocal.getLuckyNumber(Semester(1, 1, "", 1, 3, 2019, true, LocalDate.now(), LocalDate.now(), 1, 1),
val luckyNumber = luckyNumberLocal.getLuckyNumber(Semester(1, 1, "", 1, 3, 2019, LocalDate.now(), LocalDate.now(), 1, 1),
LocalDate.of(2019, 1, 20)
).blockingGet()

View File

@ -41,7 +41,7 @@ class TimetableLocalTest {
))
val exams = timetableDb.getTimetable(
Semester(1, 2, "", 1, 1, 2019, true, LocalDate.now(), LocalDate.now(), 1, 1),
Semester(1, 2, "", 1, 1, 2019, LocalDate.now(), LocalDate.now(), 1, 1),
LocalDate.of(2018, 9, 10),
LocalDate.of(2018, 9, 14)
).blockingGet()

View File

@ -27,9 +27,6 @@ data class Semester(
@ColumnInfo(name = "semester_name")
val semesterName: Int,
@ColumnInfo(name = "is_current")
val isCurrent: Boolean,
val start: LocalDate,
val end: LocalDate,
@ -43,4 +40,8 @@ data class Semester(
@PrimaryKey(autoGenerate = true)
var id: Long = 0
@ColumnInfo(name = "is_current")
var current: Boolean = false
}

View File

@ -19,6 +19,6 @@ class SemesterLocal @Inject constructor(private val semesterDb: SemesterDao) {
}
fun getSemesters(student: Student): Maybe<List<Semester>> {
return semesterDb.loadAll(student.studentId, student.classId).filter { !it.isEmpty() }
return semesterDb.loadAll(student.studentId, student.classId).filter { it.isNotEmpty() }
}
}

View File

@ -20,7 +20,6 @@ class SemesterRemote @Inject constructor(private val sdk: Sdk) {
schoolYear = it.schoolYear,
semesterId = it.semesterId,
semesterName = it.semesterNumber,
isCurrent = it.current,
start = it.start,
end = it.end,
classId = it.classId,

View File

@ -5,10 +5,11 @@ import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.Inter
import io.github.wulkanowy.data.SdkHelper
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.utils.getCurrentOrLast
import io.github.wulkanowy.utils.isCurrent
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Maybe
import io.reactivex.Single
import timber.log.Timber
import java.net.UnknownHostException
import javax.inject.Inject
import javax.inject.Singleton
@ -21,28 +22,30 @@ class SemesterRepository @Inject constructor(
private val sdkHelper: SdkHelper
) {
fun getSemesters(student: Student, forceRefresh: Boolean = false): Single<List<Semester>> {
fun getSemesters(student: Student, forceRefresh: Boolean = false, refreshOnNoCurrent: Boolean = false): Single<List<Semester>> {
return Maybe.just(sdkHelper.init(student))
.flatMap { local.getSemesters(student).filter { !forceRefresh } }
.flatMap {
local.getSemesters(student).filter { !forceRefresh }.filter {
if (refreshOnNoCurrent) {
it.any { semester -> semester.isCurrent }
} else true
}
}
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getSemesters(student) else Single.error(UnknownHostException())
if (it) remote.getSemesters(student)
else Single.error(UnknownHostException())
}.flatMap { new ->
val currentSemesters = new.filter { it.isCurrent }
if (currentSemesters.size == 1) {
local.getSemesters(student).toSingle(emptyList())
.doOnSuccess { old ->
local.deleteSemesters(old.uniqueSubtract(new))
local.saveSemesters(new.uniqueSubtract(old))
}
} else {
Timber.i("Current semesters list:\n${new.joinToString(separator = "\n")}")
throw IllegalArgumentException("Current semester can be only one.")
if (new.isEmpty()) throw IllegalArgumentException("Empty semester list!")
local.getSemesters(student).toSingle(emptyList()).doOnSuccess { old ->
local.deleteSemesters(old.uniqueSubtract(new))
local.saveSemesters(new.uniqueSubtract(old))
}
}.flatMap { local.getSemesters(student).toSingle(emptyList()) })
}
fun getCurrentSemester(student: Student, forceRefresh: Boolean = false): Single<Semester> {
return getSemesters(student, forceRefresh).map { item -> item.single { it.isCurrent } }
return getSemesters(student, forceRefresh).map { it.getCurrentOrLast() }
}
}

View File

@ -7,7 +7,9 @@ import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.getCurrentOrLast
import timber.log.Timber
import java.util.concurrent.TimeUnit.MILLISECONDS
import javax.inject.Inject
class GradePresenter @Inject constructor(
@ -98,17 +100,16 @@ class GradePresenter @Inject constructor(
private fun loadData() {
Timber.i("Loading grade data started")
disposable.add(studentRepository.getCurrentStudent()
.flatMap { semesterRepository.getSemesters(it) }
.flatMap { semesterRepository.getSemesters(it, refreshOnNoCurrent = true) }
.delay(200, MILLISECONDS)
.subscribeOn(schedulers.backgroundThread)
.observeOn(schedulers.mainThread)
.doFinally { view?.showProgress(false) }
.subscribe({
it.first { item -> item.isCurrent }.also { current ->
selectedIndex = if (selectedIndex == 0) current.semesterName else selectedIndex
schoolYear = current.schoolYear
semesters = it.filter { semester -> semester.diaryId == current.diaryId }
view?.setCurrentSemesterName(current.semesterName, schoolYear)
}
val current = it.getCurrentOrLast()
selectedIndex = if (selectedIndex == 0) current.semesterName else selectedIndex
schoolYear = current.schoolYear
semesters = it.filter { semester -> semester.diaryId == current.diaryId }
view?.setCurrentSemesterName(current.semesterName, schoolYear)
view?.run {
Timber.i("Loading grade result: Attempt load index $currentPageIndex")
@ -125,6 +126,7 @@ class GradePresenter @Inject constructor(
private fun showErrorViewOnError(message: String, error: Throwable) {
lastError = error
view?.run {
showProgress(false)
showErrorView(true)
setErrorDetails(message)
}

View File

@ -0,0 +1,19 @@
package io.github.wulkanowy.utils
import io.github.wulkanowy.data.db.entities.Semester
import org.threeten.bp.LocalDate.now
inline val Semester.isCurrent: Boolean
get() = now() in start..end
fun List<Semester>.getCurrentOrLast(): Semester {
if (isEmpty()) throw RuntimeException("Empty semester list")
// when there is only one current semester
singleOrNull { it.isCurrent }?.let { return it }
// when there is more than one current semester - find one with higher id
singleOrNull { semester -> semester.semesterId == maxBy { it.semesterId }?.semesterId }?.let { return it }
throw IllegalArgumentException("Duplicated last semester! Semesters: ${joinToString(separator = "\n")}")
}

View File

@ -1,42 +1,30 @@
package io.github.wulkanowy.utils
import org.threeten.bp.DateTimeUtils
import org.threeten.bp.DayOfWeek.FRIDAY
import org.threeten.bp.DayOfWeek.MONDAY
import org.threeten.bp.DayOfWeek.SATURDAY
import org.threeten.bp.DayOfWeek.SUNDAY
import org.threeten.bp.Instant
import org.threeten.bp.Instant.ofEpochMilli
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDateTime
import org.threeten.bp.Month
import org.threeten.bp.ZoneId
import org.threeten.bp.format.DateTimeFormatter.ofPattern
import org.threeten.bp.format.TextStyle.FULL_STANDALONE
import org.threeten.bp.temporal.TemporalAdjusters.firstInMonth
import org.threeten.bp.temporal.TemporalAdjusters.next
import org.threeten.bp.temporal.TemporalAdjusters.previous
import java.util.Date
import java.util.Locale
private const val DATE_PATTERN = "dd.MM.yyyy"
fun Date.toLocalDate(): LocalDate = Instant.ofEpochMilli(time).atZone(ZoneId.systemDefault()).toLocalDate()
fun Date.toLocalDateTime(): LocalDateTime = ofEpochMilli(time).atZone(ZoneId.systemDefault()).toLocalDateTime()
fun String.toLocalDate(format: String = DATE_PATTERN): LocalDate = LocalDate.parse(this, ofPattern(format))
fun LocalDate.toFormattedString(format: String = DATE_PATTERN): String = format(ofPattern(format))
fun LocalDateTime.toFormattedString(format: String = DATE_PATTERN): String = format(ofPattern(format))
fun LocalDateTime.toDate(): Date = DateTimeUtils.toDate(atZone(ZoneId.systemDefault()).toInstant())
/**
* https://github.com/ThreeTen/threetenbp/issues/55
*/
fun Month.getFormattedName(): String {
return getDisplayName(FULL_STANDALONE, Locale.getDefault())
.let {
@ -93,9 +81,6 @@ inline val LocalDate.previousOrSameSchoolDay: LocalDate
inline val LocalDate.weekDayName: String
get() = format(ofPattern("EEEE", Locale.getDefault()))
inline val LocalDate.shortcutWeekDayName: String
get() = format(ofPattern("EEE", Locale.getDefault()))
inline val LocalDate.monday: LocalDate
get() = with(MONDAY)
@ -105,7 +90,6 @@ inline val LocalDate.friday: LocalDate
/**
* [Dz.U. 2016 poz. 1335](http://prawo.sejm.gov.pl/isap.nsf/DocDetails.xsp?id=WDU20160001335)
*/
inline val LocalDate.isHolidays: Boolean
get() = isBefore(firstSchoolDay) && isAfter(lastSchoolDay)
@ -121,7 +105,6 @@ inline val LocalDate.lastSchoolDay: LocalDate
get() = LocalDate.of(year, 6, 20)
.with(next(FRIDAY))
private fun Int.getSchoolYearByMonth(monthValue: Int): Int {
return when (monthValue) {
in 9..12 -> this

View File

@ -31,7 +31,6 @@
android:spinnerMode="dialog" />
</io.github.wulkanowy.ui.widgets.MaterialLinearLayout>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/gradeStatisticsSwipe"
android:layout_width="match_parent"

View File

@ -7,6 +7,7 @@ import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.UnitTestInternetObservingStrategy
import io.reactivex.Maybe
import io.reactivex.Single
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
@ -14,6 +15,7 @@ import org.mockito.Mockito.doNothing
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import org.threeten.bp.LocalDate.now
class SemesterRepositoryTest {
@ -42,10 +44,10 @@ class SemesterRepositoryTest {
}
@Test
fun singleCurrentSemesterTest() {
fun getSemesters_noSemesters() {
val semesters = listOf(
createSemesterEntity(false),
createSemesterEntity(true)
createSemesterEntity(0, 0, now().minusMonths(6), now().minusMonths(3)),
createSemesterEntity(0, 0, now().minusMonths(3), now())
)
doNothing().`when`(sdkHelper).init(student)
@ -58,17 +60,112 @@ class SemesterRepositoryTest {
verify(semesterLocal).saveSemesters(semesters)
}
@Test(expected = IllegalArgumentException::class)
fun twoCurrentSemesterTest() {
@Test
fun getSemesters_noCurrent() {
val semesters = listOf(
createSemesterEntity(true),
createSemesterEntity(true)
createSemesterEntity(0, 0, now().minusMonths(12), now().minusMonths(6)),
createSemesterEntity(0, 0, now().minusMonths( 6), now().minusMonths(1))
)
doNothing().`when`(sdkHelper).init(student)
doReturn(Maybe.just(semesters)).`when`(semesterLocal).getSemesters(student)
val items = semesterRepository.getSemesters(student).blockingGet()
assertEquals(2, items.size)
}
@Test
fun getSemesters_oneCurrent() {
val semesters = listOf(
createSemesterEntity(0, 0, now().minusMonths(6), now().minusMonths(3)),
createSemesterEntity(0, 0, now().minusMonths(3), now())
)
doNothing().`when`(sdkHelper).init(student)
doReturn(Maybe.just(semesters)).`when`(semesterLocal).getSemesters(student)
val items = semesterRepository.getSemesters(student).blockingGet()
assertEquals(2, items.size)
}
@Test
fun getSemesters_doubleCurrent() {
val semesters = listOf(
createSemesterEntity(0, 0, now(), now()),
createSemesterEntity(0, 0, now(), now())
)
doNothing().`when`(sdkHelper).init(student)
doReturn(Maybe.just(semesters)).`when`(semesterLocal).getSemesters(student)
val items = semesterRepository.getSemesters(student).blockingGet()
assertEquals(2, items.size)
}
@Test
fun getSemesters_noSemesters_refreshOnNoCurrent() {
val semesters = listOf(
createSemesterEntity(0, 0, now().minusMonths(6), now().minusMonths(3)),
createSemesterEntity(0, 0, now().minusMonths(3), now())
)
doNothing().`when`(sdkHelper).init(student)
doReturn(Maybe.empty<Semester>()).`when`(semesterLocal).getSemesters(student)
doReturn(Single.just(semesters)).`when`(semesterRemote).getSemesters(student)
semesterRepository.getSemesters(student).blockingGet()
semesterRepository.getSemesters(student, refreshOnNoCurrent = true).blockingGet()
verify(semesterLocal).deleteSemesters(emptyList())
verify(semesterLocal).saveSemesters(semesters)
}
@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))
)
doNothing().`when`(sdkHelper).init(student)
doReturn(Maybe.just(semesters)).`when`(semesterLocal).getSemesters(student)
doReturn(Single.just(semesters)).`when`(semesterRemote).getSemesters(student)
val items = semesterRepository.getSemesters(student, refreshOnNoCurrent = true).blockingGet()
assertEquals(2, items.size)
}
@Test
fun getSemesters_doubleCurrent_refreshOnNoCurrent() {
val semesters = listOf(
createSemesterEntity(0, 0, now(), now()),
createSemesterEntity(0, 0, now(), now())
)
doNothing().`when`(sdkHelper).init(student)
doReturn(Maybe.just(semesters)).`when`(semesterLocal).getSemesters(student)
val items = semesterRepository.getSemesters(student, refreshOnNoCurrent = true).blockingGet()
assertEquals(2, items.size)
}
@Test(expected = IllegalArgumentException::class)
fun getCurrentSemester_doubleCurrent() {
val semesters = listOf(
createSemesterEntity(0, 0, now(), now()),
createSemesterEntity(0, 0, now(), now())
)
doNothing().`when`(sdkHelper).init(student)
doReturn(Maybe.just(semesters)).`when`(semesterLocal).getSemesters(student)
semesterRepository.getCurrentSemester(student).blockingGet()
}
@Test(expected = RuntimeException::class)
fun getCurrentSemester_emptyList() {
doNothing().`when`(sdkHelper).init(student)
doReturn(Maybe.just(emptyList<Semester>())).`when`(semesterLocal).getSemesters(student)
semesterRepository.getCurrentSemester(student).blockingGet()
}
}

View File

@ -1,20 +1,19 @@
package io.github.wulkanowy.data.repositories.semester
import io.github.wulkanowy.data.db.entities.Semester
import org.threeten.bp.LocalDate.now
import org.threeten.bp.LocalDate
fun createSemesterEntity(current: Boolean): Semester {
fun createSemesterEntity(diaryId: Int, semesterId: Int, start: LocalDate, end: LocalDate, semesterName: Int = 1): Semester {
return Semester(
studentId = 0,
diaryId = 0,
semesterId = 0,
diaryName = "",
studentId = 1,
diaryId = diaryId,
semesterId = semesterId,
diaryName = "$semesterId",
schoolYear = 1970,
classId = 0,
isCurrent = current,
semesterName = 0,
unitId = 0,
start = now(),
end = now()
semesterName = semesterName,
unitId = 1,
start = start,
end = end
)
}

View File

@ -2,11 +2,11 @@ package io.github.wulkanowy.ui.modules.grade
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.grade.GradeRepository
import io.github.wulkanowy.data.repositories.gradessummary.GradeSummaryRepository
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
import io.github.wulkanowy.data.repositories.semester.createSemesterEntity
import io.github.wulkanowy.sdk.Sdk
import io.reactivex.Single
import org.junit.Assert.assertEquals
@ -16,6 +16,7 @@ import org.mockito.Mock
import org.mockito.Mockito.doReturn
import org.mockito.MockitoAnnotations
import org.threeten.bp.LocalDate.now
import org.threeten.bp.LocalDate.of
import org.threeten.bp.LocalDateTime
class GradeAverageProviderTest {
@ -34,9 +35,9 @@ class GradeAverageProviderTest {
private val student = Student("", "", "", "SCRAPPER", "", "", false, "", "", "", 101, 0, "", "", "", "", 1, true, LocalDateTime.now())
private val semesters = mutableListOf(
Semester(101, 10, "", 1, 21, 1, false, now(), now(), 1, 1),
Semester(101, 11, "", 1, 22, 1, false, now(), now(), 1, 1),
Semester(101, 11, "", 1, 23, 2, true, now(), now(), 1, 1)
createSemesterEntity(10, 21, of(2019, 1, 31), of(2019, 6, 23)),
createSemesterEntity(11, 22, of(2019, 9, 1), of(2020, 1, 31)),
createSemesterEntity(11, 23, of(2020, 2, 1), now(), semesterName = 2)
)
private val firstGrades = listOf(