Browse Source

Merge pull request #2518 from element-hq/feature/bma/testPollHistoryView

Test poll history view
pull/2531/head
Benoit Marty 6 months ago committed by GitHub
parent
commit
b237f28895
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationView.kt
  2. 7
      features/poll/api/src/main/kotlin/io/element/android/features/poll/api/pollcontent/PollContentStateFixtures.kt
  3. 8
      features/poll/impl/build.gradle.kts
  4. 28
      features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryStateProvider.kt
  5. 192
      features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/history/PollHistoryViewTest.kt
  6. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.impl.history_PollHistoryView_null_PollHistoryView-Day-1_2_null_2,NEXUS_5,1.0,en].png
  7. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.impl.history_PollHistoryView_null_PollHistoryView-Day-1_2_null_3,NEXUS_5,1.0,en].png
  8. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.impl.history_PollHistoryView_null_PollHistoryView-Night-1_3_null_2,NEXUS_5,1.0,en].png
  9. BIN
      tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.impl.history_PollHistoryView_null_PollHistoryView-Night-1_3_null_3,NEXUS_5,1.0,en].png

2
features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationView.kt

@ -142,7 +142,7 @@ fun SendLocationView(
lon = cameraPositionState.position.target!!.longitude, lon = cameraPositionState.position.target!!.longitude,
zoom = cameraPositionState.position.zoom, zoom = cameraPositionState.position.zoom,
), ),
cameraPositionState.location?.let { location = cameraPositionState.location?.let {
Location( Location(
lat = it.latitude, lat = it.latitude,
lon = it.longitude, lon = it.longitude,

7
features/poll/api/src/main/kotlin/io/element/android/features/poll/api/pollcontent/PollContentStateFixtures.kt

@ -16,6 +16,7 @@
package io.element.android.features.poll.api.pollcontent package io.element.android.features.poll.api.pollcontent
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.poll.PollAnswer import io.element.android.libraries.matrix.api.poll.PollAnswer
import io.element.android.libraries.matrix.api.poll.PollKind import io.element.android.libraries.matrix.api.poll.PollKind
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
@ -83,9 +84,11 @@ fun aPollAnswerItem(
) )
fun aPollContentState( fun aPollContentState(
eventId: EventId? = null,
isMine: Boolean = false, isMine: Boolean = false,
isEnded: Boolean = false, isEnded: Boolean = false,
isDisclosed: Boolean = true, isDisclosed: Boolean = true,
isPollEditable: Boolean = true,
hasVotes: Boolean = true, hasVotes: Boolean = true,
question: String = aPollQuestion(), question: String = aPollQuestion(),
pollKind: PollKind = PollKind.Disclosed, pollKind: PollKind = PollKind.Disclosed,
@ -95,11 +98,11 @@ fun aPollContentState(
hasVotes = hasVotes hasVotes = hasVotes
), ),
) = PollContentState( ) = PollContentState(
eventId = null, eventId = eventId,
question = question, question = question,
answerItems = answerItems, answerItems = answerItems,
pollKind = pollKind, pollKind = pollKind,
isPollEditable = isMine && !isEnded, isPollEditable = isMine && !isEnded && isPollEditable,
isPollEnded = isEnded, isPollEnded = isEnded,
isMine = isMine, isMine = isMine,
) )

8
features/poll/impl/build.gradle.kts

@ -23,6 +23,11 @@ plugins {
android { android {
namespace = "io.element.android.features.poll.impl" namespace = "io.element.android.features.poll.impl"
testOptions {
unitTests {
isIncludeAndroidResources = true
}
}
} }
anvil { anvil {
@ -48,12 +53,15 @@ dependencies {
testImplementation(libs.molecule.runtime) testImplementation(libs.molecule.runtime)
testImplementation(libs.test.truth) testImplementation(libs.test.truth)
testImplementation(libs.test.turbine) testImplementation(libs.test.turbine)
testImplementation(libs.test.robolectric)
testImplementation(projects.libraries.matrix.test) testImplementation(projects.libraries.matrix.test)
testImplementation(projects.services.analytics.test) testImplementation(projects.services.analytics.test)
testImplementation(projects.features.messages.test) testImplementation(projects.features.messages.test)
testImplementation(projects.tests.testutils) testImplementation(projects.tests.testutils)
testImplementation(projects.libraries.dateformatter.test) testImplementation(projects.libraries.dateformatter.test)
testImplementation(projects.features.poll.test) testImplementation(projects.features.poll.test)
testImplementation(libs.androidx.compose.ui.test.junit)
testReleaseImplementation(libs.androidx.compose.ui.test.manifest)
ksp(libs.showkase.processor) ksp(libs.showkase.processor)
} }

28
features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryStateProvider.kt

@ -22,44 +22,48 @@ import io.element.android.features.poll.api.pollcontent.aPollContentState
import io.element.android.features.poll.impl.history.model.PollHistoryFilter import io.element.android.features.poll.impl.history.model.PollHistoryFilter
import io.element.android.features.poll.impl.history.model.PollHistoryItem import io.element.android.features.poll.impl.history.model.PollHistoryItem
import io.element.android.features.poll.impl.history.model.PollHistoryItems import io.element.android.features.poll.impl.history.model.PollHistoryItems
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toPersistentList
import kotlinx.collections.immutable.persistentListOf
class PollHistoryStateProvider : PreviewParameterProvider<PollHistoryState> { class PollHistoryStateProvider : PreviewParameterProvider<PollHistoryState> {
override val values: Sequence<PollHistoryState> override val values: Sequence<PollHistoryState>
get() = sequenceOf( get() = sequenceOf(
aPollHistoryState(),
aPollHistoryState(
isLoading = true,
hasMoreToLoad = true,
activeFilter = PollHistoryFilter.PAST,
),
aPollHistoryState( aPollHistoryState(
isLoading = false,
hasMoreToLoad = false,
activeFilter = PollHistoryFilter.ONGOING, activeFilter = PollHistoryFilter.ONGOING,
currentItems = emptyList(),
), ),
aPollHistoryState( aPollHistoryState(
isLoading = true,
hasMoreToLoad = true,
activeFilter = PollHistoryFilter.PAST, activeFilter = PollHistoryFilter.PAST,
currentItems = emptyList(),
), ),
) )
} }
private fun aPollHistoryState( internal fun aPollHistoryState(
isLoading: Boolean = false, isLoading: Boolean = false,
hasMoreToLoad: Boolean = false, hasMoreToLoad: Boolean = false,
activeFilter: PollHistoryFilter = PollHistoryFilter.ONGOING, activeFilter: PollHistoryFilter = PollHistoryFilter.ONGOING,
currentItems: ImmutableList<PollHistoryItem> = persistentListOf( currentItems: List<PollHistoryItem> = listOf(
aPollHistoryItem(), aPollHistoryItem(),
), ),
eventSink: (PollHistoryEvents) -> Unit = {},
) = PollHistoryState( ) = PollHistoryState(
isLoading = isLoading, isLoading = isLoading,
hasMoreToLoad = hasMoreToLoad, hasMoreToLoad = hasMoreToLoad,
activeFilter = activeFilter, activeFilter = activeFilter,
pollHistoryItems = PollHistoryItems( pollHistoryItems = PollHistoryItems(
ongoing = currentItems, ongoing = currentItems.toPersistentList(),
past = currentItems, past = currentItems.toPersistentList(),
), ),
eventSink = {}, eventSink = eventSink,
) )
private fun aPollHistoryItem( internal fun aPollHistoryItem(
formattedDate: String = "01/12/2023", formattedDate: String = "01/12/2023",
state: PollContentState = aPollContentState(), state: PollContentState = aPollContentState(),
) = PollHistoryItem( ) = PollHistoryItem(

192
features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/history/PollHistoryViewTest.kt

@ -0,0 +1,192 @@
/*
* Copyright (c) 2024 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.features.poll.impl.history
import androidx.activity.ComponentActivity
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.element.android.features.poll.api.pollcontent.aPollContentState
import io.element.android.features.poll.impl.R
import io.element.android.features.poll.impl.history.model.PollHistoryFilter
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.ui.strings.CommonStrings
import io.element.android.tests.testutils.EnsureNeverCalled
import io.element.android.tests.testutils.EnsureNeverCalledWithParam
import io.element.android.tests.testutils.EventsRecorder
import io.element.android.tests.testutils.clickOn
import io.element.android.tests.testutils.ensureCalledOnce
import io.element.android.tests.testutils.ensureCalledOnceWithParam
import io.element.android.tests.testutils.pressBack
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TestRule
import org.junit.runner.RunWith
import org.robolectric.annotation.Config
@RunWith(AndroidJUnit4::class)
class PollHistoryViewTest {
@get:Rule
val rule = createAndroidComposeRule<ComponentActivity>()
@Test
fun `clicking on back invokes the expected callback`() {
val eventsRecorder = EventsRecorder<PollHistoryEvents>(expectEvents = false)
ensureCalledOnce {
rule.setPollHistoryViewView(
aPollHistoryState(
eventSink = eventsRecorder
),
goBack = it
)
rule.pressBack()
}
}
@Config(qualifiers = "h1024dp")
@Test
fun `clicking on edit poll invokes the expected callback`() {
val eventsRecorder = EventsRecorder<PollHistoryEvents>(expectEvents = false)
val eventId = EventId("\$anEventId")
val state = aPollHistoryState(
currentItems = listOf(
aPollHistoryItem(
state = aPollContentState(
eventId = eventId,
isMine = true,
isEnded = false,
)
)
),
eventSink = eventsRecorder
)
ensureCalledOnceWithParam(eventId) {
rule.setPollHistoryViewView(
state = state,
onEditPoll = it
)
rule.clickOn(CommonStrings.action_edit_poll)
}
}
@Config(qualifiers = "h1024dp")
@Test
fun `clicking on poll end emits the expected Event`() {
val eventsRecorder = EventsRecorder<PollHistoryEvents>()
val eventId = EventId("\$anEventId")
val state = aPollHistoryState(
currentItems = listOf(
aPollHistoryItem(
state = aPollContentState(
eventId = eventId,
isMine = true,
isEnded = false,
isPollEditable = false,
)
)
),
eventSink = eventsRecorder
)
rule.setPollHistoryViewView(
state = state,
)
rule.clickOn(CommonStrings.action_end_poll)
// Cancel the dialog
rule.clickOn(CommonStrings.action_cancel)
// Do it again, and confirm the dialog
rule.clickOn(CommonStrings.action_end_poll)
eventsRecorder.assertEmpty()
rule.clickOn(CommonStrings.action_ok)
eventsRecorder.assertSingle(
PollHistoryEvents.PollEndClicked(eventId)
)
}
@Config(qualifiers = "h1024dp")
@Test
fun `clicking on poll answer emits the expected Event`() {
val eventsRecorder = EventsRecorder<PollHistoryEvents>()
val eventId = EventId("\$anEventId")
val state = aPollHistoryState(
currentItems = listOf(
aPollHistoryItem(
state = aPollContentState(
eventId = eventId,
isMine = true,
isEnded = false,
isPollEditable = false,
)
)
),
eventSink = eventsRecorder
)
val answer = state.pollHistoryItems.ongoing.first().state.answerItems.first().answer
rule.setPollHistoryViewView(
state = state,
)
rule.onNodeWithText(answer.text).performClick()
eventsRecorder.assertSingle(
PollHistoryEvents.PollAnswerSelected(eventId, answer.id)
)
}
@Test
fun `clicking on past tab emits the expected Event`() {
val eventsRecorder = EventsRecorder<PollHistoryEvents>()
rule.setPollHistoryViewView(
aPollHistoryState(
eventSink = eventsRecorder
),
)
rule.clickOn(R.string.screen_polls_history_filter_past)
eventsRecorder.assertSingle(
PollHistoryEvents.OnFilterSelected(filter = PollHistoryFilter.PAST)
)
}
@Config(qualifiers = "h1024dp")
@Test
fun `clicking on load more emits the expected Event`() {
val eventsRecorder = EventsRecorder<PollHistoryEvents>()
rule.setPollHistoryViewView(
aPollHistoryState(
hasMoreToLoad = true,
eventSink = eventsRecorder,
),
)
rule.clickOn(CommonStrings.action_load_more)
eventsRecorder.assertSingle(
PollHistoryEvents.LoadMore
)
}
}
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setPollHistoryViewView(
state: PollHistoryState,
onEditPoll: (EventId) -> Unit = EnsureNeverCalledWithParam(),
goBack: () -> Unit = EnsureNeverCalled(),
) {
setContent {
PollHistoryView(
state = state,
onEditPoll = onEditPoll,
goBack = goBack,
)
}
}

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.impl.history_PollHistoryView_null_PollHistoryView-Day-1_2_null_2,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.impl.history_PollHistoryView_null_PollHistoryView-Day-1_2_null_3,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.impl.history_PollHistoryView_null_PollHistoryView-Night-1_3_null_2,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/ui_S_t[f.poll.impl.history_PollHistoryView_null_PollHistoryView-Night-1_3_null_3,NEXUS_5,1.0,en].png (Stored with Git LFS)

Binary file not shown.
Loading…
Cancel
Save