diff --git a/app/build.gradle b/app/build.gradle index e2aab017..cb735b3b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -124,7 +124,7 @@ configurations.all { } dependencies { - implementation "io.github.wulkanowy:sdk:0.18.2" + implementation "io.github.wulkanowy:sdk:a57afdb" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation "androidx.core:core-ktx:1.2.0" diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/preferences/PreferencesRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/preferences/PreferencesRepository.kt index 6b13563a..7715cde0 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/preferences/PreferencesRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/preferences/PreferencesRepository.kt @@ -3,6 +3,7 @@ package io.github.wulkanowy.data.repositories.preferences import android.content.Context import android.content.SharedPreferences import io.github.wulkanowy.R +import io.github.wulkanowy.ui.modules.grade.GradeAverageMode import javax.inject.Inject import javax.inject.Singleton @@ -17,8 +18,8 @@ class PreferencesRepository @Inject constructor( val isShowPresent: Boolean get() = getBoolean(R.string.pref_key_attendance_present, R.bool.pref_default_attendance_present) - val gradeAverageMode: String - get() = getString(R.string.pref_key_grade_average_mode, R.string.pref_default_grade_average_mode) + val gradeAverageMode: GradeAverageMode + get() = GradeAverageMode.getByValue(getString(R.string.pref_key_grade_average_mode, R.string.pref_default_grade_average_mode)) val gradeAverageForceCalc: Boolean get() = getBoolean(R.string.pref_key_grade_average_force_calc, R.bool.pref_default_grade_average_force_calc) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageMode.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageMode.kt new file mode 100644 index 00000000..1960c3df --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageMode.kt @@ -0,0 +1,11 @@ +package io.github.wulkanowy.ui.modules.grade + +enum class GradeAverageMode(val value: String) { + ALL_YEAR("all_year"), + ONE_SEMESTER("only_one_semester"), + BOTH_SEMESTERS("both_semesters"); + + companion object { + fun getByValue(value: String) = values().firstOrNull { it.value == value } ?: ONE_SEMESTER + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProvider.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProvider.kt index 9582a5db..bda098f4 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProvider.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProvider.kt @@ -8,6 +8,9 @@ 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.ui.modules.grade.GradeAverageMode.ALL_YEAR +import io.github.wulkanowy.ui.modules.grade.GradeAverageMode.BOTH_SEMESTERS +import io.github.wulkanowy.ui.modules.grade.GradeAverageMode.ONE_SEMESTER import io.github.wulkanowy.utils.calcAverage import io.github.wulkanowy.utils.changeModifier import io.reactivex.Single @@ -19,21 +22,21 @@ class GradeAverageProvider @Inject constructor( private val preferencesRepository: PreferencesRepository ) { - private val plusModifier = preferencesRepository.gradePlusModifier + private val plusModifier get() = preferencesRepository.gradePlusModifier - private val minusModifier = preferencesRepository.gradeMinusModifier + private val minusModifier get() = preferencesRepository.gradeMinusModifier fun getGradesDetailsWithAverage(student: Student, semesterId: Int, forceRefresh: Boolean = false): Single> { 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} ") + ONE_SEMESTER -> getSemesterDetailsWithAverage(student, semesters.single { it.semesterId == semesterId }, forceRefresh) + BOTH_SEMESTERS -> calculateBothSemestersAverage(student, semesters, semesterId, forceRefresh) + ALL_YEAR -> calculateAllYearAverage(student, semesters, semesterId, forceRefresh) } } } - private fun calculateWholeYearAverage(student: Student, semesters: List, semesterId: Int, forceRefresh: Boolean): Single> { + private fun calculateBothSemestersAverage(student: Student, semesters: List, semesterId: Int, forceRefresh: Boolean): Single> { val selectedSemester = semesters.single { it.semesterId == semesterId } val firstSemester = semesters.single { it.diaryId == selectedSemester.diaryId && it.semesterName == 1 } @@ -44,11 +47,30 @@ class GradeAverageProvider @Inject constructor( 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 - ) + selected.copy(average = if (!isAnyAverage || preferencesRepository.gradeAverageForceCalc) { + val selectedGrades = selected.grades.updateModifiers(student).calcAverage() + (selectedGrades + (second?.grades?.updateModifiers(student)?.calcAverage() ?: selectedGrades)) / 2 + } else (selected.average + (second?.average ?: selected.average)) / 2) + } + } + } else Single.just(selectedDetails) + } + } + + private fun calculateAllYearAverage(student: Student, semesters: List, semesterId: Int, forceRefresh: Boolean): Single> { + val selectedSemester = semesters.single { it.semesterId == semesterId } + val firstSemester = semesters.single { it.diaryId == selectedSemester.diaryId && it.semesterName == 1 } + + 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.updateModifiers(student) + second?.grades?.updateModifiers(student).orEmpty()).calcAverage() + } else selected.average) } } } else Single.just(selectedDetails) @@ -65,9 +87,7 @@ class GradeAverageProvider @Inject constructor( GradeDetailsWithAverage( subject = summary.subject, average = if (!isAnyAverage || preferencesRepository.gradeAverageForceCalc) { - (if (student.loginMode == Sdk.Mode.SCRAPPER.name) - grades.map { it.changeModifier(plusModifier, minusModifier) } - else grades).calcAverage() + grades.updateModifiers(student).calcAverage() } else summary.average, points = summary.pointsSum, summary = summary, @@ -92,10 +112,14 @@ class GradeAverageProvider @Inject constructor( proposedPoints = "", finalPoints = "", pointsSum = "", - average = if (calcAverage) (if (student.loginMode == Sdk.Mode.SCRAPPER.name) { - details.map { it.changeModifier(plusModifier, minusModifier) } - } else details).calcAverage() else .0 + average = if (calcAverage) details.updateModifiers(student).calcAverage() else .0 ) } } + + private fun List.updateModifiers(student: Student): List { + return if (student.loginMode == Sdk.Mode.SCRAPPER.name) { + map { it.changeModifier(plusModifier, minusModifier) } + } else this + } } diff --git a/app/src/main/res/values-de/preferences_values.xml b/app/src/main/res/values-de/preferences_values.xml index 28ad08bc..49628798 100644 --- a/app/src/main/res/values-de/preferences_values.xml +++ b/app/src/main/res/values-de/preferences_values.xml @@ -36,6 +36,7 @@ Durchschnittsnote für das 2. Semester + Average of grades from both semesters Durchschnitt der Bewertungen für das ganze Jahr diff --git a/app/src/main/res/values-pl/preferences_values.xml b/app/src/main/res/values-pl/preferences_values.xml index 475f7327..1d81fb58 100644 --- a/app/src/main/res/values-pl/preferences_values.xml +++ b/app/src/main/res/values-pl/preferences_values.xml @@ -35,8 +35,9 @@ Kolory ocen w dzienniku - Średnia ocen z 2 semestru - Średnia ocen z całego roku + Średnia ocen z drugiego semestru + Średnia średnich z obu semestrów + Średnia wszystkich ocen z całego roku Nie pokazuj diff --git a/app/src/main/res/values-ru/preferences_values.xml b/app/src/main/res/values-ru/preferences_values.xml index 6c152268..bd8bb844 100644 --- a/app/src/main/res/values-ru/preferences_values.xml +++ b/app/src/main/res/values-ru/preferences_values.xml @@ -36,6 +36,7 @@ Средняя оценка со 2 семестра + Average of grades from both semesters Средняя оценка с целого года diff --git a/app/src/main/res/values-uk/preferences_values.xml b/app/src/main/res/values-uk/preferences_values.xml index 3c70c9d0..be2179c3 100644 --- a/app/src/main/res/values-uk/preferences_values.xml +++ b/app/src/main/res/values-uk/preferences_values.xml @@ -36,6 +36,7 @@ Середня оцінка з 2 семестру + Average of grades from both semesters Середня оцінка за весь рік diff --git a/app/src/main/res/values/preferences_values.xml b/app/src/main/res/values/preferences_values.xml index 76427a48..5824658c 100644 --- a/app/src/main/res/values/preferences_values.xml +++ b/app/src/main/res/values/preferences_values.xml @@ -88,10 +88,12 @@ Average of grades only from the 2nd semester + Average of grades from both semesters Average of grades from the whole year only_one_semester + both_semesters all_year diff --git a/app/src/test/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProviderTest.kt b/app/src/test/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProviderTest.kt index ee8634ca..984bbbcf 100644 --- a/app/src/test/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProviderTest.kt +++ b/app/src/test/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProviderTest.kt @@ -86,6 +86,8 @@ class GradeAverageProviderTest { `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false) `when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters)) + `when`(preferencesRepository.gradeMinusModifier).thenReturn(.33) + `when`(preferencesRepository.gradePlusModifier).thenReturn(.33) gradeAverageProvider = GradeAverageProvider(semesterRepository, gradeRepository, preferencesRepository) } @@ -93,7 +95,7 @@ class GradeAverageProviderTest { @Test fun `force calc current semester average with default modifiers in scraper mode`() { `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true) - `when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester") + `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.ONE_SEMESTER) `when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters)) `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier)) @@ -110,7 +112,7 @@ class GradeAverageProviderTest { `when`(preferencesRepository.gradeMinusModifier).thenReturn(.33) `when`(preferencesRepository.gradePlusModifier).thenReturn(.33) - `when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester") + `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.ONE_SEMESTER) `when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters)) `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier)) @@ -127,7 +129,7 @@ class GradeAverageProviderTest { `when`(preferencesRepository.gradeMinusModifier).thenReturn(.33) // useless in this mode `when`(preferencesRepository.gradePlusModifier).thenReturn(.33) - `when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester") + `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.ONE_SEMESTER) `when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters)) `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier)) @@ -144,7 +146,7 @@ class GradeAverageProviderTest { `when`(preferencesRepository.gradeMinusModifier).thenReturn(.33) // useless in this mode `when`(preferencesRepository.gradePlusModifier).thenReturn(.33) - `when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester") + `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.ONE_SEMESTER) `when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters)) `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier)) @@ -156,7 +158,7 @@ class GradeAverageProviderTest { @Test fun `calc current semester average`() { `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false) - `when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester") + `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.ONE_SEMESTER) `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries)) val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet() @@ -169,7 +171,7 @@ class GradeAverageProviderTest { @Test fun `force calc current semester average`() { `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true) - `when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester") + `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.ONE_SEMESTER) `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries)) val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet() @@ -182,7 +184,7 @@ class GradeAverageProviderTest { @Test fun `force calc full year average when current is first`() { `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true) - `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year") + `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.ALL_YEAR) `when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries)) val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[1].semesterId).blockingGet() @@ -192,16 +194,9 @@ class GradeAverageProviderTest { assertEquals(3.5, items.single { it.subject == "Fizyka" }.average, .0) // (from summary): 3,5 } - @Test(expected = IllegalArgumentException::class) - fun `calc average on invalid mode`() { - `when`(preferencesRepository.gradeAverageMode).thenReturn("test_mode") - - gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, true).blockingGet() - } - @Test - fun `calc full year average`() { - `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year") + fun `calc both semesters average`() { + `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.BOTH_SEMESTERS) `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false) `when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to listOf( getSummary(22, "Matematyka", 3.0), @@ -222,7 +217,7 @@ class GradeAverageProviderTest { @Test fun `force calc full year average`() { `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true) - `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year") + `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.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 listOf( getSummary(22, "Matematyka", 1.1), @@ -237,9 +232,9 @@ class GradeAverageProviderTest { } @Test - fun `calc full year average when no summaries`() { + fun `calc both semesters average when no summaries`() { `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false) - `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year") + `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.BOTH_SEMESTERS) `when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to emptyList())) `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to emptyList())) @@ -247,14 +242,14 @@ class GradeAverageProviderTest { val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet() assertEquals(2, items.size) - assertEquals(3.0, items.single { it.subject == "Matematyka" }.average, .0) // (from details): 2,5 + 3,5 → 3,0 - assertEquals(3.25, items.single { it.subject == "Fizyka" }.average, .0) // (from details): 3,5 + 3,0 → 3,25 + assertEquals(3.0, items.single { it.subject == "Matematyka" }.average, .0) // (from details): 3,5 + 2,5 → 3,0 + assertEquals(3.25, items.single { it.subject == "Fizyka" }.average, .0) // (from details): 3,5 + 3,0 → 3,25 } @Test fun `force calc full year average when no summaries`() { `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true) - `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year") + `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.ALL_YEAR) `when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to emptyList())) `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to emptyList())) @@ -267,9 +262,9 @@ class GradeAverageProviderTest { } @Test - fun `calc full year average when missing summaries in both semesters`() { + fun `calc both semesters average when missing summaries in both semesters`() { `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false) - `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year") + `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.BOTH_SEMESTERS) `when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to listOf( getSummary(22, "Matematyka", 4.0) @@ -286,9 +281,9 @@ class GradeAverageProviderTest { } @Test - fun `calc full year average when missing summary in second semester`() { + fun `calc both semesters average when missing summary in second semester`() { `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false) - `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year") + `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.BOTH_SEMESTERS) `when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries)) `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries.dropLast(1))) @@ -301,9 +296,9 @@ class GradeAverageProviderTest { } @Test - fun `calc full year average when missing summary in first semester`() { + fun `calc both semesters average when missing summary in first semester`() { `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false) - `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year") + `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.BOTH_SEMESTERS) `when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries.dropLast(1))) `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries)) @@ -318,7 +313,7 @@ class GradeAverageProviderTest { @Test fun `force calc full year average when missing summary in first semester`() { `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true) - `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year") + `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.ALL_YEAR) `when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries.dropLast(1))) `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries)) @@ -330,14 +325,130 @@ class GradeAverageProviderTest { assertEquals(3.25, items.single { it.subject == "Fizyka" }.average, .0) // (from details): 3,5 + 3,0 → 3,25 } - private fun getGrade(semesterId: Int, subject: String, value: Double, modifier: Double = 0.0): Grade { + @Test + fun `force calc both semesters average with different average from all grades and from two semesters`() { + `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true) + `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.BOTH_SEMESTERS) + + `when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(listOf( + getGrade(22, "Fizyka", 5.0, weight = 2.0), + getGrade(22, "Fizyka", 6.0, weight = 2.0), + getGrade(22, "Fizyka", 5.0, weight = 4.0), + getGrade(22, "Fizyka", 6.0, weight = 2.0), + getGrade(22, "Fizyka", 6.0, weight = 2.0), + getGrade(22, "Fizyka", 6.0, weight = 4.0), + getGrade(22, "Fizyka", 6.0, weight = 4.0), + getGrade(22, "Fizyka", 6.0, weight = 2.0) + ) to listOf(getSummary(semesterId = 22, subject = "Fizyka", average = .0)))) + `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(listOf( + getGrade(23, "Fizyka", 5.0, weight = 1.0), + getGrade(23, "Fizyka", 5.0, weight = 2.0), + getGrade(23, "Fizyka", 4.0, modifier = 0.3, weight = 2.0) + ) to listOf(getSummary(semesterId = 23, subject = "Fizyka", average = .0)))) + + val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet() + + assertEquals(5.2296, items.single { it.subject == "Fizyka" }.average, .0001) // (from details): 5.72727272 + 4,732 → 5.229636363636364 + } + + @Test + fun `force calc full year average with different average from all grades and from two semesters`() { + `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true) + `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.ALL_YEAR) + + `when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(listOf( + getGrade(22, "Fizyka", 5.0, weight = 2.0), + getGrade(22, "Fizyka", 6.0, weight = 2.0), + getGrade(22, "Fizyka", 5.0, weight = 4.0), + getGrade(22, "Fizyka", 6.0, weight = 2.0), + getGrade(22, "Fizyka", 6.0, weight = 2.0), + getGrade(22, "Fizyka", 6.0, weight = 4.0), + getGrade(22, "Fizyka", 6.0, weight = 4.0), + getGrade(22, "Fizyka", 6.0, weight = 2.0) + ) to listOf(getSummary(semesterId = 22, subject = "Fizyka", average = .0)))) + `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(listOf( + getGrade(23, "Fizyka", 5.0, weight = 1.0), + getGrade(23, "Fizyka", 5.0, weight = 2.0), + getGrade(23, "Fizyka", 4.0, modifier = 0.3, weight = 2.0) + ) to listOf(getSummary(semesterId = 23, subject = "Fizyka", average = .0)))) + + val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet() + + assertEquals(5.5429, items.single { it.subject == "Fizyka" }.average, .0001) // (from details): 5.72727272 + 4,732 → .average() + } + + @Test + fun `force calc both semesters average with different average from all grades and from two semesters with custom modifiers`() { + val student = student.copy(loginMode = Sdk.Mode.SCRAPPER.name) + + `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true) + `when`(preferencesRepository.gradeMinusModifier).thenReturn(.33) + `when`(preferencesRepository.gradePlusModifier).thenReturn(.5) + + `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.BOTH_SEMESTERS) + `when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters)) + + `when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(listOf( + getGrade(22, "Fizyka", 5.0, weight = 2.0), + getGrade(22, "Fizyka", 6.0, weight = 2.0), + getGrade(22, "Fizyka", 5.0, weight = 4.0), + getGrade(22, "Fizyka", 6.0, weight = 2.0), + getGrade(22, "Fizyka", 6.0, weight = 2.0), + getGrade(22, "Fizyka", 6.0, weight = 4.0), + getGrade(22, "Fizyka", 6.0, weight = 4.0), + getGrade(22, "Fizyka", 6.0, weight = 2.0) + ) to listOf(getSummary(semesterId = 22, subject = "Fizyka", average = .0)))) + `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(listOf( + getGrade(23, "Fizyka", 5.0, weight = 1.0), + getGrade(23, "Fizyka", 5.0, weight = 2.0), + getGrade(23, "Fizyka", 4.0, modifier = 0.33, weight = 2.0) + ) to listOf(getSummary(semesterId = 23, subject = "Fizyka", average = .0)))) + + val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet() + + assertEquals(5.2636, items.single { it.subject == "Fizyka" }.average, .0001) // (from details): 5.72727272 + 4,8 → 5.26363636 + } + + @Test + fun `force calc full year average with different average from all grades and from two semesters with custom modifiers`() { + val student = student.copy(loginMode = Sdk.Mode.SCRAPPER.name) + + `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true) + `when`(preferencesRepository.gradeMinusModifier).thenReturn(.33) + `when`(preferencesRepository.gradePlusModifier).thenReturn(.5) + + `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.ALL_YEAR) + `when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters)) + + `when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(listOf( + getGrade(22, "Fizyka", 5.0, weight = 2.0), + getGrade(22, "Fizyka", 6.0, weight = 2.0), + getGrade(22, "Fizyka", 5.0, weight = 4.0), + getGrade(22, "Fizyka", 6.0, weight = 2.0), + getGrade(22, "Fizyka", 6.0, weight = 2.0), + getGrade(22, "Fizyka", 6.0, weight = 4.0), + getGrade(22, "Fizyka", 6.0, weight = 4.0), + getGrade(22, "Fizyka", 6.0, weight = 2.0) + ) to listOf(getSummary(semesterId = 22, subject = "Fizyka", average = .0)))) + `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(listOf( + getGrade(23, "Fizyka", 5.0, weight = 1.0), + getGrade(23, "Fizyka", 5.0, weight = 2.0), + getGrade(23, "Fizyka", 4.0, modifier = 0.33, weight = 2.0) + ) to listOf(getSummary(semesterId = 23, subject = "Fizyka", average = .0)))) + + val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet() + + assertEquals(5.5555, items.single { it.subject == "Fizyka" }.average, .0001) // (from details): 5.72727272 + 4,8 → .average() + } + + private fun getGrade(semesterId: Int, subject: String, value: Double, modifier: Double = 0.0, weight: Double = 1.0): Grade { return Grade( studentId = 101, semesterId = semesterId, subject = subject, value = value, modifier = modifier, - weightValue = 1.0, + weightValue = weight, teacher = "", date = now(), weight = "",