From edd1c9442e080ea9367a66abef8a84b98a242a1d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Borcz?= <RafalBO99@outlook.com>
Date: Sat, 12 Feb 2022 22:22:15 +0100
Subject: [PATCH] Fix calc vulcan average in second semester (#1779)

---
 .../ui/modules/grade/GradeAverageProvider.kt  | 26 +++++------
 .../modules/grade/GradeAverageProviderTest.kt | 45 +++++++++++++++++--
 2 files changed, 54 insertions(+), 17 deletions(-)

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 2784f429..0c18ce95 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
@@ -10,9 +10,7 @@ import io.github.wulkanowy.data.repositories.GradeRepository
 import io.github.wulkanowy.data.repositories.PreferencesRepository
 import io.github.wulkanowy.data.repositories.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.ui.modules.grade.GradeAverageMode.*
 import io.github.wulkanowy.utils.calcAverage
 import io.github.wulkanowy.utils.changeModifier
 import io.github.wulkanowy.utils.flowWithResourceIn
@@ -144,20 +142,20 @@ class GradeAverageProvider @Inject constructor(
         isGradeAverageForceCalc: Boolean,
         secondSemesterSubject: GradeSubject,
         firstSemesterSubject: GradeSubject?
-    ): Double {
+    ): Double = if (!isAnyVulcanAverage || isGradeAverageForceCalc) {
         val divider = if (secondSemesterSubject.grades.any { it.weightValue > .0 }) 2 else 1
 
-        return if (!isAnyVulcanAverage || isGradeAverageForceCalc) {
-            val secondSemesterAverage =
-                secondSemesterSubject.grades.updateModifiers(student)
-                    .calcAverage(isOptionalArithmeticAverage)
-            val firstSemesterAverage = firstSemesterSubject?.grades?.updateModifiers(student)
-                ?.calcAverage(isOptionalArithmeticAverage) ?: secondSemesterAverage
+        val secondSemesterAverage = secondSemesterSubject.grades.updateModifiers(student)
+            .calcAverage(isOptionalArithmeticAverage)
+        val firstSemesterAverage = firstSemesterSubject?.grades?.updateModifiers(student)
+            ?.calcAverage(isOptionalArithmeticAverage) ?: secondSemesterAverage
 
-            (secondSemesterAverage + firstSemesterAverage) / divider
-        } else {
-            (secondSemesterSubject.average + (firstSemesterSubject?.average ?: secondSemesterSubject.average)) / divider
-        }
+        (secondSemesterAverage + firstSemesterAverage) / divider
+    } else {
+        val divider = if (secondSemesterSubject.average > 0) 2 else 1
+
+        (secondSemesterSubject.average + (firstSemesterSubject?.average
+            ?: secondSemesterSubject.average)) / divider
     }
 
     private fun getGradeSubjects(
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 f097cb84..5e8c4c11 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
@@ -859,12 +859,51 @@ class GradeAverageProviderTest {
             ) to listOf(getSummary(semesterId = 23, subject = "Fizyka", average = .0))
         }
 
-        val items = runBlocking { gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, true).getResult() }
+        val items = runBlocking {
+            gradeAverageProvider.getGradesDetailsWithAverage(
+                student,
+                semesters[2].semesterId,
+                true
+            ).getResult()
+        }
 
-        assertEquals(5.5555, items.single { it.subject == "Fizyka" }.average, .0001) // (from details): 5.72727272  + 4,8 → .average()
+        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, entry: String = ""): Grade {
+    @Test
+    fun `calc both semesters average when both summary have same average from vulcan and second semester has no grades`() {
+        every { preferencesRepository.gradeAverageForceCalc } returns false
+        every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.BOTH_SEMESTERS
+        every { preferencesRepository.isOptionalArithmeticAverage } returns false
+
+        coEvery { gradeRepository.getGrades(student, semesters[1], true) } returns
+                flowWithResource { firstGrades to firstSummaries }
+        coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns
+                flowWithResource { listOf<Grade>() to firstSummaries }
+
+        val items = runBlocking {
+            gradeAverageProvider.getGradesDetailsWithAverage(
+                student,
+                semesters[2].semesterId,
+                true
+            ).getResult()
+        }
+
+        assertEquals(3.1, items.single { it.subject == "Fizyka" }.average, .0001)
+    }
+
+    private fun getGrade(
+        semesterId: Int,
+        subject: String,
+        value: Double,
+        modifier: Double = 0.0,
+        weight: Double = 1.0,
+        entry: String = ""
+    ): Grade {
         return Grade(
             studentId = 101,
             semesterId = semesterId,