diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeRepositoryTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeRepositoryTest.kt index 711e2911..f3c6b7a1 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeRepositoryTest.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeRepositoryTest.kt @@ -6,7 +6,6 @@ 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.data.SdkHelper import io.github.wulkanowy.data.db.AppDatabase import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student @@ -15,9 +14,6 @@ import io.github.wulkanowy.sdk.Sdk import io.mockk.MockKAnnotations import io.mockk.every import io.mockk.impl.annotations.MockK -import io.mockk.impl.annotations.SpyK -import io.mockk.just -import io.mockk.runs import io.reactivex.Single import org.junit.After import org.junit.Before diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/MessagesDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/MessagesDao.kt index 6d14ad01..40ba0fe7 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/MessagesDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/MessagesDao.kt @@ -4,6 +4,7 @@ import androidx.room.Dao import androidx.room.Query import io.github.wulkanowy.data.db.entities.Message import io.reactivex.Maybe +import io.reactivex.Single @Dao interface MessagesDao : BaseDao { @@ -12,7 +13,7 @@ interface MessagesDao : BaseDao { fun loadAll(studentId: Int, folder: Int): Maybe> @Query("SELECT * FROM Messages WHERE id = :id") - fun load(id: Long): Maybe + fun load(id: Long): Single @Query("SELECT * FROM Messages WHERE student_id = :studentId AND removed = 1 ORDER BY date DESC") fun loadDeleted(studentId: Int): Maybe> diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageLocal.kt index ce08d13e..386391b4 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageLocal.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageLocal.kt @@ -5,6 +5,7 @@ import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.repositories.message.MessageFolder.TRASHED import io.reactivex.Maybe +import io.reactivex.Single import javax.inject.Inject import javax.inject.Singleton @@ -23,7 +24,7 @@ class MessageLocal @Inject constructor(private val messagesDb: MessagesDao) { messagesDb.deleteAll(messages) } - fun getMessage(id: Long): Maybe { + fun getMessage(id: Long): Single { return messagesDb.load(id) } diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRepository.kt index 0dfdd72f..3d860a04 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRepository.kt @@ -13,6 +13,7 @@ import io.github.wulkanowy.utils.uniqueSubtract import io.reactivex.Completable import io.reactivex.Maybe import io.reactivex.Single +import timber.log.Timber import java.net.UnknownHostException import javax.inject.Inject import javax.inject.Singleton @@ -51,21 +52,26 @@ class MessageRepository @Inject constructor( return Single.just(sdkHelper.init(student)) .flatMap { _ -> local.getMessage(messageDbId) - .filter { it.content.isNotEmpty() } + .filter { + it.content.isNotEmpty().also { status -> + Timber.d("Message content in db empty: ${!status}") + } + } .switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings) .flatMap { - if (it) local.getMessage(messageDbId).toSingle() + if (it) local.getMessage(messageDbId) else Single.error(UnknownHostException()) } .flatMap { dbMessage -> remote.getMessagesContent(dbMessage, markAsRead).doOnSuccess { - local.updateMessages(listOf(dbMessage.copy(unread = false).apply { + local.updateMessages(listOf(dbMessage.copy(unread = !markAsRead).apply { id = dbMessage.id content = content.ifBlank { it } })) + Timber.d("Message $messageDbId with blank content: ${dbMessage.content.isBlank()}, marked as read") } }.flatMap { - local.getMessage(messageDbId).toSingle() + local.getMessage(messageDbId) } ) } diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/UnitTestInternetObservingStrategy.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/UnitTestInternetObservingStrategy.kt index 28abbb99..954c191c 100644 --- a/app/src/test/java/io/github/wulkanowy/data/repositories/UnitTestInternetObservingStrategy.kt +++ b/app/src/test/java/io/github/wulkanowy/data/repositories/UnitTestInternetObservingStrategy.kt @@ -5,14 +5,14 @@ import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.error import io.reactivex.Observable import io.reactivex.Single -class UnitTestInternetObservingStrategy : InternetObservingStrategy { +class UnitTestInternetObservingStrategy(var isInternetConnection: Boolean = true) : InternetObservingStrategy { override fun checkInternetConnectivity(host: String?, port: Int, timeoutInMs: Int, httpResponse: Int, errorHandler: ErrorHandler?): Single { - return Single.just(true) + return Single.just(isInternetConnection) } override fun observeInternetConnectivity(initialIntervalInMs: Int, intervalInMs: Int, host: String?, port: Int, timeoutInMs: Int, httpResponse: Int, errorHandler: ErrorHandler?): Observable { - return Observable.just(true) + return Observable.just(isInternetConnection) } override fun getDefaultPingHost() = "localhost" diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/message/MessageRepositoryTest.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/message/MessageRepositoryTest.kt new file mode 100644 index 00000000..fc3b960f --- /dev/null +++ b/app/src/test/java/io/github/wulkanowy/data/repositories/message/MessageRepositoryTest.kt @@ -0,0 +1,97 @@ +package io.github.wulkanowy.data.repositories.message + +import androidx.room.EmptyResultSetException +import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings +import io.github.wulkanowy.data.SdkHelper +import io.github.wulkanowy.data.db.entities.Message +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.data.repositories.UnitTestInternetObservingStrategy +import io.reactivex.Single +import io.reactivex.observers.TestObserver +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Test +import org.mockito.Mock +import org.mockito.Mockito.`when` +import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations +import org.threeten.bp.LocalDateTime.now +import java.net.UnknownHostException + +class MessageRepositoryTest { + + @Mock + lateinit var sdk: SdkHelper + + @Mock + lateinit var local: MessageLocal + + @Mock + lateinit var remote: MessageRemote + + @Mock + lateinit var student: Student + + private val testObservingStrategy = UnitTestInternetObservingStrategy() + + private lateinit var repo: MessageRepository + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + + repo = MessageRepository(InternetObservingSettings.builder() + .strategy(testObservingStrategy) + .build(), local, remote, sdk) + } + + @Test + fun `throw error when message is not in the db`() { + `when`(local.getMessage(123)).thenReturn(Single.error(EmptyResultSetException("No message in database"))) + + val message = repo.getMessage(student, 123) + val messageObserver = TestObserver() + message.subscribe(messageObserver) + messageObserver.assertError(EmptyResultSetException::class.java) + } + + @Test + fun `get message when content already in db`() { + `when`(local.getMessage(123)).thenReturn(Single.just( + Message(1, 1, 123, "", 1, "", "", "Test", now(), 1, false, 1, 1, false) + )) + + val message = repo.getMessage(student, 123).blockingGet() + + assertEquals("Test", message.content) + } + + @Test + fun `get message when content in db is empty`() { + val testMessage = Message(1, 1, 123, "", 1, "", "", "", now(), 1, true, 1, 1, false) + val testMessageWithContent = testMessage.copy(content = "Test") + + `when`(local.getMessage(123)) + .thenReturn(Single.just(testMessage)) + .thenReturn(Single.just(testMessageWithContent)) + `when`(remote.getMessagesContent(testMessageWithContent)).thenReturn(Single.just("Test")) + + val message = repo.getMessage(student, 123).blockingGet() + + assertEquals("Test", message.content) + verify(local).updateMessages(listOf(testMessageWithContent)) + } + + @Test + fun `get message when content in db is empty and there is no internet connection`() { + val testMessage = Message(1, 1, 123, "", 1, "", "", "", now(), 1, false, 1, 1, false) + + testObservingStrategy.isInternetConnection = false + `when`(local.getMessage(123)).thenReturn(Single.just(testMessage)) + + val message = repo.getMessage(student, 123) + val messageObserver = TestObserver() + message.subscribe(messageObserver) + messageObserver.assertError(UnknownHostException::class.java) + } +} diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/student/StudentRemoteTest.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/student/StudentRemoteTest.kt index b99bf345..b6b195c9 100644 --- a/app/src/test/java/io/github/wulkanowy/data/repositories/student/StudentRemoteTest.kt +++ b/app/src/test/java/io/github/wulkanowy/data/repositories/student/StudentRemoteTest.kt @@ -1,15 +1,12 @@ package io.github.wulkanowy.data.repositories.student -import io.github.wulkanowy.data.SdkHelper import io.github.wulkanowy.sdk.Sdk import io.github.wulkanowy.sdk.pojo.Student -import io.mockk.impl.annotations.SpyK import io.reactivex.Single import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test import org.mockito.Mock -import org.mockito.Mockito.anyBoolean import org.mockito.Mockito.anyString import org.mockito.Mockito.doReturn import org.mockito.MockitoAnnotations