From 9fbb90ab0e74634d587338752139a63822d250e1 Mon Sep 17 00:00:00 2001 From: JH Date: Sun, 3 Dec 2023 23:13:18 +0900 Subject: [PATCH 01/10] :recycle: Modified testcas for EmailVerificationScreen --- .../speechbuddy/EmailVerificationScreenForResetPWTest.kt | 2 +- .../speechbuddy/EmailVerificationScreenForSignupTest.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/app/src/androidTest/java/com/example/speechbuddy/EmailVerificationScreenForResetPWTest.kt b/frontend/app/src/androidTest/java/com/example/speechbuddy/EmailVerificationScreenForResetPWTest.kt index 2ebc0d62..4e10c4ee 100644 --- a/frontend/app/src/androidTest/java/com/example/speechbuddy/EmailVerificationScreenForResetPWTest.kt +++ b/frontend/app/src/androidTest/java/com/example/speechbuddy/EmailVerificationScreenForResetPWTest.kt @@ -136,7 +136,7 @@ class EmailVerificationScreenForResetPWTest { // inputs const val INVALID_EMAIL = "invalidemail" const val UNREGISTERED_EMAIL_EXAMPLE = "noSuchEmail@test.com" - const val REGISTERED_EMAIL = "hahaa@gmail.com" + const val REGISTERED_EMAIL = "chess109@snu.ac.kr" const val INVALID_CODE = "invalid" } diff --git a/frontend/app/src/androidTest/java/com/example/speechbuddy/EmailVerificationScreenForSignupTest.kt b/frontend/app/src/androidTest/java/com/example/speechbuddy/EmailVerificationScreenForSignupTest.kt index 2e943bbe..0e7800ed 100644 --- a/frontend/app/src/androidTest/java/com/example/speechbuddy/EmailVerificationScreenForSignupTest.kt +++ b/frontend/app/src/androidTest/java/com/example/speechbuddy/EmailVerificationScreenForSignupTest.kt @@ -74,7 +74,7 @@ class EmailVerificationScreenForSignupTest { composeTestRule.onNodeWithText(EMAIL).performTextInput(ALREADY_TAKEN_EMAIL) composeTestRule.onNodeWithText(SEND_CODE).performClick() // wait for server's response - Thread.sleep(5000) + Thread.sleep(10000) composeTestRule.onNodeWithText(EMAIL_ALREADY_TAKEN).assertIsDisplayed() composeTestRule.onNodeWithText(NEXT).assertIsDisplayed().assertHasClickAction().assertIsNotEnabled() @@ -135,7 +135,7 @@ class EmailVerificationScreenForSignupTest { // inputs const val INVALID_EMAIL = "invalidemail" - const val ALREADY_TAKEN_EMAIL = "hahaa@gmail.com" + const val ALREADY_TAKEN_EMAIL = "chess109@snu.ac.kr" const val VALID_EMAIL = "valid@test.com" const val INVALID_CODE = "invalid" } From 2b4edd6f53c087211acfb90c1f560f2692adb97f Mon Sep 17 00:00:00 2001 From: JH Date: Sun, 3 Dec 2023 23:15:31 +0900 Subject: [PATCH 02/10] :recycle: Modified testcase for tts screen --- .../java/com/example/speechbuddy/TextToSpeechScreenTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/app/src/androidTest/java/com/example/speechbuddy/TextToSpeechScreenTest.kt b/frontend/app/src/androidTest/java/com/example/speechbuddy/TextToSpeechScreenTest.kt index 3f877e97..f4eb3591 100644 --- a/frontend/app/src/androidTest/java/com/example/speechbuddy/TextToSpeechScreenTest.kt +++ b/frontend/app/src/androidTest/java/com/example/speechbuddy/TextToSpeechScreenTest.kt @@ -46,7 +46,7 @@ class TextToSpeechScreenTest { @Test fun should_display_all_elements_when_text_to_speech_screen_appears() { - composeTestRule.onNodeWithText(TALK_WITH_SPEECH).assertIsDisplayed() + composeTestRule.onNodeWithText(TTS_TEXT).assertIsDisplayed() composeTestRule.onNodeWithText(TTS_DESCRIPTION).assertIsDisplayed() composeTestRule.onNode(hasSetTextAction()).assertIsDisplayed() //OutlinedTextField @@ -92,7 +92,7 @@ class TextToSpeechScreenTest { } companion object { - const val TALK_WITH_SPEECH = "음성으로 말하기" + const val TTS_TEXT = "소리로 말해요" const val TTS_DESCRIPTION = "텍스트를 입력하면 SpeechBuddy가 직접 읽어줘요" const val PLAY_TEXT = "재생" From 2701a7caae459aa3e8fead89e54481c221b8d07e Mon Sep 17 00:00:00 2001 From: JH Date: Sun, 3 Dec 2023 23:58:49 +0900 Subject: [PATCH 03/10] :recycle: Increase reflection of user feedback to weighttable --- .../speechbuddy/SymbolCreationScreenTest.kt | 83 ------------------- .../repository/WeightTableRepository.kt | 2 +- 2 files changed, 1 insertion(+), 84 deletions(-) diff --git a/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolCreationScreenTest.kt b/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolCreationScreenTest.kt index 18a57ec4..e69de29b 100644 --- a/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolCreationScreenTest.kt +++ b/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolCreationScreenTest.kt @@ -1,83 +0,0 @@ -//package com.example.speechbuddy -// -//import android.app.Activity -//import android.app.Instrumentation -//import android.content.ContentResolver -//import android.content.Intent -//import android.graphics.Bitmap -//import android.net.Uri -//import androidx.activity.compose.setContent -//import androidx.compose.foundation.layout.PaddingValues -//import androidx.compose.ui.test.junit4.createAndroidComposeRule -//import androidx.compose.ui.test.onNodeWithContentDescription -//import androidx.compose.ui.test.performClick -//import androidx.compose.ui.unit.dp -//import androidx.test.espresso.intent.Intents -//import androidx.test.espresso.intent.matcher.IntentMatchers -//import com.example.speechbuddy.compose.symbolcreation.SymbolCreationScreen -//import com.example.speechbuddy.ui.SpeechBuddyTheme -//import dagger.hilt.android.testing.HiltAndroidRule -//import dagger.hilt.android.testing.HiltAndroidTest -//import io.mockk.mockk -//import org.junit.After -//import org.junit.Before -//import org.junit.Rule -//import org.junit.Test -//import java.io.ByteArrayInputStream -//import java.io.ByteArrayOutputStream -// -//@HiltAndroidTest -//class SymbolCreationScreenTest { -// -// @get:Rule(order = 0) -// val hiltRule = HiltAndroidRule(this) -// -// @get:Rule(order = 1) -// val composeTestRule = createAndroidComposeRule() -// -// @Before -// fun setup() { -// Intents.init() -// composeTestRule.activity.setContent { -// hiltRule.inject() -// SpeechBuddyTheme { -// SymbolCreationScreen( -// bottomPaddingValues = PaddingValues(16.dp) -// ) -// } -// } -// } -// -// @After -// fun cleanup() { -// Intents.release() -// } -// -// @Test -// fun should_select_photo_when_add_photo_button_is_clicked() { -// //Arrange -// val resultData = Intent().apply { -// data = Uri.parse("content://path/to/photo") -// } -// val result = Instrumentation.ActivityResult(Activity.RESULT_OK, resultData) -// Intents.intending(IntentMatchers.hasAction(Intent.ACTION_GET_CONTENT)).respondWith(result) -// -// val bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888) -// val byteArrayOutputStream = ByteArrayOutputStream() -// bitmap.compress(Bitmap.CompressFormat.PNG, 0, byteArrayOutputStream) -// val byteArrayInputStream = ByteArrayInputStream(byteArrayOutputStream.toByteArray()) -// -// val contentResolver = mockk() -// every { contentResolver.openInputStream(any()) } returns byteArrayInputStream -// -// // Act -// composeTestRule.onNodeWithContentDescription(PHOTO_ICON_DESCRIPTION).performClick() -// // Assert -// Intents.intended(IntentMatchers.hasAction(Intent.ACTION_GET_CONTENT)) -// // Add more assertions to check that the photo was correctly loaded -// } -// -// companion object { -// const val PHOTO_ICON_DESCRIPTION = "새 상징 만들기" -// } -//} \ No newline at end of file diff --git a/frontend/app/src/main/java/com/example/speechbuddy/repository/WeightTableRepository.kt b/frontend/app/src/main/java/com/example/speechbuddy/repository/WeightTableRepository.kt index bb939c0d..cbb5f8c7 100644 --- a/frontend/app/src/main/java/com/example/speechbuddy/repository/WeightTableRepository.kt +++ b/frontend/app/src/main/java/com/example/speechbuddy/repository/WeightTableRepository.kt @@ -187,7 +187,7 @@ class WeightTableRepository @Inject constructor( val weights = targetRow.weights val preSymbolWeights = weights.toIntArray() // 앞 symbol의 weights - preSymbolWeights[dbIndex2] += 1 + preSymbolWeights[dbIndex2] += 5 val aftSymbolWeights = preSymbolWeights From 2b34a50e9aaba67fe51134ca19f2f106e1f98a28 Mon Sep 17 00:00:00 2001 From: JH Date: Mon, 4 Dec 2023 02:33:19 +0900 Subject: [PATCH 04/10] :white_check_mark: Add SymbolCreationScreenTest --- .../speechbuddy/SymbolCreationScreenTest.kt | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolCreationScreenTest.kt b/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolCreationScreenTest.kt index e69de29b..737ac827 100644 --- a/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolCreationScreenTest.kt +++ b/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolCreationScreenTest.kt @@ -0,0 +1,99 @@ +package com.example.speechbuddy + +import android.app.Activity +import android.app.Instrumentation +import android.content.ContentResolver +import android.content.Intent +import android.graphics.Bitmap +import android.net.Uri +import androidx.activity.compose.setContent +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.ui.test.assertHasClickAction +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.assertIsEnabled +import androidx.compose.ui.test.assertIsNotEnabled +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onNodeWithContentDescription +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.performClick +import androidx.compose.ui.test.performTextInput +import androidx.test.espresso.intent.Intents +import androidx.test.espresso.intent.matcher.IntentMatchers +import com.example.speechbuddy.compose.emailverification.EmailVerificationScreen +import com.example.speechbuddy.compose.symbolcreation.SymbolCreationScreen +import com.example.speechbuddy.ui.SpeechBuddyTheme +import dagger.hilt.android.testing.HiltAndroidRule +import dagger.hilt.android.testing.HiltAndroidTest + +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream + +@HiltAndroidTest +class SymbolCreationScreenTest { + + @get:Rule(order = 0) + var hiltRule = HiltAndroidRule(this) + + @get:Rule(order = 1) + val composeTestRule = createAndroidComposeRule() + + @Before + fun setUp() { + hiltRule.inject() + composeTestRule.activity.setContent { + SpeechBuddyTheme( + settingsRepository = composeTestRule.activity.settingsRepository, + initialDarkMode = false + ) { + SymbolCreationScreen( + paddingValues = PaddingValues() + ) + } + } + } + + @Test + fun should_display_all_elements_when_symbolcreation_screen_appears() { + composeTestRule.onNodeWithText(CREATE_NEW_SYMBOL).assertIsDisplayed() + composeTestRule.onNodeWithText(CREATE_NEW_SYMBOL_TEXT).assertIsDisplayed() + composeTestRule.onNodeWithContentDescription(PHOTO_ICON_DESCRIPTION).assertIsDisplayed() + composeTestRule.onNodeWithText(BIG_CATEGORY_BOX_TEXT).assertIsDisplayed() + composeTestRule.onNodeWithText(SYMBOL_NAME_BOX_TEXT).assertIsDisplayed() + composeTestRule.onNodeWithText(MAKE_BUTTON_TEXT).assertIsDisplayed() + } + + @Test + fun should_display_alertdialog_with_three_options_when_symbolcreation_clicked(){ + composeTestRule.onNodeWithContentDescription(PHOTO_ICON_DESCRIPTION).performClick() + Thread.sleep(1000) + composeTestRule.onNodeWithText(ALERT_MESSAGE).assertIsDisplayed() + composeTestRule.onNodeWithText(TAKE_PICTURE).assertIsDisplayed() + composeTestRule.onNodeWithText(SELECT_FROM_EXISTING).assertIsDisplayed() + composeTestRule.onNodeWithText(CANCEL).assertIsDisplayed() + } + @Test + fun should_display_all_categories_when_category_selection_is_clicked(){ + composeTestRule.onNodeWithText(BIG_CATEGORY_BOX_TEXT).performClick() + Thread.sleep(1000) + composeTestRule.onNodeWithText("가족").assertIsDisplayed() + } + + // + + companion object { + const val CREATE_NEW_SYMBOL = "새 상징 만들기" + const val CREATE_NEW_SYMBOL_TEXT = "직접 찍은 사진으로 새로운 상징을 만들어보세요" + const val BIG_CATEGORY_BOX_TEXT = "대분류" + const val SYMBOL_NAME_BOX_TEXT = "상징 이름을 입력해주세요" + const val MAKE_BUTTON_TEXT = "만들기" + const val PHOTO_ICON_DESCRIPTION = "새 상징 만들기" + const val ALERT_MESSAGE = "사진을 어떻게 추가하실 건가요?" + const val TAKE_PICTURE = "사진 촬영하기" + const val SELECT_FROM_EXISTING = "사진 보관함에서 사진 선택하기" + const val CANCEL = "취소" + } + +} \ No newline at end of file From 402d20197aaff4777a78e014f95aab935f1214c7 Mon Sep 17 00:00:00 2001 From: JH Date: Mon, 4 Dec 2023 02:40:15 +0900 Subject: [PATCH 05/10] :white_check_mark: Add MySymbolSettingsScreenTest --- .../speechbuddy/MySymbolSettingsScreenTest.kt | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 frontend/app/src/androidTest/java/com/example/speechbuddy/MySymbolSettingsScreenTest.kt diff --git a/frontend/app/src/androidTest/java/com/example/speechbuddy/MySymbolSettingsScreenTest.kt b/frontend/app/src/androidTest/java/com/example/speechbuddy/MySymbolSettingsScreenTest.kt new file mode 100644 index 00000000..c097bee1 --- /dev/null +++ b/frontend/app/src/androidTest/java/com/example/speechbuddy/MySymbolSettingsScreenTest.kt @@ -0,0 +1,82 @@ +package com.example.speechbuddy + +import androidx.activity.compose.setContent +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.ui.test.assertHasClickAction +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.assertIsEnabled +import androidx.compose.ui.test.assertIsNotDisplayed +import androidx.compose.ui.test.assertIsNotEnabled +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onNodeWithContentDescription +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.performClick +import androidx.compose.ui.test.performTextInput +import androidx.test.espresso.intent.Intents +import androidx.test.espresso.intent.matcher.IntentMatchers +import com.example.speechbuddy.compose.emailverification.EmailVerificationScreen +import com.example.speechbuddy.compose.settings.MySymbolSettings +import com.example.speechbuddy.compose.symbolcreation.SymbolCreationScreen +import com.example.speechbuddy.ui.SpeechBuddyTheme +import dagger.hilt.android.testing.HiltAndroidRule +import dagger.hilt.android.testing.HiltAndroidTest + +import org.junit.Before +import org.junit.Rule +import org.junit.Test + + +@HiltAndroidTest +class MySymbolSettingsScreenTest { + + @get:Rule(order = 0) + var hiltRule = HiltAndroidRule(this) + + @get:Rule(order = 1) + val composeTestRule = createAndroidComposeRule() + + @Before + fun setUp() { + hiltRule.inject() + composeTestRule.activity.setContent { + SpeechBuddyTheme( + settingsRepository = composeTestRule.activity.settingsRepository, + initialDarkMode = false + ) { + MySymbolSettings( + paddingValues = PaddingValues() + ) + } + } + } + + @Test + fun should_display_all_elements_when_mysybolsettings_screen_with_my_symbol_menu_appears() { + composeTestRule.onNodeWithText(SEARCH_BOX_TEXT).assertIsDisplayed() + composeTestRule.onNodeWithText(MY_SYMBOL_MENU_TEXT).assertIsDisplayed() + + composeTestRule.onNodeWithText(FAVORITES_MENU_TEXT).assertIsDisplayed() + composeTestRule.onNodeWithText(DELETE_TEXT).assertIsDisplayed() + } + + @Test + fun should_display_all_elements_when_mysybolsettings_screen_with_favorite_menu_appears() { + composeTestRule.onNodeWithText(FAVORITES_MENU_TEXT).performClick() + composeTestRule.onNodeWithText(SEARCH_BOX_TEXT).assertIsDisplayed() + composeTestRule.onNodeWithText(MY_SYMBOL_MENU_TEXT).assertIsDisplayed() + composeTestRule.onNodeWithText(FAVORITES_MENU_TEXT).assertIsDisplayed() + //composeTestRule.onNodeWithText(DELETE_TEXT).assertIsNotDisplayed() + } + + + // + + companion object { + const val SEARCH_BOX_TEXT = "검색어를 입력하세요" + const val MY_SYMBOL_MENU_TEXT = "내가 만든 상징" + const val FAVORITES_MENU_TEXT = "즐겨찾기" + const val DELETE_TEXT = "삭제" + + } + +} \ No newline at end of file From 677342567f320665c472e0e3658b347f75fa4726 Mon Sep 17 00:00:00 2001 From: JH Date: Mon, 4 Dec 2023 03:39:12 +0900 Subject: [PATCH 06/10] :white_check_mark: Add SymbolSelectionScreenTest --- .../speechbuddy/SymbolSelectionScreenTest.kt | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolSelectionScreenTest.kt diff --git a/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolSelectionScreenTest.kt b/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolSelectionScreenTest.kt new file mode 100644 index 00000000..0149dd63 --- /dev/null +++ b/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolSelectionScreenTest.kt @@ -0,0 +1,97 @@ +package com.example.speechbuddy + +import androidx.activity.compose.setContent +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.test.assertHasClickAction +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.assertIsEnabled +import androidx.compose.ui.test.assertIsFocused +import androidx.compose.ui.test.assertIsNotDisplayed +import androidx.compose.ui.test.assertIsNotEnabled +import androidx.compose.ui.test.assertIsSelected +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onNodeWithContentDescription +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.performClick +import androidx.compose.ui.test.performTextInput +import androidx.test.espresso.intent.Intents +import androidx.test.espresso.intent.matcher.IntentMatchers +import com.example.speechbuddy.compose.emailverification.EmailVerificationScreen +import com.example.speechbuddy.compose.settings.MySymbolSettings +import com.example.speechbuddy.compose.symbolcreation.SymbolCreationScreen +import com.example.speechbuddy.compose.symbolselection.SymbolSelectionScreen +import com.example.speechbuddy.ui.SpeechBuddyTheme +import dagger.hilt.android.testing.HiltAndroidRule +import dagger.hilt.android.testing.HiltAndroidTest + +import org.junit.Before +import org.junit.Rule +import org.junit.Test + + +@HiltAndroidTest +class SymbolSelectionScreenTest { + + @get:Rule(order = 0) + var hiltRule = HiltAndroidRule(this) + + @get:Rule(order = 1) + val composeTestRule = createAndroidComposeRule() + + @Before + fun setUp() { + hiltRule.inject() + composeTestRule.activity.setContent { + SpeechBuddyTheme( + settingsRepository = composeTestRule.activity.settingsRepository, + initialDarkMode = false + ) { + SymbolSelectionScreen( + paddingValues = PaddingValues(), + topAppBarState = remember{ mutableStateOf(true) }, + bottomNavBarState = remember{ mutableStateOf(true) } + ) + } + } + } + + @Test + fun should_display_all_elements_when_mysybolsettings_screen_with_big_category_menu_appears() { + composeTestRule.onNodeWithText(SEARCH_BOX_TEXT).assertIsDisplayed() + composeTestRule.onNodeWithText(SEE_BIG_BUTTON_TEXT).assertIsDisplayed() + composeTestRule.onNodeWithText(DELETE_ALL_BUTTON_TEXT).assertIsDisplayed() + composeTestRule.onNodeWithText(ALL_MENU_TEXT).assertIsDisplayed() + composeTestRule.onNodeWithText(SYMBOL_MENU_TEXT).assertIsDisplayed() + composeTestRule.onNodeWithText(BIG_CATEGORY_TEXT).assertIsDisplayed() + composeTestRule.onNodeWithText(FAVORITE_MENU_TEXT).assertIsDisplayed() + //composeTestRule.onNodeWithText(ALL_MENU_TEXT).assertIsFocused() + } + + @Test + fun should_change_symbols_displayed_when_each_menu_clicked() { + composeTestRule.onNodeWithText(ALL_MENU_TEXT).performClick() + Thread.sleep(10000) + //composeTestRule.onNodeWithText(TEST_CATEGORY_TEXT).assertIsDisplayed() + //composeTestRule.onNodeWithText(TEST_SYMBOL_TEXT).assertIsDisplayed() + + } + + + + // + + companion object { + const val SEARCH_BOX_TEXT = "검색어를 입력하세요" + const val SEE_BIG_BUTTON_TEXT = "크게 보기" + const val DELETE_ALL_BUTTON_TEXT = "모두 삭제" + const val ALL_MENU_TEXT = "전체" + const val SYMBOL_MENU_TEXT = "상징" + const val BIG_CATEGORY_TEXT = "대분류" + const val FAVORITE_MENU_TEXT = "즐겨찾기" + const val TEST_CATEGORY_TEXT = "가족" + const val TEST_SYMBOL_TEXT = "119에 전화해주세요" + } + +} \ No newline at end of file From 6cd8f2085b39838ba22fabe2c97b69b70e34a672 Mon Sep 17 00:00:00 2001 From: JH Date: Mon, 4 Dec 2023 14:13:31 +0900 Subject: [PATCH 07/10] :white_check_mark: Implemented database for testing environment --- frontend/app/build.gradle.kts | 2 + .../speechbuddy/SymbolSelectionScreenTest.kt | 126 ++++++++++++++++-- 2 files changed, 119 insertions(+), 9 deletions(-) diff --git a/frontend/app/build.gradle.kts b/frontend/app/build.gradle.kts index fe0cbd63..ac88281e 100644 --- a/frontend/app/build.gradle.kts +++ b/frontend/app/build.gradle.kts @@ -104,6 +104,8 @@ dependencies { implementation("com.squareup.retrofit2:retrofit:$retrofitVersion") implementation("com.squareup.retrofit2:converter-moshi:$retrofitVersion") implementation("com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.1") + androidTestImplementation("com.squareup.retrofit2:retrofit:$retrofitVersion") + androidTestImplementation("com.squareup.retrofit2:converter-gson:$retrofitVersion") // Gson implementation("com.google.code.gson:gson:2.9.0") diff --git a/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolSelectionScreenTest.kt b/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolSelectionScreenTest.kt index 0149dd63..d83593e4 100644 --- a/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolSelectionScreenTest.kt +++ b/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolSelectionScreenTest.kt @@ -1,5 +1,7 @@ package com.example.speechbuddy +import android.content.Context +import android.provider.ContactsContract.Data import androidx.activity.compose.setContent import androidx.compose.foundation.layout.PaddingValues import androidx.compose.runtime.mutableStateOf @@ -15,20 +17,49 @@ import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick -import androidx.compose.ui.test.performTextInput -import androidx.test.espresso.intent.Intents -import androidx.test.espresso.intent.matcher.IntentMatchers -import com.example.speechbuddy.compose.emailverification.EmailVerificationScreen -import com.example.speechbuddy.compose.settings.MySymbolSettings -import com.example.speechbuddy.compose.symbolcreation.SymbolCreationScreen +import androidx.room.Database + +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.work.OneTimeWorkRequestBuilder +import androidx.work.WorkManager +import androidx.work.WorkerParameters + import com.example.speechbuddy.compose.symbolselection.SymbolSelectionScreen +import com.example.speechbuddy.data.local.AppDatabase +import com.example.speechbuddy.data.local.CategoryDao +import com.example.speechbuddy.data.local.SymbolDao + +import com.example.speechbuddy.data.local.WeightRowDao +import com.example.speechbuddy.data.local.models.CategoryMapper +import com.example.speechbuddy.data.local.models.SymbolMapper +import com.example.speechbuddy.data.remote.MySymbolRemoteSource +import com.example.speechbuddy.data.remote.ProxyImageDownloader +import com.example.speechbuddy.data.remote.RealImageDownloader +import com.example.speechbuddy.data.remote.models.MySymbolDtoMapper +import com.example.speechbuddy.domain.SessionManager +import com.example.speechbuddy.domain.utils.Converters +import com.example.speechbuddy.repository.SymbolRepository +import com.example.speechbuddy.repository.WeightTableRepository +import com.example.speechbuddy.service.BackupService +import com.example.speechbuddy.service.SymbolCreationService import com.example.speechbuddy.ui.SpeechBuddyTheme +import com.example.speechbuddy.utils.ResponseHandler +import com.example.speechbuddy.viewmodel.SymbolSelectionViewModel +import com.example.speechbuddy.worker.SeedDatabaseWorker import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest +import kotlinx.coroutines.runBlocking + +import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory @HiltAndroidTest @@ -40,9 +71,50 @@ class SymbolSelectionScreenTest { @get:Rule(order = 1) val composeTestRule = createAndroidComposeRule() + // Room database instance + private lateinit var database: AppDatabase + private lateinit var symbolDao: SymbolDao + private lateinit var categoryDao: CategoryDao + private lateinit var weightRowDao: WeightRowDao + + val retrofit = Retrofit.Builder() + .baseUrl("https://speechbuddy-1.herokuapp.com/") + .addConverterFactory(GsonConverterFactory.create()) + .build() + + val backupService = retrofit.create(BackupService::class.java) + val symbolCreationService = retrofit.create(SymbolCreationService::class.java) + @Before fun setUp() { hiltRule.inject() + + val context = ApplicationProvider.getApplicationContext() +// val worker = SeedDatabaseWorker(context, WorkerParameters.DEFAULT) + val path = context.getDatabasePath("speechbuddy-db") + + database = Room.databaseBuilder( + context, + AppDatabase::class.java, + path.toString() + ).build() + +// database = Room.inMemoryDatabaseBuilder( +// context, +// AppDatabase::class.java +// ).build() + + symbolDao = database.symbolDao() + categoryDao = database.categoryDao() + weightRowDao = database.weightRowDao() + + runBlocking { + val request = OneTimeWorkRequestBuilder().build() + WorkManager.getInstance(context).enqueue(request) + Thread.sleep(10000) + } + + composeTestRule.activity.setContent { SpeechBuddyTheme( settingsRepository = composeTestRule.activity.settingsRepository, @@ -51,12 +123,46 @@ class SymbolSelectionScreenTest { SymbolSelectionScreen( paddingValues = PaddingValues(), topAppBarState = remember{ mutableStateOf(true) }, - bottomNavBarState = remember{ mutableStateOf(true) } + bottomNavBarState = remember{ mutableStateOf(true) }, + viewModel = SymbolSelectionViewModel( + repository = SymbolRepository( + symbolDao = symbolDao, + categoryDao = categoryDao, + mySymbolRemoteSource = MySymbolRemoteSource( + symbolCreationService = symbolCreationService, + responseHandler = ResponseHandler() + ), + proxyImageDownloader = ProxyImageDownloader( + realImageDownloader = RealImageDownloader( + backupService = backupService, + context = context + //InstrumentationRegistry.getInstrumentation().context + ), + context = context + //InstrumentationRegistry.getInstrumentation().context + ), + mySymbolDtoMapper = MySymbolDtoMapper(), + symbolMapper = SymbolMapper(), + categoryMapper = CategoryMapper(), + sessionManager = SessionManager(), + responseHandler = ResponseHandler() + ), + weightTableRepository = WeightTableRepository( + symbolDao = symbolDao, + weightRowDao = weightRowDao, + converters = Converters(), + ), + ) ) } } } + @After + fun tearDown(){ + database.close() + } + @Test fun should_display_all_elements_when_mysybolsettings_screen_with_big_category_menu_appears() { composeTestRule.onNodeWithText(SEARCH_BOX_TEXT).assertIsDisplayed() @@ -67,14 +173,15 @@ class SymbolSelectionScreenTest { composeTestRule.onNodeWithText(BIG_CATEGORY_TEXT).assertIsDisplayed() composeTestRule.onNodeWithText(FAVORITE_MENU_TEXT).assertIsDisplayed() //composeTestRule.onNodeWithText(ALL_MENU_TEXT).assertIsFocused() + Thread.sleep(5000) } @Test fun should_change_symbols_displayed_when_each_menu_clicked() { composeTestRule.onNodeWithText(ALL_MENU_TEXT).performClick() Thread.sleep(10000) - //composeTestRule.onNodeWithText(TEST_CATEGORY_TEXT).assertIsDisplayed() - //composeTestRule.onNodeWithText(TEST_SYMBOL_TEXT).assertIsDisplayed() + composeTestRule.onNodeWithText(TEST_CATEGORY_TEXT).assertIsDisplayed() + composeTestRule.onNodeWithText(TEST_SYMBOL_TEXT).assertIsDisplayed() } @@ -82,6 +189,7 @@ class SymbolSelectionScreenTest { // + companion object { const val SEARCH_BOX_TEXT = "검색어를 입력하세요" const val SEE_BIG_BUTTON_TEXT = "크게 보기" From c5d8e4c81065049c70abaaf2d5a11f5a103bf9da Mon Sep 17 00:00:00 2001 From: JH Date: Tue, 5 Dec 2023 02:49:23 +0900 Subject: [PATCH 08/10] :white_check_mark: Add Symbol related integration test cases --- .../speechbuddy/MySymbolSettingsScreenTest.kt | 142 +++++++++++++++++- .../speechbuddy/SymbolCreationScreenTest.kt | 94 +++++++++++- .../speechbuddy/SymbolSelectionScreenTest.kt | 75 ++++++++- .../symbolselection/SymbolSearchTextField.kt | 1 + 4 files changed, 299 insertions(+), 13 deletions(-) diff --git a/frontend/app/src/androidTest/java/com/example/speechbuddy/MySymbolSettingsScreenTest.kt b/frontend/app/src/androidTest/java/com/example/speechbuddy/MySymbolSettingsScreenTest.kt index c097bee1..44758dbe 100644 --- a/frontend/app/src/androidTest/java/com/example/speechbuddy/MySymbolSettingsScreenTest.kt +++ b/frontend/app/src/androidTest/java/com/example/speechbuddy/MySymbolSettingsScreenTest.kt @@ -1,5 +1,6 @@ package com.example.speechbuddy +import android.content.Context import androidx.activity.compose.setContent import androidx.compose.foundation.layout.PaddingValues import androidx.compose.ui.test.assertHasClickAction @@ -12,18 +13,46 @@ import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performTextInput +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider import androidx.test.espresso.intent.Intents import androidx.test.espresso.intent.matcher.IntentMatchers +import androidx.work.OneTimeWorkRequestBuilder +import androidx.work.WorkManager import com.example.speechbuddy.compose.emailverification.EmailVerificationScreen import com.example.speechbuddy.compose.settings.MySymbolSettings import com.example.speechbuddy.compose.symbolcreation.SymbolCreationScreen +import com.example.speechbuddy.data.local.AppDatabase +import com.example.speechbuddy.data.local.CategoryDao +import com.example.speechbuddy.data.local.SymbolDao +import com.example.speechbuddy.data.local.WeightRowDao +import com.example.speechbuddy.data.local.models.CategoryMapper +import com.example.speechbuddy.data.local.models.SymbolEntity +import com.example.speechbuddy.data.local.models.SymbolMapper +import com.example.speechbuddy.data.remote.MySymbolRemoteSource +import com.example.speechbuddy.data.remote.ProxyImageDownloader +import com.example.speechbuddy.data.remote.RealImageDownloader +import com.example.speechbuddy.data.remote.models.MySymbolDtoMapper +import com.example.speechbuddy.domain.SessionManager +import com.example.speechbuddy.domain.utils.Converters +import com.example.speechbuddy.repository.SymbolRepository +import com.example.speechbuddy.repository.WeightTableRepository +import com.example.speechbuddy.service.BackupService +import com.example.speechbuddy.service.SymbolCreationService import com.example.speechbuddy.ui.SpeechBuddyTheme +import com.example.speechbuddy.utils.ResponseHandler +import com.example.speechbuddy.viewmodel.MySymbolSettingsViewModel +import com.example.speechbuddy.worker.SeedDatabaseWorker import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.runBlocking import org.junit.Before import org.junit.Rule import org.junit.Test +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory @HiltAndroidTest @@ -35,23 +64,108 @@ class MySymbolSettingsScreenTest { @get:Rule(order = 1) val composeTestRule = createAndroidComposeRule() + // Room database instance + private lateinit var database: AppDatabase + private lateinit var symbolDao: SymbolDao + private lateinit var categoryDao: CategoryDao + private lateinit var weightRowDao: WeightRowDao + + val retrofit = Retrofit.Builder() + .baseUrl("https://speechbuddy-1.herokuapp.com/") + .addConverterFactory(GsonConverterFactory.create()) + .build() + + val backupService = retrofit.create(BackupService::class.java) + val symbolCreationService = retrofit.create(SymbolCreationService::class.java) + @Before fun setUp() { hiltRule.inject() + + val context = ApplicationProvider.getApplicationContext() +// val worker = SeedDatabaseWorker(context, WorkerParameters.DEFAULT) + val path = context.getDatabasePath("speechbuddy-db") + + database = Room.databaseBuilder( + context, + AppDatabase::class.java, + path.toString() + ).build() + + symbolDao = database.symbolDao() + categoryDao = database.categoryDao() + weightRowDao = database.weightRowDao() + + runBlocking { + val request = OneTimeWorkRequestBuilder().build() + WorkManager.getInstance(context).enqueue(request) + Thread.sleep(5000) + + val symbolEntity = symbolDao.getSymbolById(1) + val symbol = SymbolMapper().mapToDomainModel(symbolEntity.first()) + symbolDao.updateSymbol( + SymbolMapper().mapFromDomainModel( + symbol.copy( + isMine = false, + isFavorite = true + ) + ) + ) + symbolDao.insertSymbol( + SymbolEntity( + id = 1000, + text = "test", + imageUrl = null, + categoryId = 1, + isFavorite = false, + isMine = true + ) + ) + } + composeTestRule.activity.setContent { SpeechBuddyTheme( settingsRepository = composeTestRule.activity.settingsRepository, initialDarkMode = false ) { MySymbolSettings( - paddingValues = PaddingValues() + paddingValues = PaddingValues(), + viewModel = MySymbolSettingsViewModel( + weightTableRepository = WeightTableRepository( + symbolDao = symbolDao, + weightRowDao = weightRowDao, + converters = Converters(), + ), + symbolRepository = SymbolRepository( + symbolDao = symbolDao, + categoryDao = categoryDao, + mySymbolRemoteSource = MySymbolRemoteSource( + symbolCreationService = symbolCreationService, + responseHandler = ResponseHandler() + ), + proxyImageDownloader = ProxyImageDownloader( + realImageDownloader = RealImageDownloader( + backupService = backupService, + context = context + //InstrumentationRegistry.getInstrumentation().context + ), + context = context + //InstrumentationRegistry.getInstrumentation().context + ), + mySymbolDtoMapper = MySymbolDtoMapper(), + symbolMapper = SymbolMapper(), + categoryMapper = CategoryMapper(), + sessionManager = SessionManager(), + responseHandler = ResponseHandler() + ), + ) ) } } } @Test - fun should_display_all_elements_when_mysybolsettings_screen_with_my_symbol_menu_appears() { + fun should_display_all_elements_when_mysybolsettings_screen_appears() { composeTestRule.onNodeWithText(SEARCH_BOX_TEXT).assertIsDisplayed() composeTestRule.onNodeWithText(MY_SYMBOL_MENU_TEXT).assertIsDisplayed() @@ -60,12 +174,24 @@ class MySymbolSettingsScreenTest { } @Test - fun should_display_all_elements_when_mysybolsettings_screen_with_favorite_menu_appears() { + fun should_display_proper_symbols_when_in_MY_SYMBOL_MODE() { + composeTestRule.onNodeWithText(TEST_SYMBOL_TEXT_FOR_CREATION).assertIsDisplayed() + } + + @Test + fun should_display_proper_symbols_when_in_FAVORITES_MODE() { composeTestRule.onNodeWithText(FAVORITES_MENU_TEXT).performClick() - composeTestRule.onNodeWithText(SEARCH_BOX_TEXT).assertIsDisplayed() - composeTestRule.onNodeWithText(MY_SYMBOL_MENU_TEXT).assertIsDisplayed() - composeTestRule.onNodeWithText(FAVORITES_MENU_TEXT).assertIsDisplayed() - //composeTestRule.onNodeWithText(DELETE_TEXT).assertIsNotDisplayed() + composeTestRule.waitForIdle() + composeTestRule.onNodeWithText(TEST_SYMBOL_TEXT_FOR_FAVORITE).assertIsDisplayed() + } + + @Test + fun should_delete_symbol_when_delete_button_is_clicked() { + composeTestRule.onNodeWithText(TEST_SYMBOL_TEXT_FOR_CREATION).performClick() + composeTestRule.waitForIdle() + //composeTestRule.onNodeWithText(DELETE_TEXT).performClick() + //composeTestRule.waitForIdle() + //composeTestRule.onNodeWithText(TEST_SYMBOL_TEXT_FOR_CREATION).assertIsNotDisplayed() } @@ -76,6 +202,8 @@ class MySymbolSettingsScreenTest { const val MY_SYMBOL_MENU_TEXT = "내가 만든 상징" const val FAVORITES_MENU_TEXT = "즐겨찾기" const val DELETE_TEXT = "삭제" + const val TEST_SYMBOL_TEXT_FOR_CREATION = "test" + const val TEST_SYMBOL_TEXT_FOR_FAVORITE = "119에 전화해주세요" } diff --git a/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolCreationScreenTest.kt b/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolCreationScreenTest.kt index 737ac827..1c6e9c90 100644 --- a/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolCreationScreenTest.kt +++ b/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolCreationScreenTest.kt @@ -3,6 +3,7 @@ package com.example.speechbuddy import android.app.Activity import android.app.Instrumentation import android.content.ContentResolver +import android.content.Context import android.content.Intent import android.graphics.Bitmap import android.net.Uri @@ -17,17 +18,43 @@ import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performTextInput +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider import androidx.test.espresso.intent.Intents import androidx.test.espresso.intent.matcher.IntentMatchers +import androidx.work.OneTimeWorkRequestBuilder +import androidx.work.WorkManager import com.example.speechbuddy.compose.emailverification.EmailVerificationScreen import com.example.speechbuddy.compose.symbolcreation.SymbolCreationScreen +import com.example.speechbuddy.data.local.AppDatabase +import com.example.speechbuddy.data.local.CategoryDao +import com.example.speechbuddy.data.local.SymbolDao +import com.example.speechbuddy.data.local.WeightRowDao +import com.example.speechbuddy.data.local.models.CategoryMapper +import com.example.speechbuddy.data.local.models.SymbolMapper +import com.example.speechbuddy.data.remote.MySymbolRemoteSource +import com.example.speechbuddy.data.remote.ProxyImageDownloader +import com.example.speechbuddy.data.remote.RealImageDownloader +import com.example.speechbuddy.data.remote.models.MySymbolDtoMapper +import com.example.speechbuddy.domain.SessionManager +import com.example.speechbuddy.domain.utils.Converters +import com.example.speechbuddy.repository.SymbolRepository +import com.example.speechbuddy.repository.WeightTableRepository +import com.example.speechbuddy.service.BackupService +import com.example.speechbuddy.service.SymbolCreationService import com.example.speechbuddy.ui.SpeechBuddyTheme +import com.example.speechbuddy.utils.ResponseHandler +import com.example.speechbuddy.viewmodel.SymbolCreationViewModel +import com.example.speechbuddy.worker.SeedDatabaseWorker import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest +import kotlinx.coroutines.runBlocking import org.junit.Before import org.junit.Rule import org.junit.Test +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream @@ -40,16 +67,81 @@ class SymbolCreationScreenTest { @get:Rule(order = 1) val composeTestRule = createAndroidComposeRule() + // Room database instance + private lateinit var database: AppDatabase + private lateinit var symbolDao: SymbolDao + private lateinit var categoryDao: CategoryDao + private lateinit var weightRowDao: WeightRowDao + + val retrofit = Retrofit.Builder() + .baseUrl("https://speechbuddy-1.herokuapp.com/") + .addConverterFactory(GsonConverterFactory.create()) + .build() + + val backupService = retrofit.create(BackupService::class.java) + val symbolCreationService = retrofit.create(SymbolCreationService::class.java) + @Before fun setUp() { hiltRule.inject() + + val context = ApplicationProvider.getApplicationContext() +// val worker = SeedDatabaseWorker(context, WorkerParameters.DEFAULT) + val path = context.getDatabasePath("speechbuddy-db") + + database = Room.databaseBuilder( + context, + AppDatabase::class.java, + path.toString() + ).build() + + symbolDao = database.symbolDao() + categoryDao = database.categoryDao() + weightRowDao = database.weightRowDao() + + runBlocking { + val request = OneTimeWorkRequestBuilder().build() + WorkManager.getInstance(context).enqueue(request) + Thread.sleep(5000) + } + composeTestRule.activity.setContent { SpeechBuddyTheme( settingsRepository = composeTestRule.activity.settingsRepository, initialDarkMode = false ) { SymbolCreationScreen( - paddingValues = PaddingValues() + paddingValues = PaddingValues(), + viewModel = SymbolCreationViewModel( + symbolRepository = SymbolRepository( + symbolDao = symbolDao, + categoryDao = categoryDao, + mySymbolRemoteSource = MySymbolRemoteSource( + symbolCreationService = symbolCreationService, + responseHandler = ResponseHandler() + ), + proxyImageDownloader = ProxyImageDownloader( + realImageDownloader = RealImageDownloader( + backupService = backupService, + context = context + //InstrumentationRegistry.getInstrumentation().context + ), + context = context + //InstrumentationRegistry.getInstrumentation().context + ), + mySymbolDtoMapper = MySymbolDtoMapper(), + symbolMapper = SymbolMapper(), + categoryMapper = CategoryMapper(), + sessionManager = SessionManager(), + responseHandler = ResponseHandler() + ), + weightTableRepository = WeightTableRepository( + symbolDao = symbolDao, + weightRowDao = weightRowDao, + converters = Converters(), + ), + sessionManager = SessionManager() + ) ) } } diff --git a/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolSelectionScreenTest.kt b/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolSelectionScreenTest.kt index d83593e4..3c5186a9 100644 --- a/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolSelectionScreenTest.kt +++ b/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolSelectionScreenTest.kt @@ -14,9 +14,12 @@ import androidx.compose.ui.test.assertIsNotDisplayed import androidx.compose.ui.test.assertIsNotEnabled import androidx.compose.ui.test.assertIsSelected import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onAllNodesWithText import androidx.compose.ui.test.onNodeWithContentDescription +import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick +import androidx.compose.ui.test.performTextInput import androidx.room.Database import androidx.room.Room @@ -51,6 +54,7 @@ import com.example.speechbuddy.viewmodel.SymbolSelectionViewModel import com.example.speechbuddy.worker.SeedDatabaseWorker import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest +import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking import org.junit.After @@ -111,10 +115,9 @@ class SymbolSelectionScreenTest { runBlocking { val request = OneTimeWorkRequestBuilder().build() WorkManager.getInstance(context).enqueue(request) - Thread.sleep(10000) + Thread.sleep(5000) } - composeTestRule.activity.setContent { SpeechBuddyTheme( settingsRepository = composeTestRule.activity.settingsRepository, @@ -172,25 +175,86 @@ class SymbolSelectionScreenTest { composeTestRule.onNodeWithText(SYMBOL_MENU_TEXT).assertIsDisplayed() composeTestRule.onNodeWithText(BIG_CATEGORY_TEXT).assertIsDisplayed() composeTestRule.onNodeWithText(FAVORITE_MENU_TEXT).assertIsDisplayed() - //composeTestRule.onNodeWithText(ALL_MENU_TEXT).assertIsFocused() - Thread.sleep(5000) + } @Test fun should_change_symbols_displayed_when_each_menu_clicked() { composeTestRule.onNodeWithText(ALL_MENU_TEXT).performClick() - Thread.sleep(10000) + composeTestRule.waitForIdle() composeTestRule.onNodeWithText(TEST_CATEGORY_TEXT).assertIsDisplayed() + + composeTestRule.onNodeWithText(SYMBOL_MENU_TEXT).performClick() + composeTestRule.waitForIdle() composeTestRule.onNodeWithText(TEST_SYMBOL_TEXT).assertIsDisplayed() + composeTestRule.onNodeWithText(BIG_CATEGORY_TEXT).performClick() + composeTestRule.waitForIdle() + composeTestRule.onNodeWithText(TEST_CATEGORY_TEXT).assertIsDisplayed() + } + + @Test + fun should_display_proper_symbols_when_each_category_clicked() { +// composeTestRule.onNodeWithText(TEST_CATEGORY_TEXT).performClick() +// Thread.sleep(3000) +// composeTestRule.onAllNodesWithText("가족")[0].performClick() + composeTestRule.onNodeWithText("가족").performClick() + composeTestRule.waitForIdle() + composeTestRule.onNodeWithText("남동생").assertIsDisplayed() + } + + @Test + fun should_display_proper_symbols_when_search_box_typed() { + composeTestRule.onNodeWithText(SEARCH_BOX_TEXT).performTextInput("가") + //composeTestRule.waitForIdle() + //composeTestRule.onNodeWithText(DELETE_ALL_BUTTON_TEXT).performClick() + //composeTestRule.waitForIdle() + + //composeTestRule.onNodeWithText("가게").assertIsDisplayed() + //composeTestRule.onNodeWithText("가다").assertIsDisplayed() + //composeTestRule.onNodeWithText("가방").assertIsDisplayed() } + @Test + fun should_display_proper_symbols_on_selected_symbols_when_symbols_clicked(){ + composeTestRule.onNodeWithText("가족").performClick() + composeTestRule.waitForIdle() + composeTestRule.onNodeWithText("남동생").performClick() + composeTestRule.waitForIdle() + composeTestRule.onNodeWithText(BIG_CATEGORY_TEXT).performClick() + composeTestRule.waitForIdle() + composeTestRule.onNodeWithText("남동생").assertIsDisplayed() + } + + @Test + fun should_clear_symbols_on_selected_symbols_when_DELETE_ALL_BUTTON_clicked(){ + composeTestRule.onNodeWithText("가족").performClick() + composeTestRule.waitForIdle() + composeTestRule.onNodeWithText("남동생").performClick() + composeTestRule.waitForIdle() + composeTestRule.onNodeWithText(BIG_CATEGORY_TEXT).performClick() + composeTestRule.waitForIdle() + composeTestRule.onNodeWithText("남동생").assertIsDisplayed() + } + + @Test + fun should_display_in_SEE_BIG_mode_when_SEE_BIG_BUTTON_clicked(){ + composeTestRule.onNodeWithText("가족").performClick() + composeTestRule.waitForIdle() + composeTestRule.onNodeWithText("남동생").performClick() + composeTestRule.waitForIdle() + composeTestRule.onNodeWithText(SEE_BIG_BUTTON_TEXT).performClick() + composeTestRule.waitForIdle() + composeTestRule.onNodeWithText(EXIT_BUTTON_TEXT).assertIsDisplayed() + + } // companion object { + //const val SEARCH_BOX_TEXT = "SymbolSearchTextField" const val SEARCH_BOX_TEXT = "검색어를 입력하세요" const val SEE_BIG_BUTTON_TEXT = "크게 보기" const val DELETE_ALL_BUTTON_TEXT = "모두 삭제" @@ -200,6 +264,7 @@ class SymbolSelectionScreenTest { const val FAVORITE_MENU_TEXT = "즐겨찾기" const val TEST_CATEGORY_TEXT = "가족" const val TEST_SYMBOL_TEXT = "119에 전화해주세요" + const val EXIT_BUTTON_TEXT = "나가기" } } \ No newline at end of file diff --git a/frontend/app/src/main/java/com/example/speechbuddy/compose/symbolselection/SymbolSearchTextField.kt b/frontend/app/src/main/java/com/example/speechbuddy/compose/symbolselection/SymbolSearchTextField.kt index 96f44130..2b6544ab 100644 --- a/frontend/app/src/main/java/com/example/speechbuddy/compose/symbolselection/SymbolSearchTextField.kt +++ b/frontend/app/src/main/java/com/example/speechbuddy/compose/symbolselection/SymbolSearchTextField.kt @@ -13,6 +13,7 @@ import androidx.compose.material3.Text import androidx.compose.material3.TextFieldDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp From 2f04d29b51d63caf1679fd5e7c3cb88d9f537168 Mon Sep 17 00:00:00 2001 From: JH Date: Sun, 10 Dec 2023 05:25:56 +0900 Subject: [PATCH 09/10] :white_check_mark: Updated testcases --- .../speechbuddy/MySymbolSettingsScreenTest.kt | 10 ++-------- .../speechbuddy/SymbolCreationScreenTest.kt | 4 ++-- .../speechbuddy/SymbolSelectionScreenTest.kt | 20 ++++++++----------- 3 files changed, 12 insertions(+), 22 deletions(-) diff --git a/frontend/app/src/androidTest/java/com/example/speechbuddy/MySymbolSettingsScreenTest.kt b/frontend/app/src/androidTest/java/com/example/speechbuddy/MySymbolSettingsScreenTest.kt index 44758dbe..08f5a34e 100644 --- a/frontend/app/src/androidTest/java/com/example/speechbuddy/MySymbolSettingsScreenTest.kt +++ b/frontend/app/src/androidTest/java/com/example/speechbuddy/MySymbolSettingsScreenTest.kt @@ -9,6 +9,7 @@ import androidx.compose.ui.test.assertIsEnabled import androidx.compose.ui.test.assertIsNotDisplayed import androidx.compose.ui.test.assertIsNotEnabled import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onAllNodesWithText import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick @@ -185,14 +186,7 @@ class MySymbolSettingsScreenTest { composeTestRule.onNodeWithText(TEST_SYMBOL_TEXT_FOR_FAVORITE).assertIsDisplayed() } - @Test - fun should_delete_symbol_when_delete_button_is_clicked() { - composeTestRule.onNodeWithText(TEST_SYMBOL_TEXT_FOR_CREATION).performClick() - composeTestRule.waitForIdle() - //composeTestRule.onNodeWithText(DELETE_TEXT).performClick() - //composeTestRule.waitForIdle() - //composeTestRule.onNodeWithText(TEST_SYMBOL_TEXT_FOR_CREATION).assertIsNotDisplayed() - } + // diff --git a/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolCreationScreenTest.kt b/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolCreationScreenTest.kt index 1c6e9c90..0a1e8c30 100644 --- a/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolCreationScreenTest.kt +++ b/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolCreationScreenTest.kt @@ -160,7 +160,7 @@ class SymbolCreationScreenTest { @Test fun should_display_alertdialog_with_three_options_when_symbolcreation_clicked(){ composeTestRule.onNodeWithContentDescription(PHOTO_ICON_DESCRIPTION).performClick() - Thread.sleep(1000) + composeTestRule.waitForIdle() composeTestRule.onNodeWithText(ALERT_MESSAGE).assertIsDisplayed() composeTestRule.onNodeWithText(TAKE_PICTURE).assertIsDisplayed() composeTestRule.onNodeWithText(SELECT_FROM_EXISTING).assertIsDisplayed() @@ -169,7 +169,7 @@ class SymbolCreationScreenTest { @Test fun should_display_all_categories_when_category_selection_is_clicked(){ composeTestRule.onNodeWithText(BIG_CATEGORY_BOX_TEXT).performClick() - Thread.sleep(1000) + composeTestRule.waitForIdle() composeTestRule.onNodeWithText("가족").assertIsDisplayed() } diff --git a/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolSelectionScreenTest.kt b/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolSelectionScreenTest.kt index 3c5186a9..e78f0034 100644 --- a/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolSelectionScreenTest.kt +++ b/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolSelectionScreenTest.kt @@ -20,6 +20,7 @@ import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performTextInput +import androidx.compose.ui.test.performTextReplacement import androidx.room.Database import androidx.room.Room @@ -56,6 +57,7 @@ import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking +import okhttp3.internal.wait import org.junit.After @@ -203,17 +205,7 @@ class SymbolSelectionScreenTest { composeTestRule.onNodeWithText("남동생").assertIsDisplayed() } - @Test - fun should_display_proper_symbols_when_search_box_typed() { - composeTestRule.onNodeWithText(SEARCH_BOX_TEXT).performTextInput("가") - //composeTestRule.waitForIdle() - //composeTestRule.onNodeWithText(DELETE_ALL_BUTTON_TEXT).performClick() - //composeTestRule.waitForIdle() - - //composeTestRule.onNodeWithText("가게").assertIsDisplayed() - //composeTestRule.onNodeWithText("가다").assertIsDisplayed() - //composeTestRule.onNodeWithText("가방").assertIsDisplayed() - } + @Test fun should_display_proper_symbols_on_selected_symbols_when_symbols_clicked(){ @@ -245,7 +237,11 @@ class SymbolSelectionScreenTest { composeTestRule.waitForIdle() composeTestRule.onNodeWithText(SEE_BIG_BUTTON_TEXT).performClick() composeTestRule.waitForIdle() - composeTestRule.onNodeWithText(EXIT_BUTTON_TEXT).assertIsDisplayed() + composeTestRule.waitUntil { + composeTestRule.onAllNodesWithText(EXIT_BUTTON_TEXT).fetchSemanticsNodes().size == 1 + //composeTestRule.onNodeWithText(EXIT_BUTTON_TEXT).assertIsDisplayed() + } + } From 4e36d15e72222a6825f8af32808638931e180c34 Mon Sep 17 00:00:00 2001 From: JH Date: Sun, 10 Dec 2023 05:29:08 +0900 Subject: [PATCH 10/10] :white_check_mark: Removed redundant imports and annotations --- .../speechbuddy/MySymbolSettingsScreenTest.kt | 18 +------ .../speechbuddy/SymbolCreationScreenTest.kt | 27 +++------- .../speechbuddy/SymbolSelectionScreenTest.kt | 54 +++++-------------- 3 files changed, 21 insertions(+), 78 deletions(-) diff --git a/frontend/app/src/androidTest/java/com/example/speechbuddy/MySymbolSettingsScreenTest.kt b/frontend/app/src/androidTest/java/com/example/speechbuddy/MySymbolSettingsScreenTest.kt index 08f5a34e..4781bb5f 100644 --- a/frontend/app/src/androidTest/java/com/example/speechbuddy/MySymbolSettingsScreenTest.kt +++ b/frontend/app/src/androidTest/java/com/example/speechbuddy/MySymbolSettingsScreenTest.kt @@ -3,26 +3,15 @@ package com.example.speechbuddy import android.content.Context import androidx.activity.compose.setContent import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.ui.test.assertHasClickAction import androidx.compose.ui.test.assertIsDisplayed -import androidx.compose.ui.test.assertIsEnabled -import androidx.compose.ui.test.assertIsNotDisplayed -import androidx.compose.ui.test.assertIsNotEnabled import androidx.compose.ui.test.junit4.createAndroidComposeRule -import androidx.compose.ui.test.onAllNodesWithText -import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick -import androidx.compose.ui.test.performTextInput import androidx.room.Room import androidx.test.core.app.ApplicationProvider -import androidx.test.espresso.intent.Intents -import androidx.test.espresso.intent.matcher.IntentMatchers import androidx.work.OneTimeWorkRequestBuilder import androidx.work.WorkManager -import com.example.speechbuddy.compose.emailverification.EmailVerificationScreen import com.example.speechbuddy.compose.settings.MySymbolSettings -import com.example.speechbuddy.compose.symbolcreation.SymbolCreationScreen import com.example.speechbuddy.data.local.AppDatabase import com.example.speechbuddy.data.local.CategoryDao import com.example.speechbuddy.data.local.SymbolDao @@ -48,7 +37,6 @@ import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest import kotlinx.coroutines.flow.first import kotlinx.coroutines.runBlocking - import org.junit.Before import org.junit.Rule import org.junit.Test @@ -148,10 +136,10 @@ class MySymbolSettingsScreenTest { realImageDownloader = RealImageDownloader( backupService = backupService, context = context - //InstrumentationRegistry.getInstrumentation().context + ), context = context - //InstrumentationRegistry.getInstrumentation().context + ), mySymbolDtoMapper = MySymbolDtoMapper(), symbolMapper = SymbolMapper(), @@ -187,8 +175,6 @@ class MySymbolSettingsScreenTest { } - - // companion object { diff --git a/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolCreationScreenTest.kt b/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolCreationScreenTest.kt index 0a1e8c30..ceaab58b 100644 --- a/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolCreationScreenTest.kt +++ b/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolCreationScreenTest.kt @@ -1,30 +1,17 @@ package com.example.speechbuddy -import android.app.Activity -import android.app.Instrumentation -import android.content.ContentResolver import android.content.Context -import android.content.Intent -import android.graphics.Bitmap -import android.net.Uri import androidx.activity.compose.setContent import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.ui.test.assertHasClickAction import androidx.compose.ui.test.assertIsDisplayed -import androidx.compose.ui.test.assertIsEnabled -import androidx.compose.ui.test.assertIsNotEnabled import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick -import androidx.compose.ui.test.performTextInput import androidx.room.Room import androidx.test.core.app.ApplicationProvider -import androidx.test.espresso.intent.Intents -import androidx.test.espresso.intent.matcher.IntentMatchers import androidx.work.OneTimeWorkRequestBuilder import androidx.work.WorkManager -import com.example.speechbuddy.compose.emailverification.EmailVerificationScreen import com.example.speechbuddy.compose.symbolcreation.SymbolCreationScreen import com.example.speechbuddy.data.local.AppDatabase import com.example.speechbuddy.data.local.CategoryDao @@ -49,14 +36,11 @@ import com.example.speechbuddy.worker.SeedDatabaseWorker import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest import kotlinx.coroutines.runBlocking - import org.junit.Before import org.junit.Rule import org.junit.Test import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory -import java.io.ByteArrayInputStream -import java.io.ByteArrayOutputStream @HiltAndroidTest class SymbolCreationScreenTest { @@ -86,7 +70,7 @@ class SymbolCreationScreenTest { hiltRule.inject() val context = ApplicationProvider.getApplicationContext() -// val worker = SeedDatabaseWorker(context, WorkerParameters.DEFAULT) + val path = context.getDatabasePath("speechbuddy-db") database = Room.databaseBuilder( @@ -124,10 +108,10 @@ class SymbolCreationScreenTest { realImageDownloader = RealImageDownloader( backupService = backupService, context = context - //InstrumentationRegistry.getInstrumentation().context + ), context = context - //InstrumentationRegistry.getInstrumentation().context + ), mySymbolDtoMapper = MySymbolDtoMapper(), symbolMapper = SymbolMapper(), @@ -158,7 +142,7 @@ class SymbolCreationScreenTest { } @Test - fun should_display_alertdialog_with_three_options_when_symbolcreation_clicked(){ + fun should_display_alertdialog_with_three_options_when_symbolcreation_clicked() { composeTestRule.onNodeWithContentDescription(PHOTO_ICON_DESCRIPTION).performClick() composeTestRule.waitForIdle() composeTestRule.onNodeWithText(ALERT_MESSAGE).assertIsDisplayed() @@ -166,8 +150,9 @@ class SymbolCreationScreenTest { composeTestRule.onNodeWithText(SELECT_FROM_EXISTING).assertIsDisplayed() composeTestRule.onNodeWithText(CANCEL).assertIsDisplayed() } + @Test - fun should_display_all_categories_when_category_selection_is_clicked(){ + fun should_display_all_categories_when_category_selection_is_clicked() { composeTestRule.onNodeWithText(BIG_CATEGORY_BOX_TEXT).performClick() composeTestRule.waitForIdle() composeTestRule.onNodeWithText("가족").assertIsDisplayed() diff --git a/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolSelectionScreenTest.kt b/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolSelectionScreenTest.kt index e78f0034..717544d1 100644 --- a/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolSelectionScreenTest.kt +++ b/frontend/app/src/androidTest/java/com/example/speechbuddy/SymbolSelectionScreenTest.kt @@ -1,41 +1,23 @@ package com.example.speechbuddy import android.content.Context -import android.provider.ContactsContract.Data import androidx.activity.compose.setContent import androidx.compose.foundation.layout.PaddingValues import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.ui.test.assertHasClickAction import androidx.compose.ui.test.assertIsDisplayed -import androidx.compose.ui.test.assertIsEnabled -import androidx.compose.ui.test.assertIsFocused -import androidx.compose.ui.test.assertIsNotDisplayed -import androidx.compose.ui.test.assertIsNotEnabled -import androidx.compose.ui.test.assertIsSelected import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.onAllNodesWithText -import androidx.compose.ui.test.onNodeWithContentDescription -import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick -import androidx.compose.ui.test.performTextInput -import androidx.compose.ui.test.performTextReplacement -import androidx.room.Database - import androidx.room.Room import androidx.test.core.app.ApplicationProvider - -import androidx.test.platform.app.InstrumentationRegistry import androidx.work.OneTimeWorkRequestBuilder import androidx.work.WorkManager -import androidx.work.WorkerParameters - import com.example.speechbuddy.compose.symbolselection.SymbolSelectionScreen import com.example.speechbuddy.data.local.AppDatabase import com.example.speechbuddy.data.local.CategoryDao import com.example.speechbuddy.data.local.SymbolDao - import com.example.speechbuddy.data.local.WeightRowDao import com.example.speechbuddy.data.local.models.CategoryMapper import com.example.speechbuddy.data.local.models.SymbolMapper @@ -55,12 +37,8 @@ import com.example.speechbuddy.viewmodel.SymbolSelectionViewModel import com.example.speechbuddy.worker.SeedDatabaseWorker import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest -import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking -import okhttp3.internal.wait - import org.junit.After - import org.junit.Before import org.junit.Rule import org.junit.Test @@ -96,7 +74,7 @@ class SymbolSelectionScreenTest { hiltRule.inject() val context = ApplicationProvider.getApplicationContext() -// val worker = SeedDatabaseWorker(context, WorkerParameters.DEFAULT) + val path = context.getDatabasePath("speechbuddy-db") database = Room.databaseBuilder( @@ -105,10 +83,7 @@ class SymbolSelectionScreenTest { path.toString() ).build() -// database = Room.inMemoryDatabaseBuilder( -// context, -// AppDatabase::class.java -// ).build() + symbolDao = database.symbolDao() categoryDao = database.categoryDao() @@ -127,8 +102,8 @@ class SymbolSelectionScreenTest { ) { SymbolSelectionScreen( paddingValues = PaddingValues(), - topAppBarState = remember{ mutableStateOf(true) }, - bottomNavBarState = remember{ mutableStateOf(true) }, + topAppBarState = remember { mutableStateOf(true) }, + bottomNavBarState = remember { mutableStateOf(true) }, viewModel = SymbolSelectionViewModel( repository = SymbolRepository( symbolDao = symbolDao, @@ -141,10 +116,10 @@ class SymbolSelectionScreenTest { realImageDownloader = RealImageDownloader( backupService = backupService, context = context - //InstrumentationRegistry.getInstrumentation().context + ), context = context - //InstrumentationRegistry.getInstrumentation().context + ), mySymbolDtoMapper = MySymbolDtoMapper(), symbolMapper = SymbolMapper(), @@ -164,7 +139,7 @@ class SymbolSelectionScreenTest { } @After - fun tearDown(){ + fun tearDown() { database.close() } @@ -197,18 +172,15 @@ class SymbolSelectionScreenTest { @Test fun should_display_proper_symbols_when_each_category_clicked() { -// composeTestRule.onNodeWithText(TEST_CATEGORY_TEXT).performClick() -// Thread.sleep(3000) -// composeTestRule.onAllNodesWithText("가족")[0].performClick() + composeTestRule.onNodeWithText("가족").performClick() composeTestRule.waitForIdle() composeTestRule.onNodeWithText("남동생").assertIsDisplayed() } - @Test - fun should_display_proper_symbols_on_selected_symbols_when_symbols_clicked(){ + fun should_display_proper_symbols_on_selected_symbols_when_symbols_clicked() { composeTestRule.onNodeWithText("가족").performClick() composeTestRule.waitForIdle() composeTestRule.onNodeWithText("남동생").performClick() @@ -219,7 +191,7 @@ class SymbolSelectionScreenTest { } @Test - fun should_clear_symbols_on_selected_symbols_when_DELETE_ALL_BUTTON_clicked(){ + fun should_clear_symbols_on_selected_symbols_when_DELETE_ALL_BUTTON_clicked() { composeTestRule.onNodeWithText("가족").performClick() composeTestRule.waitForIdle() composeTestRule.onNodeWithText("남동생").performClick() @@ -230,7 +202,7 @@ class SymbolSelectionScreenTest { } @Test - fun should_display_in_SEE_BIG_mode_when_SEE_BIG_BUTTON_clicked(){ + fun should_display_in_SEE_BIG_mode_when_SEE_BIG_BUTTON_clicked() { composeTestRule.onNodeWithText("가족").performClick() composeTestRule.waitForIdle() composeTestRule.onNodeWithText("남동생").performClick() @@ -239,7 +211,7 @@ class SymbolSelectionScreenTest { composeTestRule.waitForIdle() composeTestRule.waitUntil { composeTestRule.onAllNodesWithText(EXIT_BUTTON_TEXT).fetchSemanticsNodes().size == 1 - //composeTestRule.onNodeWithText(EXIT_BUTTON_TEXT).assertIsDisplayed() + } @@ -250,7 +222,7 @@ class SymbolSelectionScreenTest { companion object { - //const val SEARCH_BOX_TEXT = "SymbolSearchTextField" + const val SEARCH_BOX_TEXT = "검색어를 입력하세요" const val SEE_BIG_BUTTON_TEXT = "크게 보기" const val DELETE_ALL_BUTTON_TEXT = "모두 삭제"