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