From 7ebeac7daa439a0da7b7d5ffdc8edfba61fb8440 Mon Sep 17 00:00:00 2001 From: Sadturtleman Date: Tue, 25 Aug 2026 09:47:47 +0900 Subject: [PATCH 1/2] =?UTF-8?q?fix(mindrecord):=20MEMORIES=20=EC=B9=B4?= =?UTF-8?q?=EB=93=9C=EC=9D=98=20'=EA=B7=B8=EB=82=A0=EC=9D=98=20=EA=B8=B0?= =?UTF-8?q?=EB=A1=9D=20=EB=8B=A4=EC=8B=9C=20=EC=9D=BD=EA=B8=B0'=20?= =?UTF-8?q?=EC=A3=BD=EC=9D=80=20=EC=98=81=EC=97=AD=EC=9D=84=20=EC=97=86?= =?UTF-8?q?=EC=95=A4=EB=8B=A4=20(#793)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 목적지가 미확정이라 onReadAgainClick 을 비워 뒀는데, 버튼이 자체 clickable 이라 클릭을 삼켰다. 결과는 «카드 여백을 누르면 추억 공간이 열리고, 정작 가장 눌러 보고 싶은 버튼만 아무 일도 안 한다» 였다. 새 목적지를 지어내지 않는다 — 이미 동작하는 카드 자신의 목적지를 물려준다. 확정이 오면 호출부의 인자 하나만 바꾸면 된다. Co-Authored-By: Claude Opus 5 (1M context) --- .../presentation/component/MemoriesCard.kt | 6 +-- .../hometab/HomeTabMindRecordLazyItems.kt | 12 +++-- .../hometab/MemoriesReadAgainTest.kt | 48 +++++++++++++++++++ 3 files changed, 59 insertions(+), 7 deletions(-) create mode 100644 feature/mindrecord/presentation/src/test/kotlin/com/afternote/feature/mindrecord/presentation/hometab/MemoriesReadAgainTest.kt diff --git a/feature/mindrecord/presentation/src/main/kotlin/com/afternote/feature/mindrecord/presentation/component/MemoriesCard.kt b/feature/mindrecord/presentation/src/main/kotlin/com/afternote/feature/mindrecord/presentation/component/MemoriesCard.kt index 90faeb36e7..5ae919d2ac 100644 --- a/feature/mindrecord/presentation/src/main/kotlin/com/afternote/feature/mindrecord/presentation/component/MemoriesCard.kt +++ b/feature/mindrecord/presentation/src/main/kotlin/com/afternote/feature/mindrecord/presentation/component/MemoriesCard.kt @@ -46,9 +46,9 @@ import com.afternote.feature.mindrecord.presentation.R * * @param question 최근 기록의 제목(데일리질문이면 질문 원문). null 이면 표시할 기록이 없다. * @param answer 그 기록의 본문 미리보기. - * @param onReadAgainClick "그날의 기록 다시 읽기" 목적지. **아직 확정되지 않았다** — Figma 의 - * 이 버튼에 프로토타입 연결이 없고 #559 에도 확정 답변이 없어, 기본값은 아무 데도 보내지 - * 않는다. 목적지가 정해지면 호출부에서 이 인자만 채우면 된다. + * @param onReadAgainClick "그날의 기록 다시 읽기" 목적지. **최종 확정은 아직이다** — Figma 의 + * 이 버튼에 프로토타입 연결이 없다. 다만 비워 두면 버튼이 클릭을 삼켜 카드 안에서 버튼만 + * 죽은 영역이 되므로, 홈 호출부는 카드 자신의 목적지(추억 공간)를 물려준다 (#793). */ @Composable fun MemoriesCard( diff --git a/feature/mindrecord/presentation/src/main/kotlin/com/afternote/feature/mindrecord/presentation/hometab/HomeTabMindRecordLazyItems.kt b/feature/mindrecord/presentation/src/main/kotlin/com/afternote/feature/mindrecord/presentation/hometab/HomeTabMindRecordLazyItems.kt index ca9f33b806..ce7cc8deb7 100644 --- a/feature/mindrecord/presentation/src/main/kotlin/com/afternote/feature/mindrecord/presentation/hometab/HomeTabMindRecordLazyItems.kt +++ b/feature/mindrecord/presentation/src/main/kotlin/com/afternote/feature/mindrecord/presentation/hometab/HomeTabMindRecordLazyItems.kt @@ -118,7 +118,7 @@ private fun HomeTabMindRecordMemoriesItem( } @Composable -private fun MemoriesSectionContent( +internal fun MemoriesSectionContent( onMemoriesSectionClick: () -> Unit, clickLabel: String, interactionSource: MutableInteractionSource, @@ -140,12 +140,16 @@ private fun MemoriesSectionContent( ) { AfternoteSectionHeader(title = stringResource(mindrecord_home_tab_memories_section_title)) Spacer(modifier = Modifier.height(12.dp)) - // "그날의 기록 다시 읽기" 목적지는 넘기지 않는다 — Figma 의 이 버튼에 프로토타입 - // 연결이 없고 #559 에도 확정 답변이 없다. 임의 목적지를 붙이면 미확정 탐색 동작이 - // 제품 동작으로 굳는다. 확정되면 여기서 `onReadAgainClick` 을 채운다. + // 버튼은 **자기 컨테이너와 같은 곳**으로 보낸다 (#793). + // + // 목적지가 미확정이라 비워 뒀는데, 버튼이 자체 clickable 이라 클릭을 삼켜 카드 + // 안에서 버튼만 죽은 영역이 됐다 — 카드 여백을 누르면 추억 공간이 열리고, 가장 + // 눌러 보고 싶은 버튼만 아무 일도 안 한다. 새 목적지를 지어내는 게 아니라 이미 + // 동작하는 카드의 목적지를 물려주는 것이라, 확정이 오면 이 인자만 바꾸면 된다. MemoriesCard( question = question, answer = answer, + onReadAgainClick = onMemoriesSectionClick, ) } } diff --git a/feature/mindrecord/presentation/src/test/kotlin/com/afternote/feature/mindrecord/presentation/hometab/MemoriesReadAgainTest.kt b/feature/mindrecord/presentation/src/test/kotlin/com/afternote/feature/mindrecord/presentation/hometab/MemoriesReadAgainTest.kt new file mode 100644 index 0000000000..9c98b0ad38 --- /dev/null +++ b/feature/mindrecord/presentation/src/test/kotlin/com/afternote/feature/mindrecord/presentation/hometab/MemoriesReadAgainTest.kt @@ -0,0 +1,48 @@ +package com.afternote.feature.mindrecord.presentation.hometab + +import androidx.activity.ComponentActivity +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.performClick +import com.afternote.core.ui.theme.AfternoteTheme +import org.junit.Assert.assertEquals +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config + +/** + * MEMORIES 카드의 "그날의 기록 다시 읽기" 가 죽은 영역이 아닌지 (#793). + * + * 목적지가 미확정이라 인자를 비워 뒀는데, 버튼이 자체 `clickable` 이라 클릭을 삼켰다. + * 결과는 «카드 여백을 누르면 추억 공간이 열리고, 정작 버튼만 아무 일도 안 한다» 였다. + * 최종 목적지가 확정될 때까지 버튼은 자기 컨테이너와 같은 곳으로 간다. + */ +@RunWith(RobolectricTestRunner::class) +@Config(sdk = [35]) +class MemoriesReadAgainTest { + @get:Rule + val composeRule = createAndroidComposeRule() + + @Test + fun `버튼을 누르면 카드와 같은 목적지로 간다`() { + var clicks = 0 + composeRule.setContent { + AfternoteTheme { + MemoriesSectionContent( + onMemoriesSectionClick = { clicks += 1 }, + clickLabel = "추억 공간 열기", + interactionSource = MutableInteractionSource(), + question = "가장 소중했던 순간은?", + answer = "아이가 태어났을 때.", + ) + } + } + + composeRule.onNodeWithText("그날의 기록 다시 읽기").performClick() + + assertEquals(1, clicks) + } +} From 1ca279c73b715246942306ac222e1415d6b6d844 Mon Sep 17 00:00:00 2001 From: Sadturtleman Date: Tue, 25 Aug 2026 15:58:00 +0900 Subject: [PATCH 2/2] =?UTF-8?q?fix(mindrecord):=20=EC=83=88=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EA=B0=80=20=EA=B9=A8=EB=9C=A8=EB=A6=B0=20And?= =?UTF-8?q?roid=20Lint=20=EB=A5=BC=20=EA=B3=A0=EC=B9=9C=EB=8B=A4=20(#793?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MutableInteractionSource 는 @RememberInComposition 이라 컴포지션 안에서 맨손으로 만들 수 없다 — 컴포지션 밖에서 만들어 넘긴다. 테스트 접근을 위해 넓힌 가시성에는 @VisibleForTesting 을 붙여 의도를 표시하고, 목적지 승계가 «종전 결정을 뒤집은 것이 아니라 구멍을 메운 것» 이라는 근거를 docs/qa/assumptions.md 에 남긴다. Co-Authored-By: Claude Opus 5 (1M context) --- docs/qa/assumptions.md | 10 ++++++++++ .../presentation/hometab/HomeTabMindRecordLazyItems.kt | 2 ++ .../presentation/hometab/MemoriesReadAgainTest.kt | 5 ++++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/qa/assumptions.md b/docs/qa/assumptions.md index c0e0367ea7..3318853925 100644 --- a/docs/qa/assumptions.md +++ b/docs/qa/assumptions.md @@ -258,3 +258,13 @@ Compose 테스트로 고정했다. **분리한 것** — 일기의 기록 날짜는 생성·수정 어느 쪽으로도 서버에 보낼 수 없다(양쪽 스키마에 `date` 없음, 보내도 무시됨을 실측). 날짜 선택이 표시 전용인 문제는 BE 계약 확장이나 기획 결정이 필요해 #1008 로 분리했다. + +## #793 — MEMORIES 카드 「그날의 기록 다시 읽기」 목적지 (임시 승계) + +- **최종 목적지는 여전히 미확정이다.** Figma 카드 노드(`109:15028`)의 이 버튼에는 프로토타입 + 연결이 없고, 「정리 Screen Design」 페이지에도 이 버튼의 목적지를 정해 주는 프레임이 없다. +- 그때까지 버튼은 **자기 컨테이너와 같은 곳**(추억 공간)으로 간다. 비워 두면 버튼이 클릭을 + 삼켜 카드 안에서 버튼만 죽은 영역이 되기 때문이다 — «미확정이라 비워 둔다» 가 실제로는 + «카드에 구멍을 낸다» 로 나타났다. +- 즉 종전 결정(PR #721 리뷰의 «임의 목적지를 붙이지 않는다»)을 **뒤집은 것이 아니라**, + 새 목적지를 만들지 않는 선에서 구멍만 메운 것이다. 확정이 오면 호출부 인자 하나만 바꾼다. diff --git a/feature/mindrecord/presentation/src/main/kotlin/com/afternote/feature/mindrecord/presentation/hometab/HomeTabMindRecordLazyItems.kt b/feature/mindrecord/presentation/src/main/kotlin/com/afternote/feature/mindrecord/presentation/hometab/HomeTabMindRecordLazyItems.kt index ce7cc8deb7..543c0838fd 100644 --- a/feature/mindrecord/presentation/src/main/kotlin/com/afternote/feature/mindrecord/presentation/hometab/HomeTabMindRecordLazyItems.kt +++ b/feature/mindrecord/presentation/src/main/kotlin/com/afternote/feature/mindrecord/presentation/hometab/HomeTabMindRecordLazyItems.kt @@ -1,5 +1,6 @@ package com.afternote.feature.mindrecord.presentation.hometab +import androidx.annotation.VisibleForTesting import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement @@ -117,6 +118,7 @@ private fun HomeTabMindRecordMemoriesItem( ) } +@VisibleForTesting @Composable internal fun MemoriesSectionContent( onMemoriesSectionClick: () -> Unit, diff --git a/feature/mindrecord/presentation/src/test/kotlin/com/afternote/feature/mindrecord/presentation/hometab/MemoriesReadAgainTest.kt b/feature/mindrecord/presentation/src/test/kotlin/com/afternote/feature/mindrecord/presentation/hometab/MemoriesReadAgainTest.kt index 9c98b0ad38..ad009dabe1 100644 --- a/feature/mindrecord/presentation/src/test/kotlin/com/afternote/feature/mindrecord/presentation/hometab/MemoriesReadAgainTest.kt +++ b/feature/mindrecord/presentation/src/test/kotlin/com/afternote/feature/mindrecord/presentation/hometab/MemoriesReadAgainTest.kt @@ -29,12 +29,15 @@ class MemoriesReadAgainTest { @Test fun `버튼을 누르면 카드와 같은 목적지로 간다`() { var clicks = 0 + // MutableInteractionSource 는 @RememberInComposition 이라 컴포지션 안에서 맨손으로 + // 만들 수 없다 — 컴포지션마다 새 인스턴스가 생겨 상호작용 상태가 유실된다. + val interactionSource = MutableInteractionSource() composeRule.setContent { AfternoteTheme { MemoriesSectionContent( onMemoriesSectionClick = { clicks += 1 }, clickLabel = "추억 공간 열기", - interactionSource = MutableInteractionSource(), + interactionSource = interactionSource, question = "가장 소중했던 순간은?", answer = "아이가 태어났을 때.", )