Skip to content

Commit

Permalink
Merge pull request #130 from snuhcs-course/develop
Browse files Browse the repository at this point in the history
Update latest features for UI testing
  • Loading branch information
yangchanhk98 authored Dec 10, 2023
2 parents 9ceecf0 + 57cad25 commit 580fae7
Show file tree
Hide file tree
Showing 155 changed files with 34,715 additions and 1,367 deletions.
9 changes: 6 additions & 3 deletions .github/workflows/android.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ jobs:
run: chmod +x gradlew
- name: Add API_BASE_URL to local.properties
run: echo "API_BASE_URL= \"${{ secrets.API_BASE_URL }}\"" >> local.properties
- name: Add CLIP_BASE_URL to local.properties
run: echo "CLIP_BASE_URL= \"${{ secrets.CLIP_BASE_URL }}\"" >> local.properties
- name: Add CLIP_API_KEY to local.properties
run: echo "CLIP_API_KEY= \"${{ secrets.CLIP_API_KEY }}\"" >> local.properties

- name: Build with Gradle
run: ./gradlew clean build
- name: Test with Gradle
run: ./gradlew test
run: ./gradlew clean build
2 changes: 0 additions & 2 deletions .github/workflows/springboot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,3 @@ jobs:
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew clean build
- name: Test with Gradle
run: ./gradlew test
17 changes: 0 additions & 17 deletions android/.idea/deploymentTargetDropDown.xml

This file was deleted.

