diff --git a/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched/data/sessions/FakeSessionsApiClient.kt b/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched/data/sessions/FakeSessionsApiClient.kt index 0ff982ede..9cab2803a 100644 --- a/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched/data/sessions/FakeSessionsApiClient.kt +++ b/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched/data/sessions/FakeSessionsApiClient.kt @@ -6,6 +6,7 @@ import io.github.droidkaigi.confsched.data.sessions.response.CategoryResponse import io.github.droidkaigi.confsched.data.sessions.response.LocaledResponse import io.github.droidkaigi.confsched.data.sessions.response.RoomResponse import io.github.droidkaigi.confsched.data.sessions.response.SessionAssetResponse +import io.github.droidkaigi.confsched.data.sessions.response.SessionMessageResponse import io.github.droidkaigi.confsched.data.sessions.response.SessionResponse import io.github.droidkaigi.confsched.data.sessions.response.SessionsAllResponse import io.github.droidkaigi.confsched.data.sessions.response.SpeakerResponse @@ -48,6 +49,12 @@ public class FakeSessionsApiClient : SessionsApiClient { } } + public data object OperationalMessageExists : Status() { + override suspend fun sessionsAllResponse(): SessionsAllResponse { + return SessionsAllResponse.messageExistsFake() + } + } + public data object Error : Status() { override suspend fun sessionsAllResponse(): SessionsAllResponse { throw IOException("Fake IO Exception") @@ -126,6 +133,17 @@ public fun SessionsAllResponse.Companion.onlyVideoAssetAvailableFake(): Sessions ), ) +public fun SessionsAllResponse.Companion.messageExistsFake(): SessionsAllResponse = SessionsAllResponse.fake( + sessions = SessionResponse.fakes( + message = SessionMessageResponse.fake(), + ), +) + +public fun SessionMessageResponse.Companion.fake(): SessionMessageResponse = SessionMessageResponse( + ja = "このセッションは中止になりました", + en = "This session has been canceled.", +) + private fun RoomResponse.Companion.fakes(): List = listOf( RoomResponse(name = LocaledResponse(ja = "Hedgehog ja", en = "Hedgehog"), id = 1, sort = 1), RoomResponse( @@ -180,6 +198,7 @@ private fun SessionResponse.Companion.fakes( rooms: List = RoomResponse.fakes(), categories: List = CategoryResponse.fakes(), asset: SessionAssetResponse = SessionAssetResponse.fake(), + message: SessionMessageResponse? = null, ): List { val sessions = mutableListOf() @@ -204,7 +223,7 @@ private fun SessionResponse.Companion.fakes( sessionCategoryItemId = 3, interpretationTarget = false, asset = asset, - message = null, + message = message, sessionType = "WELCOME_TALK", levels = listOf("UNSPECIFIED"), ), @@ -266,7 +285,7 @@ private fun SessionResponse.Companion.fakes( roomId = room.id, sessionCategoryItemId = sessionCategoryItemId, sessionType = "NORMAL", - message = null, + message = message, isPlenumSession = false, targetAudience = "For App developer アプリ開発者向け", interpretationTarget = false, diff --git a/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/robot/MiniRobots.kt b/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/robot/MiniRobots.kt index 3e999aff2..9701e196e 100644 --- a/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/robot/MiniRobots.kt +++ b/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/robot/MiniRobots.kt @@ -43,6 +43,7 @@ import io.github.droidkaigi.confsched.testing.robot.TimetableItemCardRobot.Langu import io.github.droidkaigi.confsched.testing.robot.TimetableServerRobot.ServerStatus.Error import io.github.droidkaigi.confsched.testing.robot.TimetableServerRobot.ServerStatus.Operational import io.github.droidkaigi.confsched.testing.robot.TimetableServerRobot.ServerStatus.OperationalBothAssetAvailable +import io.github.droidkaigi.confsched.testing.robot.TimetableServerRobot.ServerStatus.OperationalMessageExists import io.github.droidkaigi.confsched.testing.robot.TimetableServerRobot.ServerStatus.OperationalOnlySlideAssetAvailable import io.github.droidkaigi.confsched.testing.robot.TimetableServerRobot.ServerStatus.OperationalOnlyVideoAssetAvailable import io.github.droidkaigi.confsched.testing.rules.RobotTestRule @@ -333,6 +334,7 @@ interface TimetableServerRobot { OperationalBothAssetAvailable, OperationalOnlySlideAssetAvailable, OperationalOnlyVideoAssetAvailable, + OperationalMessageExists, Error, } @@ -349,6 +351,7 @@ class DefaultTimetableServerRobot @Inject constructor(sessionsApiClient: Session OperationalBothAssetAvailable -> Status.OperationalBothAssetAvailable OperationalOnlySlideAssetAvailable -> Status.OperationalOnlySlideAssetAvailable OperationalOnlyVideoAssetAvailable -> Status.OperationalOnlyVideoAssetAvailable + OperationalMessageExists -> Status.OperationalMessageExists Error -> Status.Error }, ) diff --git a/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/robot/TimetableItemDetailScreenRobot.kt b/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/robot/TimetableItemDetailScreenRobot.kt index c811565cd..aee74ce7b 100644 --- a/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/robot/TimetableItemDetailScreenRobot.kt +++ b/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/robot/TimetableItemDetailScreenRobot.kt @@ -22,6 +22,8 @@ import com.github.takahirom.roborazzi.captureRoboImage import io.github.droidkaigi.confsched.data.sessions.FakeSessionsApiClient import io.github.droidkaigi.confsched.designsystem.theme.KaigiTheme import io.github.droidkaigi.confsched.sessions.TimetableItemDetailBookmarkIconTestTag +import io.github.droidkaigi.confsched.sessions.TimetableItemDetailMessageRowTestTag +import io.github.droidkaigi.confsched.sessions.TimetableItemDetailMessageRowTextTestTag import io.github.droidkaigi.confsched.sessions.TimetableItemDetailScreen import io.github.droidkaigi.confsched.sessions.TimetableItemDetailScreenLazyColumnTestTag import io.github.droidkaigi.confsched.sessions.component.DescriptionMoreButtonTestTag @@ -118,6 +120,18 @@ class TimetableItemDetailScreenRobot @Inject constructor( .performScrollToNode(hasTestTag(TimetableItemDetailContentArchiveSectionTestTag)) } + fun scrollToMessageRow() { + composeTestRule + .onNode(hasTestTag(TimetableItemDetailScreenLazyColumnTestTag)) + .performScrollToNode(hasTestTag(TimetableItemDetailMessageRowTestTag)) + + // FIXME Without this, you won't be able to scroll to the exact middle of the message section. + composeTestRule.onRoot().performTouchInput { + swipeUp(startY = centerY, endY = centerY - 175) + } + waitUntilIdle() + } + fun checkScreenCapture() { composeTestRule .onNode(isRoot()) @@ -248,6 +262,15 @@ class TimetableItemDetailScreenRobot @Inject constructor( .assertDoesNotExist() } + fun checkMessageDisplayed() { + composeTestRule + .onAllNodes(hasTestTag(TimetableItemDetailMessageRowTextTestTag)) + .onFirst() + .assertExists() + .assertIsDisplayed() + .assertTextEquals("This session has been canceled.") + } + companion object { val defaultSessionId = FakeSessionsApiClient.defaultSession.id } diff --git a/feature/sessions/src/androidUnitTest/kotlin/io/github/droidkaigi/confsched/sessions/TimetableItemDetailScreenTest.kt b/feature/sessions/src/androidUnitTest/kotlin/io/github/droidkaigi/confsched/sessions/TimetableItemDetailScreenTest.kt index a4dc566c3..5dfe28cbc 100644 --- a/feature/sessions/src/androidUnitTest/kotlin/io/github/droidkaigi/confsched/sessions/TimetableItemDetailScreenTest.kt +++ b/feature/sessions/src/androidUnitTest/kotlin/io/github/droidkaigi/confsched/sessions/TimetableItemDetailScreenTest.kt @@ -214,6 +214,22 @@ class TimetableItemDetailScreenTest(private val testCase: DescribedBehavior