Poll history : add tests and fix others
This commit is contained in:
parent
8f1e1398f2
commit
6378f6cffe
17 changed files with 831 additions and 529 deletions
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2023 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
|
||||
|
||||
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.timeline.MatrixTimelineItem
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.PollContent
|
||||
import io.element.android.libraries.matrix.test.timeline.FakeMatrixTimeline
|
||||
import io.element.android.libraries.matrix.test.timeline.aPollContent
|
||||
import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
fun aPollTimeline(
|
||||
polls: Map<EventId, PollContent> = emptyMap(),
|
||||
): FakeMatrixTimeline {
|
||||
return FakeMatrixTimeline(
|
||||
initialTimelineItems = polls.map { entry ->
|
||||
MatrixTimelineItem.Event(
|
||||
entry.key.hashCode().toLong(),
|
||||
anEventTimelineItem(
|
||||
eventId = entry.key,
|
||||
content = entry.value,
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun anOngoingPollContent() = aPollContent(
|
||||
question = "Do you like polls?",
|
||||
answers = persistentListOf(
|
||||
PollAnswer("1", "Yes"),
|
||||
PollAnswer("2", "No"),
|
||||
PollAnswer("2", "Maybe"),
|
||||
),
|
||||
)
|
||||
|
||||
fun anEndedPollContent() = anOngoingPollContent().copy(
|
||||
endTime = 1702400215U
|
||||
)
|
||||
|
|
@ -25,21 +25,17 @@ import im.vector.app.features.analytics.plan.Composer
|
|||
import im.vector.app.features.analytics.plan.PollCreation
|
||||
import io.element.android.features.messages.test.FakeMessageComposerContext
|
||||
import io.element.android.features.poll.api.create.CreatePollMode
|
||||
import io.element.android.features.poll.impl.aPollTimeline
|
||||
import io.element.android.features.poll.impl.anOngoingPollContent
|
||||
import io.element.android.features.poll.impl.data.PollRepository
|
||||
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.room.MatrixRoom
|
||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.PollContent
|
||||
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
||||
import io.element.android.libraries.matrix.test.room.SavePollInvocation
|
||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||
import io.element.android.libraries.matrix.test.room.aPollContent
|
||||
import io.element.android.libraries.matrix.test.room.anEventTimelineItem
|
||||
import io.element.android.libraries.matrix.test.timeline.FakeMatrixTimeline
|
||||
import io.element.android.libraries.matrix.test.room.SavePollInvocation
|
||||
import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
|
|
@ -52,8 +48,12 @@ class CreatePollPresenterTest {
|
|||
|
||||
private val pollEventId = AN_EVENT_ID
|
||||
private var navUpInvocationsCount = 0
|
||||
private val existingPoll = anExistingPoll()
|
||||
private val fakeMatrixRoom = createFakeMatrixRoom(existingPoll)
|
||||
private val existingPoll = anOngoingPollContent()
|
||||
private val fakeMatrixRoom = FakeMatrixRoom(
|
||||
matrixTimeline = aPollTimeline(
|
||||
mapOf(pollEventId to existingPoll)
|
||||
)
|
||||
)
|
||||
private val fakeAnalyticsService = FakeAnalyticsService()
|
||||
private val fakeMessageComposerContext = FakeMessageComposerContext()
|
||||
|
||||
|
|
@ -80,7 +80,9 @@ class CreatePollPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `in edit mode, if poll doesn't exist, error is tracked and screen is closed`() = runTest {
|
||||
val room = createFakeMatrixRoom(existingPoll = null)
|
||||
val room = FakeMatrixRoom(
|
||||
matrixTimeline = aPollTimeline()
|
||||
)
|
||||
val presenter = createCreatePollPresenter(mode = CreatePollMode.EditPoll(AN_EVENT_ID), room = room)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -475,7 +477,6 @@ class CreatePollPresenterTest {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private suspend fun TurbineTestContext<CreatePollState>.awaitDefaultItem() =
|
||||
awaitItem().apply {
|
||||
Truth.assertThat(canSave).isFalse()
|
||||
|
|
@ -518,35 +519,8 @@ class CreatePollPresenterTest {
|
|||
navigateUp = { navUpInvocationsCount++ },
|
||||
mode = mode,
|
||||
)
|
||||
|
||||
private fun createFakeMatrixRoom(
|
||||
existingPoll: PollContent? = anExistingPoll(),
|
||||
) = FakeMatrixRoom(
|
||||
matrixTimeline = FakeMatrixTimeline(
|
||||
initialTimelineItems = existingPoll?.let {
|
||||
listOf(
|
||||
MatrixTimelineItem.Event(
|
||||
0,
|
||||
anEventTimelineItem(
|
||||
eventId = pollEventId,
|
||||
content = it,
|
||||
)
|
||||
)
|
||||
)
|
||||
}.orEmpty()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun anExistingPoll() = aPollContent(
|
||||
question = "Do you like polls?",
|
||||
answers = persistentListOf(
|
||||
PollAnswer("1", "Yes"),
|
||||
PollAnswer("2", "No"),
|
||||
PollAnswer("2", "Maybe"),
|
||||
),
|
||||
)
|
||||
|
||||
private fun PollContent.expectedAnswersState() = answers.map { answer ->
|
||||
Answer(
|
||||
text = answer.text,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* Copyright (c) 2023 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 app.cash.molecule.RecompositionMode
|
||||
import app.cash.molecule.moleculeFlow
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.features.poll.api.actions.EndPollAction
|
||||
import io.element.android.features.poll.api.actions.SendPollResponseAction
|
||||
import io.element.android.features.poll.impl.aPollTimeline
|
||||
import io.element.android.features.poll.impl.anEndedPollContent
|
||||
import io.element.android.features.poll.impl.anOngoingPollContent
|
||||
import io.element.android.features.poll.impl.history.model.PollHistoryFilter
|
||||
import io.element.android.features.poll.impl.history.model.PollHistoryItemsFactory
|
||||
import io.element.android.features.poll.impl.model.DefaultPollContentStateFactory
|
||||
import io.element.android.features.poll.test.actions.FakeEndPollAction
|
||||
import io.element.android.features.poll.test.actions.FakeSendPollResponseAction
|
||||
import io.element.android.libraries.dateformatter.test.FakeDaySeparatorFormatter
|
||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
||||
import io.element.android.libraries.matrix.test.AN_EVENT_ID_2
|
||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import io.element.android.tests.testutils.consumeItemsUntilPredicate
|
||||
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.runCurrent
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
class PollHistoryPresenterTest {
|
||||
|
||||
@get:Rule
|
||||
val warmUpRule = WarmUpRule()
|
||||
|
||||
private val room = FakeMatrixRoom(
|
||||
matrixTimeline = aPollTimeline(
|
||||
polls = mapOf(
|
||||
AN_EVENT_ID to anOngoingPollContent(),
|
||||
AN_EVENT_ID_2 to anEndedPollContent()
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `present - initial states`() = runTest {
|
||||
val presenter = createPollHistoryPresenter(room = room)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
awaitItem().also { state ->
|
||||
assertThat(state.activeFilter).isEqualTo(PollHistoryFilter.ONGOING)
|
||||
assertThat(state.pollHistoryItems.size).isEqualTo(0)
|
||||
assertThat(state.isLoading).isTrue()
|
||||
assertThat(state.hasMoreToLoad).isTrue()
|
||||
}
|
||||
consumeItemsUntilPredicate {
|
||||
it.pollHistoryItems.size == 2
|
||||
}.last().also { state ->
|
||||
assertThat(state.pollHistoryItems.size).isEqualTo(2)
|
||||
assertThat(state.pollHistoryItems.ongoing).hasSize(1)
|
||||
assertThat(state.pollHistoryItems.past).hasSize(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - change filter scenario`() = runTest {
|
||||
val presenter = createPollHistoryPresenter(room = room)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
awaitItem().also { state ->
|
||||
assertThat(state.activeFilter).isEqualTo(PollHistoryFilter.ONGOING)
|
||||
state.eventSink(PollHistoryEvents.OnFilterSelected(PollHistoryFilter.PAST))
|
||||
}
|
||||
consumeItemsUntilPredicate {
|
||||
it.activeFilter == PollHistoryFilter.PAST
|
||||
}.last().also { state ->
|
||||
state.eventSink(PollHistoryEvents.OnFilterSelected(PollHistoryFilter.ONGOING))
|
||||
}
|
||||
consumeItemsUntilPredicate {
|
||||
it.activeFilter == PollHistoryFilter.ONGOING
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Test
|
||||
fun `present - poll actions scenario`() = runTest {
|
||||
val sendPollResponseAction = FakeSendPollResponseAction()
|
||||
val endPollAction = FakeEndPollAction()
|
||||
val presenter = createPollHistoryPresenter(
|
||||
sendPollResponseAction = sendPollResponseAction,
|
||||
endPollAction = endPollAction
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val state = awaitItem()
|
||||
state.eventSink(PollHistoryEvents.PollEndClicked(AN_EVENT_ID))
|
||||
runCurrent()
|
||||
endPollAction.verifyExecutionCount(1)
|
||||
state.eventSink(PollHistoryEvents.PollAnswerSelected(AN_EVENT_ID, "answer"))
|
||||
runCurrent()
|
||||
sendPollResponseAction.verifyExecutionCount(1)
|
||||
cancelAndConsumeRemainingEvents()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - load more scenario`() = runTest {
|
||||
val presenter = createPollHistoryPresenter(room = room)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
consumeItemsUntilPredicate {
|
||||
it.pollHistoryItems.size == 2 && !it.isLoading
|
||||
}.last().also { state ->
|
||||
state.eventSink(PollHistoryEvents.LoadMore)
|
||||
}
|
||||
consumeItemsUntilPredicate {
|
||||
it.isLoading
|
||||
}
|
||||
consumeItemsUntilPredicate {
|
||||
!it.isLoading
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun TestScope.createPollHistoryPresenter(
|
||||
room: MatrixRoom = FakeMatrixRoom(),
|
||||
appCoroutineScope: CoroutineScope = this,
|
||||
endPollAction: EndPollAction = FakeEndPollAction(),
|
||||
sendPollResponseAction: SendPollResponseAction = FakeSendPollResponseAction(),
|
||||
pollHistoryItemFactory: PollHistoryItemsFactory = PollHistoryItemsFactory(
|
||||
pollContentStateFactory = DefaultPollContentStateFactory(FakeMatrixClient()),
|
||||
daySeparatorFormatter = FakeDaySeparatorFormatter(),
|
||||
dispatchers = testCoroutineDispatchers(),
|
||||
),
|
||||
): PollHistoryPresenter {
|
||||
return PollHistoryPresenter(
|
||||
room = room,
|
||||
appCoroutineScope = appCoroutineScope,
|
||||
sendPollResponseAction = sendPollResponseAction,
|
||||
endPollAction = endPollAction,
|
||||
pollHistoryItemFactory = pollHistoryItemFactory,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,288 @@
|
|||
/*
|
||||
* Copyright (c) 2023 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.pollcontent
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.features.poll.api.pollcontent.PollAnswerItem
|
||||
import io.element.android.features.poll.api.pollcontent.PollContentState
|
||||
import io.element.android.features.poll.impl.model.DefaultPollContentStateFactory
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
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.timeline.item.event.PollContent
|
||||
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
||||
import io.element.android.libraries.matrix.test.A_USER_ID
|
||||
import io.element.android.libraries.matrix.test.A_USER_ID_10
|
||||
import io.element.android.libraries.matrix.test.A_USER_ID_2
|
||||
import io.element.android.libraries.matrix.test.A_USER_ID_3
|
||||
import io.element.android.libraries.matrix.test.A_USER_ID_4
|
||||
import io.element.android.libraries.matrix.test.A_USER_ID_5
|
||||
import io.element.android.libraries.matrix.test.A_USER_ID_6
|
||||
import io.element.android.libraries.matrix.test.A_USER_ID_7
|
||||
import io.element.android.libraries.matrix.test.A_USER_ID_8
|
||||
import io.element.android.libraries.matrix.test.A_USER_ID_9
|
||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||
import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.ImmutableMap
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.persistentMapOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableMap
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
||||
class PollContentStateFactoryTest {
|
||||
|
||||
private val factory = DefaultPollContentStateFactory(FakeMatrixClient())
|
||||
private val eventTimelineItem = anEventTimelineItem()
|
||||
|
||||
@Test
|
||||
fun `Disclosed poll - not ended, no votes`() = runTest {
|
||||
val state = factory.create(eventTimelineItem, aPollContent())
|
||||
val expectedState = aPollContentState()
|
||||
assertThat(state).isEqualTo(expectedState)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Disclosed poll - not ended, some votes, including one from current user`() = runTest {
|
||||
val votes = MY_USER_WINNING_VOTES.mapKeys { it.key.id }.toImmutableMap()
|
||||
val state = factory.create(
|
||||
eventTimelineItem, aPollContent(votes = votes)
|
||||
)
|
||||
val expectedState = aPollContentState(
|
||||
answerItems = listOf(
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_1, votesCount = 3, percentage = 0.3f),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_2, isSelected = true, votesCount = 6, percentage = 0.6f),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_3),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_4, votesCount = 1, percentage = 0.1f),
|
||||
)
|
||||
)
|
||||
assertThat(state).isEqualTo(expectedState)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Disclosed poll - ended, no votes, no winner`() = runTest {
|
||||
val state = factory.create(eventTimelineItem, aPollContent(endTime = 1UL))
|
||||
val expectedState = aPollContentState().let {
|
||||
it.copy(
|
||||
answerItems = it.answerItems.map { answerItem -> answerItem.copy(isEnabled = false) }.toImmutableList(),
|
||||
isPollEnded = true,
|
||||
)
|
||||
}
|
||||
assertThat(state).isEqualTo(expectedState)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Disclosed poll - ended, some votes, including one from current user (winner)`() = runTest {
|
||||
val votes = MY_USER_WINNING_VOTES.mapKeys { it.key.id }.toImmutableMap()
|
||||
val state = factory.create(
|
||||
eventTimelineItem, aPollContent(votes = votes, endTime = 1UL)
|
||||
)
|
||||
val expectedState = aPollContentState(
|
||||
answerItems = listOf(
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_1, isEnabled = false, votesCount = 3, percentage = 0.3f),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_2, isSelected = true, isEnabled = false, isWinner = true, votesCount = 6, percentage = 0.6f),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_3, isEnabled = false),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_4, isEnabled = false, votesCount = 1, percentage = 0.1f),
|
||||
),
|
||||
isEnded = true,
|
||||
)
|
||||
assertThat(state).isEqualTo(expectedState)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Disclosed poll - ended, some votes, including one from current user (not winner) and two winning votes`() = runTest {
|
||||
val votes = OTHER_WINNING_VOTES.mapKeys { it.key.id }.toImmutableMap()
|
||||
val state = factory.create(
|
||||
eventTimelineItem, aPollContent(votes = votes, endTime = 1UL)
|
||||
)
|
||||
val expectedState = aPollContentState(
|
||||
answerItems = listOf(
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_1, isEnabled = false, isWinner = true, votesCount = 4, percentage = 0.4f),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_2, isSelected = true, isEnabled = false, votesCount = 2, percentage = 0.2f),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_3, isEnabled = false),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_4, isEnabled = false, isWinner = true, votesCount = 4, percentage = 0.4f),
|
||||
),
|
||||
isEnded = true,
|
||||
)
|
||||
assertThat(state).isEqualTo(expectedState)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Undisclosed poll - not ended, no votes`() = runTest {
|
||||
val state = factory.create(eventTimelineItem, aPollContent(PollKind.Undisclosed))
|
||||
val expectedState = aPollContentState(pollKind = PollKind.Undisclosed).let {
|
||||
it.copy(
|
||||
answerItems = it.answerItems.map { answerItem -> answerItem.copy(isDisclosed = false) }.toImmutableList()
|
||||
)
|
||||
}
|
||||
assertThat(state).isEqualTo(expectedState)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Undisclosed poll - not ended, some votes, including one from current user`() = runTest {
|
||||
val votes = MY_USER_WINNING_VOTES.mapKeys { it.key.id }.toImmutableMap()
|
||||
val state = factory.create(
|
||||
eventTimelineItem, aPollContent(PollKind.Undisclosed, votes = votes)
|
||||
)
|
||||
val expectedState = aPollContentState(
|
||||
pollKind = PollKind.Undisclosed,
|
||||
answerItems = listOf(
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_1, isDisclosed = false, votesCount = 3, percentage = 0.3f),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_2, isDisclosed = false, isSelected = true, votesCount = 6, percentage = 0.6f),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_3, isDisclosed = false),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_4, isDisclosed = false, votesCount = 1, percentage = 0.1f),
|
||||
),
|
||||
)
|
||||
assertThat(state).isEqualTo(expectedState)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Undisclosed poll - ended, no votes, no winner`() = runTest {
|
||||
val state = factory.create(eventTimelineItem, aPollContent(PollKind.Undisclosed, endTime = 1UL))
|
||||
val expectedState = aPollContentState(
|
||||
isEnded = true,
|
||||
pollKind = PollKind.Undisclosed
|
||||
).let {
|
||||
it.copy(
|
||||
answerItems = it.answerItems.map { answerItem -> answerItem.copy(isDisclosed = true, isEnabled = false) }.toImmutableList(),
|
||||
)
|
||||
}
|
||||
assertThat(state).isEqualTo(expectedState)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Undisclosed poll - ended, some votes, including one from current user (winner)`() = runTest {
|
||||
val votes = MY_USER_WINNING_VOTES.mapKeys { it.key.id }.toImmutableMap()
|
||||
val state = factory.create(
|
||||
eventTimelineItem, aPollContent(PollKind.Undisclosed, votes = votes, endTime = 1UL)
|
||||
)
|
||||
val expectedState = aPollContentState(
|
||||
pollKind = PollKind.Undisclosed,
|
||||
answerItems = listOf(
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_1, isEnabled = false, votesCount = 3, percentage = 0.3f),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_2, isSelected = true, isEnabled = false, isWinner = true, votesCount = 6, percentage = 0.6f),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_3, isEnabled = false),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_4, isEnabled = false, votesCount = 1, percentage = 0.1f),
|
||||
),
|
||||
isEnded = true,
|
||||
)
|
||||
assertThat(state).isEqualTo(expectedState)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Undisclosed poll - ended, some votes, including one from current user (not winner) and two winning votes`() = runTest {
|
||||
val votes = OTHER_WINNING_VOTES.mapKeys { it.key.id }.toImmutableMap()
|
||||
val state = factory.create(
|
||||
eventTimelineItem, aPollContent(PollKind.Undisclosed, votes = votes, endTime = 1UL)
|
||||
)
|
||||
val expectedState = aPollContentState(
|
||||
pollKind = PollKind.Undisclosed,
|
||||
answerItems = listOf(
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_1, isEnabled = false, isWinner = true, votesCount = 4, percentage = 0.4f),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_2, isSelected = true, isEnabled = false, votesCount = 2, percentage = 0.2f),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_3, isEnabled = false),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_4, isEnabled = false, isWinner = true, votesCount = 4, percentage = 0.4f),
|
||||
),
|
||||
isEnded = true,
|
||||
)
|
||||
assertThat(state).isEqualTo(expectedState)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `eventId is populated`() = runTest {
|
||||
val state = factory.create(eventTimelineItem, aPollContent())
|
||||
assertThat(state.eventId).isEqualTo(eventTimelineItem.eventId)
|
||||
}
|
||||
|
||||
private fun aPollContent(
|
||||
pollKind: PollKind = PollKind.Disclosed,
|
||||
votes: ImmutableMap<String, ImmutableList<UserId>> = persistentMapOf(),
|
||||
endTime: ULong? = null,
|
||||
): PollContent = PollContent(
|
||||
question = A_POLL_QUESTION,
|
||||
kind = pollKind,
|
||||
maxSelections = 1UL,
|
||||
answers = persistentListOf(A_POLL_ANSWER_1, A_POLL_ANSWER_2, A_POLL_ANSWER_3, A_POLL_ANSWER_4),
|
||||
votes = votes,
|
||||
endTime = endTime,
|
||||
)
|
||||
|
||||
private fun aPollContentState(
|
||||
eventId: EventId? = AN_EVENT_ID,
|
||||
pollKind: PollKind = PollKind.Disclosed,
|
||||
answerItems: List<PollAnswerItem> = listOf(
|
||||
aPollAnswerItem(A_POLL_ANSWER_1),
|
||||
aPollAnswerItem(A_POLL_ANSWER_2),
|
||||
aPollAnswerItem(A_POLL_ANSWER_3),
|
||||
aPollAnswerItem(A_POLL_ANSWER_4),
|
||||
),
|
||||
isEnded: Boolean = false,
|
||||
isMine: Boolean = false,
|
||||
isEditable: Boolean = false,
|
||||
question: String = A_POLL_QUESTION,
|
||||
) = PollContentState(
|
||||
eventId = eventId,
|
||||
question = question,
|
||||
answerItems = answerItems.toImmutableList(),
|
||||
pollKind = pollKind,
|
||||
isMine = isMine,
|
||||
isPollEnded = isEnded,
|
||||
isPollEditable = isEditable,
|
||||
)
|
||||
|
||||
private fun aPollAnswerItem(
|
||||
answer: PollAnswer,
|
||||
isSelected: Boolean = false,
|
||||
isEnabled: Boolean = true,
|
||||
isWinner: Boolean = false,
|
||||
isDisclosed: Boolean = true,
|
||||
votesCount: Int = 0,
|
||||
percentage: Float = 0f,
|
||||
) = PollAnswerItem(
|
||||
answer = answer,
|
||||
isSelected = isSelected,
|
||||
isEnabled = isEnabled,
|
||||
isWinner = isWinner,
|
||||
isDisclosed = isDisclosed,
|
||||
votesCount = votesCount,
|
||||
percentage = percentage,
|
||||
)
|
||||
|
||||
private companion object TestData {
|
||||
private const val A_POLL_QUESTION = "What is your favorite food?"
|
||||
private val A_POLL_ANSWER_1 = PollAnswer("id_1", "Pizza")
|
||||
private val A_POLL_ANSWER_2 = PollAnswer("id_2", "Pasta")
|
||||
private val A_POLL_ANSWER_3 = PollAnswer("id_3", "French Fries")
|
||||
private val A_POLL_ANSWER_4 = PollAnswer("id_4", "Hamburger")
|
||||
|
||||
private val MY_USER_WINNING_VOTES = persistentMapOf(
|
||||
A_POLL_ANSWER_1 to persistentListOf(A_USER_ID_2, A_USER_ID_3, A_USER_ID_4),
|
||||
A_POLL_ANSWER_2 to persistentListOf(A_USER_ID /* my vote */, A_USER_ID_5, A_USER_ID_6, A_USER_ID_7, A_USER_ID_8, A_USER_ID_9), // winner
|
||||
A_POLL_ANSWER_3 to persistentListOf(),
|
||||
A_POLL_ANSWER_4 to persistentListOf(A_USER_ID_10),
|
||||
)
|
||||
private val OTHER_WINNING_VOTES = persistentMapOf(
|
||||
A_POLL_ANSWER_1 to persistentListOf(A_USER_ID_2, A_USER_ID_3, A_USER_ID_4, A_USER_ID_5), // winner
|
||||
A_POLL_ANSWER_2 to persistentListOf(A_USER_ID /* my vote */, A_USER_ID_6),
|
||||
A_POLL_ANSWER_3 to persistentListOf(),
|
||||
A_POLL_ANSWER_4 to persistentListOf(A_USER_ID_7, A_USER_ID_8, A_USER_ID_9, A_USER_ID_10), // winner
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue