From 1b7db4bfbbd2865a2713670d2ec8d97463271e39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Pich?= Date: Thu, 7 Mar 2019 13:08:11 +0100 Subject: [PATCH] Mitigate disappearing room numbers in timetable (#265) --- ...tyFactory.kt => TestGradeEntityCreator.kt} | 0 .../GradeStatisticsLocalTest.kt | 3 +- .../timetable/TestTimetableEntityCreator.kt | 42 +++++++++ .../timetable/TimetableLocalTest.kt | 20 ++--- .../timetable/TimetableRepositoryTest.kt | 85 +++++++++++++++++++ .../timetable/TimetableRepository.kt | 9 +- .../github/wulkanowy/utils/TimeExtension.kt | 3 + build.gradle | 2 +- 8 files changed, 149 insertions(+), 15 deletions(-) rename app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/{GradeEntityFactory.kt => TestGradeEntityCreator.kt} (100%) rename app/src/androidTest/java/io/github/wulkanowy/data/repositories/{grade => gradestatistics}/GradeStatisticsLocalTest.kt (93%) create mode 100644 app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TestTimetableEntityCreator.kt create mode 100644 app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableRepositoryTest.kt diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeEntityFactory.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/TestGradeEntityCreator.kt similarity index 100% rename from app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeEntityFactory.kt rename to app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/TestGradeEntityCreator.kt diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeStatisticsLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocalTest.kt similarity index 93% rename from app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeStatisticsLocalTest.kt rename to app/src/androidTest/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocalTest.kt index f85dabf36..6c0bd4170 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeStatisticsLocalTest.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocalTest.kt @@ -1,4 +1,4 @@ -package io.github.wulkanowy.data.repositories.grade +package io.github.wulkanowy.data.repositories.gradestatistics import androidx.room.Room import androidx.test.core.app.ApplicationProvider @@ -6,7 +6,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import io.github.wulkanowy.data.db.AppDatabase import io.github.wulkanowy.data.db.entities.GradeStatistics import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.repositories.gradestatistics.GradeStatisticsLocal import org.junit.After import org.junit.Before import org.junit.Test diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TestTimetableEntityCreator.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TestTimetableEntityCreator.kt new file mode 100644 index 000000000..8c8bb4c19 --- /dev/null +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TestTimetableEntityCreator.kt @@ -0,0 +1,42 @@ +package io.github.wulkanowy.data.repositories.timetable + +import io.github.wulkanowy.api.toDate +import io.github.wulkanowy.utils.toDate +import org.threeten.bp.LocalDateTime +import org.threeten.bp.LocalDateTime.now +import io.github.wulkanowy.api.timetable.Timetable as TimetableRemote +import io.github.wulkanowy.data.db.entities.Timetable as TimetableLocal + +fun createTimetableLocal(number: Int, start: LocalDateTime, room: String = "", subject: String = ""): TimetableLocal { + return TimetableLocal( + studentId = 1, + diaryId = 2, + number = number, + start = start, + end = now(), + date = start.toLocalDate(), + subject = subject, + group = "", + room = room, + teacher = "", + info = "", + changes = false, + canceled = false + ) +} + +fun createTimetableRemote(number: Int, start: LocalDateTime, room: String, subject: String = ""): TimetableRemote { + return TimetableRemote( + number = number, + start = start.toDate(), + end = start.plusMinutes(45).toDate(), + date = start.toLocalDate().toDate(), + subject = subject, + group = "", + room = room, + teacher = "", + info = "", + changes = false, + canceled = false + ) +} diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableLocalTest.kt index bc0615c66..0ecbcf92e 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableLocalTest.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableLocalTest.kt @@ -5,13 +5,12 @@ import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import io.github.wulkanowy.data.db.AppDatabase import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Timetable import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.threeten.bp.LocalDate -import org.threeten.bp.LocalDateTime +import org.threeten.bp.LocalDateTime.of import kotlin.test.assertEquals @RunWith(AndroidJUnit4::class) @@ -23,7 +22,8 @@ class TimetableLocalTest { @Before fun createDb() { - testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java).build() + testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java) + .build() timetableDb = TimetableLocal(testDb.timetableDao) } @@ -35,19 +35,17 @@ class TimetableLocalTest { @Test fun saveAndReadTest() { timetableDb.saveTimetable(listOf( - Timetable(1, 2, 1, LocalDateTime.now(), LocalDateTime.now(), - LocalDate.of(2018, 9, 10), "", "", "", "", "", false, false), - Timetable(1, 2, 1, LocalDateTime.now(), LocalDateTime.now(), - LocalDate.of(2018, 9, 14), "", "", "", "", "", false, false), - Timetable(1, 2, 1, LocalDateTime.now(), LocalDateTime.now(), - LocalDate.of(2018, 9, 17), "", "", "", "", "", false, false) + createTimetableLocal(1, of(2018, 9, 10, 0, 0, 0)), + createTimetableLocal(1, of(2018, 9, 14, 0, 0, 0)), + createTimetableLocal(1, of(2018, 9, 17, 0, 0, 0)) )) val exams = timetableDb.getTimetable( Semester(1, 2, "", 1, 1, true, 1, 1), - LocalDate.of(2018, 9, 10), - LocalDate.of(2018, 9, 14) + LocalDate.of(2018, 9, 10), + LocalDate.of(2018, 9, 14) ).blockingGet() + assertEquals(2, exams.size) assertEquals(exams[0].date, LocalDate.of(2018, 9, 10)) assertEquals(exams[1].date, LocalDate.of(2018, 9, 14)) diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableRepositoryTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableRepositoryTest.kt new file mode 100644 index 000000000..1c0802637 --- /dev/null +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableRepositoryTest.kt @@ -0,0 +1,85 @@ +package io.github.wulkanowy.data.repositories.timetable + +import android.os.Build.VERSION_CODES.P +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider.getApplicationContext +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SdkSuppress +import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings +import io.github.wulkanowy.api.Api +import io.github.wulkanowy.data.db.AppDatabase +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.repositories.TestInternetObservingStrategy +import io.mockk.MockKAnnotations +import io.mockk.every +import io.mockk.impl.annotations.MockK +import io.mockk.impl.annotations.SpyK +import io.reactivex.Single +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.threeten.bp.LocalDate +import org.threeten.bp.LocalDateTime.of +import kotlin.test.assertEquals + +@SdkSuppress(minSdkVersion = P) +@RunWith(AndroidJUnit4::class) +class TimetableRepositoryTest { + + @SpyK + private var mockApi = Api() + + private val settings = InternetObservingSettings.builder() + .strategy(TestInternetObservingStrategy()) + .build() + + @MockK + private lateinit var semesterMock: Semester + + private lateinit var timetableRemote: TimetableRemote + + private lateinit var timetableLocal: TimetableLocal + + private lateinit var testDb: AppDatabase + + @Before + fun initApi() { + MockKAnnotations.init(this) + testDb = Room.inMemoryDatabaseBuilder(getApplicationContext(), AppDatabase::class.java).build() + timetableLocal = TimetableLocal(testDb.timetableDao) + timetableRemote = TimetableRemote(mockApi) + + every { semesterMock.studentId } returns 1 + every { semesterMock.diaryId } returns 2 + } + + @After + fun closeDb() { + testDb.close() + } + + @Test + fun copyDetailsToCompletedFromPrevious() { + timetableLocal.saveTimetable(listOf( + createTimetableLocal(1, of(2019, 3, 5, 8, 0), "123", "Przyroda"), + createTimetableLocal(1, of(2019, 3, 5, 8, 50), "321", "Religia"), + createTimetableLocal(1, of(2019, 3, 5, 9, 40), "213", "W-F") + )) + + every { mockApi.getTimetable(any(), any()) } returns Single.just(listOf( + createTimetableRemote(1, of(2019, 3, 5, 8, 0), "", "Przyroda"), + createTimetableRemote(1, of(2019, 3, 5, 8, 50), "", "Religia"), + createTimetableRemote(1, of(2019, 3, 5, 9, 40), "", "W-F") + )) + + val lessons = TimetableRepository(settings, timetableLocal, timetableRemote) + .getTimetable(semesterMock, LocalDate.of(2019, 3, 5), LocalDate.of(2019, 3, 5), true) + .blockingGet() + + assertEquals(3, lessons.size) + assertEquals("123", lessons[0].room) + assertEquals("321", lessons[1].room) + assertEquals("213", lessons[2].room) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableRepository.kt index 405f7faea..722fc3227 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableRepository.kt @@ -33,7 +33,14 @@ class TimetableRepository @Inject constructor( .toSingle(emptyList()) .doOnSuccess { oldTimetable -> local.deleteTimetable(oldTimetable - newTimetable) - local.saveTimetable(newTimetable - oldTimetable) + local.saveTimetable((newTimetable - oldTimetable).map { item -> + item.apply { + if (room.isEmpty()) { + oldTimetable.singleOrNull { it.start == this.start && it.room.isNotEmpty() } + ?.let { return@map copy(room = it.room) } + } + } + }) } }.flatMap { local.getTimetable(semester, dates.first, dates.second) diff --git a/app/src/main/java/io/github/wulkanowy/utils/TimeExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/TimeExtension.kt index 3cd38c732..886b3d4da 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/TimeExtension.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/TimeExtension.kt @@ -1,5 +1,6 @@ package io.github.wulkanowy.utils +import org.threeten.bp.DateTimeUtils import org.threeten.bp.DayOfWeek.FRIDAY import org.threeten.bp.DayOfWeek.MONDAY import org.threeten.bp.DayOfWeek.SATURDAY @@ -36,6 +37,8 @@ fun LocalDate.toFormattedString(format: String = DATE_PATTERN): String = this.fo fun LocalDateTime.toFormattedString(format: String = DATE_PATTERN): String = this.format(ofPattern(format)) +fun LocalDateTime.toDate(): Date = DateTimeUtils.toDate(atZone(ZoneId.systemDefault()).toInstant()) + /** * https://github.com/ThreeTen/threetenbp/issues/55 */ diff --git a/build.gradle b/build.gradle index f6b97d7df..fb7f76136 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ buildscript { } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath 'com.android.tools.build:gradle:3.3.1' + classpath 'com.android.tools.build:gradle:3.3.2' classpath 'com.google.gms:google-services:4.2.0' classpath "io.fabric.tools:gradle:1.27.0" classpath "com.github.triplet.gradle:play-publisher:2.1.0"