Skip to content
Merged
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
@@ -1,24 +1,20 @@
package com.afternote.afternote_fe
package com.afternote.feature.mindrecord.presentation

import androidx.compose.ui.graphics.asAndroidBitmap
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.captureToImage
import androidx.compose.ui.test.hasClickAction
import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.junit4.v2.createComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.onRoot
import androidx.compose.ui.test.performClick
import androidx.lifecycle.SavedStateHandle
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.afternote.afternote_fe.test.FailureArtifactRule
import com.afternote.afternote_fe.test.FakeErrorReporter
import com.afternote.afternote_fe.test.appTestUserRepository
import com.afternote.core.domain.testing.FakePhotoUploadRepository
import com.afternote.core.domain.testing.FakeUserRepository
import com.afternote.core.model.user.Receiver
import com.afternote.core.ui.theme.AfternoteTheme
import com.afternote.feature.mindrecord.domain.model.TodayMood
import com.afternote.feature.mindrecord.domain.testing.FakeDailyQuestionRepository
import com.afternote.feature.mindrecord.domain.testing.FakeDiaryRepository
import com.afternote.feature.mindrecord.presentation.reporting.RecordingErrorReporter
import com.afternote.feature.mindrecord.presentation.screen.sender.DailyQuestionWriteScreen
import com.afternote.feature.mindrecord.presentation.screen.sender.DiaryWriteScreen
import com.afternote.feature.mindrecord.presentation.viewmodel.DailyQuestionWriteViewModel
Expand All @@ -30,18 +26,17 @@ import org.junit.Assert.assertFalse
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class MindRecordFlowAndroidTest {
@get:Rule(order = 0)
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import org.robolectric.annotation.GraphicsMode

@RunWith(RobolectricTestRunner::class)
@GraphicsMode(GraphicsMode.Mode.NATIVE)
@Config(sdk = [35])
class MindRecordFlowTest {
@get:Rule
val composeRule = createComposeRule()

@get:Rule(order = 1)
val failureArtifactRule =
FailureArtifactRule {
composeRule.onRoot().captureToImage().asAndroidBitmap()
}

@Test
fun diaryFailureThenRetry_preservesInputAndSendsExactPayload() {
val repository = FakeDiaryRepository()
Expand All @@ -54,7 +49,7 @@ class MindRecordFlowAndroidTest {
),
)
repository.onCreate = { createResults.removeFirst() }
val reporter = FakeErrorReporter()
val reporter = RecordingErrorReporter()
val viewModel = diaryViewModel(repository, reporter)
var successCalls = 0

Expand Down Expand Up @@ -95,7 +90,7 @@ class MindRecordFlowAndroidTest {

// 실패는 한 번뿐이었으므로 기록도 한 번이다. 성공한 재시도가 더 남기면 Crashlytics
// 보관 한도(최근 8건)를 잡음으로 채운다 (#964).
assertEquals(listOf("diary_submit"), reporter.mindRecordStages)
assertEquals(listOf("diary_submit"), reporter.stages)
}

@Test
Expand Down Expand Up @@ -128,7 +123,7 @@ class MindRecordFlowAndroidTest {
),
)
repository.onCreate = { createResults.removeFirst() }
val reporter = FakeErrorReporter()
val reporter = RecordingErrorReporter()
val viewModel =
DailyQuestionWriteViewModel(
savedStateHandle = SavedStateHandle(emptyMap()),
Expand Down Expand Up @@ -158,7 +153,7 @@ class MindRecordFlowAndroidTest {
// 실제 화면을 태우므로 에디터가 되돌려 주는 HTML 이 그대로 상태에 들어간다 —
// 종전 테스트는 화면을 건너뛰어 원문 문자열이 남았다.
assertEquals("<p>오늘은 용기 냈다</p>", viewModel.uiState.value.answer)
assertEquals(listOf("daily_question_submit"), reporter.mindRecordStages)
assertEquals(listOf("daily_question_submit"), reporter.stages)

composeRule.runOnIdle { viewModel.consumeSubmitResult() }
composeRule.onNode(hasText("저장") and hasClickAction()).performClick()
Expand All @@ -171,12 +166,12 @@ class MindRecordFlowAndroidTest {
assertEquals("<p>오늘은 용기 냈다</p>", repository.createdPayloads.last().content)
assertFalse(repository.createdPayloads.last().isDraft)
// 성공한 재시도는 기록을 늘리지 않는다.
assertEquals(listOf("daily_question_submit"), reporter.mindRecordStages)
assertEquals(listOf("daily_question_submit"), reporter.stages)
}

private fun diaryViewModel(
repository: FakeDiaryRepository,
reporter: FakeErrorReporter = FakeErrorReporter(),
reporter: RecordingErrorReporter = RecordingErrorReporter(),
): DiaryWriteViewModel =
DiaryWriteViewModel(
savedStateHandle =
Expand All @@ -192,8 +187,23 @@ class MindRecordFlowAndroidTest {
uploadedUrl = "https://cdn.test/image.jpg",
uploadedKey = "mindrecords/1/image.jpg",
),
userRepository = appTestUserRepository(),
userRepository = mindRecordFlowUserRepository(),
draftLoader = MindRecordDraftLoader(repository, FakeDailyQuestionRepository()),
errorReporter = reporter,
)
}

private fun mindRecordFlowUserRepository(): FakeUserRepository =
FakeUserRepository.strict().apply {
receiverState.value = listOf(Receiver(7L, "김수신", "가족", "fake-auth-7"))
onReceiverListFlow = null
onGetReceivers = null
onCreateReceiver = null
onGetMyProfile = null
onUpdateMyProfile = null
onDeleteAccount = null
onLogActivity = null
onGetMyPushSettings = null
onUpdateMyPushSettings = null
onGetConnectedAccounts = null
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
package com.afternote.afternote_fe
package com.afternote.feature.mindrecord.presentation

import androidx.compose.ui.graphics.asAndroidBitmap
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.captureToImage
import androidx.compose.ui.test.hasClickAction
import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.junit4.v2.createComposeRule
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.onRoot
import androidx.compose.ui.test.performClick
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.afternote.afternote_fe.test.FailureArtifactRule
import com.afternote.afternote_fe.test.FakeErrorReporter
import com.afternote.core.domain.testing.FakeUserRepository
import com.afternote.core.model.user.User
import com.afternote.core.ui.theme.AfternoteTheme
Expand All @@ -38,6 +32,7 @@ import com.afternote.feature.mindrecord.domain.testing.FakeWeeklyReportRepositor
import com.afternote.feature.mindrecord.domain.testing.unexpectedCall
import com.afternote.feature.mindrecord.presentation.model.DayBackground
import com.afternote.feature.mindrecord.presentation.model.DayContent
import com.afternote.feature.mindrecord.presentation.reporting.RecordingErrorReporter
import com.afternote.feature.mindrecord.presentation.screen.receiver.ReceiverMindRecordScreen
import com.afternote.feature.mindrecord.presentation.screen.sender.DiaryScreen
import com.afternote.feature.mindrecord.presentation.screen.sender.DraftListScreen
Expand All @@ -59,21 +54,20 @@ import org.junit.Assert.assertTrue
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import org.robolectric.annotation.GraphicsMode
import java.time.DayOfWeek
import java.time.LocalDate
import java.time.YearMonth

@RunWith(AndroidJUnit4::class)
class MindRecordLifecycleAndroidTest {
@get:Rule(order = 0)
@RunWith(RobolectricTestRunner::class)
@GraphicsMode(GraphicsMode.Mode.NATIVE)
@Config(sdk = [35], qualifiers = "w360dp-h800dp-xhdpi")
class MindRecordLifecycleTest {
@get:Rule
val composeRule = createComposeRule()

@get:Rule(order = 1)
val failureArtifactRule =
FailureArtifactRule {
composeRule.onRoot().captureToImage().asAndroidBitmap()
}

@Test
fun diaryList_excludesDraftChangesMonthAndReloadsAfterDelete() {
val currentMonth = YearMonth.now()
Expand Down Expand Up @@ -162,7 +156,7 @@ class MindRecordLifecycleAndroidTest {
loader = MindRecordDraftLoader(diaryRepository, dailyQuestionRepository),
diaryRepository = diaryRepository,
dailyQuestionRepository = dailyQuestionRepository,
errorReporter = FakeErrorReporter(),
errorReporter = RecordingErrorReporter(),
)

composeRule.setContent {
Expand Down Expand Up @@ -302,7 +296,7 @@ class MindRecordLifecycleAndroidTest {
),
),
)
val viewModel = ReceiverMindRecordViewModel(repository, FakeErrorReporter())
val viewModel = ReceiverMindRecordViewModel(repository, RecordingErrorReporter())

composeRule.setContent {
AfternoteTheme {
Expand Down Expand Up @@ -338,6 +332,10 @@ class MindRecordLifecycleAndroidTest {
.onNode(hasText("2026-08-10 - 2026-08-31") and hasClickAction())
.performClick()
composeRule.onNodeWithText("초기화").performClick()
composeRule.waitUntil(timeoutMillis = TIMEOUT) {
(viewModel.uiState.value as? ReceiverMindRecordUiState.Success)?.filter?.isApplied == false
}
composeRule.waitForIdle()
composeRule.onNodeWithText("2026-08-10 - 2026-08-31").assertDoesNotExist()
composeRule.onNodeWithText("범위 밖 일기").assertIsDisplayed()
composeRule.onNodeWithText("데일리 질문").performClick()
Expand Down
Loading