Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/emoji repo test #78

Merged
merged 4 commits into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.Flow
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import retrofit2.HttpException
import retrofit2.Response
import java.io.File
Expand Down Expand Up @@ -52,32 +53,31 @@ class EmojiRepositoryImpl @Inject constructor(

override suspend fun uploadEmoji(videoFile: File, emojiDto: UploadEmojiDto): Boolean {
val emojiDtoJson = Gson().toJson(emojiDto)
val emojiDtoRequestBody = RequestBody.create("application/json".toMediaTypeOrNull(), emojiDtoJson)
val emojiDtoRequestBody = emojiDtoJson.toRequestBody("application/json".toMediaTypeOrNull())

val videoFileRequestBody = RequestBody.create("video/mp4".toMediaTypeOrNull(), videoFile)
val videoFileRequestBody = videoFile.asRequestBody("video/mp4".toMediaTypeOrNull())
val videoFileMultipartBody = MultipartBody.Part.createFormData("file", videoFile.name, videoFileRequestBody)

val thumbnailFile = createVideoThumbnail(context, videoFile)

val thumbnailRequestBody = RequestBody.create("image/jpg".toMediaTypeOrNull(),
thumbnailFile!!
)
val thumbnailMultipartBody = MultipartBody.Part.createFormData("thumbnail", thumbnailFile?.name, thumbnailRequestBody)
val thumbnailRequestBody = thumbnailFile!!
.asRequestBody("image/jpg".toMediaTypeOrNull())
val thumbnailMultipartBody = MultipartBody.Part.createFormData("thumbnail",
thumbnailFile.name, thumbnailRequestBody)

return try {
emojiApi.uploadEmoji(videoFileMultipartBody, thumbnailMultipartBody, emojiDtoRequestBody)
true
}
catch (e: IOException) {
Log.d("EmojiRepository", "IOException")
Log.e("EmojiRepository", "IOException")
false
}
catch (e: HttpException) {
Log.d("EmojiRepository", "HttpException")
Log.e("EmojiRepository", "HttpException")
false
}
catch (e: Exception) {
Log.d("EmojiRepository", e.message.toString())
Log.e("EmojiRepository", "Unknown Exception: ${e.message}")
false
}
}
Expand All @@ -94,7 +94,7 @@ class EmojiRepositoryImpl @Inject constructor(
TODO("Not yet implemented")
}

private fun createVideoThumbnail(context: Context, videoFile: File): File? {
fun createVideoThumbnail(context: Context, videoFile: File): File? {
val retriever = MediaMetadataRetriever()
try {
retriever.setDataSource(videoFile.absolutePath)
Expand All @@ -109,8 +109,7 @@ class EmojiRepositoryImpl @Inject constructor(
return thumbnailFile
}
} catch (e: Exception) {
Log.d("create_TN", "ERROR...")
e.printStackTrace()
Log.e("EmojiRepository_create_TN", "ERROR creating thumbnail: ${e.message?:"Unknown error"}")
} finally {
retriever.release()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.goliath.emojihub.repositories.remote

import androidx.paging.testing.asSnapshot
import com.goliath.emojihub.data_sources.api.EmojiApi
import com.goliath.emojihub.mockLogClass
import com.goliath.emojihub.models.EmojiDto
import com.goliath.emojihub.models.UploadEmojiDto
import retrofit2.Response
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkStatic
import io.mockk.spyk
Expand All @@ -24,15 +27,42 @@ import java.lang.Exception
@RunWith(JUnit4::class)
class EmojiRepositoryImplTest {
private val emojiApi = mockk<EmojiApi>()
private val emojiRepositoryImpl = EmojiRepositoryImpl(emojiApi)
private val context = mockk<android.content.Context>()
private val emojiRepositoryImpl = EmojiRepositoryImpl(emojiApi, context)
private val sampleEmojiDto = EmojiDto(
createdBy = "channn",
createdAt = "2023-11-24 14:25:05",
savedCount = 1600,
videoLink = "https://storage.googleapis.com/emojihub-e2023.appspot.com/uu_2023-11-24%2014%3A25%3A05.mp4?GoogleAccessId=firebase-adminsdk-zynbm@emojihub-e2023.iam.gserviceaccount.com&Expires=1709443506&Signature=I%2BNRJSZ7nYtmrWs%2Fjv4uVAeW8%2BfHGF6GeV0pZRE4Sp5gCFuXLXBTKpgRBl1j2F%2BSSUStSqvBlktHZofZznGHWtsMYHQ99%2Bv7wcenqZweSWSmzse4s9sKAOkykn7pB9EMnFgax4VqGK4U5ey5HNSCKsjyNa5ZqDH8%2BqF%2FcIjQ3huChDMB2Xw1InaHUve0syvW6uz%2BeooDLo2nkGxdtElsDtomq2cAUMgk7nRNIYciYLGJ%2FsrscW7%2FXfD3rn%2BH3EM9z5S9DHKHWiEmh1xf0wpTtDsXom7p14XnZunnnOxpNO5OMFJi2x1kxZBFVc7U88V19eTmasWxdGV5TZipfN2ZMA%3D%3D",
thumbnailLink = "https://storage.googleapis.com/emojihub-e2023.appspot.com/uu_2023-11-24%2014%3A25%3A05.jpeg?GoogleAccessId=firebase-adminsdk-zynbm@emojihub-e2023.iam.gserviceaccount.com&Expires=1709443506&Signature=lZK4otdQOXBVKz3EeOEgpSqAH5QE3U6KuTz8bo5RwYQ463i0cBEx44zVPJO3dIP%2B3%2FdKkBbJy%2BzIBogKAKUl5jLyP9FwInOZChspQOuI8zp%2FKivvEZImPnoG2C1UiiwB03tHYq0tWEhgj76BB4SarWRtZY4xRZhuVvuJg9%2FNV%2B5XZ7%2BGGjLbzfjc5rA45iwWQGPfgQN0%2FKJsdTieNb5%2F6%2B5QHW4pq7QLxYAGqvea5X6VY1JcUjXU0iZ%2FfI16L%2F1cFZAMPDPNPxC2bbllFH6vkOdb3qKuvGm0M3Y99GCLTv%2BAiObbBCs13AgmBO1OngrBV4db4zNnjUZOtB0rPRgyFw%3D%3D",
id = "0ZF0MFHOV7974YTV3SBN",
label = "love it",
unicode = "U+2764 U+FE0F"
)
@Before
fun setUp() {
mockLogClass()
}

// @Test
fun fetchEmojiList() {
TODO("Implement after applying pagination")
@Test
fun fetchEmojiList_returnsFlowOfPagingDataOfEmojiDto() {
// given
val numSampleEmojis = 10
val sampleEmojiDtoList = List(numSampleEmojis) { sampleEmojiDto }
val expectedFetchedEmojiDtoList = List(numSampleEmojis*2) { sampleEmojiDto }
// *2 because of .asSnapshot() load one more time
coEvery {
emojiApi.fetchEmojiList(any(), any(), any())
} returns Response.success(sampleEmojiDtoList)
// when
val fetchedEmojiPagingDataFlow = runBlocking { emojiRepositoryImpl.fetchEmojiList() }
val fetchedEmojiDtoList = runBlocking { fetchedEmojiPagingDataFlow.asSnapshot() }
// then
coVerify(exactly = 2) { emojiApi.fetchEmojiList(any(), any(), any()) }
runBlocking {
assertEquals(expectedFetchedEmojiDtoList.size, fetchedEmojiDtoList.size)
assertEquals(expectedFetchedEmojiDtoList, fetchedEmojiDtoList)
}
}

// @Test
Expand All @@ -47,14 +77,23 @@ class EmojiRepositoryImplTest {
val sampleVideoFile = File("sampleVideoFile")
val sampleUploadEmojiDto = mockk<UploadEmojiDto>()
coEvery {
emojiApi.uploadEmoji(any(), any())
emojiApi.uploadEmoji(any(), any(), any())
} returns Response.success(Unit)

val emojiRepositoryImpl = spyk(EmojiRepositoryImpl(emojiApi, context))
every {
emojiRepositoryImpl.createVideoThumbnail(any(), any())
} returns File("sampleThumbnailFile")
coEvery {
emojiRepositoryImpl.uploadEmoji(any(), any())
} answers { callOriginal() }

// when
val isUploaded = runBlocking {
emojiRepositoryImpl.uploadEmoji(sampleVideoFile, sampleUploadEmojiDto)
}
// then
coVerify(exactly = 1) { emojiApi.uploadEmoji(any(), any()) }
coVerify(exactly = 1) { emojiApi.uploadEmoji(any(), any(), any()) }
assertTrue(isUploaded)
}

Expand All @@ -65,14 +104,23 @@ class EmojiRepositoryImplTest {
val sampleVideoFile = File("sampleVideoFile")
val sampleUploadEmojiDto = mockk<UploadEmojiDto>()
coEvery {
emojiApi.uploadEmoji(any(), any())
emojiApi.uploadEmoji(any(), any(), any())
} throws mockk<IOException>()

val emojiRepositoryImpl = spyk(EmojiRepositoryImpl(emojiApi, context))
every {
emojiRepositoryImpl.createVideoThumbnail(any(), any())
} returns File("sampleThumbnailFile")
coEvery {
emojiRepositoryImpl.uploadEmoji(any(), any())
} answers { callOriginal() }

// when
val isUploaded = runBlocking {
emojiRepositoryImpl.uploadEmoji(sampleVideoFile, sampleUploadEmojiDto)
}
// then
coVerify(exactly = 1) { emojiApi.uploadEmoji(any(), any()) }
coVerify(exactly = 1) { emojiApi.uploadEmoji(any(), any(), any()) }
assertFalse(isUploaded)
}

Expand All @@ -83,14 +131,23 @@ class EmojiRepositoryImplTest {
val sampleVideoFile = File("sampleVideoFile")
val sampleUploadEmojiDto = mockk<UploadEmojiDto>()
coEvery {
emojiApi.uploadEmoji(any(), any())
emojiApi.uploadEmoji(any(), any(), any())
} throws mockk<HttpException>()

val emojiRepositoryImpl = spyk(EmojiRepositoryImpl(emojiApi, context))
every {
emojiRepositoryImpl.createVideoThumbnail(any(), any())
} returns File("sampleThumbnailFile")
coEvery {
emojiRepositoryImpl.uploadEmoji(any(), any())
} answers { callOriginal() }

// when
val isUploaded = runBlocking {
emojiRepositoryImpl.uploadEmoji(sampleVideoFile, sampleUploadEmojiDto)
}
// then
coVerify(exactly = 1) { emojiApi.uploadEmoji(any(), any()) }
coVerify(exactly = 1) { emojiApi.uploadEmoji(any(), any(), any()) }
assertFalse(isUploaded)
}

Expand All @@ -101,14 +158,23 @@ class EmojiRepositoryImplTest {
val sampleVideoFile = File("sampleVideoFile")
val sampleUploadEmojiDto = mockk<UploadEmojiDto>()
coEvery {
emojiApi.uploadEmoji(any(), any())
emojiApi.uploadEmoji(any(), any(), any())
} throws spyk<Exception>()

val emojiRepositoryImpl = spyk(EmojiRepositoryImpl(emojiApi, context))
every {
emojiRepositoryImpl.createVideoThumbnail(any(), any())
} returns File("sampleThumbnailFile")
coEvery {
emojiRepositoryImpl.uploadEmoji(any(), any())
} answers { callOriginal() }

// when
val isUploaded = runBlocking {
emojiRepositoryImpl.uploadEmoji(sampleVideoFile, sampleUploadEmojiDto)
}
// then
coVerify(exactly = 1) { emojiApi.uploadEmoji(any(), any()) }
coVerify(exactly = 1) { emojiApi.uploadEmoji(any(), any(), any()) }
assertFalse(isUploaded)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class PostRepositoryImplTest {
}

@Test
fun fetchPostList_returnsPagingSourceFactory() {
fun fetchPostList_returnsFlowOfPagingDataOfPostDto() {
// given
val numSamplePosts = 10
val samplePostDtoList = List(numSamplePosts) { samplePostDto }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package com.goliath.emojihub.usecases

import androidx.paging.PagingData
import androidx.paging.map
import androidx.paging.testing.asSnapshot
import com.goliath.emojihub.data_sources.ApiErrorController
import com.goliath.emojihub.mockLogClass
import com.goliath.emojihub.models.CreatedEmoji
import com.goliath.emojihub.models.Emoji
import com.goliath.emojihub.models.EmojiDto
import com.goliath.emojihub.models.UploadEmojiDto
import com.goliath.emojihub.repositories.local.X3dRepository
import com.goliath.emojihub.repositories.remote.EmojiRepository
Expand All @@ -12,6 +17,8 @@ import io.mockk.mockk
import io.mockk.mockkStatic
import io.mockk.spyk
import io.mockk.verify
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.runBlocking
import org.junit.Assert.*
import org.junit.Before
Expand All @@ -35,9 +42,34 @@ class EmojiUseCaseImplTest {
mockLogClass()
}

// @Test
fun fetchEmojiList() {
TODO("Implement after pagination is implemented")
@Test
fun updateEmojiList_withSamplePagingEmojiData_updatesEmojiListStateFlow() {
// given
val samplePagingEmojiData = mockk<PagingData<Emoji>>()
// when
runBlocking { emojiUseCaseImpl.updateEmojiList(samplePagingEmojiData) }
// then
assertEquals(samplePagingEmojiData, emojiUseCaseImpl.emojiList.value)
}

@Test
fun fetchEmojiList_returnsFlowOfEmojiPagingData() {
// given
val sampleEmojiPagingDataFlow = spyk<Flow<PagingData<EmojiDto>>>()
val sampleAnswer = sampleEmojiPagingDataFlow.map { it.map { dto -> Emoji(dto) } }
coEvery {
emojiRepository.fetchEmojiList()
} returns sampleEmojiPagingDataFlow
// when
val fetchedEmojiPagingDataFlow = runBlocking { emojiUseCaseImpl.fetchEmojiList() }
// then
coVerify(exactly = 1) { emojiRepository.fetchEmojiList() }
runBlocking {
assertEquals(
sampleAnswer.asSnapshot(),
fetchedEmojiPagingDataFlow.asSnapshot()
)
}
}

@Test
Expand Down

This file was deleted.

Loading