Merge pull request #6366 from vector-im/feature/ons/poll_view_state_unit_tests
Poll view state unit tests [PSF-1130]
This commit is contained in:
commit
a398391908
|
@ -0,0 +1 @@
|
|||
Poll view state unit tests
|
|
@ -25,4 +25,7 @@ data class PollCreationInfo(
|
|||
@Json(name = "kind") val kind: PollType? = PollType.DISCLOSED_UNSTABLE,
|
||||
@Json(name = "max_selections") val maxSelections: Int = 1,
|
||||
@Json(name = "answers") val answers: List<PollAnswer>? = null
|
||||
)
|
||||
) {
|
||||
|
||||
fun isUndisclosed() = kind in listOf(PollType.UNDISCLOSED_UNSTABLE, PollType.UNDISCLOSED)
|
||||
}
|
||||
|
|
|
@ -59,12 +59,6 @@ import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceItem
|
|||
import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceItem_
|
||||
import im.vector.app.features.home.room.detail.timeline.item.PollItem
|
||||
import im.vector.app.features.home.room.detail.timeline.item.PollItem_
|
||||
import im.vector.app.features.home.room.detail.timeline.item.PollOptionViewState.PollEnded
|
||||
import im.vector.app.features.home.room.detail.timeline.item.PollOptionViewState.PollReady
|
||||
import im.vector.app.features.home.room.detail.timeline.item.PollOptionViewState.PollSending
|
||||
import im.vector.app.features.home.room.detail.timeline.item.PollOptionViewState.PollUndisclosed
|
||||
import im.vector.app.features.home.room.detail.timeline.item.PollOptionViewState.PollVoted
|
||||
import im.vector.app.features.home.room.detail.timeline.item.PollResponseData
|
||||
import im.vector.app.features.home.room.detail.timeline.item.RedactedMessageItem
|
||||
import im.vector.app.features.home.room.detail.timeline.item.RedactedMessageItem_
|
||||
import im.vector.app.features.home.room.detail.timeline.item.VerificationRequestItem
|
||||
|
@ -81,18 +75,11 @@ import im.vector.app.features.location.UrlMapProvider
|
|||
import im.vector.app.features.location.toLocationData
|
||||
import im.vector.app.features.media.ImageContentRenderer
|
||||
import im.vector.app.features.media.VideoContentRenderer
|
||||
import im.vector.app.features.poll.PollState
|
||||
import im.vector.app.features.poll.PollState.Ended
|
||||
import im.vector.app.features.poll.PollState.Ready
|
||||
import im.vector.app.features.poll.PollState.Sending
|
||||
import im.vector.app.features.poll.PollState.Undisclosed
|
||||
import im.vector.app.features.poll.PollState.Voted
|
||||
import im.vector.app.features.settings.VectorPreferences
|
||||
import im.vector.app.features.voice.AudioWaveformView
|
||||
import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence
|
||||
import me.gujun.android.span.span
|
||||
import org.matrix.android.sdk.api.MatrixUrls.isMxcUrl
|
||||
import org.matrix.android.sdk.api.extensions.orFalse
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.crypto.attachments.toElementToDecrypt
|
||||
import org.matrix.android.sdk.api.session.events.model.RelationType
|
||||
|
@ -113,8 +100,6 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageTextContent
|
|||
import org.matrix.android.sdk.api.session.room.model.message.MessageType
|
||||
import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationRequestContent
|
||||
import org.matrix.android.sdk.api.session.room.model.message.MessageVideoContent
|
||||
import org.matrix.android.sdk.api.session.room.model.message.PollAnswer
|
||||
import org.matrix.android.sdk.api.session.room.model.message.PollType
|
||||
import org.matrix.android.sdk.api.session.room.model.message.getFileUrl
|
||||
import org.matrix.android.sdk.api.session.room.model.message.getThumbnailUrl
|
||||
import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent
|
||||
|
@ -149,6 +134,7 @@ class MessageItemFactory @Inject constructor(
|
|||
private val vectorPreferences: VectorPreferences,
|
||||
private val urlMapProvider: UrlMapProvider,
|
||||
private val liveLocationShareMessageItemFactory: LiveLocationShareMessageItemFactory,
|
||||
private val pollItemViewStateFactory: PollItemViewStateFactory,
|
||||
) {
|
||||
|
||||
// TODO inject this properly?
|
||||
|
@ -251,62 +237,21 @@ class MessageItemFactory @Inject constructor(
|
|||
callback: TimelineEventController.Callback?,
|
||||
attributes: AbsMessageItem.Attributes,
|
||||
): PollItem {
|
||||
val pollResponseSummary = informationData.pollResponseAggregatedSummary
|
||||
val pollState = createPollState(informationData, pollResponseSummary, pollContent)
|
||||
val pollCreationInfo = pollContent.getBestPollCreationInfo()
|
||||
val questionText = pollCreationInfo?.question?.getBestQuestion().orEmpty()
|
||||
val question = createPollQuestion(informationData, questionText, callback)
|
||||
val optionViewStates = pollCreationInfo?.answers?.mapToOptions(pollState, informationData)
|
||||
val totalVotesText = createTotalVotesText(pollState, pollResponseSummary)
|
||||
val pollViewState = pollItemViewStateFactory.create(pollContent, informationData)
|
||||
|
||||
return PollItem_()
|
||||
.attributes(attributes)
|
||||
.eventId(informationData.eventId)
|
||||
.pollQuestion(question)
|
||||
.canVote(pollState.isVotable())
|
||||
.totalVotesText(totalVotesText)
|
||||
.optionViewStates(optionViewStates)
|
||||
.pollQuestion(createPollQuestion(informationData, pollViewState.question, callback))
|
||||
.canVote(pollViewState.canVote)
|
||||
.totalVotesText(pollViewState.totalVotes)
|
||||
.optionViewStates(pollViewState.optionViewStates)
|
||||
.edited(informationData.hasBeenEdited)
|
||||
.highlighted(highlight)
|
||||
.leftGuideline(avatarSizeProvider.leftGuideline)
|
||||
.callback(callback)
|
||||
}
|
||||
|
||||
private fun createPollState(
|
||||
informationData: MessageInformationData,
|
||||
pollResponseSummary: PollResponseData?,
|
||||
pollContent: MessagePollContent,
|
||||
): PollState = when {
|
||||
!informationData.sendState.isSent() -> Sending
|
||||
pollResponseSummary?.isClosed.orFalse() -> Ended
|
||||
pollContent.getBestPollCreationInfo()?.kind == PollType.UNDISCLOSED -> Undisclosed
|
||||
pollResponseSummary?.myVote?.isNotEmpty().orFalse() -> Voted(pollResponseSummary?.totalVotes ?: 0)
|
||||
else -> Ready
|
||||
}
|
||||
|
||||
private fun List<PollAnswer>.mapToOptions(
|
||||
pollState: PollState,
|
||||
informationData: MessageInformationData,
|
||||
) = map { answer ->
|
||||
val pollResponseSummary = informationData.pollResponseAggregatedSummary
|
||||
val winnerVoteCount = pollResponseSummary?.winnerVoteCount
|
||||
val optionId = answer.id ?: ""
|
||||
val optionAnswer = answer.getBestAnswer() ?: ""
|
||||
val voteSummary = pollResponseSummary?.votes?.get(answer.id)
|
||||
val voteCount = voteSummary?.total ?: 0
|
||||
val votePercentage = voteSummary?.percentage ?: 0.0
|
||||
val isMyVote = pollResponseSummary?.myVote == answer.id
|
||||
val isWinner = winnerVoteCount != 0 && voteCount == winnerVoteCount
|
||||
|
||||
when (pollState) {
|
||||
Sending -> PollSending(optionId, optionAnswer)
|
||||
Ready -> PollReady(optionId, optionAnswer)
|
||||
is Voted -> PollVoted(optionId, optionAnswer, voteCount, votePercentage, isMyVote)
|
||||
Undisclosed -> PollUndisclosed(optionId, optionAnswer, isMyVote)
|
||||
Ended -> PollEnded(optionId, optionAnswer, voteCount, votePercentage, isWinner)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createPollQuestion(
|
||||
informationData: MessageInformationData,
|
||||
question: String,
|
||||
|
@ -317,20 +262,6 @@ class MessageItemFactory @Inject constructor(
|
|||
question
|
||||
}.toEpoxyCharSequence()
|
||||
|
||||
private fun createTotalVotesText(
|
||||
pollState: PollState,
|
||||
pollResponseSummary: PollResponseData?,
|
||||
): String {
|
||||
val votes = pollResponseSummary?.totalVotes ?: 0
|
||||
return when {
|
||||
pollState is Ended -> stringProvider.getQuantityString(R.plurals.poll_total_vote_count_after_ended, votes, votes)
|
||||
pollState is Undisclosed -> ""
|
||||
pollState is Voted -> stringProvider.getQuantityString(R.plurals.poll_total_vote_count_before_ended_and_voted, votes, votes)
|
||||
votes == 0 -> stringProvider.getString(R.string.poll_no_votes_cast)
|
||||
else -> stringProvider.getQuantityString(R.plurals.poll_total_vote_count_before_ended_and_not_voted, votes, votes)
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildAudioMessageItem(
|
||||
params: TimelineItemFactoryParams,
|
||||
messageContent: MessageAudioContent,
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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 im.vector.app.features.home.room.detail.timeline.factory
|
||||
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData
|
||||
import im.vector.app.features.home.room.detail.timeline.item.PollOptionViewState
|
||||
import im.vector.app.features.home.room.detail.timeline.item.PollResponseData
|
||||
import im.vector.app.features.poll.PollViewState
|
||||
import org.matrix.android.sdk.api.extensions.orFalse
|
||||
import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent
|
||||
import org.matrix.android.sdk.api.session.room.model.message.PollCreationInfo
|
||||
import javax.inject.Inject
|
||||
|
||||
class PollItemViewStateFactory @Inject constructor(
|
||||
private val stringProvider: StringProvider,
|
||||
) {
|
||||
|
||||
fun create(
|
||||
pollContent: MessagePollContent,
|
||||
informationData: MessageInformationData,
|
||||
): PollViewState {
|
||||
val pollCreationInfo = pollContent.getBestPollCreationInfo()
|
||||
|
||||
val question = pollCreationInfo?.question?.getBestQuestion().orEmpty()
|
||||
|
||||
val pollResponseSummary = informationData.pollResponseAggregatedSummary
|
||||
val winnerVoteCount = pollResponseSummary?.winnerVoteCount
|
||||
val totalVotes = pollResponseSummary?.totalVotes ?: 0
|
||||
|
||||
return when {
|
||||
!informationData.sendState.isSent() -> {
|
||||
createSendingPollViewState(question, pollCreationInfo)
|
||||
}
|
||||
informationData.pollResponseAggregatedSummary?.isClosed.orFalse() -> {
|
||||
createEndedPollViewState(question, pollCreationInfo, pollResponseSummary, totalVotes, winnerVoteCount)
|
||||
}
|
||||
pollContent.getBestPollCreationInfo()?.isUndisclosed().orFalse() -> {
|
||||
createUndisclosedPollViewState(question, pollCreationInfo, pollResponseSummary)
|
||||
}
|
||||
informationData.pollResponseAggregatedSummary?.myVote?.isNotEmpty().orFalse() -> {
|
||||
createVotedPollViewState(question, pollCreationInfo, pollResponseSummary, totalVotes)
|
||||
}
|
||||
else -> {
|
||||
createReadyPollViewState(question, pollCreationInfo, totalVotes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createSendingPollViewState(question: String, pollCreationInfo: PollCreationInfo?): PollViewState {
|
||||
return PollViewState(
|
||||
question = question,
|
||||
totalVotes = stringProvider.getString(R.string.poll_no_votes_cast),
|
||||
canVote = false,
|
||||
optionViewStates = pollCreationInfo?.answers?.map { answer ->
|
||||
PollOptionViewState.PollSending(
|
||||
optionId = answer.id ?: "",
|
||||
optionAnswer = answer.getBestAnswer() ?: ""
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun createEndedPollViewState(
|
||||
question: String,
|
||||
pollCreationInfo: PollCreationInfo?,
|
||||
pollResponseSummary: PollResponseData?,
|
||||
totalVotes: Int,
|
||||
winnerVoteCount: Int?,
|
||||
): PollViewState {
|
||||
return PollViewState(
|
||||
question = question,
|
||||
totalVotes = stringProvider.getQuantityString(R.plurals.poll_total_vote_count_after_ended, totalVotes, totalVotes),
|
||||
canVote = false,
|
||||
optionViewStates = pollCreationInfo?.answers?.map { answer ->
|
||||
val voteSummary = pollResponseSummary?.getVoteSummaryOfAnOption(answer.id ?: "")
|
||||
PollOptionViewState.PollEnded(
|
||||
optionId = answer.id ?: "",
|
||||
optionAnswer = answer.getBestAnswer() ?: "",
|
||||
voteCount = voteSummary?.total ?: 0,
|
||||
votePercentage = voteSummary?.percentage ?: 0.0,
|
||||
isWinner = winnerVoteCount != 0 && voteSummary?.total == winnerVoteCount
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun createUndisclosedPollViewState(
|
||||
question: String,
|
||||
pollCreationInfo: PollCreationInfo?,
|
||||
pollResponseSummary: PollResponseData?
|
||||
): PollViewState {
|
||||
return PollViewState(
|
||||
question = question,
|
||||
totalVotes = "",
|
||||
canVote = true,
|
||||
optionViewStates = pollCreationInfo?.answers?.map { answer ->
|
||||
val isMyVote = pollResponseSummary?.myVote == answer.id
|
||||
PollOptionViewState.PollUndisclosed(
|
||||
optionId = answer.id ?: "",
|
||||
optionAnswer = answer.getBestAnswer() ?: "",
|
||||
isSelected = isMyVote
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun createVotedPollViewState(
|
||||
question: String,
|
||||
pollCreationInfo: PollCreationInfo?,
|
||||
pollResponseSummary: PollResponseData?,
|
||||
totalVotes: Int
|
||||
): PollViewState {
|
||||
return PollViewState(
|
||||
question = question,
|
||||
totalVotes = stringProvider.getQuantityString(R.plurals.poll_total_vote_count_before_ended_and_voted, totalVotes, totalVotes),
|
||||
canVote = true,
|
||||
optionViewStates = pollCreationInfo?.answers?.map { answer ->
|
||||
val isMyVote = pollResponseSummary?.myVote == answer.id
|
||||
val voteSummary = pollResponseSummary?.getVoteSummaryOfAnOption(answer.id ?: "")
|
||||
PollOptionViewState.PollVoted(
|
||||
optionId = answer.id ?: "",
|
||||
optionAnswer = answer.getBestAnswer() ?: "",
|
||||
voteCount = voteSummary?.total ?: 0,
|
||||
votePercentage = voteSummary?.percentage ?: 0.0,
|
||||
isSelected = isMyVote
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun createReadyPollViewState(question: String, pollCreationInfo: PollCreationInfo?, totalVotes: Int): PollViewState {
|
||||
val totalVotesText = if (totalVotes == 0) {
|
||||
stringProvider.getString(R.string.poll_no_votes_cast)
|
||||
} else {
|
||||
stringProvider.getQuantityString(R.plurals.poll_total_vote_count_before_ended_and_not_voted, totalVotes, totalVotes)
|
||||
}
|
||||
return PollViewState(
|
||||
question = question,
|
||||
totalVotes = totalVotesText,
|
||||
canVote = true,
|
||||
optionViewStates = pollCreationInfo?.answers?.map { answer ->
|
||||
PollOptionViewState.PollReady(
|
||||
optionId = answer.id ?: "",
|
||||
optionAnswer = answer.getBestAnswer() ?: ""
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
|
@ -91,7 +91,10 @@ data class PollResponseData(
|
|||
val totalVotes: Int = 0,
|
||||
val winnerVoteCount: Int = 0,
|
||||
val isClosed: Boolean = false
|
||||
) : Parcelable
|
||||
) : Parcelable {
|
||||
|
||||
fun getVoteSummaryOfAnOption(optionId: String) = votes?.get(optionId)
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
data class PollVoteSummaryData(
|
||||
|
|
|
@ -16,12 +16,11 @@
|
|||
|
||||
package im.vector.app.features.poll
|
||||
|
||||
sealed interface PollState {
|
||||
object Sending : PollState
|
||||
object Ready : PollState
|
||||
data class Voted(val votes: Int) : PollState
|
||||
object Undisclosed : PollState
|
||||
object Ended : PollState
|
||||
import im.vector.app.features.home.room.detail.timeline.item.PollOptionViewState
|
||||
|
||||
fun isVotable() = this !is Sending && this !is Ended
|
||||
}
|
||||
data class PollViewState(
|
||||
val question: String,
|
||||
val totalVotes: String,
|
||||
val canVote: Boolean,
|
||||
val optionViewStates: List<PollOptionViewState>?,
|
||||
)
|
|
@ -0,0 +1,223 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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 im.vector.app.features.home.room.detail.timeline.factory
|
||||
|
||||
import im.vector.app.R
|
||||
import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData
|
||||
import im.vector.app.features.home.room.detail.timeline.item.PollOptionViewState
|
||||
import im.vector.app.features.home.room.detail.timeline.item.PollResponseData
|
||||
import im.vector.app.features.home.room.detail.timeline.item.PollVoteSummaryData
|
||||
import im.vector.app.features.home.room.detail.timeline.item.ReactionsSummaryData
|
||||
import im.vector.app.features.home.room.detail.timeline.style.TimelineMessageLayout
|
||||
import im.vector.app.features.poll.PollViewState
|
||||
import im.vector.app.test.fakes.FakeStringProvider
|
||||
import org.amshove.kluent.shouldBeEqualTo
|
||||
import org.junit.Test
|
||||
import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent
|
||||
import org.matrix.android.sdk.api.session.room.model.message.PollAnswer
|
||||
import org.matrix.android.sdk.api.session.room.model.message.PollCreationInfo
|
||||
import org.matrix.android.sdk.api.session.room.model.message.PollQuestion
|
||||
import org.matrix.android.sdk.api.session.room.model.message.PollType
|
||||
import org.matrix.android.sdk.api.session.room.send.SendState
|
||||
|
||||
private val A_MESSAGE_INFORMATION_DATA = MessageInformationData(
|
||||
eventId = "eventId",
|
||||
senderId = "senderId",
|
||||
ageLocalTS = 0,
|
||||
avatarUrl = "",
|
||||
sendState = SendState.SENT,
|
||||
messageLayout = TimelineMessageLayout.Default(showAvatar = true, showDisplayName = true, showTimestamp = true),
|
||||
reactionsSummary = ReactionsSummaryData(),
|
||||
sentByMe = true,
|
||||
)
|
||||
|
||||
private val A_POLL_RESPONSE_DATA = PollResponseData(
|
||||
myVote = null,
|
||||
votes = emptyMap(),
|
||||
)
|
||||
|
||||
private val A_POLL_OPTION_IDS = listOf("5ef5f7b0-c9a1-49cf-a0b3-374729a43e76", "ec1a4db0-46d8-4d7a-9bb6-d80724715938", "3677ca8e-061b-40ab-bffe-b22e4e88fcad")
|
||||
|
||||
private val A_POLL_CONTENT = MessagePollContent(
|
||||
unstablePollCreationInfo = PollCreationInfo(
|
||||
question = PollQuestion(
|
||||
unstableQuestion = "What is your favourite coffee?"
|
||||
),
|
||||
kind = PollType.UNDISCLOSED_UNSTABLE,
|
||||
maxSelections = 1,
|
||||
answers = listOf(
|
||||
PollAnswer(
|
||||
id = A_POLL_OPTION_IDS[0],
|
||||
unstableAnswer = "Double Espresso"
|
||||
),
|
||||
PollAnswer(
|
||||
id = A_POLL_OPTION_IDS[1],
|
||||
unstableAnswer = "Macchiato"
|
||||
),
|
||||
PollAnswer(
|
||||
id = A_POLL_OPTION_IDS[2],
|
||||
unstableAnswer = "Iced Coffee"
|
||||
),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
class PollItemViewStateFactoryTest {
|
||||
|
||||
@Test
|
||||
fun `given a sending poll state then poll is not votable and option states are PollSending`() {
|
||||
val stringProvider = FakeStringProvider()
|
||||
val pollItemViewStateFactory = PollItemViewStateFactory(stringProvider.instance)
|
||||
|
||||
val sendingPollInformationData = A_MESSAGE_INFORMATION_DATA.copy(sendState = SendState.SENDING)
|
||||
val pollViewState = pollItemViewStateFactory.create(
|
||||
pollContent = A_POLL_CONTENT,
|
||||
informationData = sendingPollInformationData,
|
||||
)
|
||||
|
||||
pollViewState shouldBeEqualTo PollViewState(
|
||||
question = A_POLL_CONTENT.getBestPollCreationInfo()?.question?.getBestQuestion() ?: "",
|
||||
totalVotes = stringProvider.instance.getString(R.string.poll_no_votes_cast),
|
||||
canVote = false,
|
||||
optionViewStates = A_POLL_CONTENT.getBestPollCreationInfo()?.answers?.map { answer ->
|
||||
PollOptionViewState.PollSending(
|
||||
optionId = answer.id ?: "",
|
||||
optionAnswer = answer.getBestAnswer() ?: ""
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given a sent poll state when poll is closed then poll is not votable and option states are Ended`() {
|
||||
val stringProvider = FakeStringProvider()
|
||||
val pollItemViewStateFactory = PollItemViewStateFactory(stringProvider.instance)
|
||||
|
||||
val closedPollSummary = A_POLL_RESPONSE_DATA.copy(isClosed = true)
|
||||
val closedPollInformationData = A_MESSAGE_INFORMATION_DATA.copy(pollResponseAggregatedSummary = closedPollSummary)
|
||||
|
||||
val pollViewState = pollItemViewStateFactory.create(
|
||||
pollContent = A_POLL_CONTENT,
|
||||
informationData = closedPollInformationData,
|
||||
)
|
||||
|
||||
pollViewState shouldBeEqualTo PollViewState(
|
||||
question = A_POLL_CONTENT.getBestPollCreationInfo()?.question?.getBestQuestion() ?: "",
|
||||
totalVotes = stringProvider.instance.getQuantityString(R.plurals.poll_total_vote_count_after_ended, 0, 0),
|
||||
canVote = false,
|
||||
optionViewStates = A_POLL_CONTENT.getBestPollCreationInfo()?.answers?.map { answer ->
|
||||
PollOptionViewState.PollEnded(
|
||||
optionId = answer.id ?: "",
|
||||
optionAnswer = answer.getBestAnswer() ?: "",
|
||||
voteCount = 0,
|
||||
votePercentage = 0.0,
|
||||
isWinner = false
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given a sent poll when undisclosed poll type is selected then poll is votable and option states are PollUndisclosed`() {
|
||||
val stringProvider = FakeStringProvider()
|
||||
val pollItemViewStateFactory = PollItemViewStateFactory(stringProvider.instance)
|
||||
|
||||
val pollViewState = pollItemViewStateFactory.create(
|
||||
pollContent = A_POLL_CONTENT,
|
||||
informationData = A_MESSAGE_INFORMATION_DATA,
|
||||
)
|
||||
|
||||
pollViewState shouldBeEqualTo PollViewState(
|
||||
question = A_POLL_CONTENT.getBestPollCreationInfo()?.question?.getBestQuestion() ?: "",
|
||||
totalVotes = "",
|
||||
canVote = true,
|
||||
optionViewStates = A_POLL_CONTENT.getBestPollCreationInfo()?.answers?.map { answer ->
|
||||
PollOptionViewState.PollUndisclosed(
|
||||
optionId = answer.id ?: "",
|
||||
optionAnswer = answer.getBestAnswer() ?: "",
|
||||
isSelected = false
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given a sent poll when my vote exists then poll is still votable and options states are PollVoted`() {
|
||||
val stringProvider = FakeStringProvider()
|
||||
val pollItemViewStateFactory = PollItemViewStateFactory(stringProvider.instance)
|
||||
|
||||
val votedPollData = A_POLL_RESPONSE_DATA.copy(
|
||||
totalVotes = 1,
|
||||
myVote = A_POLL_OPTION_IDS[0],
|
||||
votes = mapOf(A_POLL_OPTION_IDS[0] to PollVoteSummaryData(total = 1, percentage = 1.0))
|
||||
)
|
||||
val disclosedPollContent = A_POLL_CONTENT.copy(
|
||||
unstablePollCreationInfo = A_POLL_CONTENT.getBestPollCreationInfo()?.copy(
|
||||
kind = PollType.DISCLOSED_UNSTABLE
|
||||
),
|
||||
)
|
||||
val votedInformationData = A_MESSAGE_INFORMATION_DATA.copy(pollResponseAggregatedSummary = votedPollData)
|
||||
|
||||
val pollViewState = pollItemViewStateFactory.create(
|
||||
pollContent = disclosedPollContent,
|
||||
informationData = votedInformationData,
|
||||
)
|
||||
|
||||
pollViewState shouldBeEqualTo PollViewState(
|
||||
question = A_POLL_CONTENT.getBestPollCreationInfo()?.question?.getBestQuestion() ?: "",
|
||||
totalVotes = stringProvider.instance.getQuantityString(R.plurals.poll_total_vote_count_before_ended_and_voted, 1, 1),
|
||||
canVote = true,
|
||||
optionViewStates = A_POLL_CONTENT.getBestPollCreationInfo()?.answers?.mapIndexed { index, answer ->
|
||||
PollOptionViewState.PollVoted(
|
||||
optionId = answer.id ?: "",
|
||||
optionAnswer = answer.getBestAnswer() ?: "",
|
||||
voteCount = if (index == 0) 1 else 0,
|
||||
votePercentage = if (index == 0) 1.0 else 0.0,
|
||||
isSelected = index == 0
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given a sent poll when poll type is disclosed then poll is votable and option view states are PollReady`() {
|
||||
val stringProvider = FakeStringProvider()
|
||||
val pollItemViewStateFactory = PollItemViewStateFactory(stringProvider.instance)
|
||||
|
||||
val disclosedPollContent = A_POLL_CONTENT.copy(
|
||||
unstablePollCreationInfo = A_POLL_CONTENT.getBestPollCreationInfo()?.copy(
|
||||
kind = PollType.DISCLOSED_UNSTABLE
|
||||
)
|
||||
)
|
||||
val pollViewState = pollItemViewStateFactory.create(
|
||||
pollContent = disclosedPollContent,
|
||||
informationData = A_MESSAGE_INFORMATION_DATA,
|
||||
)
|
||||
|
||||
pollViewState shouldBeEqualTo PollViewState(
|
||||
question = A_POLL_CONTENT.getBestPollCreationInfo()?.question?.getBestQuestion() ?: "",
|
||||
totalVotes = stringProvider.instance.getString(R.string.poll_no_votes_cast),
|
||||
canVote = true,
|
||||
optionViewStates = A_POLL_CONTENT.getBestPollCreationInfo()?.answers?.map { answer ->
|
||||
PollOptionViewState.PollReady(
|
||||
optionId = answer.id ?: "",
|
||||
optionAnswer = answer.getBestAnswer() ?: ""
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
|
@ -27,6 +27,10 @@ class FakeStringProvider {
|
|||
every { instance.getString(any()) } answers {
|
||||
"test-${args[0]}"
|
||||
}
|
||||
|
||||
every { instance.getQuantityString(any(), any(), any()) } answers {
|
||||
"test-${args[0]}-${args[1]}"
|
||||
}
|
||||
}
|
||||
|
||||
fun given(id: Int, result: String) {
|
||||
|
|
Loading…
Reference in New Issue