Repository navigation
fix(home): 주간 요약 그리드에 실제 기록 수를 연결한다 (#562) #1055
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
58 commits
Select commit
Hold shift + click to select a range
e2e4141
Merge branch 'feat/725-emotion-analysis-status' into fix/562-weekly-g…
Sadturtleman e0a0199
fix(home): 주간 요약 그리드에 실제 기록 수를 연결한다
Sadturtleman 818977c
style(mindrecord): 머지에서 겹친 고아 KDoc 을 정리한다
Sadturtleman 0b930df
Merge feat/207-home-summary-usecase into fix/562-weekly-grid-real-data
Sadturtleman 7d6038f
Merge fix/736-request-count into fix/562-weekly-grid-real-data
Sadturtleman c32d9ad
Merge remote-tracking branch 'origin/fix/736-request-count' into HEAD
OnlyReadOneBook eea83e5
Merge fix/736-request-count into fix/562-weekly-grid-real-data
Sadturtleman 50d6f53
Merge remote-tracking branch 'origin/fix/562-weekly-grid-real-data' i…
Sadturtleman 5567b38
merge: base(fix/736-request-count) 를 물린다 — 픽스처 도입 import 와 주간 실데이터 im…
Sadturtleman 62c8cde
fix(home): 느린 주간 수 조회가 홈 전체를 붙잡지 못하게 한다
Sadturtleman e1c3ab9
Merge remote-tracking branch 'origin/fix/736-request-count' into fix/…
OnlyReadOneBook 8a05801
Merge fix/736-request-count into fix/562-weekly-grid-real-data for PR…
OnlyReadOneBook 34104af
Merge branch 'fix/736-request-count' into fix/562-weekly-grid-real-data
OnlyReadOneBook 308ff0d
Merge branch 'fix/736-request-count' into fix/562-weekly-grid-real-data
OnlyReadOneBook d562e10
Merge branch 'fix/736-request-count' into fix/562-weekly-grid-real-data
OnlyReadOneBook 94d6911
Merge branch 'fix/736-request-count' into fix/562-weekly-grid-real-data
OnlyReadOneBook 023c6f9
Merge branch 'fix/736-request-count' into fix/562-weekly-grid-real-data
OnlyReadOneBook 34516a2
Merge branch 'fix/736-request-count' into fix/562-weekly-grid-real-data
OnlyReadOneBook 8d15687
Merge branch 'fix/736-request-count' into fix/562-weekly-grid-real-data
OnlyReadOneBook 78183ab
Merge fix/736-request-count into fix/562-weekly-grid-real-data for PR…
OnlyReadOneBook a8ace84
Merge fix/736-request-count into fix/562-weekly-grid-real-data for PR…
OnlyReadOneBook 2166d2e
Merge remote-tracking branch 'origin/develop' into fix/562-weekly-gri…
Sadturtleman b277c93
test(home): 실제 홈 경로가 주간 기록 수를 그리드까지 전달하는지 계측한다
Sadturtleman 4486365
Merge remote-tracking branch 'origin/fix/736-request-count' into fix/…
Sadturtleman 88ee83d
fix(test): 주간 수 계측을 좁은 화면에서도 통과하게 한다
Sadturtleman 8059da3
Merge branch 'fix/736-request-count' into fix/562-weekly-grid-real-data
OnlyReadOneBook eed6e99
Merge commit 'b5006fa2316e93d40037a03cbc1c6da38b4d1c32' into HEAD
OnlyReadOneBook be242a6
Merge commit '46e3ec40bf17c9c012c807d62307ef12161bb366' into HEAD
OnlyReadOneBook 99d6875
test(android): isolate weekly report after login (#1288)
OnlyReadOneBook c3a5737
Merge branch 'fix/736-request-count' into fix/562-weekly-grid-real-data
OnlyReadOneBook d7c2fd5
Merge branch 'fix/562-weekly-grid-real-data' into test/1288-weekly-re…
OnlyReadOneBook af2955d
Merge branch 'fix/736-request-count' into fix/562-weekly-grid-real-data
OnlyReadOneBook edbd6b2
Merge branch 'fix/562-weekly-grid-real-data' into test/1288-weekly-re…
OnlyReadOneBook acbefd6
Merge remote-tracking branch 'origin/fix/736-request-count' into fix/…
Sadturtleman e3f2100
test(app): 계측 테스트의 주간 리포트 조회를 fake 로 격리한다
Sadturtleman 69f5e1f
Merge branch 'fix/562-weekly-grid-real-data' into test/1288-weekly-re…
OnlyReadOneBook c606293
Merge branch 'fix/736-request-count' into fix/562-weekly-grid-real-data
OnlyReadOneBook 19d97a4
Merge branch 'fix/562-weekly-grid-real-data' into test/1288-weekly-re…
OnlyReadOneBook df6a625
Merge branch 'fix/736-request-count' into fix/562-weekly-grid-real-data
OnlyReadOneBook b7719f9
Merge branch 'fix/562-weekly-grid-real-data' into test/1288-weekly-re…
OnlyReadOneBook 51a012f
Merge branch 'fix/736-request-count' into fix/562-weekly-grid-real-data
OnlyReadOneBook f8e34a9
Merge branch 'fix/562-weekly-grid-real-data' into test/1288-weekly-re…
OnlyReadOneBook 470a019
Merge branch 'fix/736-request-count' into fix/562-weekly-grid-real-data
OnlyReadOneBook c9d2ffe
Merge branch 'fix/562-weekly-grid-real-data' into test/1288-weekly-re…
OnlyReadOneBook b9c13d6
Merge branch 'develop' into fix/562-weekly-grid-real-data
Sadturtleman 4d190f9
Merge branch 'fix/562-weekly-grid-real-data' into test/1288-weekly-re…
OnlyReadOneBook 3d6345b
Merge branch 'develop' into fix/562-weekly-grid-real-data
Sadturtleman cf94ed9
Merge branch 'fix/736-request-count' into fix/562-weekly-grid-real-data
Sadturtleman 2abd28a
test(app): 주간 리포트 fake 를 정본 strict 판으로 되돌린다
Sadturtleman 69ac3ff
Merge branch 'fix/736-request-count' into fix/562-weekly-grid-real-data
Sadturtleman ed46431
Merge branch 'fix/736-request-count' into fix/562-weekly-grid-real-data
Sadturtleman 125a340
Merge branch 'fix/736-request-count' into fix/562-weekly-grid-real-data
Sadturtleman 95c0316
Merge branch 'fix/562-weekly-grid-real-data' into test/1288-weekly-re…
OnlyReadOneBook d4b2eaf
test(android): base 추종 병합 잔재 정리 — 주간 리포트 주입·큐잉 중복 제거 (#1288)
OnlyReadOneBook 5337439
Merge pull request #1316 from Afternote/test/1288-weekly-report-fake
OnlyReadOneBook 4cf0cbd
Merge branch 'fix/736-request-count' into fix/562-weekly-grid-real-data
Sadturtleman 364cef5
Merge branch 'fix/736-request-count' into fix/562-weekly-grid-real-data
Sadturtleman ec1cc8a
fix(test): 주간 리포트 fake 에 fallback 을 열어 계측이 홈에서 죽지 않게 한다
Sadturtleman File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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
This file contains hidden or 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
182 changes: 182 additions & 0 deletions
182
app/src/androidTest/java/com/afternote/afternote_fe/HomeWeeklyCountAndroidTest.kt
This file contains hidden or 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,182 @@ | ||
| package com.afternote.afternote_fe | ||
|
|
||
| import androidx.compose.runtime.getValue | ||
| import androidx.compose.ui.graphics.asAndroidBitmap | ||
| import androidx.compose.ui.test.assertIsDisplayed | ||
| import androidx.compose.ui.test.captureToImage | ||
| import androidx.compose.ui.test.hasScrollToNodeAction | ||
| import androidx.compose.ui.test.hasText | ||
| import androidx.compose.ui.test.junit4.ComposeContentTestRule | ||
| import androidx.compose.ui.test.junit4.createAndroidComposeRule | ||
| import androidx.compose.ui.test.onAllNodesWithText | ||
| import androidx.compose.ui.test.onNodeWithText | ||
| import androidx.compose.ui.test.onRoot | ||
| import androidx.compose.ui.test.performScrollToNode | ||
| import androidx.lifecycle.compose.collectAsStateWithLifecycle | ||
| import androidx.test.ext.junit.runners.AndroidJUnit4 | ||
| import com.afternote.afternote_fe.test.FailureArtifactRule | ||
| import com.afternote.afternote_fe.test.HiltTestActivity | ||
| import com.afternote.afternote_fe.test.appTestUserRepository | ||
| import com.afternote.core.common.reporting.ErrorReporter | ||
| import com.afternote.core.domain.testing.FakeUserProfileRepository | ||
| import com.afternote.core.ui.theme.AfternoteTheme | ||
| import com.afternote.feature.home.presentation.HomeTabScreen | ||
| import com.afternote.feature.home.presentation.HomeTabUiState | ||
| import com.afternote.feature.home.presentation.HomeTabViewModel | ||
| import com.afternote.feature.home.presentation.usecase.GetHomeSummaryUseCase | ||
| import com.afternote.feature.mindrecord.domain.model.WeeklyReport | ||
| import com.afternote.feature.mindrecord.domain.repository.WeeklyReportRepository | ||
| import com.afternote.feature.mindrecord.domain.testing.FakeDailyQuestionRepository | ||
| import com.afternote.feature.mindrecord.domain.testing.FakeDiaryRepository | ||
| import com.afternote.feature.mindrecord.domain.usecase.GetWeeklyRecordCountUseCase | ||
| 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 org.junit.runner.RunWith | ||
|
|
||
| /** | ||
| * 실제 홈 경로가 주간 기록 수를 그리드까지 **전달하는지** (#562). | ||
| * | ||
| * 원래 결함은 그리드가 값을 못 그린 것이 아니라 **호출부가 값을 넘기지 않은 것**이었다. | ||
| * 컴포넌트에 숫자를 직접 넣는 테스트는 그 자리를 지나지 않으므로, ViewModel 이 만든 상태를 | ||
| * 화면에 물려 숫자가 실제로 보이는 데까지를 여기서 고정한다. | ||
| */ | ||
| @HiltAndroidTest | ||
| @RunWith(AndroidJUnit4::class) | ||
| class HomeWeeklyCountAndroidTest { | ||
| @get:Rule(order = 0) | ||
| val hiltRule = HiltAndroidRule(this) | ||
|
|
||
| // 홈은 MEMORIES 섹션에서 hiltViewModel() 을 부른다. 좁은 화면(Pixel 2 API 30)에서 주간 | ||
| // 카드까지 스크롤하면 그 항목도 composition 되므로 Hilt 가 붙은 Activity 여야 한다 — | ||
| // 맨 ComponentActivity 로는 "does not implement GeneratedComponent" 로 죽는다. | ||
| // MainActivity 는 이미 콘텐츠를 세팅해 setContent 가 거부되므로 빈 테스트 Activity 를 쓴다. | ||
| @get:Rule(order = 1) | ||
| val composeRule = createAndroidComposeRule<HiltTestActivity>() | ||
|
|
||
| @get:Rule(order = 2) | ||
| val failureArtifactRule = | ||
| FailureArtifactRule { | ||
| composeRule.onRoot().captureToImage().asAndroidBitmap() | ||
| } | ||
|
|
||
| @Before | ||
| fun inject() { | ||
| hiltRule.inject() | ||
| } | ||
|
|
||
| @Test | ||
| fun homeScreen_showsWeeklyRecordCountFromViewModel() { | ||
| val viewModel = homeViewModel(dailyQuestionAmount = 3, diaryAmount = 4) | ||
|
|
||
| composeRule.setContent { | ||
| AfternoteTheme { | ||
| val uiState by viewModel.uiState.collectAsStateWithLifecycle() | ||
| HomeTabScreen(uiState = uiState, todayDateText = "2026.04.10") | ||
| } | ||
| } | ||
|
|
||
| // 3 + 4 = 7. 이 숫자가 보이려면 UseCase → UiState → HomeTabScreen → WeeklySummaryGrid | ||
| // 배선이 전부 살아 있어야 한다. | ||
| awaitSuccess(viewModel) | ||
| composeRule.scrollToWeeklyCard() | ||
| composeRule.onNodeWithText(EXPECTED_COUNT).assertIsDisplayed() | ||
| } | ||
|
|
||
| @Test | ||
| fun homeScreen_showsPlaceholderWhenWeeklyCountUnavailable() { | ||
| // 조회 실패를 0 으로 접으면 «기록이 없음» 을 확정한다 — 미상은 대시로 남아야 한다 (#562). | ||
| val viewModel = homeViewModel(weeklyFailure = IllegalStateException("주간 조회 실패")) | ||
|
|
||
| composeRule.setContent { | ||
| AfternoteTheme { | ||
| val uiState by viewModel.uiState.collectAsStateWithLifecycle() | ||
| HomeTabScreen(uiState = uiState, todayDateText = "2026.04.10") | ||
| } | ||
| } | ||
|
|
||
| awaitSuccess(viewModel) | ||
| composeRule.scrollToWeeklyCard() | ||
| composeRule.onNodeWithText(UNKNOWN_COUNT).assertIsDisplayed() | ||
| } | ||
|
|
||
| /** | ||
| * 상태가 Success 가 될 때까지 기다린다. 화면 단언보다 먼저 두는 이유는, 조회가 끝나기 전에 | ||
| * 스크롤하면 주간 카드가 아직 목록에 없어 스크롤 자체가 실패하기 때문이다. | ||
| */ | ||
| private fun awaitSuccess(viewModel: HomeTabViewModel) { | ||
| composeRule.waitUntil(timeoutMillis = TIMEOUT) { | ||
| viewModel.uiState.value is HomeTabUiState.Success | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * 주간 카드까지 스크롤한다. | ||
| * | ||
| * `WeeklySummaryGrid` 는 `LazyColumn` 의 뒤쪽 item 이라 좁은 화면(Pixel 2 API 30)에서는 | ||
| * 아직 composition 되지 않는다. 노드가 «생기기만» 기다리면 스스로 노출되지 않아 timeout | ||
| * 이다 — 내 에뮬레이터(화면이 더 큼)에서만 통과했던 이유다 (#562 리뷰). | ||
| */ | ||
| private fun ComposeContentTestRule.scrollToWeeklyCard() { | ||
| onNode(hasScrollToNodeAction()).performScrollToNode(hasText(WEEKLY_CARD_LABEL)) | ||
| waitForIdle() | ||
| } | ||
|
|
||
| private fun homeViewModel( | ||
| dailyQuestionAmount: Int = 0, | ||
| diaryAmount: Int = 0, | ||
| weeklyFailure: Throwable? = null, | ||
| ): HomeTabViewModel = | ||
| HomeTabViewModel( | ||
| getHomeSummary = | ||
| GetHomeSummaryUseCase( | ||
| userRepository = appTestUserRepository(), | ||
| diaryRepository = FakeDiaryRepository(), | ||
| dailyQuestionRepository = FakeDailyQuestionRepository(), | ||
| getWeeklyRecordCount = | ||
| GetWeeklyRecordCountUseCase( | ||
| FakeWeeklyReportRepository(dailyQuestionAmount, diaryAmount, weeklyFailure), | ||
| ), | ||
| ), | ||
| userProfileRepository = FakeUserProfileRepository(), | ||
| errorReporter = SilentErrorReporter, | ||
| ) | ||
|
|
||
| private companion object { | ||
| const val TIMEOUT = 5_000L | ||
| const val EXPECTED_COUNT = "7" | ||
| const val WEEKLY_CARD_LABEL = "THIS WEEK" | ||
| const val UNKNOWN_COUNT = "–" | ||
| } | ||
| } | ||
|
|
||
| /** 이 테스트는 보고 여부를 보지 않는다 — 조회 실패 경로가 리포터를 부르므로 자리만 채운다. */ | ||
| private object SilentErrorReporter : ErrorReporter { | ||
| override fun writeFailure( | ||
| throwable: Throwable, | ||
| attributes: Map<String, String>, | ||
| ) = Unit | ||
| } | ||
|
|
||
| private class FakeWeeklyReportRepository( | ||
| private val dailyQuestionAmount: Int, | ||
| private val diaryAmount: Int, | ||
| private val failure: Throwable?, | ||
| ) : WeeklyReportRepository { | ||
| override suspend fun getWeeklyReport(date: String): Result<WeeklyReport> { | ||
| failure?.let { return Result.failure(it) } | ||
| return Result.success( | ||
| WeeklyReport( | ||
| dailyQuestionAmount = dailyQuestionAmount, | ||
| diaryAmount = diaryAmount, | ||
| summaryText = "", | ||
| week = emptyList(), | ||
| dailyQuestions = emptyList(), | ||
| emotions = emptyList(), | ||
| emotionAnalysis = null, | ||
| ), | ||
| ) | ||
| } | ||
| } |
This file contains hidden or 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
This file contains hidden or 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
This file contains hidden or 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
18 changes: 18 additions & 0 deletions
18
app/src/debug/java/com/afternote/afternote_fe/test/HiltTestActivity.kt
This file contains hidden or 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,18 @@ | ||
| package com.afternote.afternote_fe.test | ||
|
|
||
| import androidx.activity.ComponentActivity | ||
| import dagger.hilt.android.AndroidEntryPoint | ||
|
|
||
| /** | ||
| * `setContent` 로 화면 일부만 띄우면서 `hiltViewModel()` 도 써야 하는 계측 테스트용 빈 Activity. | ||
| * | ||
| * `createComposeRule()` 의 기본 Activity 는 Hilt 컴포넌트를 갖지 않아, 화면 안에서 | ||
| * `hiltViewModel()` 을 부르는 자리(예: 홈의 MEMORIES 섹션)가 composition 되는 순간 | ||
| * "does not implement GeneratedComponent" 로 죽는다. 그렇다고 `MainActivity` 를 쓰면 | ||
| * 그쪽이 이미 콘텐츠를 세팅해 `setContent` 가 거부된다. | ||
| * | ||
| * debug 소스셋에 두는 이유는 androidTest 가 앱 APK 의 Activity 만 띄울 수 있어서다 — | ||
| * 릴리스 빌드에는 들어가지 않는다. | ||
| */ | ||
| @AndroidEntryPoint | ||
| class HiltTestActivity : ComponentActivity() |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[minor] 재승인을 막지 않습니다 — 다만 큐에 정확히 한 건이라, 홈을 두 번 부르는 테스트가 이 클래스에 들어오는 순간 무관한 이유로 터집니다.
앱 셸은 홈에 복귀할 때마다 요약을 다시 부릅니다(
AppNavigation의LifecycleEventEffect(ON_RESUME)→refreshOnReturn(), 첫 resume 만 스킵). 지금 이 클래스의 홈 경유 테스트는 전부 «한 번 들어가고 끝» 이라 1건으로 충분하고 CI 도 green 입니다만, 홈 → 다른 화면 → 홈 시나리오를 하나 더하면 두 번째 호출에서results가 비어requireNotNull이 터집니다. 그때 실패 메시지는 «주간 리포트 응답이 큐에 없다» 라, 새 테스트를 쓰는 사람은 자기 시나리오와 무관한 곳을 보게 됩니다.TestFakes에 헬퍼를 하나 더 두면 그 자리에서 바로 읽힙니다.«왜 하필 1건인가» 를 주석 한 줄로 남겨 주는 것만으로도 충분합니다. 큐잉을 택한 판단(조용히 접으면 요청 횟수 어긋남을 놓친다) 자체는 맞습니다.