Adding unit tests for RoomPollDetailMapper

This commit is contained in:
Maxime NATUREL 2023-02-03 18:01:09 +01:00
parent 055ed35fa6
commit 0a2b1f8ad1
4 changed files with 259 additions and 46 deletions

View File

@ -27,7 +27,6 @@ import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
import timber.log.Timber
import javax.inject.Inject
// TODO add unit tests
class RoomPollDetailMapper @Inject constructor(
private val pollResponseDataFactory: PollResponseDataFactory,
private val pollItemViewStateFactory: PollItemViewStateFactory,

View File

@ -0,0 +1,186 @@
/*
* 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 im.vector.app.features.roomprofile.polls.detail.ui
import im.vector.app.features.home.room.detail.timeline.factory.PollItemViewStateFactory
import im.vector.app.features.home.room.detail.timeline.helper.PollResponseDataFactory
import im.vector.app.features.poll.PollItemViewState
import im.vector.app.features.roomprofile.polls.detail.domain.GetEndedPollEventIdUseCase
import im.vector.app.test.fixtures.RoomPollFixture
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkStatic
import io.mockk.unmockkAll
import org.amshove.kluent.shouldBe
import org.amshove.kluent.shouldBeEqualTo
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.matrix.android.sdk.api.session.room.model.message.MessageTextContent
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
private const val AN_EVENT_ID = "event-id"
private const val A_ROOM_ID = "room-id"
private const val AN_EVENT_TIMESTAMP = 123L
internal class RoomPollDetailMapperTest {
private val fakePollResponseDataFactory = mockk<PollResponseDataFactory>()
private val fakePollItemViewStateFactory = mockk<PollItemViewStateFactory>()
private val fakeGetEndedPollEventIdUseCase = mockk<GetEndedPollEventIdUseCase>()
private val roomPollDetailMapper = RoomPollDetailMapper(
pollResponseDataFactory = fakePollResponseDataFactory,
pollItemViewStateFactory = fakePollItemViewStateFactory,
getEndedPollEventIdUseCase = fakeGetEndedPollEventIdUseCase,
)
@Before
fun setup() {
mockkStatic("im.vector.app.core.extensions.TimelineEventKt")
}
@After
fun tearDown() {
unmockkAll()
}
@Test
fun `given a not ended poll event when mapping to model then result contains correct poll details`() {
// Given
val aPollItemViewState = givenAPollItemViewState()
val aPollEvent = givenAPollTimelineEvent(
eventId = AN_EVENT_ID,
creationTimestamp = AN_EVENT_TIMESTAMP,
isClosed = false,
pollItemViewState = aPollItemViewState,
)
val expectedResult = RoomPollDetail(
creationTimestamp = AN_EVENT_TIMESTAMP,
isEnded = false,
endedPollEventId = null,
pollItemViewState = aPollItemViewState,
)
// When
val result = roomPollDetailMapper.map(aPollEvent)
// Then
result shouldBeEqualTo expectedResult
}
@Test
fun `given an ended poll event when mapping to model then result contains correct poll details`() {
// Given
val aPollItemViewState = givenAPollItemViewState()
val aPollEvent = givenAPollTimelineEvent(
eventId = AN_EVENT_ID,
creationTimestamp = AN_EVENT_TIMESTAMP,
isClosed = true,
pollItemViewState = aPollItemViewState,
)
val endedPollEventId = givenEndedPollEventId()
val expectedResult = RoomPollDetail(
creationTimestamp = AN_EVENT_TIMESTAMP,
isEnded = true,
endedPollEventId = endedPollEventId,
pollItemViewState = aPollItemViewState,
)
// When
val result = roomPollDetailMapper.map(aPollEvent)
// Then
result shouldBeEqualTo expectedResult
}
@Test
fun `given missing data in event when mapping to model then result is null`() {
// Given
val aPollItemViewState = givenAPollItemViewState()
val noIdPollEvent = givenAPollTimelineEvent(
eventId = "",
creationTimestamp = AN_EVENT_TIMESTAMP,
isClosed = false,
pollItemViewState = aPollItemViewState,
)
val noTimestampPollEvent = givenAPollTimelineEvent(
eventId = AN_EVENT_ID,
creationTimestamp = 0,
isClosed = false,
pollItemViewState = aPollItemViewState,
)
val notAPollEvent = RoomPollFixture.givenATimelineEvent(
eventId = AN_EVENT_ID,
roomId = "room-id",
creationTimestamp = 0,
content = mockk<MessageTextContent>(),
)
// When
val result1 = roomPollDetailMapper.map(noIdPollEvent)
val result2 = roomPollDetailMapper.map(noTimestampPollEvent)
val result3 = roomPollDetailMapper.map(notAPollEvent)
// Then
result1 shouldBe null
result2 shouldBe null
result3 shouldBe null
}
private fun givenAPollItemViewState(): PollItemViewState {
return PollItemViewState(
question = "",
votesStatus = "",
canVote = true,
optionViewStates = emptyList(),
)
}
private fun givenAPollTimelineEvent(
eventId: String,
creationTimestamp: Long,
isClosed: Boolean,
pollItemViewState: PollItemViewState,
): TimelineEvent {
val pollCreationInfo = RoomPollFixture.givenPollCreationInfo("pollTitle")
val messageContent = RoomPollFixture.givenAMessagePollContent(pollCreationInfo)
val timelineEvent = RoomPollFixture.givenATimelineEvent(eventId, A_ROOM_ID, creationTimestamp, messageContent)
val pollResponseData = RoomPollFixture.givenAPollResponseData(isClosed, totalVotes = 1)
every { fakePollResponseDataFactory.create(timelineEvent) } returns pollResponseData
every {
fakePollItemViewStateFactory.create(
pollContent = messageContent,
pollResponseData = pollResponseData,
isSent = true
)
} returns pollItemViewState
return timelineEvent
}
private fun givenEndedPollEventId(): String {
val eventId = "ended-poll-event-id"
every {
fakeGetEndedPollEventIdUseCase.execute(
startPollEventId = AN_EVENT_ID,
roomId = A_ROOM_ID,
)
} returns eventId
return eventId
}
}

View File

@ -16,11 +16,10 @@
package im.vector.app.features.roomprofile.polls.list.ui
import im.vector.app.core.extensions.getVectorLastMessageContent
import im.vector.app.features.home.room.detail.timeline.factory.PollOptionViewStateFactory
import im.vector.app.features.home.room.detail.timeline.helper.PollResponseDataFactory
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.test.fixtures.RoomPollFixture
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkStatic
@ -30,11 +29,7 @@ import org.amshove.kluent.shouldBeEqualTo
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent
import org.matrix.android.sdk.api.session.room.model.message.MessageTextContent
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.timeline.TimelineEvent
private const val AN_EVENT_ID = "event-id"
@ -128,10 +123,11 @@ internal class PollSummaryMapperTest {
pollTitle = A_POLL_TITLE,
isClosed = false,
)
val notAPollEvent = givenATimelineEvent(
val notAPollEvent = RoomPollFixture.givenATimelineEvent(
eventId = AN_EVENT_ID,
roomId = "room-id",
creationTimestamp = 0,
content = mockk<MessageTextContent>()
content = mockk<MessageTextContent>(),
)
// When
@ -145,18 +141,6 @@ internal class PollSummaryMapperTest {
result3 shouldBe null
}
private fun givenATimelineEvent(
eventId: String,
creationTimestamp: Long,
content: MessageContent,
): TimelineEvent {
val timelineEvent = mockk<TimelineEvent>()
every { timelineEvent.root.eventId } returns eventId
every { timelineEvent.root.originServerTs } returns creationTimestamp
every { timelineEvent.getVectorLastMessageContent() } returns content
return timelineEvent
}
private fun givenAPollTimelineEvent(
eventId: String,
creationTimestamp: Long,
@ -165,10 +149,10 @@ internal class PollSummaryMapperTest {
totalVotes: Int = 0,
winnerOptions: List<PollOptionViewState.PollEnded> = emptyList(),
): TimelineEvent {
val pollCreationInfo = givenPollCreationInfo(pollTitle)
val messageContent = givenAMessagePollContent(pollCreationInfo)
val timelineEvent = givenATimelineEvent(eventId, creationTimestamp, messageContent)
val pollResponseData = givenAPollResponseData(isClosed, totalVotes)
val pollCreationInfo = RoomPollFixture.givenPollCreationInfo(pollTitle)
val messageContent = RoomPollFixture.givenAMessagePollContent(pollCreationInfo)
val timelineEvent = RoomPollFixture.givenATimelineEvent(eventId, "room-id", creationTimestamp, messageContent)
val pollResponseData = RoomPollFixture.givenAPollResponseData(isClosed, totalVotes)
every { fakePollResponseDataFactory.create(timelineEvent) } returns pollResponseData
every {
fakePollOptionViewStateFactory.createPollEndedOptions(
@ -180,27 +164,6 @@ internal class PollSummaryMapperTest {
return timelineEvent
}
private fun givenAMessagePollContent(pollCreationInfo: PollCreationInfo): MessagePollContent {
return MessagePollContent(
unstablePollCreationInfo = pollCreationInfo,
)
}
private fun givenPollCreationInfo(pollTitle: String): PollCreationInfo {
return PollCreationInfo(
question = PollQuestion(unstableQuestion = pollTitle),
)
}
private fun givenAPollResponseData(isClosed: Boolean, totalVotes: Int): PollResponseData {
return PollResponseData(
myVote = "",
votes = emptyMap(),
isClosed = isClosed,
totalVotes = totalVotes,
)
}
private fun givenAPollEndedOption(isWinner: Boolean): PollOptionViewState.PollEnded {
return mockk<PollOptionViewState.PollEnded>().also {
every { it.isWinner } returns isWinner

View File

@ -0,0 +1,65 @@
/*
* 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 im.vector.app.test.fixtures
import im.vector.app.core.extensions.getVectorLastMessageContent
import im.vector.app.features.home.room.detail.timeline.item.PollResponseData
import io.mockk.every
import io.mockk.mockk
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent
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.timeline.TimelineEvent
object RoomPollFixture {
fun givenATimelineEvent(
eventId: String,
roomId: String,
creationTimestamp: Long,
content: MessageContent,
): TimelineEvent {
val timelineEvent = mockk<TimelineEvent>()
every { timelineEvent.root.eventId } returns eventId
every { timelineEvent.roomId } returns roomId
every { timelineEvent.root.originServerTs } returns creationTimestamp
every { timelineEvent.getVectorLastMessageContent() } returns content
return timelineEvent
}
fun givenAMessagePollContent(pollCreationInfo: PollCreationInfo): MessagePollContent {
return MessagePollContent(
unstablePollCreationInfo = pollCreationInfo,
)
}
fun givenPollCreationInfo(pollTitle: String): PollCreationInfo {
return PollCreationInfo(
question = PollQuestion(unstableQuestion = pollTitle),
)
}
fun givenAPollResponseData(isClosed: Boolean, totalVotes: Int): PollResponseData {
return PollResponseData(
myVote = "",
votes = emptyMap(),
isClosed = isClosed,
totalVotes = totalVotes,
)
}
}