Skip to content

GiveNicknameActivity Compose 전환 및 테스트 추가#404

Open
unam98 wants to merge 1 commit into
developfrom
feature/give-nickname-compose-tdd-migration
Open

GiveNicknameActivity Compose 전환 및 테스트 추가#404
unam98 wants to merge 1 commit into
developfrom
feature/give-nickname-compose-tdd-migration

Conversation

@unam98

@unam98 unam98 commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

작업 배경

  • 닉네임 입력 화면을 Compose 기반으로 전환해 XML/DataBinding 의존을 줄이고, 입력/로딩/상태 전이를 테스트로 고정합니다.

변경 사항

영역 내용
GiveNicknameActivity XML 바인딩 기반 화면 구성을 setContent Compose 화면으로 전환하고 기존 Analytics/토큰 저장/화면 이동 side effect를 유지
GiveNicknameScreen 닉네임 입력, 시작 버튼, 로딩 인디케이터를 Compose UI로 분리하고 테스트 태그 추가
GiveNickNameViewModel Compose 입력 상태 연결을 위한 updateNickNameInput 추가
GiveNickNameViewModelTest 닉네임 입력, 성공/실패 상태 전이를 유닛 테스트로 검증
GiveNicknameScreenTest 화면 노출, 버튼 활성화, 입력 콜백, 클릭 콜백, 로딩 노출을 Compose UI 테스트로 검증
activity_give_nickname.xml Compose 전환으로 기존 XML 레이아웃 제거

영향 범위

  • 회원가입/소셜 로그인 이후 닉네임 입력 화면
  • 닉네임 입력값, 시작 버튼 활성화, 로딩 상태 표시, 닉네임 변경 API 결과 처리
  • 런타임에서는 기존 Activity 진입점과 성공/실패 후속 동작을 유지하고, UI 렌더링 계층만 Compose로 변경

검증 매트릭스

영향 범위 항목 테스트 코드
닉네임 입력값이 ViewModel 상태로 반영된다 updateNickNameInput은 닉네임 값을 갱신한다
닉네임 변경 성공 시 Loading 이후 Success 상태로 전이된다 updateNickName 성공 시 Loading 이후 Success 상태로 갱신된다
닉네임 변경 실패 시 Failure 상태와 중복 닉네임 에러 코드가 유지된다 updateNickName 실패 시 statusCode와 Failure 상태로 갱신된다
닉네임 입력 화면의 주요 문구와 버튼이 노출된다 닉네임_입력_화면_요소가_노출된다
빈 닉네임이면 시작하기 버튼이 비활성화된다 닉네임이_비어있으면_시작하기_버튼은_비활성화된다
닉네임 입력 시 변경 콜백이 호출된다 닉네임을_입력하면_변경_콜백이_호출된다
시작하기 버튼 클릭 시 제출 콜백이 호출된다 시작하기_버튼을_누르면_콜백이_호출된다
로딩 상태면 인디케이터가 노출된다 로딩_상태면_인디케이터가_노출된다

Test Plan

  • ./gradlew testDebugUnitTest --tests 'com.runnect.runnect.presentation.login.GiveNickNameViewModelTest' 3/3 통과
  • ./gradlew connectedDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=com.runnect.runnect.presentation.login.GiveNicknameScreenTest 5/5 통과
  • ./gradlew assembleDebug 통과

Before / After 영상

Before After
give_nickname_before.mp4
give_nickname_after.mp4

빈 닉네임 상태와 닉네임 입력 후 시작 버튼 활성화 상태를 비교했습니다.

🤖 Generated with Claude Code

@unam98 unam98 self-assigned this Jun 29, 2026
@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

GiveNicknameActivity is migrated from a ViewBinding/XML layout to Jetpack Compose. A new GiveNicknameScreen composable and GiveNicknameUiState model are introduced. GiveNickNameViewModel gains an updateNickNameInput method. The XML layout is deleted. Unit tests and instrumented Compose UI tests are added.

Changes

GiveNickname Compose Migration

Layer / File(s) Summary
GiveNicknameUiState model and composables
app/src/main/java/com/runnect/runnect/presentation/login/GiveNicknameScreen.kt
Defines GiveNicknameScreenTestTags constants, GiveNicknameUiState with from() factory, and composables GiveNicknameScreen, GiveNicknameTitle, NicknameTextField, StartButton, and NICKNAME_MAX_LENGTH.
ViewModel input method and Activity wiring
app/src/main/java/com/runnect/runnect/presentation/login/GiveNickNameViewModel.kt, app/src/main/java/com/runnect/runnect/presentation/login/GiveNicknameActivity.kt, app/src/main/res/layout/activity_give_nickname.xml
Adds updateNickNameInput to the ViewModel; refactors the Activity to AppCompatActivity using setContent and observeAsState, removing ViewBinding, dispatchTouchEvent, addListener, and the XML layout.
ViewModel unit tests and Compose UI tests
app/src/test/.../GiveNickNameViewModelTest.kt, app/src/androidTest/.../GiveNicknameScreenTest.kt
Adds GiveNickNameViewModelTest covering input update, success, and failure states; adds GiveNicknameScreenTest covering UI rendering, empty nickname disabled state, nickname change callback, start click callback, and loading indicator.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 Hop hop, the XML's gone away,
Compose now rules the nickname day!
A from() factory, states so neat,
Test tags make testing quite a treat.
The rabbit cheers for cleaner code—
No binding views left in this abode! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: converting GiveNicknameActivity to Compose and adding tests.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/give-nickname-compose-tdd-migration

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
app/src/main/java/com/runnect/runnect/presentation/login/GiveNickNameViewModel.kt (1)

27-29: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Keep the nickname-length rule below the Compose layer too.

updateNickNameInput() is now a public entrypoint, but the 7-character cap only exists in GiveNicknameScreen.kt. Move that validation into the ViewModel or a shared validator so non-UI callers cannot submit over-limit nicknames through this method.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@app/src/main/java/com/runnect/runnect/presentation/login/GiveNickNameViewModel.kt`
around lines 27 - 29, The nickname length check currently only exists in
GiveNicknameScreen, so public callers can still push over-limit values through
GiveNickNameViewModel.updateNickNameInput. Move the 7-character validation into
GiveNickNameViewModel itself or a shared validator used by updateNickNameInput
and the Compose screen, and ensure the ViewModel rejects or truncates invalid
input before assigning nickName.value.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@app/src/main/java/com/runnect/runnect/presentation/login/GiveNicknameScreen.kt`:
- Around line 102-106: Freeze nickname edits during the loading state by
preventing input changes while UiState.Loading is active. Update
GiveNicknameScreen and the NicknameTextField usage so onNickNameChange is
ignored or the field is disabled whenever state is Loading, keeping the
displayed nickname and the in-flight save request in sync. Apply the same
protection anywhere else nickname input is wired up, including the related code
in the other affected section.
- Around line 159-160: The nickname input handling in GiveNicknameScreen
currently ignores any pasted value longer than NICKNAME_MAX_LENGTH, so oversized
input is dropped instead of being accepted predictably. Update the onValueChange
logic in the nickname field to clamp nextValue to NICKNAME_MAX_LENGTH before
calling onNickNameChange, so the field always forwards a truncated value rather
than skipping the update.

---

Nitpick comments:
In
`@app/src/main/java/com/runnect/runnect/presentation/login/GiveNickNameViewModel.kt`:
- Around line 27-29: The nickname length check currently only exists in
GiveNicknameScreen, so public callers can still push over-limit values through
GiveNickNameViewModel.updateNickNameInput. Move the 7-character validation into
GiveNickNameViewModel itself or a shared validator used by updateNickNameInput
and the Compose screen, and ensure the ViewModel rejects or truncates invalid
input before assigning nickName.value.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 11d156a0-7eb3-45c0-aa2c-2b75755f2e43

