-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #89 from snuhcs-course/test/integration-settings
Test/integration settings
- Loading branch information
Showing
19 changed files
with
761 additions
and
66 deletions.
There are no files selected for viewing
304 changes: 304 additions & 0 deletions
304
frontend/app/src/androidTest/java/com/example/speechbuddy/AccountSettingsScreenTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,304 @@ | ||
package com.example.speechbuddy | ||
|
||
import android.content.Intent | ||
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.onAllNodesWithText | ||
import androidx.compose.ui.test.onNodeWithText | ||
import androidx.compose.ui.test.performClick | ||
import com.example.speechbuddy.compose.settings.AccountSettings | ||
import com.example.speechbuddy.ui.SpeechBuddyTheme | ||
import dagger.hilt.android.testing.HiltAndroidRule | ||
import dagger.hilt.android.testing.HiltAndroidTest | ||
import kotlinx.coroutines.DelicateCoroutinesApi | ||
import org.junit.After | ||
import org.junit.Before | ||
import org.junit.Rule | ||
import org.junit.Test | ||
|
||
@HiltAndroidTest | ||
class AccountSettingsScreenTest { | ||
|
||
private val androidTestUtil = AndroidTestUtil() | ||
|
||
@get:Rule(order = 0) | ||
val hiltRule = HiltAndroidRule(this) | ||
|
||
@get:Rule(order = 1) | ||
val composeTestRule = androidTestUtil.createAndroidIntentComposeRule<HomeActivity> { | ||
Intent(it, HomeActivity::class.java).apply { | ||
putExtra("isTest", true) | ||
} | ||
} | ||
|
||
@Before | ||
fun setUp() { | ||
hiltRule.inject() | ||
val fakeId = 1 | ||
val fakeEmail = "[email protected]" | ||
val fakeNickname = "nickname" | ||
composeTestRule.activity.sessionManager.setUserId(fakeId) | ||
composeTestRule.activity.userRepository.setMyInfo(fakeId, fakeEmail, fakeNickname) | ||
composeTestRule.activity.setContent { | ||
SpeechBuddyTheme( | ||
settingsRepository = composeTestRule.activity.settingsRepository, | ||
initialDarkMode = false | ||
) { | ||
AccountSettings( | ||
paddingValues = PaddingValues() | ||
) | ||
} | ||
} | ||
} | ||
|
||
@Test | ||
fun should_display_all_elements_when_account_settings_screen_appears() { | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(LOGOUT).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onNodeWithText(ACCOUNT).assertIsDisplayed() | ||
composeTestRule.onNodeWithText(EMAIL).assertIsDisplayed() | ||
composeTestRule.onNodeWithText(NICKNAME).assertIsDisplayed() | ||
composeTestRule.onNodeWithText(LOGOUT).assertIsDisplayed().assertHasClickAction().assertIsEnabled() | ||
composeTestRule.onNodeWithText(WITHDRAW).assertIsDisplayed().assertHasClickAction().assertIsEnabled() | ||
composeTestRule.onNodeWithText(FAKE_EMAIL).assertIsDisplayed() | ||
composeTestRule.onNodeWithText(FAKE_NICKNAME).assertIsDisplayed() | ||
} | ||
|
||
@Test | ||
fun should_display_backup_dialog_when_clicking_backup_button() { | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(LOGOUT).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onAllNodesWithText(LOGOUT)[0].performClick() | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(BACKUP_DIALOG).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onAllNodesWithText(LOGOUT)[0].assertIsNotEnabled() | ||
composeTestRule.onNodeWithText(WITHDRAW).assertIsNotEnabled() | ||
composeTestRule.onNodeWithText(BACKUP).assertIsDisplayed().assertHasClickAction() | ||
composeTestRule.onNodeWithText(BACKUP_DIALOG).assertIsDisplayed() | ||
composeTestRule.onAllNodesWithText(LOGOUT)[1].assertIsDisplayed() | ||
composeTestRule.onAllNodesWithText(LOGOUT)[2].assertIsDisplayed().assertHasClickAction() | ||
} | ||
|
||
@Test | ||
fun should_remove_dialog_when_clicking_backup_button_in_backup_dialog() { | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(LOGOUT).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onNodeWithText(LOGOUT).performClick() | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(BACKUP_DIALOG).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onNodeWithText(BACKUP).performClick() | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(BACKUP_DIALOG).fetchSemanticsNodes().isEmpty() | ||
} | ||
composeTestRule.onNodeWithText(BACKUP_DIALOG).assertDoesNotExist() | ||
composeTestRule.onNodeWithText(BACKUP).assertDoesNotExist() | ||
composeTestRule.onNodeWithText(LOGOUT).assertIsNotEnabled() | ||
composeTestRule.onNodeWithText(WITHDRAW).assertIsNotEnabled() | ||
} | ||
|
||
@Test | ||
fun should_display_logout_dialog_when_clicking_logout_button_in_backup_dialog() { | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(LOGOUT).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onNodeWithText(LOGOUT).performClick() | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(BACKUP_DIALOG).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onAllNodesWithText(LOGOUT)[0].assertIsNotEnabled() | ||
composeTestRule.onAllNodesWithText(LOGOUT)[1].assertIsDisplayed() | ||
composeTestRule.onAllNodesWithText(LOGOUT)[2].assertHasClickAction().assertIsEnabled() | ||
composeTestRule.onAllNodesWithText(LOGOUT)[2].performClick() | ||
composeTestRule.waitUntil { | ||
composeTestRule.onAllNodesWithText(LOGOUT_DIALOG).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onNodeWithText(CANCEL).assertIsDisplayed() | ||
composeTestRule.onNodeWithText(LOGOUT_DIALOG).assertIsDisplayed() | ||
composeTestRule.onAllNodesWithText(LOGOUT)[0].assertIsNotEnabled() | ||
composeTestRule.onAllNodesWithText(LOGOUT)[1].assertIsDisplayed() | ||
composeTestRule.onAllNodesWithText(LOGOUT)[2].assertHasClickAction().assertIsEnabled() | ||
composeTestRule.onNodeWithText(WITHDRAW).assertIsNotEnabled() | ||
} | ||
|
||
@Test | ||
fun should_remove_dialog_when_clicking_logout_button_in_logout_dialog() { | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(LOGOUT).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onNodeWithText(LOGOUT).performClick() | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(BACKUP_DIALOG).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onAllNodesWithText(LOGOUT)[0].assertIsNotEnabled() | ||
composeTestRule.onAllNodesWithText(LOGOUT)[1].assertIsDisplayed() | ||
composeTestRule.onAllNodesWithText(LOGOUT)[2].assertHasClickAction().assertIsEnabled() | ||
composeTestRule.onAllNodesWithText(LOGOUT)[2].performClick() | ||
composeTestRule.waitUntil { | ||
composeTestRule.onAllNodesWithText(LOGOUT_DIALOG).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onAllNodesWithText(LOGOUT)[0].assertIsNotEnabled() | ||
composeTestRule.onAllNodesWithText(LOGOUT)[1].assertIsDisplayed() | ||
composeTestRule.onAllNodesWithText(LOGOUT)[2].assertHasClickAction().assertIsEnabled() | ||
composeTestRule.onAllNodesWithText(LOGOUT)[2].performClick() | ||
composeTestRule.waitUntil { | ||
composeTestRule.onAllNodesWithText(LOGOUT_DIALOG).fetchSemanticsNodes().isEmpty() | ||
} | ||
composeTestRule.onNodeWithText(LOGOUT_DIALOG).assertDoesNotExist() | ||
composeTestRule.onNodeWithText(CANCEL).assertDoesNotExist() | ||
} | ||
|
||
@Test | ||
fun should_display_account_settings_screen_when_clicking_cancel_button_in_logout_dialog() { | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(LOGOUT).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onNodeWithText(LOGOUT).performClick() | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(BACKUP_DIALOG).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onAllNodesWithText(LOGOUT)[0].assertIsNotEnabled() | ||
composeTestRule.onAllNodesWithText(LOGOUT)[1].assertIsDisplayed() | ||
composeTestRule.onAllNodesWithText(LOGOUT)[2].assertHasClickAction().assertIsEnabled() | ||
composeTestRule.onAllNodesWithText(LOGOUT)[2].performClick() | ||
composeTestRule.onNodeWithText(CANCEL).performClick() | ||
composeTestRule.waitUntil { | ||
composeTestRule.onAllNodesWithText(LOGOUT_DIALOG).fetchSemanticsNodes().isEmpty() | ||
} | ||
composeTestRule.onNodeWithText(LOGOUT_DIALOG).assertDoesNotExist() | ||
composeTestRule.onNodeWithText(CANCEL).assertDoesNotExist() | ||
} | ||
|
||
@Test | ||
fun should_display_first_withdraw_dialog_when_clicking_withdraw_button() { | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(WITHDRAW).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onNodeWithText(WITHDRAW).performClick() | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(FIRST_WITHDRAW_DIALOG).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onNodeWithText(FIRST_WITHDRAW_DIALOG).assertIsDisplayed() | ||
composeTestRule.onNodeWithText(CANCEL).assertIsDisplayed().assertHasClickAction() | ||
composeTestRule.onNodeWithText(PROCEED).assertIsDisplayed().assertHasClickAction() | ||
composeTestRule.onNodeWithText(LOGOUT).assertIsNotEnabled() | ||
composeTestRule.onAllNodesWithText(WITHDRAW)[0].assertIsNotEnabled() | ||
composeTestRule.onAllNodesWithText(WITHDRAW)[1].assertIsEnabled() | ||
} | ||
|
||
@Test | ||
fun should_display_second_withdraw_dialog_when_clicking_progress_button_in_first_withdraw_dialog() { | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(WITHDRAW).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onNodeWithText(WITHDRAW).performClick() | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(FIRST_WITHDRAW_DIALOG).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onNodeWithText(PROCEED).performClick() | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(SECOND_WITHDRAW_DIALOG).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onNodeWithText(SECOND_WITHDRAW_DIALOG).assertIsDisplayed() | ||
composeTestRule.onNodeWithText(CANCEL).assertIsDisplayed().assertHasClickAction() | ||
composeTestRule.onNodeWithText(LOGOUT).assertIsNotEnabled() | ||
composeTestRule.onAllNodesWithText(WITHDRAW)[0].assertIsNotEnabled() | ||
composeTestRule.onAllNodesWithText(WITHDRAW)[1].assertIsDisplayed() | ||
composeTestRule.onAllNodesWithText(WITHDRAW)[2].assertHasClickAction().assertIsEnabled() | ||
} | ||
|
||
@Test | ||
fun should_remove_dialog_when_clicking_cancel_button_in_first_withdraw_dialog() { | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(WITHDRAW).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onNodeWithText(WITHDRAW).performClick() | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(FIRST_WITHDRAW_DIALOG).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onNodeWithText(CANCEL).performClick() | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(FIRST_WITHDRAW_DIALOG).fetchSemanticsNodes().isEmpty() | ||
} | ||
composeTestRule.onNodeWithText(FIRST_WITHDRAW_DIALOG).assertDoesNotExist() | ||
composeTestRule.onNodeWithText(CANCEL).assertDoesNotExist() | ||
composeTestRule.onNodeWithText(LOGOUT).assertIsEnabled() | ||
composeTestRule.onNodeWithText(WITHDRAW).assertIsEnabled() | ||
} | ||
|
||
@Test | ||
fun should_remove_dialog_when_clicking_withdraw_button_in_second_withdraw_dialog() { | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(WITHDRAW).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onNodeWithText(WITHDRAW).performClick() | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(FIRST_WITHDRAW_DIALOG).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onNodeWithText(PROCEED).performClick() | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(SECOND_WITHDRAW_DIALOG).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onAllNodesWithText(WITHDRAW)[0].assertIsNotEnabled() | ||
composeTestRule.onAllNodesWithText(WITHDRAW)[1].assertIsDisplayed() | ||
composeTestRule.onAllNodesWithText(WITHDRAW)[2].assertHasClickAction().assertIsEnabled() | ||
composeTestRule.onAllNodesWithText(WITHDRAW)[2].performClick() | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(SECOND_WITHDRAW_DIALOG).fetchSemanticsNodes().isEmpty() | ||
} | ||
composeTestRule.onNodeWithText(SECOND_WITHDRAW_DIALOG).assertDoesNotExist() | ||
composeTestRule.onNodeWithText(CANCEL).assertDoesNotExist() | ||
} | ||
|
||
@Test | ||
fun should_display_account_settings_screen_when_clicking_cancel_button_in_second_withdraw_dialog() { | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(WITHDRAW).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onNodeWithText(WITHDRAW).performClick() | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(FIRST_WITHDRAW_DIALOG).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onNodeWithText(PROCEED).performClick() | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(SECOND_WITHDRAW_DIALOG).fetchSemanticsNodes().size == 1 | ||
} | ||
composeTestRule.onNodeWithText(CANCEL).performClick() | ||
composeTestRule.waitUntil{ | ||
composeTestRule.onAllNodesWithText(SECOND_WITHDRAW_DIALOG).fetchSemanticsNodes().isEmpty() | ||
} | ||
composeTestRule.onNodeWithText(SECOND_WITHDRAW_DIALOG).assertDoesNotExist() | ||
composeTestRule.onNodeWithText(CANCEL).assertDoesNotExist() | ||
} | ||
|
||
@After | ||
fun tearDown() { | ||
composeTestRule.activityRule.scenario.close() | ||
} | ||
|
||
companion object { | ||
const val ACCOUNT = "계정" | ||
const val EMAIL = "이메일" | ||
const val NICKNAME = "닉네임" | ||
const val LOGOUT = "로그아웃" | ||
const val WITHDRAW = "회원탈퇴" | ||
const val FAKE_EMAIL = "[email protected]" | ||
const val FAKE_NICKNAME = "nickname" | ||
const val BACKUP = "백업" | ||
const val BACKUP_DIALOG = "로그아웃하기 전 백업하시겠습니까? 변경사항을 백업하지 않으면 이용 기록이 손실될 수 있습니다." | ||
const val LOGOUT_DIALOG = "정말로 로그아웃하시겠습니까?" | ||
const val CANCEL = "취소" | ||
const val PROCEED = "진행" | ||
const val FIRST_WITHDRAW_DIALOG = "회원탈퇴를 하면 지금까지의 이용 기록이 모두 사라지며 복구할 수 없습니다. SpeechBuddy를 다시 이용하시려면 게스트 모드를 이용하거나 회원가입을 새로 해야 합니다. 정말로 탈퇴하시겠습니까?" | ||
const val SECOND_WITHDRAW_DIALOG = "정말로 탈퇴하시겠습니까? 이 동작은 취소할 수 없습니다." | ||
} | ||
|
||
} |
39 changes: 39 additions & 0 deletions
39
frontend/app/src/androidTest/java/com/example/speechbuddy/AndroidTestUtil.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package com.example.speechbuddy | ||
|
||
import android.content.Context | ||
import android.content.Intent | ||
import androidx.activity.ComponentActivity | ||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule | ||
import androidx.test.core.app.ApplicationProvider | ||
import androidx.test.ext.junit.rules.ActivityScenarioRule | ||
|
||
class AndroidTestUtil { | ||
/** | ||
* Factory method to provide Android specific implementation of createComposeRule, for a given | ||
* activity class type A that needs to be launched via an intent. | ||
* | ||
* @param intentFactory A lambda that provides a Context that can used to create an intent. A intent needs to be returned. | ||
*/ | ||
inline fun <A: ComponentActivity> createAndroidIntentComposeRule(intentFactory: (context: Context) -> Intent) : AndroidComposeTestRule<ActivityScenarioRule<A>, A> { | ||
val context = ApplicationProvider.getApplicationContext<Context>() | ||
val intent = intentFactory(context) | ||
|
||
return AndroidComposeTestRule( | ||
activityRule = ActivityScenarioRule(intent), | ||
activityProvider = { scenarioRule -> scenarioRule.getActivity() } | ||
) | ||
} | ||
|
||
/** | ||
* Gets the activity from a scenarioRule. | ||
* | ||
* https://androidx.tech/artifacts/compose.ui/ui-test-junit4/1.0.0-alpha11-source/androidx/compose/ui/test/junit4/AndroidComposeTestRule.kt.html | ||
*/ | ||
fun <A : ComponentActivity> ActivityScenarioRule<A>.getActivity(): A { | ||
var activity: A? = null | ||
|
||
scenario.onActivity { activity = it } | ||
|
||
return activity ?: throw IllegalStateException("Activity was not set in the ActivityScenarioRule!") | ||
} | ||
} |
Oops, something went wrong.