9 changes: 7 additions & 2 deletions android/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ android {

defaultConfig {
applicationId = "com.goliath.emojihub"
minSdk = 33
minSdk = 31
targetSdk = 33
versionCode = 1
versionName = "1.0"
Expand All @@ -31,11 +31,13 @@ android {

// get properties from `local.properties`
buildConfigField("String", "API_BASE_URL", getProperty("API_BASE_URL"))
buildConfigField("String", "CLIP_BASE_URL", getProperty("CLIP_BASE_URL"))
buildConfigField("String", "CLIP_API_KEY", getProperty("CLIP_API_KEY"))
}

buildTypes {
release {
isMinifyEnabled = false
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
Expand Down Expand Up @@ -124,6 +126,9 @@ dependencies {
kapt("com.google.dagger:hilt-android-compiler:2.44")
kaptAndroidTest("com.google.dagger:hilt-android-compiler:2.44")

// json
implementation("org.json:json:20210307")

// navigation
implementation("androidx.navigation:navigation-compose:2.5.3")

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package com.goliath.emojihub.data_sources.local

import android.media.MediaMetadataRetriever
import android.net.Uri
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import io.mockk.every
import io.mockk.mockkObject
import org.junit.Assert.*

import org.junit.Test
import org.junit.runner.RunWith
import java.io.File
import java.io.IOException

@RunWith(AndroidJUnit4::class)
class MediaDataSourceImplTest {
private val context = InstrumentationRegistry.getInstrumentation().targetContext
private val mediaDataSourceImpl = MediaDataSourceImpl(context)

private fun getSampleVideoUri(videoFileName: String): Uri {
val x3dDataSourceImpl = X3dDataSourceImpl(context)
val sampleVideoAbsolutePath = x3dDataSourceImpl.assetFilePath(videoFileName)
return Uri.fromFile(File(sampleVideoAbsolutePath))
}

@Test
fun loadVideoMediaMetadataRetriever_validVideoUri_returnsMediaMetadataRetriever() {
// given
val videoUri = getSampleVideoUri("Hagrid/test_palm_video.mp4")
// when
val mediaMetadataRetriever = mediaDataSourceImpl.loadVideoMediaMetadataRetriever(videoUri)
// then
assert(mediaMetadataRetriever is MediaMetadataRetriever)
assertTrue(
(mediaMetadataRetriever?.extractMetadata(
MediaMetadataRetriever.METADATA_KEY_DURATION
)?.toLong() ?: 0) > 0
)
}

@Test
fun loadVideoMediaMetadataRetriever_invalidVideoUri_returnsNull() {
// given
val videoUri = Uri.EMPTY
// when
val mediaMetadataRetriever = mediaDataSourceImpl.loadVideoMediaMetadataRetriever(videoUri)
// then
assertNull(mediaMetadataRetriever)
}

@Test
fun extractFrameImagesFromVideo_validMediaMetadataRetriever_returnsBitmapList() {
// given
val videoUri = getSampleVideoUri("Hagrid/test_palm_video.mp4")
val mediaMetadataRetriever = mediaDataSourceImpl.loadVideoMediaMetadataRetriever(videoUri)
// when
val bitmapList = mediaDataSourceImpl
.extractFrameImagesFromVideo(mediaMetadataRetriever!!, 1)
// then
assertEquals(1, bitmapList.size)
}

@Test
fun extractFrameImagesFromVideo_errorOnLoadingVideo_returnsEmptyBitmapList() {
// given
val videoUri = getSampleVideoUri("Hagrid/test_palm_video.mp4")
val mediaMetadataRetriever = mediaDataSourceImpl.loadVideoMediaMetadataRetriever(videoUri)
mockkObject(mediaMetadataRetriever!!)
every {
mediaMetadataRetriever.getFrameAtTime(any(), any())
} throws IOException()
// when
val bitmapList = mediaDataSourceImpl
.extractFrameImagesFromVideo(mediaMetadataRetriever, 1)
// then
assertTrue(bitmapList.isEmpty())
}

@Test
fun bitmapToBase64Utf8_withBitmapImage_returnsBase64String() {
// given
val videoUri = getSampleVideoUri("Hagrid/test_palm_video.mp4")
val mediaMetadataRetriever = mediaDataSourceImpl.loadVideoMediaMetadataRetriever(videoUri)
val bitmapList = mediaDataSourceImpl
.extractFrameImagesFromVideo(mediaMetadataRetriever!!, 1)
// when
val base64String = mediaDataSourceImpl.bitmapToBase64Utf8(bitmapList[0])
// then
assertTrue(base64String.isNotEmpty())
}

@Test
fun getJSONObjectFromAssets_zeroShotClassNameToUnicodeFileName_returnsJSONObject() {
// given
val classNameToUnicodeFileName = "zero_shot_classname_to_unicode.json"
// when
val jsonObject = mediaDataSourceImpl.getJSONObjectFromAssets(classNameToUnicodeFileName)
// then
val likeUnicode = jsonObject?.getString("like")
assertEquals("U+1F44D", likeUnicode)
}

@Test
fun getJSONObjectFromAssets_invalidFileName_returnsNull() {
// given
val invalidFileName = "invalid_file_name.json"
// when
val jsonObject = mediaDataSourceImpl.getJSONObjectFromAssets(invalidFileName)
// then
assertNull(jsonObject)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import java.io.IOException
@RunWith(AndroidJUnit4::class)
class X3dDataSourceImplTest {
private val context = InstrumentationRegistry.getInstrumentation().targetContext
private val mediaDataSourceImpl = MediaDataSourceImpl(context)
private val x3dDataSourceImpl = X3dDataSourceImpl(context)
// X3D TESTING UTILS
private fun getSampleVideoUri(videoFileName: String): Uri {
Expand Down Expand Up @@ -124,38 +125,11 @@ class X3dDataSourceImplTest {
assertNull(filePaths)
}

// how can I access to the video file in the device?
// -> route this issue by using file in assets folder
@Test
fun loadVideoMediaMetadataRetriever_validVideoUri_returnsMediaMetadataRetriever() {
// given
val videoUri = getSampleVideoUri("Hagrid/test_palm_video.mp4")
// when
val mediaMetadataRetriever = x3dDataSourceImpl.loadVideoMediaMetadataRetriever(videoUri)
// then
assert(mediaMetadataRetriever is MediaMetadataRetriever)
assertTrue(
(mediaMetadataRetriever?.extractMetadata(
MediaMetadataRetriever.METADATA_KEY_DURATION
)?.toLong() ?: 0) > 0
)
}

@Test
fun loadVideoMediaMetadataRetriever_invalidVideoUri_returnsNull() {
// given
val videoUri = Uri.EMPTY
// when
val mediaMetadataRetriever = x3dDataSourceImpl.loadVideoMediaMetadataRetriever(videoUri)
// then
assertNull(mediaMetadataRetriever)
}

@Test
fun extractFrameTensorsFromVideo_validMediaMetadataRetriever_returnsTensors() {
// given
val videoUri = getSampleVideoUri("Hagrid/test_palm_video.mp4")
val mediaMetadataRetriever = x3dDataSourceImpl.loadVideoMediaMetadataRetriever(videoUri)
val mediaMetadataRetriever = mediaDataSourceImpl.loadVideoMediaMetadataRetriever(videoUri)
// when
val inputVideoFrameTensors = x3dDataSourceImpl
.extractFrameTensorsFromVideo(mediaMetadataRetriever!!)
Expand All @@ -176,7 +150,7 @@ class X3dDataSourceImplTest {
fun extractFrameTensorsFromVideo_errorOnLoadingVideo_returnsNull() {
// given
val videoUri = getSampleVideoUri("Hagrid/test_palm_video.mp4")
val mediaMetadataRetriever = x3dDataSourceImpl.loadVideoMediaMetadataRetriever(videoUri)
val mediaMetadataRetriever = mediaDataSourceImpl.loadVideoMediaMetadataRetriever(videoUri)
mockkObject(mediaMetadataRetriever!!)
every {
mediaMetadataRetriever.getFrameAtTime(any(), any())
Expand Down
Binary file not shown.
12 changes: 12 additions & 0 deletions android/app/src/main/assets/zero_shot_classname_to_unicode.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"call": "U+1F919",
"dislike": "U+1F645",
"fist": "U+1F44A",
"like": "U+1F44D",
"mute": "U+1F92B",
"ok": "U+1F646",
"palm": "U+1F64B",
"peace": "U+270C",
"rock": "U+1F918",
"stop": "U+270B"
}
59 changes: 54 additions & 5 deletions android/app/src/main/java/com/goliath/emojihub/RootActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
Expand All @@ -32,8 +33,11 @@ import com.goliath.emojihub.views.LoginPage
import com.goliath.emojihub.views.MainPage
import com.goliath.emojihub.views.SignUpPage
import com.goliath.emojihub.views.TransformVideoPage
import com.goliath.emojihub.views.components.CreatedEmojiListView
import com.goliath.emojihub.views.components.CreatedPostListView
import com.goliath.emojihub.views.components.CustomDialog
import com.goliath.emojihub.views.components.PlayEmojiView
import com.goliath.emojihub.views.components.SavedEmojiListView
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject

Expand All @@ -50,7 +54,10 @@ class RootActivity : ComponentActivity() {

setContent {
EmojiHubTheme {
Box(Modifier.fillMaxSize().background(Color.White)) {
Box(
Modifier
.fillMaxSize()
.background(Color.White)) {
val accessToken = userViewModel.accessTokenState.collectAsState().value
val error by apiErrorController.apiErrorState.collectAsState()

Expand Down Expand Up @@ -110,20 +117,62 @@ class RootActivity : ComponentActivity() {
}

composable(NavigationDestination.TransformVideo) {
val emojiViewModel = hiltViewModel<EmojiViewModel>()
val parentEntry = remember(it) {
navController.getBackStackEntry(NavigationDestination.MainPage)
}
val emojiViewModel = hiltViewModel<EmojiViewModel>(parentEntry)
TransformVideoPage(emojiViewModel)
}

composable(NavigationDestination.PlayEmojiVideo) {
val emojiViewModel = hiltViewModel<EmojiViewModel>()
PlayEmojiView(emojiViewModel)
val parentEntry = remember(it) {
navController.getBackStackEntry(NavigationDestination.MainPage)
}
val emojiViewModel = hiltViewModel<EmojiViewModel>(parentEntry)
val userViewModel = hiltViewModel<UserViewModel>(parentEntry)
PlayEmojiView(emojiViewModel, userViewModel)
}

composable(NavigationDestination.CreatePost) {
val postViewModel = hiltViewModel<PostViewModel>()
val parentEntry = remember(it) {
navController.getBackStackEntry(NavigationDestination.MainPage)
}
val postViewModel = hiltViewModel<PostViewModel>(parentEntry)
CreatePostPage(postViewModel)
}

composable(NavigationDestination.MyPostList) {
val parentEntry = remember(it) {
navController.getBackStackEntry(NavigationDestination.MainPage)
}
val postViewModel = hiltViewModel<PostViewModel>(parentEntry)
CreatedPostListView(postViewModel.myPostList)
}

composable(NavigationDestination.MyEmojiList) {
val parentEntry = remember(it) {
navController.getBackStackEntry(NavigationDestination.MainPage)
}
val emojiViewModel = hiltViewModel<EmojiViewModel>(parentEntry)
CreatedEmojiListView(emojiViewModel)
}

composable(NavigationDestination.MySavedEmojiList) {
val parentEntry = remember(it) {
navController.getBackStackEntry(NavigationDestination.MainPage)
}
val emojiViewModel = hiltViewModel<EmojiViewModel>(parentEntry)
SavedEmojiListView(emojiViewModel)
}
}
}
}
}

fun NavController.navigateAsOrigin(route: String) {
navigate(route) {
while (popBackStack()) { }
launchSingleTop = true
restoreState = true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ enum class CustomError(
override fun body(): String = "이미 있는 계정입니다."
},
INTERNAL_SERVER_ERROR(500) {
override fun body(): String = "접속 오류가 발생했습니다."
override fun body(): String = "네트워크 접속 오류가 발생했습니다."
},;

companion object {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package com.goliath.emojihub.data_sources

import androidx.compose.runtime.MutableState
import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import com.goliath.emojihub.views.PageItem

class BottomNavigationController {
private val _bottomNavigationDestination = mutableStateOf(PageItem.Feed.screenRoute)

@Stable
val currentDestination: MutableState<String> = _bottomNavigationDestination
val currentDestination: State<String> = _bottomNavigationDestination

fun updateDestination(destination: PageItem) {
_bottomNavigationDestination.value = destination.screenRoute
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ package com.goliath.emojihub.data_sources

import com.goliath.emojihub.BuildConfig

const val API_BASE_URL = BuildConfig.API_BASE_URL
const val API_BASE_URL = BuildConfig.API_BASE_URL
const val CLIP_BASE_URL = BuildConfig.CLIP_BASE_URL
const val CLIP_API_KEY = BuildConfig.CLIP_API_KEY
Loading

0 comments on commit 580fae7

Please sign in to comment.