📥 Commits

Reviewing files that changed from the base of the PR and between abeb1ca and f9a4eef.

📒 Files selected for processing (6)
  • app/src/androidTest/java/com/runnect/runnect/presentation/login/GiveNicknameScreenTest.kt
  • app/src/main/java/com/runnect/runnect/presentation/login/GiveNickNameViewModel.kt
  • app/src/main/java/com/runnect/runnect/presentation/login/GiveNicknameActivity.kt
  • app/src/main/java/com/runnect/runnect/presentation/login/GiveNicknameScreen.kt
  • app/src/main/res/layout/activity_give_nickname.xml
  • app/src/test/java/com/runnect/runnect/presentation/login/GiveNickNameViewModelTest.kt
💤 Files with no reviewable changes (1)
  • app/src/main/res/layout/activity_give_nickname.xml

Comment on lines +102 to +106
NicknameTextField(
nickName = state.nickName,
onNickNameChange = onNickNameChange,
onDone = { focusManager.clearFocus() }
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Freeze nickname edits while the request is in flight.

updateNickName() submits the current nickname immediately, but this field still accepts new input during UiState.Loading. That can leave the screen showing nickname B while the app is still saving nickname A.

Suggested fix
             NicknameTextField(
                 nickName = state.nickName,
+                isEditable = !state.isLoading,
                 onNickNameChange = onNickNameChange,
                 onDone = { focusManager.clearFocus() }
             )
@@
 private fun NicknameTextField(
     nickName: String,
+    isEditable: Boolean,
     onNickNameChange: (String) -> Unit,
     onDone: () -> Unit,
 ) {
     BasicTextField(
         value = nickName,
         onValueChange = { nextValue ->
-            if (nextValue.length <= NICKNAME_MAX_LENGTH) onNickNameChange(nextValue)
+            if (isEditable && nextValue.length <= NICKNAME_MAX_LENGTH) {
+                onNickNameChange(nextValue)
+            }
         },

Also applies to: 151-173

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@app/src/main/java/com/runnect/runnect/presentation/login/GiveNicknameScreen.kt`
around lines 102 - 106, Freeze nickname edits during the loading state by
preventing input changes while UiState.Loading is active. Update
GiveNicknameScreen and the NicknameTextField usage so onNickNameChange is
ignored or the field is disabled whenever state is Loading, keeping the
displayed nickname and the in-flight save request in sync. Apply the same
protection anywhere else nickname input is wired up, including the related code
in the other affected section.

Comment on lines +159 to +160
onValueChange = { nextValue ->
if (nextValue.length <= NICKNAME_MAX_LENGTH) onNickNameChange(nextValue)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Clamp oversized input instead of dropping it.

Pasting more than 7 characters into an empty field currently leaves the value unchanged. Truncate to NICKNAME_MAX_LENGTH before forwarding the update so long pastes still behave predictably.

Suggested fix
         onValueChange = { nextValue ->
-            if (nextValue.length <= NICKNAME_MAX_LENGTH) onNickNameChange(nextValue)
+            onNickNameChange(nextValue.take(NICKNAME_MAX_LENGTH))
         },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
onValueChange = { nextValue ->
if (nextValue.length <= NICKNAME_MAX_LENGTH) onNickNameChange(nextValue)
onValueChange = { nextValue ->
onNickNameChange(nextValue.take(NICKNAME_MAX_LENGTH))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@app/src/main/java/com/runnect/runnect/presentation/login/GiveNicknameScreen.kt`
around lines 159 - 160, The nickname input handling in GiveNicknameScreen
currently ignores any pasted value longer than NICKNAME_MAX_LENGTH, so oversized
input is dropped instead of being accepted predictably. Update the onValueChange
logic in the nickname field to clamp nextValue to NICKNAME_MAX_LENGTH before
calling onNickNameChange, so the field always forwards a truncated value rather
than skipping the update.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant