forked from github/wulkanowy-mirror
Optimize grade average provider (#792)
This commit is contained in:
parent
8eb0c0351b
commit
6d1fa0cf05
@ -122,7 +122,7 @@ configurations.all {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "io.github.wulkanowy:sdk:0.17.4"
|
||||
implementation "io.github.wulkanowy:sdk:445905b"
|
||||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
implementation "androidx.core:core-ktx:1.2.0"
|
||||
|
@ -24,7 +24,7 @@ class GradeLocalTest {
|
||||
fun createDb() {
|
||||
testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
|
||||
.build()
|
||||
gradeLocal = GradeLocal(testDb.gradeDao)
|
||||
gradeLocal = GradeLocal(testDb.gradeDao, testDb.gradeSummaryDao)
|
||||
}
|
||||
|
||||
@After
|
||||
@ -43,7 +43,7 @@ class GradeLocalTest {
|
||||
val semester = Semester(1, 2, "", 2019, 2, 1, now(), now(), 1, 1)
|
||||
|
||||
val grades = gradeLocal
|
||||
.getGrades(semester)
|
||||
.getGradesDetails(semester)
|
||||
.blockingGet()
|
||||
|
||||
assertEquals(2, grades.size)
|
||||
|
@ -11,6 +11,7 @@ import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.repositories.TestInternetObservingStrategy
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.sdk.pojo.Grade
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.every
|
||||
import io.mockk.impl.annotations.MockK
|
||||
@ -52,7 +53,7 @@ class GradeRepositoryTest {
|
||||
fun initApi() {
|
||||
MockKAnnotations.init(this)
|
||||
testDb = Room.inMemoryDatabaseBuilder(getApplicationContext(), AppDatabase::class.java).build()
|
||||
gradeLocal = GradeLocal(testDb.gradeDao)
|
||||
gradeLocal = GradeLocal(testDb.gradeDao, testDb.gradeSummaryDao)
|
||||
gradeRemote = GradeRemote(mockSdk)
|
||||
|
||||
every { studentMock.registrationDate } returns LocalDateTime.of(2019, 2, 27, 12, 0)
|
||||
@ -75,10 +76,10 @@ class GradeRepositoryTest {
|
||||
createGradeApi(5, 4.0, of(2019, 2, 26), "przed zalogowanie w aplikacji"),
|
||||
createGradeApi(5, 4.0, of(2019, 2, 27), "Ocena z dnia logowania"),
|
||||
createGradeApi(5, 4.0, of(2019, 2, 28), "Ocena jeszcze nowsza")
|
||||
))
|
||||
) to emptyList())
|
||||
|
||||
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
||||
.getGrades(studentMock, semesterMock, true).blockingGet().sortedByDescending { it.date }
|
||||
.getGrades(studentMock, semesterMock, true).blockingGet().first.sortedByDescending { it.date }
|
||||
|
||||
assertFalse { grades[0].isRead }
|
||||
assertFalse { grades[1].isRead }
|
||||
@ -99,10 +100,10 @@ class GradeRepositoryTest {
|
||||
createGradeApi(4, 3.0, of(2019, 2, 26), "starszą niż ostatnia lokalnie"),
|
||||
createGradeApi(3, 4.0, of(2019, 2, 27), "Ta jest z tego samego dnia co ostatnia lokalnie"),
|
||||
createGradeApi(2, 5.0, of(2019, 2, 28), "Ta jest już w ogóle nowa")
|
||||
))
|
||||
) to emptyList())
|
||||
|
||||
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
||||
.getGrades(studentMock, semesterMock, true).blockingGet().sortedByDescending { it.date }
|
||||
.getGrades(studentMock, semesterMock, true).blockingGet().first.sortedByDescending { it.date }
|
||||
|
||||
assertFalse { grades[0].isRead }
|
||||
assertFalse { grades[1].isRead }
|
||||
@ -121,12 +122,12 @@ class GradeRepositoryTest {
|
||||
every { mockSdk.getGrades(1) } returns Single.just(listOf(
|
||||
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
|
||||
createGradeApi(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
|
||||
))
|
||||
) to emptyList())
|
||||
|
||||
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
||||
.getGrades(studentMock, semesterMock, true).blockingGet()
|
||||
|
||||
assertEquals(2, grades.size)
|
||||
assertEquals(2, grades.first.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -140,12 +141,12 @@ class GradeRepositoryTest {
|
||||
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
|
||||
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
|
||||
createGradeApi(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
|
||||
))
|
||||
) to emptyList())
|
||||
|
||||
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
||||
.getGrades(studentMock, semesterMock, true).blockingGet()
|
||||
|
||||
assertEquals(3, grades.size)
|
||||
assertEquals(3, grades.first.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -156,12 +157,12 @@ class GradeRepositoryTest {
|
||||
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
|
||||
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
|
||||
createGradeApi(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
|
||||
))
|
||||
) to emptyList())
|
||||
|
||||
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
||||
.getGrades(studentMock, semesterMock, true).blockingGet()
|
||||
|
||||
assertEquals(3, grades.size)
|
||||
assertEquals(3, grades.first.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -171,11 +172,11 @@ class GradeRepositoryTest {
|
||||
createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
|
||||
))
|
||||
|
||||
every { mockSdk.getGrades(1) } returns Single.just(listOf())
|
||||
every { mockSdk.getGrades(1) } returns Single.just(emptyList<Grade>() to emptyList())
|
||||
|
||||
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
||||
.getGrades(studentMock, semesterMock, true).blockingGet()
|
||||
|
||||
assertEquals(0, grades.size)
|
||||
assertEquals(0, grades.first.size)
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,19 @@
|
||||
package io.github.wulkanowy.data.repositories.grade
|
||||
|
||||
import io.github.wulkanowy.data.db.dao.GradeDao
|
||||
import io.github.wulkanowy.data.db.dao.GradeSummaryDao
|
||||
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.reactivex.Maybe
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class GradeLocal @Inject constructor(private val gradeDb: GradeDao) {
|
||||
class GradeLocal @Inject constructor(
|
||||
private val gradeDb: GradeDao,
|
||||
private val gradeSummaryDb: GradeSummaryDao
|
||||
) {
|
||||
|
||||
fun saveGrades(grades: List<Grade>) {
|
||||
gradeDb.insertAll(grades)
|
||||
@ -22,7 +27,19 @@ class GradeLocal @Inject constructor(private val gradeDb: GradeDao) {
|
||||
gradeDb.updateAll(grades)
|
||||
}
|
||||
|
||||
fun getGrades(semester: Semester): Maybe<List<Grade>> {
|
||||
fun getGradesDetails(semester: Semester): Maybe<List<Grade>> {
|
||||
return gradeDb.loadAll(semester.semesterId, semester.studentId).filter { it.isNotEmpty() }
|
||||
}
|
||||
|
||||
fun saveGradesSummary(gradesSummary: List<GradeSummary>) {
|
||||
gradeSummaryDb.insertAll(gradesSummary)
|
||||
}
|
||||
|
||||
fun deleteGradesSummary(gradesSummary: List<GradeSummary>) {
|
||||
gradeSummaryDb.deleteAll(gradesSummary)
|
||||
}
|
||||
|
||||
fun getGradesSummary(semester: Semester): Maybe<List<GradeSummary>> {
|
||||
return gradeSummaryDb.loadAll(semester.semesterId, semester.studentId).filter { it.isNotEmpty() }
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package io.github.wulkanowy.data.repositories.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.sdk.Sdk
|
||||
@ -12,11 +13,11 @@ import javax.inject.Singleton
|
||||
@Singleton
|
||||
class GradeRemote @Inject constructor(private val sdk: Sdk) {
|
||||
|
||||
fun getGrades(student: Student, semester: Semester): Single<List<Grade>> {
|
||||
fun getGrades(student: Student, semester: Semester): Single<Pair<List<Grade>, List<GradeSummary>>> {
|
||||
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
|
||||
.getGrades(semester.semesterId)
|
||||
.map { grades ->
|
||||
grades.map {
|
||||
.map { (details, summary) ->
|
||||
details.map {
|
||||
Grade(
|
||||
studentId = semester.studentId,
|
||||
semesterId = semester.semesterId,
|
||||
@ -33,6 +34,19 @@ class GradeRemote @Inject constructor(private val sdk: Sdk) {
|
||||
date = it.date,
|
||||
teacher = it.teacher
|
||||
)
|
||||
} to summary.map {
|
||||
GradeSummary(
|
||||
semesterId = semester.semesterId,
|
||||
studentId = semester.studentId,
|
||||
position = 0,
|
||||
subject = it.name,
|
||||
predictedGrade = it.predicted,
|
||||
finalGrade = it.final,
|
||||
pointsSum = it.pointsSum,
|
||||
proposedPoints = it.proposedPoints,
|
||||
finalPoints = it.finalPoints,
|
||||
average = it.average
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package io.github.wulkanowy.data.repositories.grade
|
||||
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.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.utils.uniqueSubtract
|
||||
@ -19,34 +20,47 @@ class GradeRepository @Inject constructor(
|
||||
private val remote: GradeRemote
|
||||
) {
|
||||
|
||||
fun getGrades(student: Student, semester: Semester, forceRefresh: Boolean = false, notify: Boolean = false): Single<List<Grade>> {
|
||||
return local.getGrades(semester).filter { !forceRefresh }
|
||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||
.flatMap {
|
||||
if (it) remote.getGrades(student, semester)
|
||||
else Single.error(UnknownHostException())
|
||||
}.flatMap { new ->
|
||||
local.getGrades(semester).toSingle(emptyList())
|
||||
.doOnSuccess { old ->
|
||||
val notifyBreakDate = old.maxBy { it.date }?.date ?: student.registrationDate.toLocalDate()
|
||||
local.deleteGrades(old.uniqueSubtract(new))
|
||||
local.saveGrades(new.uniqueSubtract(old)
|
||||
.onEach {
|
||||
if (it.date >= notifyBreakDate) it.apply {
|
||||
isRead = false
|
||||
if (notify) isNotified = false
|
||||
}
|
||||
})
|
||||
}
|
||||
}.flatMap { local.getGrades(semester).toSingle(emptyList()) })
|
||||
fun getGrades(student: Student, semester: Semester, forceRefresh: Boolean = false, notify: Boolean = false): Single<Pair<List<Grade>, List<GradeSummary>>> {
|
||||
return local.getGradesDetails(semester).flatMap { details ->
|
||||
local.getGradesSummary(semester).map { summary -> details to summary }
|
||||
}.filter { !forceRefresh }
|
||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
|
||||
if (it) remote.getGrades(student, semester)
|
||||
else Single.error(UnknownHostException())
|
||||
}.flatMap { (newDetails, newSummary) ->
|
||||
local.getGradesDetails(semester).toSingle(emptyList())
|
||||
.doOnSuccess { old ->
|
||||
val notifyBreakDate = old.maxBy { it.date }?.date ?: student.registrationDate.toLocalDate()
|
||||
local.deleteGrades(old.uniqueSubtract(newDetails))
|
||||
local.saveGrades(newDetails.uniqueSubtract(old)
|
||||
.onEach {
|
||||
if (it.date >= notifyBreakDate) it.apply {
|
||||
isRead = false
|
||||
if (notify) isNotified = false
|
||||
}
|
||||
})
|
||||
}.flatMap {
|
||||
local.getGradesSummary(semester).toSingle(emptyList())
|
||||
.doOnSuccess { old ->
|
||||
local.deleteGradesSummary(old.uniqueSubtract(newSummary))
|
||||
local.saveGradesSummary(newSummary.uniqueSubtract(old))
|
||||
}
|
||||
}
|
||||
}.flatMap {
|
||||
local.getGradesDetails(semester).toSingle(emptyList()).flatMap { details ->
|
||||
local.getGradesSummary(semester).toSingle(emptyList()).map { summary ->
|
||||
details to summary
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun getUnreadGrades(semester: Semester): Single<List<Grade>> {
|
||||
return local.getGrades(semester).map { it.filter { grade -> !grade.isRead } }.toSingle(emptyList())
|
||||
return local.getGradesDetails(semester).map { it.filter { grade -> !grade.isRead } }.toSingle(emptyList())
|
||||
}
|
||||
|
||||
fun getNotNotifiedGrades(semester: Semester): Single<List<Grade>> {
|
||||
return local.getGrades(semester).map { it.filter { grade -> !grade.isNotified } }.toSingle(emptyList())
|
||||
return local.getGradesDetails(semester).map { it.filter { grade -> !grade.isNotified } }.toSingle(emptyList())
|
||||
}
|
||||
|
||||
fun updateGrade(grade: Grade): Completable {
|
||||
|
@ -1,24 +0,0 @@
|
||||
package io.github.wulkanowy.data.repositories.gradessummary
|
||||
|
||||
import io.github.wulkanowy.data.db.dao.GradeSummaryDao
|
||||
import io.github.wulkanowy.data.db.entities.GradeSummary
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.reactivex.Maybe
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class GradeSummaryLocal @Inject constructor(private val gradeSummaryDb: GradeSummaryDao) {
|
||||
|
||||
fun saveGradesSummary(gradesSummary: List<GradeSummary>) {
|
||||
gradeSummaryDb.insertAll(gradesSummary)
|
||||
}
|
||||
|
||||
fun deleteGradesSummary(gradesSummary: List<GradeSummary>) {
|
||||
gradeSummaryDb.deleteAll(gradesSummary)
|
||||
}
|
||||
|
||||
fun getGradesSummary(semester: Semester): Maybe<List<GradeSummary>> {
|
||||
return gradeSummaryDb.loadAll(semester.semesterId, semester.studentId).filter { it.isNotEmpty() }
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package io.github.wulkanowy.data.repositories.gradessummary
|
||||
|
||||
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.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.init
|
||||
import io.reactivex.Single
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class GradeSummaryRemote @Inject constructor(private val sdk: Sdk) {
|
||||
|
||||
fun getGradeSummary(student: Student, semester: Semester): Single<List<GradeSummary>> {
|
||||
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
|
||||
.getGradesSummary(semester.semesterId)
|
||||
.map { gradesSummary ->
|
||||
gradesSummary.map {
|
||||
GradeSummary(
|
||||
semesterId = semester.semesterId,
|
||||
studentId = semester.studentId,
|
||||
position = 0,
|
||||
subject = it.name,
|
||||
predictedGrade = it.predicted,
|
||||
finalGrade = it.final,
|
||||
pointsSum = it.pointsSum,
|
||||
proposedPoints = it.proposedPoints,
|
||||
finalPoints = it.finalPoints,
|
||||
average = it.average
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package io.github.wulkanowy.data.repositories.gradessummary
|
||||
|
||||
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.GradeSummary
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.utils.uniqueSubtract
|
||||
import io.reactivex.Single
|
||||
import java.net.UnknownHostException
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class GradeSummaryRepository @Inject constructor(
|
||||
private val settings: InternetObservingSettings,
|
||||
private val local: GradeSummaryLocal,
|
||||
private val remote: GradeSummaryRemote
|
||||
) {
|
||||
|
||||
fun getGradesSummary(student: Student, semester: Semester, forceRefresh: Boolean = false): Single<List<GradeSummary>> {
|
||||
return local.getGradesSummary(semester).filter { !forceRefresh }
|
||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||
.flatMap {
|
||||
if (it) remote.getGradeSummary(student, semester)
|
||||
else Single.error(UnknownHostException())
|
||||
}.flatMap { new ->
|
||||
local.getGradesSummary(semester).toSingle(emptyList())
|
||||
.doOnSuccess { old ->
|
||||
local.deleteGradesSummary(old.uniqueSubtract(new))
|
||||
local.saveGradesSummary(new.uniqueSubtract(old))
|
||||
}
|
||||
}.flatMap { local.getGradesSummary(semester).toSingle(emptyList()) })
|
||||
}
|
||||
}
|
@ -21,7 +21,6 @@ import io.github.wulkanowy.services.sync.works.AttendanceWork
|
||||
import io.github.wulkanowy.services.sync.works.CompletedLessonWork
|
||||
import io.github.wulkanowy.services.sync.works.ExamWork
|
||||
import io.github.wulkanowy.services.sync.works.GradeStatisticsWork
|
||||
import io.github.wulkanowy.services.sync.works.GradeSummaryWork
|
||||
import io.github.wulkanowy.services.sync.works.GradeWork
|
||||
import io.github.wulkanowy.services.sync.works.HomeworkWork
|
||||
import io.github.wulkanowy.services.sync.works.LuckyNumberWork
|
||||
@ -64,10 +63,6 @@ abstract class ServicesModule {
|
||||
@IntoSet
|
||||
abstract fun provideAttendanceWork(work: AttendanceWork): Work
|
||||
|
||||
@Binds
|
||||
@IntoSet
|
||||
abstract fun provideGradeSummaryWork(work: GradeSummaryWork): Work
|
||||
|
||||
@Binds
|
||||
@IntoSet
|
||||
abstract fun provideExamWork(work: ExamWork): Work
|
||||
|
@ -1,14 +0,0 @@
|
||||
package io.github.wulkanowy.services.sync.works
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.repositories.gradessummary.GradeSummaryRepository
|
||||
import io.reactivex.Completable
|
||||
import javax.inject.Inject
|
||||
|
||||
class GradeSummaryWork @Inject constructor(private val gradeSummaryRepository: GradeSummaryRepository) : Work {
|
||||
|
||||
override fun create(student: Student, semester: Semester): Completable {
|
||||
return gradeSummaryRepository.getGradesSummary(student, semester, true).ignoreElement()
|
||||
}
|
||||
}
|
@ -58,4 +58,3 @@ class GradeWork @Inject constructor(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,71 +3,76 @@ package io.github.wulkanowy.ui.modules.grade
|
||||
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.SemesterRepository
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.calcAverage
|
||||
import io.github.wulkanowy.utils.changeModifier
|
||||
import io.reactivex.Maybe
|
||||
import io.reactivex.Single
|
||||
import javax.inject.Inject
|
||||
|
||||
class GradeAverageProvider @Inject constructor(
|
||||
private val preferencesRepository: PreferencesRepository,
|
||||
private val semesterRepository: SemesterRepository,
|
||||
private val gradeRepository: GradeRepository,
|
||||
private val gradeSummaryRepository: GradeSummaryRepository
|
||||
private val preferencesRepository: PreferencesRepository
|
||||
) {
|
||||
|
||||
private val plusModifier = preferencesRepository.gradePlusModifier
|
||||
|
||||
private val minusModifier = preferencesRepository.gradeMinusModifier
|
||||
|
||||
fun getGradeAverage(student: Student, semesters: List<Semester>, selectedSemesterId: Int, forceRefresh: Boolean): Single<List<Triple<String, Double, String>>> {
|
||||
return when (preferencesRepository.gradeAverageMode) {
|
||||
"all_year" -> getAllYearAverage(student, semesters, selectedSemesterId, forceRefresh)
|
||||
"only_one_semester" -> getOnlyOneSemesterAverage(student, semesters, selectedSemesterId, forceRefresh)
|
||||
else -> throw IllegalArgumentException("Incorrect grade average mode: ${preferencesRepository.gradeAverageMode} ")
|
||||
fun getGradesDetailsWithAverage(student: Student, semesterId: Int, forceRefresh: Boolean = false): Single<List<GradeDetailsWithAverage>> {
|
||||
return semesterRepository.getSemesters(student).flatMap { semesters ->
|
||||
when (preferencesRepository.gradeAverageMode) {
|
||||
"only_one_semester" -> getSemesterDetailsWithAverage(student, semesters.single { it.semesterId == semesterId }, forceRefresh)
|
||||
"all_year" -> calculateWholeYearAverage(student, semesters, semesterId, forceRefresh)
|
||||
else -> throw IllegalArgumentException("Incorrect grade average mode: ${preferencesRepository.gradeAverageMode} ")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getAllYearAverage(student: Student, semesters: List<Semester>, semesterId: Int, forceRefresh: Boolean): Single<List<Triple<String, Double, String>>> {
|
||||
private fun calculateWholeYearAverage(student: Student, semesters: List<Semester>, semesterId: Int, forceRefresh: Boolean): Single<List<GradeDetailsWithAverage>> {
|
||||
val selectedSemester = semesters.single { it.semesterId == semesterId }
|
||||
val firstSemester = semesters.single { it.diaryId == selectedSemester.diaryId && it.semesterName == 1 }
|
||||
|
||||
return getAverageFromGradeSummary(student, selectedSemester, forceRefresh)
|
||||
.switchIfEmpty(gradeRepository.getGrades(student, selectedSemester, forceRefresh)
|
||||
.flatMap { firstGrades ->
|
||||
if (selectedSemester == firstSemester) Single.just(firstGrades)
|
||||
else {
|
||||
gradeRepository.getGrades(student, firstSemester)
|
||||
.map { secondGrades -> secondGrades + firstGrades }
|
||||
return getSemesterDetailsWithAverage(student, selectedSemester, forceRefresh).flatMap { selectedDetails ->
|
||||
val isAnyAverage = selectedDetails.any { it.average != .0 }
|
||||
|
||||
if (selectedSemester != firstSemester) {
|
||||
getSemesterDetailsWithAverage(student, firstSemester, forceRefresh).map { secondDetails ->
|
||||
selectedDetails.map { selected ->
|
||||
val second = secondDetails.singleOrNull { it.subject == selected.subject }
|
||||
selected.copy(
|
||||
average = if (!isAnyAverage || preferencesRepository.gradeAverageForceCalc) {
|
||||
(selected.grades + second?.grades.orEmpty()).calcAverage()
|
||||
} else (selected.average + (second?.average ?: selected.average)) / 2
|
||||
)
|
||||
}
|
||||
}.map { grades ->
|
||||
grades.map { if (student.loginMode == Sdk.Mode.SCRAPPER.name) it.changeModifier(plusModifier, minusModifier) else it }
|
||||
.groupBy { it.subject }
|
||||
.map { Triple(it.key, it.value.calcAverage(), "") }
|
||||
})
|
||||
}
|
||||
} else Single.just(selectedDetails)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getOnlyOneSemesterAverage(student: Student, semesters: List<Semester>, semesterId: Int, forceRefresh: Boolean): Single<List<Triple<String, Double, String>>> {
|
||||
val selectedSemester = semesters.single { it.semesterId == semesterId }
|
||||
private fun getSemesterDetailsWithAverage(student: Student, semester: Semester, forceRefresh: Boolean): Single<List<GradeDetailsWithAverage>> {
|
||||
return gradeRepository.getGrades(student, semester, forceRefresh).map { (details, summaries) ->
|
||||
val isAnyAverage = summaries.any { it.average != .0 }
|
||||
val allGrades = details.groupBy { it.subject }
|
||||
|
||||
return getAverageFromGradeSummary(student, selectedSemester, forceRefresh)
|
||||
.switchIfEmpty(gradeRepository.getGrades(student, selectedSemester, forceRefresh)
|
||||
.map { grades ->
|
||||
grades.map { if (student.loginMode == Sdk.Mode.SCRAPPER.name) it.changeModifier(plusModifier, minusModifier) else it }
|
||||
.groupBy { it.subject }
|
||||
.map { Triple(it.key, it.value.calcAverage(), "") }
|
||||
})
|
||||
}
|
||||
|
||||
private fun getAverageFromGradeSummary(student: Student, selectedSemester: Semester, forceRefresh: Boolean): Maybe<List<Triple<String, Double, String>>> {
|
||||
return gradeSummaryRepository.getGradesSummary(student, selectedSemester, forceRefresh)
|
||||
.toMaybe()
|
||||
.flatMap {
|
||||
if (it.any { summary -> summary.average != .0 }) {
|
||||
Maybe.just(it.map { summary -> Triple(summary.subject, summary.average, summary.pointsSum) })
|
||||
} else Maybe.empty()
|
||||
}.filter { !preferencesRepository.gradeAverageForceCalc }
|
||||
summaries.map { summary ->
|
||||
val grades = allGrades[summary.subject].orEmpty()
|
||||
GradeDetailsWithAverage(
|
||||
subject = summary.subject,
|
||||
average = if (!isAnyAverage || preferencesRepository.gradeAverageForceCalc) {
|
||||
grades.map {
|
||||
if (student.loginMode == Sdk.Mode.SCRAPPER.name) it.changeModifier(plusModifier, minusModifier)
|
||||
else it
|
||||
}.calcAverage()
|
||||
} else summary.average,
|
||||
points = summary.pointsSum,
|
||||
summary = summary,
|
||||
grades = grades
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,12 @@
|
||||
package io.github.wulkanowy.ui.modules.grade
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.Grade
|
||||
import io.github.wulkanowy.data.db.entities.GradeSummary
|
||||
|
||||
data class GradeDetailsWithAverage(
|
||||
val subject: String,
|
||||
val average: Double,
|
||||
val points: String,
|
||||
val summary: GradeSummary,
|
||||
val grades: List<Grade>
|
||||
)
|
@ -107,7 +107,7 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter<Recycler
|
||||
gradeHeaderAverage.text = formatAverage(header.average, root.context.resources)
|
||||
gradeHeaderPointsSum.text = root.context.getString(R.string.grade_points_sum, header.pointsSum)
|
||||
gradeHeaderPointsSum.visibility = if (!header.pointsSum.isNullOrEmpty()) View.VISIBLE else View.GONE
|
||||
gradeHeaderNumber.text = root.context.resources.getQuantityString(R.plurals.grade_number_item, header.number, header.number)
|
||||
gradeHeaderNumber.text = root.context.resources.getQuantityString(R.plurals.grade_number_item, header.grades.size, header.grades.size)
|
||||
gradeHeaderNote.visibility = if (header.newGrades > 0) View.VISIBLE else View.GONE
|
||||
if (header.newGrades > 0) gradeHeaderNote.text = header.newGrades.toString(10)
|
||||
|
||||
|
@ -12,7 +12,6 @@ data class GradeDetailsItem(
|
||||
|
||||
data class GradeDetailsHeader(
|
||||
val subject: String,
|
||||
val number: Int,
|
||||
val average: Double?,
|
||||
val pointsSum: String?,
|
||||
var newGrades: Int,
|
||||
|
@ -8,6 +8,7 @@ import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.ui.modules.grade.GradeAverageProvider
|
||||
import io.github.wulkanowy.ui.modules.grade.GradeDetailsWithAverage
|
||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||
import io.github.wulkanowy.utils.SchedulersProvider
|
||||
import timber.log.Timber
|
||||
@ -126,14 +127,7 @@ class GradeDetailsPresenter @Inject constructor(
|
||||
private fun loadData(semesterId: Int, forceRefresh: Boolean) {
|
||||
Timber.i("Loading grade details data started")
|
||||
disposable.add(studentRepository.getCurrentStudent()
|
||||
.flatMap { semesterRepository.getSemesters(it).map { semester -> it to semester } }
|
||||
.flatMap { (student, semesters) ->
|
||||
averageProvider.getGradeAverage(student, semesters, semesterId, forceRefresh).flatMap { averages ->
|
||||
gradeRepository.getGrades(student, semesters.first { it.semesterId == semesterId }, forceRefresh)
|
||||
.map { it.sortedByDescending { grade -> grade.date } }
|
||||
.map { createGradeItems(it, averages) }
|
||||
}
|
||||
}
|
||||
.flatMap { averageProvider.getGradesDetailsWithAverage(it, semesterId, forceRefresh) }
|
||||
.subscribeOn(schedulers.backgroundThread)
|
||||
.observeOn(schedulers.mainThread)
|
||||
.doFinally {
|
||||
@ -146,16 +140,14 @@ class GradeDetailsPresenter @Inject constructor(
|
||||
}
|
||||
.subscribe({ grades ->
|
||||
Timber.i("Loading grade details result: Success")
|
||||
newGradesAmount = grades
|
||||
.filter { it.viewType == ViewType.HEADER }
|
||||
.sumBy { item -> (item.value as GradeDetailsHeader).newGrades }
|
||||
newGradesAmount = grades.sumBy { it.grades.sumBy { grade -> if (!grade.isRead) 1 else 0 } }
|
||||
updateMarkAsDoneButton()
|
||||
view?.run {
|
||||
showEmpty(grades.isEmpty())
|
||||
showErrorView(false)
|
||||
showContent(grades.isNotEmpty())
|
||||
updateData(
|
||||
data = grades,
|
||||
data = createGradeItems(grades),
|
||||
isGradeExpandable = preferencesRepository.isGradeExpandable,
|
||||
gradeColorTheme = preferencesRepository.gradeColorTheme
|
||||
)
|
||||
@ -178,17 +170,16 @@ class GradeDetailsPresenter @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun createGradeItems(items: List<Grade>, averages: List<Triple<String, Double, String>>): List<GradeDetailsItem> {
|
||||
return items.groupBy { grade -> grade.subject }.toSortedMap().map { (subject, grades) ->
|
||||
private fun createGradeItems(items: List<GradeDetailsWithAverage>): List<GradeDetailsItem> {
|
||||
return items.filter { it.grades.isNotEmpty() }.map { (subject, average, points, _, grades) ->
|
||||
val subItems = grades.map {
|
||||
GradeDetailsItem(it, ViewType.ITEM)
|
||||
}
|
||||
|
||||
listOf(GradeDetailsItem(GradeDetailsHeader(
|
||||
subject = subject,
|
||||
average = averages.singleOrNull { subject == it.first }?.second,
|
||||
pointsSum = averages.singleOrNull { subject == it.first }?.third,
|
||||
number = grades.size,
|
||||
average = average,
|
||||
pointsSum = points,
|
||||
newGrades = grades.filter { grade -> !grade.isRead }.size,
|
||||
grades = subItems
|
||||
), ViewType.HEADER)) + if (preferencesRepository.isGradeExpandable) emptyList() else subItems
|
||||
|
@ -1,12 +1,11 @@
|
||||
package io.github.wulkanowy.ui.modules.grade.summary
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.GradeSummary
|
||||
import io.github.wulkanowy.data.repositories.gradessummary.GradeSummaryRepository
|
||||
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.ui.modules.grade.GradeAverageProvider
|
||||
import io.github.wulkanowy.ui.modules.grade.GradeDetailsWithAverage
|
||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||
import io.github.wulkanowy.utils.SchedulersProvider
|
||||
import timber.log.Timber
|
||||
@ -16,8 +15,6 @@ class GradeSummaryPresenter @Inject constructor(
|
||||
schedulers: SchedulersProvider,
|
||||
errorHandler: ErrorHandler,
|
||||
studentRepository: StudentRepository,
|
||||
private val gradeSummaryRepository: GradeSummaryRepository,
|
||||
private val semesterRepository: SemesterRepository,
|
||||
private val averageProvider: GradeAverageProvider,
|
||||
private val analytics: FirebaseAnalyticsHelper
|
||||
) : BasePresenter<GradeSummaryView>(errorHandler, studentRepository, schedulers) {
|
||||
@ -33,15 +30,8 @@ class GradeSummaryPresenter @Inject constructor(
|
||||
fun onParentViewLoadData(semesterId: Int, forceRefresh: Boolean) {
|
||||
Timber.i("Loading grade summary data started")
|
||||
disposable.add(studentRepository.getCurrentStudent()
|
||||
.flatMap { semesterRepository.getSemesters(it).map { semesters -> it to semesters } }
|
||||
.flatMap { (student, semesters) ->
|
||||
gradeSummaryRepository.getGradesSummary(student, semesters.first { it.semesterId == semesterId }, forceRefresh)
|
||||
.map { it.sortedBy { subject -> subject.subject } }
|
||||
.flatMap { gradesSummary ->
|
||||
averageProvider.getGradeAverage(student, semesters, semesterId, forceRefresh)
|
||||
.map { averages -> createGradeSummaryItems(gradesSummary, averages) }
|
||||
}
|
||||
}
|
||||
.flatMap { averageProvider.getGradesDetailsWithAverage(it, semesterId, forceRefresh) }
|
||||
.map { createGradeSummaryItems(it) }
|
||||
.subscribeOn(schedulers.backgroundThread)
|
||||
.observeOn(schedulers.mainThread)
|
||||
.doFinally {
|
||||
@ -112,12 +102,10 @@ class GradeSummaryPresenter @Inject constructor(
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
private fun createGradeSummaryItems(gradesSummary: List<GradeSummary>, averages: List<Triple<String, Double, String>>): List<GradeSummary> {
|
||||
return gradesSummary
|
||||
.filter { !checkEmpty(it, averages) }
|
||||
.map { gradeSummary ->
|
||||
gradeSummary.copy(average = averages.singleOrNull { gradeSummary.subject == it.first }?.second ?: .0)
|
||||
}
|
||||
private fun createGradeSummaryItems(items: List<GradeDetailsWithAverage>): List<GradeSummary> {
|
||||
return items.map {
|
||||
it.summary.copy(average = it.average)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkEmpty(gradeSummary: GradeSummary, averages: List<Triple<String, Double, String>>): Boolean {
|
||||
|
@ -3,17 +3,17 @@ 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.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.createSemesterEntity
|
||||
import io.github.wulkanowy.data.repositories.grade.GradeRepository
|
||||
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.reactivex.Single
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.doReturn
|
||||
import org.mockito.Mockito.`when`
|
||||
import org.mockito.MockitoAnnotations
|
||||
import org.threeten.bp.LocalDate.now
|
||||
import org.threeten.bp.LocalDate.of
|
||||
@ -25,10 +25,10 @@ class GradeAverageProviderTest {
|
||||
lateinit var preferencesRepository: PreferencesRepository
|
||||
|
||||
@Mock
|
||||
lateinit var gradeRepository: GradeRepository
|
||||
lateinit var semesterRepository: SemesterRepository
|
||||
|
||||
@Mock
|
||||
lateinit var gradeSummaryRepository: GradeSummaryRepository
|
||||
lateinit var gradeRepository: GradeRepository
|
||||
|
||||
private lateinit var gradeAverageProvider: GradeAverageProvider
|
||||
|
||||
@ -41,165 +41,192 @@ class GradeAverageProviderTest {
|
||||
)
|
||||
|
||||
private val firstGrades = listOf(
|
||||
// avg: 3.5
|
||||
getGrade(22, "Matematyka", 4.0),
|
||||
getGrade(22, "Matematyka", 3.0),
|
||||
|
||||
// avg: 3.5
|
||||
getGrade(22, "Fizyka", 6.0),
|
||||
getGrade(22, "Fizyka", 1.0)
|
||||
)
|
||||
|
||||
private val secondGrade = listOf(
|
||||
private val firstSummaries = listOf(
|
||||
getSummary(semesterId = 22, subject = "Matematyka", average = 3.9),
|
||||
getSummary(semesterId = 22, subject = "Fizyka", average = 3.1)
|
||||
)
|
||||
|
||||
private val secondGrades = listOf(
|
||||
// avg: 2.5
|
||||
getGrade(23, "Matematyka", 2.0),
|
||||
getGrade(23, "Matematyka", 3.0),
|
||||
|
||||
// avg: 3.0
|
||||
getGrade(23, "Fizyka", 4.0),
|
||||
getGrade(23, "Fizyka", 2.0)
|
||||
)
|
||||
|
||||
private val secondSummaries = listOf(
|
||||
getSummary(semesterId = 23, subject = "Matematyka", average = 2.9),
|
||||
getSummary(semesterId = 23, subject = "Fizyka", average = 3.4)
|
||||
)
|
||||
|
||||
private val secondGradeWithModifier = listOf(
|
||||
// avg: 3.375
|
||||
getGrade(24, "Język polski", 3.0, -0.50),
|
||||
getGrade(24, "Język polski", 4.0, 0.25)
|
||||
)
|
||||
|
||||
private val secondSummariesWithModifier = listOf(
|
||||
getSummary(24, "Język polski", 3.49)
|
||||
)
|
||||
|
||||
@Before
|
||||
fun initTest() {
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
gradeAverageProvider = GradeAverageProvider(preferencesRepository, gradeRepository, gradeSummaryRepository)
|
||||
|
||||
doReturn(.33).`when`(preferencesRepository).gradeMinusModifier
|
||||
doReturn(.33).`when`(preferencesRepository).gradePlusModifier
|
||||
doReturn(false).`when`(preferencesRepository).gradeAverageForceCalc
|
||||
`when`(preferencesRepository.gradeMinusModifier).thenReturn(.33)
|
||||
`when`(preferencesRepository.gradePlusModifier).thenReturn(.33)
|
||||
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
|
||||
`when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
|
||||
|
||||
doReturn(Single.just(firstGrades)).`when`(gradeRepository).getGrades(student, semesters[1], true)
|
||||
doReturn(Single.just(secondGrade)).`when`(gradeRepository).getGrades(student, semesters[2], true)
|
||||
gradeAverageProvider = GradeAverageProvider(semesterRepository, gradeRepository, preferencesRepository)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onlyOneSemesterTest() {
|
||||
doReturn("only_one_semester").`when`(preferencesRepository).gradeAverageMode
|
||||
doReturn(Single.just(emptyList<GradeSummary>())).`when`(gradeSummaryRepository).getGradesSummary(student, semesters[2], true)
|
||||
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
||||
`when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
|
||||
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries))
|
||||
|
||||
val averages = gradeAverageProvider.getGradeAverage(student, semesters, semesters[2].semesterId, true)
|
||||
.blockingGet()
|
||||
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
||||
|
||||
assertEquals(2, averages.size)
|
||||
assertEquals(2.5, averages.single { it.first == "Matematyka" }.second, .0)
|
||||
assertEquals(3.0, averages.single { it.first == "Fizyka" }.second, .0)
|
||||
assertEquals(2, items.size)
|
||||
assertEquals(2.5, items.single { it.subject == "Matematyka" }.average, .0)
|
||||
assertEquals(3.0, items.single { it.subject == "Fizyka" }.average, .0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onlyOneSemester_gradesWithModifiers_default() {
|
||||
doReturn("only_one_semester").`when`(preferencesRepository).gradeAverageMode
|
||||
doReturn(Single.just(emptyList<GradeSummary>())).`when`(gradeSummaryRepository).getGradesSummary(student, semesters[2], true)
|
||||
doReturn(Single.just(secondGradeWithModifier)).`when`(gradeRepository).getGrades(student, semesters[2], true)
|
||||
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
||||
`when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
|
||||
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier))
|
||||
|
||||
val averages = gradeAverageProvider.getGradeAverage(student, semesters, semesters[2].semesterId, true)
|
||||
.blockingGet()
|
||||
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
||||
|
||||
assertEquals(3.5, averages.single { it.first == "Język polski" }.second, .0)
|
||||
assertEquals(3.5, items.single { it.subject == "Język polski" }.average, .0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onlyOneSemester_gradesWithModifiers_api() {
|
||||
doReturn("only_one_semester").`when`(preferencesRepository).gradeAverageMode
|
||||
doReturn(Single.just(emptyList<GradeSummary>())).`when`(gradeSummaryRepository).getGradesSummary(student.copy(loginMode = Sdk.Mode.API.name), semesters[2], true)
|
||||
doReturn(Single.just(secondGradeWithModifier)).`when`(gradeRepository).getGrades(student.copy(loginMode = Sdk.Mode.API.name), semesters[2], true)
|
||||
val student = student.copy(loginMode = Sdk.Mode.API.name)
|
||||
|
||||
val averages = gradeAverageProvider.getGradeAverage(student.copy(loginMode = Sdk.Mode.API.name), semesters, semesters[2].semesterId, true)
|
||||
.blockingGet()
|
||||
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
||||
`when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
|
||||
`when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
|
||||
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier))
|
||||
|
||||
assertEquals(3.375, averages.single { it.first == "Język polski" }.second, .0)
|
||||
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
||||
|
||||
assertEquals(3.375, items.single { it.subject == "Język polski" }.average, .0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onlyOneSemester_gradesWithModifiers_scrapper() {
|
||||
doReturn("only_one_semester").`when`(preferencesRepository).gradeAverageMode
|
||||
doReturn(Single.just(emptyList<GradeSummary>())).`when`(gradeSummaryRepository).getGradesSummary(student, semesters[2], true)
|
||||
doReturn(Single.just(secondGradeWithModifier)).`when`(gradeRepository).getGrades(student.copy(loginMode = Sdk.Mode.SCRAPPER.name), semesters[2], true)
|
||||
val student = student.copy(loginMode = Sdk.Mode.SCRAPPER.name)
|
||||
|
||||
val averages = gradeAverageProvider.getGradeAverage(student.copy(loginMode = Sdk.Mode.SCRAPPER.name), semesters, semesters[2].semesterId, true)
|
||||
.blockingGet()
|
||||
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
||||
`when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
|
||||
`when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
|
||||
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier))
|
||||
|
||||
assertEquals(3.5, averages.single { it.first == "Język polski" }.second, .0)
|
||||
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
||||
|
||||
assertEquals(3.5, items.single { it.subject == "Język polski" }.average, .0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onlyOneSemester_gradesWithModifiers_hybrid() {
|
||||
doReturn("only_one_semester").`when`(preferencesRepository).gradeAverageMode
|
||||
doReturn(Single.just(emptyList<GradeSummary>())).`when`(gradeSummaryRepository).getGradesSummary(student.copy(loginMode = Sdk.Mode.HYBRID.name), semesters[2], true)
|
||||
doReturn(Single.just(secondGradeWithModifier)).`when`(gradeRepository).getGrades(student.copy(loginMode = Sdk.Mode.HYBRID.name), semesters[2], true)
|
||||
val student = student.copy(loginMode = Sdk.Mode.HYBRID.name)
|
||||
|
||||
val averages = gradeAverageProvider.getGradeAverage(student.copy(loginMode = Sdk.Mode.HYBRID.name), semesters, semesters[2].semesterId, true)
|
||||
.blockingGet()
|
||||
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
||||
`when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
|
||||
`when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
|
||||
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier))
|
||||
|
||||
assertEquals(3.375, averages.single { it.first == "Język polski" }.second, .0)
|
||||
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
||||
|
||||
assertEquals(3.375, items.single { it.subject == "Język polski" }.average, .0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun allYearFirstSemesterTest() {
|
||||
doReturn("all_year").`when`(preferencesRepository).gradeAverageMode
|
||||
doReturn(Single.just(emptyList<GradeSummary>())).`when`(gradeSummaryRepository).getGradesSummary(student, semesters[1], true)
|
||||
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
||||
`when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
|
||||
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries))
|
||||
|
||||
val averages = gradeAverageProvider.getGradeAverage(student, semesters, semesters[1].semesterId, true)
|
||||
.blockingGet()
|
||||
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[1].semesterId).blockingGet()
|
||||
|
||||
assertEquals(2, averages.size)
|
||||
assertEquals(3.5, averages.single { it.first == "Matematyka" }.second, .0)
|
||||
assertEquals(3.5, averages.single { it.first == "Fizyka" }.second, .0)
|
||||
assertEquals(2, items.size)
|
||||
assertEquals(3.5, items.single { it.subject == "Matematyka" }.average, .0)
|
||||
assertEquals(3.5, items.single { it.subject == "Fizyka" }.average, .0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun allYearSecondSemesterTest() {
|
||||
doReturn("all_year").`when`(preferencesRepository).gradeAverageMode
|
||||
doReturn(Single.just(firstGrades)).`when`(gradeRepository).getGrades(student, semesters[1], false)
|
||||
doReturn(Single.just(emptyList<GradeSummary>())).`when`(gradeSummaryRepository).getGradesSummary(student, semesters[2], true)
|
||||
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
||||
`when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
|
||||
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries))
|
||||
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries))
|
||||
|
||||
val averages = gradeAverageProvider.getGradeAverage(student, semesters, semesters[2].semesterId, true)
|
||||
.blockingGet()
|
||||
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
||||
|
||||
assertEquals(2, averages.size)
|
||||
assertEquals(3.0, averages.single { it.first == "Matematyka" }.second, .0)
|
||||
assertEquals(3.25, averages.single { it.first == "Fizyka" }.second, .0)
|
||||
assertEquals(2, items.size)
|
||||
assertEquals(3.0, items.single { it.subject == "Matematyka" }.average, .0)
|
||||
assertEquals(3.25, items.single { it.subject == "Fizyka" }.average, .0)
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException::class)
|
||||
fun incorrectAverageModeTest() {
|
||||
doReturn("test_mode").`when`(preferencesRepository).gradeAverageMode
|
||||
`when`(preferencesRepository.gradeAverageMode).thenReturn("test_mode")
|
||||
|
||||
gradeAverageProvider.getGradeAverage(student, semesters, semesters[2].semesterId, true).blockingGet()
|
||||
gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, true).blockingGet()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onlyOneSemester_averageFromSummary() {
|
||||
doReturn("all_year").`when`(preferencesRepository).gradeAverageMode
|
||||
doReturn(Single.just(firstGrades)).`when`(gradeRepository).getGrades(student, semesters[1], false)
|
||||
doReturn(Single.just(listOf(
|
||||
getSummary(22, "Matematyka", 3.1),
|
||||
getSummary(22, "Fizyka", 3.26)
|
||||
))).`when`(gradeSummaryRepository).getGradesSummary(student, semesters[2], true)
|
||||
fun allYearSemester_averageFromSummary() {
|
||||
`when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
|
||||
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
|
||||
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to listOf(
|
||||
getSummary(22, "Matematyka", 3.0),
|
||||
getSummary(22, "Fizyka", 3.5)
|
||||
)))
|
||||
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to listOf(
|
||||
getSummary(22, "Matematyka", 3.5),
|
||||
getSummary(22, "Fizyka", 4.0)
|
||||
)))
|
||||
|
||||
val averages = gradeAverageProvider.getGradeAverage(student, semesters, semesters[2].semesterId, true)
|
||||
.blockingGet()
|
||||
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
||||
|
||||
assertEquals(2, averages.size)
|
||||
assertEquals(3.1, averages.single { it.first == "Matematyka" }.second, .0)
|
||||
assertEquals(3.26, averages.single { it.first == "Fizyka" }.second, .0)
|
||||
assertEquals(2, items.size)
|
||||
assertEquals(3.25, items.single { it.subject == "Matematyka" }.average, .0)
|
||||
assertEquals(3.75, items.single { it.subject == "Fizyka" }.average, .0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onlyOneSemester_averageFromSummary_forceCalc() {
|
||||
doReturn(true).`when`(preferencesRepository).gradeAverageForceCalc
|
||||
doReturn("all_year").`when`(preferencesRepository).gradeAverageMode
|
||||
doReturn(Single.just(firstGrades)).`when`(gradeRepository).getGrades(student, semesters[1], false)
|
||||
doReturn(Single.just(listOf(
|
||||
getSummary(22, "Matematyka", 3.1),
|
||||
getSummary(22, "Fizyka", 3.26)
|
||||
))).`when`(gradeSummaryRepository).getGradesSummary(student, semesters[2], true)
|
||||
`when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
|
||||
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
||||
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries))
|
||||
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to listOf(
|
||||
getSummary(22, "Matematyka", 1.1),
|
||||
getSummary(22, "Fizyka", 7.26)
|
||||
)))
|
||||
|
||||
val averages = gradeAverageProvider.getGradeAverage(student, semesters, semesters[2].semesterId, true)
|
||||
.blockingGet()
|
||||
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
||||
|
||||
assertEquals(2, averages.size)
|
||||
assertEquals(3.0, averages.single { it.first == "Matematyka" }.second, .0)
|
||||
assertEquals(3.25, averages.single { it.first == "Fizyka" }.second, .0)
|
||||
assertEquals(2, items.size)
|
||||
assertEquals(3.0, items.single { it.subject == "Matematyka" }.average, .0)
|
||||
assertEquals(3.25, items.single { it.subject == "Fizyka" }.average, .0)
|
||||
}
|
||||
|
||||
private fun getGrade(semesterId: Int, subject: String, value: Double, modifier: Double = 0.0): Grade {
|
||||
@ -221,12 +248,12 @@ class GradeAverageProviderTest {
|
||||
)
|
||||
}
|
||||
|
||||
private fun getSummary(semesterId: Int, subject: String, value: Double): GradeSummary {
|
||||
private fun getSummary(semesterId: Int, subject: String, average: Double): GradeSummary {
|
||||
return GradeSummary(
|
||||
studentId = 101,
|
||||
semesterId = semesterId,
|
||||
subject = subject,
|
||||
average = value,
|
||||
average = average,
|
||||
pointsSum = "",
|
||||
proposedPoints = "",
|
||||
finalPoints = "",
|
||||
|
Loading…
x
Reference in New Issue
Block a user