Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package com.runnect.runnect.presentation.login

import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertIsNotEnabled
import androidx.compose.ui.test.junit4.createComposeRule
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 com.runnect.runnect.presentation.ui.theme.RunnectTheme
import org.junit.Assert.assertEquals
import org.junit.Rule
import org.junit.Test

class GiveNicknameScreenTest {

@get:Rule
val composeTestRule = createComposeRule()

@Test
fun 닉네임_입력_화면_요소가_노출된다() {
composeTestRule.setContent {
RunnectTheme {
GiveNicknameScreen(
state = GiveNicknameUiState(),
onNickNameChange = {},
onStartClick = {}
)
}
}

composeTestRule.onNodeWithText("RUNNECT").assertIsDisplayed()
composeTestRule.onNodeWithText("에서 사용할").assertIsDisplayed()
composeTestRule.onNodeWithText("이름을 입력해주세요").assertIsDisplayed()
composeTestRule.onNodeWithText("닉네임을 입력해주세요").assertIsDisplayed()
composeTestRule.onNodeWithText("시작하기").assertIsDisplayed()
}

@Test
fun 닉네임이_비어있으면_시작하기_버튼은_비활성화된다() {
composeTestRule.setContent {
RunnectTheme {
GiveNicknameScreen(
state = GiveNicknameUiState.from(
nickName = "",
uiState = com.runnect.runnect.presentation.state.UiState.Empty
),
onNickNameChange = {},
onStartClick = {}
)
}
}

composeTestRule.onNodeWithTag(GiveNicknameScreenTestTags.START_BUTTON).assertIsNotEnabled()
}

@Test
fun 닉네임을_입력하면_변경_콜백이_호출된다() {
val inputs = mutableListOf<String>()

composeTestRule.setContent {
RunnectTheme {
GiveNicknameScreen(
state = GiveNicknameUiState(),
onNickNameChange = { inputs.add(it) },
onStartClick = {}
)
}
}

composeTestRule.onNodeWithTag(GiveNicknameScreenTestTags.NICKNAME_INPUT)
.performTextInput("러너")

assertEquals("러너", inputs.last())
}

@Test
fun 시작하기_버튼을_누르면_콜백이_호출된다() {
var clickedCount = 0

composeTestRule.setContent {
RunnectTheme {
GiveNicknameScreen(
state = GiveNicknameUiState.from(
nickName = "러너",
uiState = com.runnect.runnect.presentation.state.UiState.Empty
),
onNickNameChange = {},
onStartClick = { clickedCount += 1 }
)
}
}

composeTestRule.onNodeWithTag(GiveNicknameScreenTestTags.START_BUTTON).performClick()

assertEquals(1, clickedCount)
}

@Test
fun 로딩_상태면_인디케이터가_노출된다() {
composeTestRule.setContent {
RunnectTheme {
GiveNicknameScreen(
state = GiveNicknameUiState.from(
nickName = "러너",
uiState = com.runnect.runnect.presentation.state.UiState.Loading
),
onNickNameChange = {},
onStartClick = {}
)
}
}

composeTestRule.onNodeWithTag(GiveNicknameScreenTestTags.LOADING_INDICATOR)
.assertIsDisplayed()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ class GiveNickNameViewModel @Inject constructor(
get() = _statusCode
private val _statusCode = MutableLiveData<Int>()

fun updateNickNameInput(nickName: String) {
this.nickName.value = nickName
}

fun updateNickName() = launchWithHandler {
val requestPatchNickName = RequestPatchNickName(nickName.value.toString())

Expand All @@ -44,4 +48,4 @@ class GiveNickNameViewModel @Inject constructor(
companion object {
const val REDUNDANT_NICKNAME_ERROR = 400
}
}
}
Original file line number Diff line number Diff line change
@@ -1,40 +1,46 @@
package com.runnect.runnect.presentation.login

import android.content.Intent
import android.graphics.Rect
import android.os.Bundle
import android.view.MotionEvent
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.core.view.isVisible
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import com.runnect.runnect.R
import com.runnect.runnect.binding.BindingActivity
import com.runnect.runnect.databinding.ActivityGiveNicknameBinding
import com.runnect.runnect.presentation.MainActivity
import com.runnect.runnect.presentation.state.UiState
import com.runnect.runnect.presentation.ui.theme.RunnectTheme
import com.runnect.runnect.util.analytics.Analytics
import com.runnect.runnect.util.analytics.EventName
import com.runnect.runnect.util.analytics.EventName.Param
import com.runnect.runnect.util.extension.hideKeyboard
import com.runnect.runnect.util.extension.showToast
import com.runnect.runnect.util.preference.AuthUtil.saveToken
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class GiveNicknameActivity :
BindingActivity<ActivityGiveNicknameBinding>(R.layout.activity_give_nickname) {
class GiveNicknameActivity : AppCompatActivity() {
private val viewModel: GiveNickNameViewModel by viewModels()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding.vm = viewModel
binding.lifecycleOwner = this
Analytics.logEvent(EventName.VIEW_GIVE_NICKNAME)
addListener()
addObserver()
}

private fun addListener() {
binding.tvGiveNicknameFinish.setOnClickListener {
viewModel.updateNickName()
setContent {
val nickName by viewModel.nickName.observeAsState("")
val uiState by viewModel.uiState.observeAsState(UiState.Empty)

RunnectTheme {
GiveNicknameScreen(
state = GiveNicknameUiState.from(
nickName = nickName,
uiState = uiState
),
onNickNameChange = viewModel::updateNickNameInput,
onStartClick = viewModel::updateNickName
)
}
}
}

Expand All @@ -46,27 +52,10 @@ class GiveNicknameActivity :
}

private fun addObserver() {
viewModel.nickName.observe(this) {
with(binding.tvGiveNicknameFinish) {
if (it.isNullOrEmpty()) {
isActivated = false
isClickable = false
} else {
isActivated = true
isClickable = true
}
}
}
viewModel.uiState.observe(this) { state ->
when (state) {
UiState.Empty -> binding.indeterminateBar.isVisible = false
UiState.Loading -> {
with(binding) {
indeterminateBar.isVisible = true
tvGiveNicknameFinish.isClickable = false
}
}

UiState.Empty,
UiState.Loading -> Unit
UiState.Success -> handleSuccessfulSignup()
UiState.Failure -> handleUnSuccessfulSignup()
}
Expand All @@ -80,7 +69,6 @@ class GiveNicknameActivity :
)
saveSignTokenInfo()
showToast("회원가입 되었습니다")
binding.indeterminateBar.isVisible = false
moveToMain()
}

Expand All @@ -93,27 +81,9 @@ class GiveNicknameActivity :
}

private fun handleUnSuccessfulSignup() {
binding.indeterminateBar.isVisible = false
if (viewModel.statusCode.value == 400) {
showToast(getString(R.string.my_page_edit_name_redundant_warning))
}
binding.tvGiveNicknameFinish.isClickable = true
}

//키보드 밖 터치 시, 키보드 내림
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
val focusView = currentFocus
if (focusView != null) {
val rect = Rect()
focusView.getGlobalVisibleRect(rect)
val x = ev!!.x.toInt()
val y = ev.y.toInt()
if (!rect.contains(x, y)) {
hideKeyboard(focusView)
}
}
return super.dispatchTouchEvent(ev)
}

}

Loading
Loading