PollHistoryView: add UI test.
This commit is contained in:
parent
3b6d148eb6
commit
44836cb4d0
4 changed files with 209 additions and 5 deletions
|
|
@ -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,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,13 +44,14 @@ class PollHistoryStateProvider : PreviewParameterProvider<PollHistoryState> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
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: List<PollHistoryItem> = listOf(
|
currentItems: List<PollHistoryItem> = listOf(
|
||||||
aPollHistoryItem(),
|
aPollHistoryItem(),
|
||||||
),
|
),
|
||||||
|
eventSink: (PollHistoryEvents) -> Unit = {},
|
||||||
) = PollHistoryState(
|
) = PollHistoryState(
|
||||||
isLoading = isLoading,
|
isLoading = isLoading,
|
||||||
hasMoreToLoad = hasMoreToLoad,
|
hasMoreToLoad = hasMoreToLoad,
|
||||||
|
|
@ -59,10 +60,10 @@ private fun aPollHistoryState(
|
||||||
ongoing = currentItems.toPersistentList(),
|
ongoing = currentItems.toPersistentList(),
|
||||||
past = currentItems.toPersistentList(),
|
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(
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue