Skip to content

Commit 65b9490

Browse files
author
Maxime NATUREL
committed
Introducing a use case to check if a message can have reply action
1 parent abea685 commit 65b9490

File tree

3 files changed

+179
-16
lines changed

3 files changed

+179
-16
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright (c) 2022 New Vector Ltd
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package im.vector.app.features.home.room.detail.timeline.action
18+
19+
import org.matrix.android.sdk.api.session.events.model.EventType
20+
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
21+
import org.matrix.android.sdk.api.session.room.model.message.MessageType
22+
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
23+
import javax.inject.Inject
24+
25+
class CheckIfCanReplyEventUseCase @Inject constructor() {
26+
27+
fun execute(event: TimelineEvent, messageContent: MessageContent?, actionPermissions: ActionPermissions): Boolean {
28+
// Only EventType.MESSAGE, EventType.POLL_START and EventType.STATE_ROOM_BEACON_INFO event types are supported for the moment
29+
if (event.root.getClearType() !in EventType.STATE_ROOM_BEACON_INFO + EventType.POLL_START + EventType.MESSAGE) return false
30+
if (!actionPermissions.canSendMessage) return false
31+
return when (messageContent?.msgType) {
32+
MessageType.MSGTYPE_TEXT,
33+
MessageType.MSGTYPE_NOTICE,
34+
MessageType.MSGTYPE_EMOTE,
35+
MessageType.MSGTYPE_IMAGE,
36+
MessageType.MSGTYPE_VIDEO,
37+
MessageType.MSGTYPE_AUDIO,
38+
MessageType.MSGTYPE_FILE,
39+
MessageType.MSGTYPE_POLL_START,
40+
MessageType.MSGTYPE_BEACON_INFO,
41+
MessageType.MSGTYPE_LOCATION -> true
42+
else -> false
43+
}
44+
}
45+
}

vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ class MessageActionsViewModel @AssistedInject constructor(
8080
private val errorFormatter: ErrorFormatter,
8181
private val stringProvider: StringProvider,
8282
private val pillsPostProcessorFactory: PillsPostProcessor.Factory,
83-
private val vectorPreferences: VectorPreferences
83+
private val vectorPreferences: VectorPreferences,
84+
private val checkIfCanReplyEventUseCase: CheckIfCanReplyEventUseCase,
8485
) : VectorViewModel<MessageActionState, MessageActionsAction, EmptyViewEvents>(initialState) {
8586

8687
private val informationData = initialState.informationData
@@ -436,21 +437,7 @@ class MessageActionsViewModel @AssistedInject constructor(
436437
}
437438

438439
private fun canReply(event: TimelineEvent, messageContent: MessageContent?, actionPermissions: ActionPermissions): Boolean {
439-
// Only EventType.MESSAGE and EventType.POLL_START event types are supported for the moment
440-
if (event.root.getClearType() !in EventType.POLL_START + EventType.MESSAGE) return false
441-
if (!actionPermissions.canSendMessage) return false
442-
return when (messageContent?.msgType) {
443-
MessageType.MSGTYPE_TEXT,
444-
MessageType.MSGTYPE_NOTICE,
445-
MessageType.MSGTYPE_EMOTE,
446-
MessageType.MSGTYPE_IMAGE,
447-
MessageType.MSGTYPE_VIDEO,
448-
MessageType.MSGTYPE_AUDIO,
449-
MessageType.MSGTYPE_FILE,
450-
MessageType.MSGTYPE_POLL_START,
451-
MessageType.MSGTYPE_LOCATION -> true
452-
else -> false
453-
}
440+
return checkIfCanReplyEventUseCase.execute(event, messageContent, actionPermissions)
454441
}
455442

456443
/**
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/*
2+
* Copyright (c) 2022 New Vector Ltd
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package im.vector.app.features.home.room.detail.timeline.action
18+
19+
import io.mockk.every
20+
import io.mockk.mockk
21+
import org.amshove.kluent.shouldBeEqualTo
22+
import org.junit.Test
23+
import org.matrix.android.sdk.api.session.events.model.Event
24+
import org.matrix.android.sdk.api.session.events.model.EventType
25+
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
26+
import org.matrix.android.sdk.api.session.room.model.message.MessageType
27+
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
28+
29+
class CheckIfCanReplyEventUseCaseTest {
30+
31+
private val checkIfCanReplyEventUseCase = CheckIfCanReplyEventUseCase()
32+
33+
@Test
34+
fun `given sending message is not allowed when use case is executed then result is false`() {
35+
val event = givenAnEvent(eventType = EventType.MESSAGE)
36+
val messageContent = givenAMessageContent(MessageType.MSGTYPE_AUDIO)
37+
val actionPermissions = givenActionPermissions(canSendMessage = false)
38+
39+
val result = checkIfCanReplyEventUseCase.execute(event, messageContent, actionPermissions)
40+
41+
result shouldBeEqualTo false
42+
}
43+
44+
@Test
45+
fun `given reply is allowed for the event type when use case is executed then result is true`() {
46+
val eventTypes = EventType.STATE_ROOM_BEACON_INFO + EventType.POLL_START + EventType.MESSAGE
47+
48+
eventTypes.forEach { eventType ->
49+
val event = givenAnEvent(eventType)
50+
val messageContent = givenAMessageContent(MessageType.MSGTYPE_AUDIO)
51+
val actionPermissions = givenActionPermissions(canSendMessage = true)
52+
53+
val result = checkIfCanReplyEventUseCase.execute(event, messageContent, actionPermissions)
54+
55+
result shouldBeEqualTo true
56+
}
57+
}
58+
59+
@Test
60+
fun `given reply is not allowed for the event type when use case is executed then result is false`() {
61+
val event = givenAnEvent(EventType.CALL_ANSWER)
62+
val messageContent = givenAMessageContent(MessageType.MSGTYPE_AUDIO)
63+
val actionPermissions = givenActionPermissions(canSendMessage = true)
64+
65+
val result = checkIfCanReplyEventUseCase.execute(event, messageContent, actionPermissions)
66+
67+
result shouldBeEqualTo false
68+
}
69+
70+
@Test
71+
fun `given reply is allowed for the message type when use case is executed then result is true`() {
72+
val messageTypes = listOf(
73+
MessageType.MSGTYPE_TEXT,
74+
MessageType.MSGTYPE_NOTICE,
75+
MessageType.MSGTYPE_EMOTE,
76+
MessageType.MSGTYPE_IMAGE,
77+
MessageType.MSGTYPE_VIDEO,
78+
MessageType.MSGTYPE_AUDIO,
79+
MessageType.MSGTYPE_FILE,
80+
MessageType.MSGTYPE_POLL_START,
81+
MessageType.MSGTYPE_BEACON_INFO,
82+
MessageType.MSGTYPE_LOCATION
83+
)
84+
85+
messageTypes.forEach { messageType ->
86+
val event = givenAnEvent(EventType.MESSAGE)
87+
val messageContent = givenAMessageContent(messageType)
88+
val actionPermissions = givenActionPermissions(canSendMessage = true)
89+
90+
val result = checkIfCanReplyEventUseCase.execute(event, messageContent, actionPermissions)
91+
92+
result shouldBeEqualTo true
93+
}
94+
}
95+
96+
@Test
97+
fun `given reply is not allowed for the message type when use case is executed then result is false`() {
98+
val event = givenAnEvent(EventType.MESSAGE)
99+
val messageContent = givenAMessageContent(MessageType.MSGTYPE_BEACON_LOCATION_DATA)
100+
val actionPermissions = givenActionPermissions(canSendMessage = true)
101+
102+
val result = checkIfCanReplyEventUseCase.execute(event, messageContent, actionPermissions)
103+
104+
result shouldBeEqualTo false
105+
}
106+
107+
private fun givenAnEvent(eventType: String): TimelineEvent {
108+
val eventId = "event-id"
109+
return TimelineEvent(
110+
root = Event(
111+
eventId = eventId,
112+
type = eventType
113+
),
114+
localId = 123L,
115+
eventId = eventId,
116+
displayIndex = 1,
117+
ownedByThreadChunk = false,
118+
senderInfo = mockk()
119+
)
120+
}
121+
122+
private fun givenAMessageContent(messageType: String): MessageContent {
123+
return mockk<MessageContent>().also {
124+
every { it.msgType } returns messageType
125+
}
126+
}
127+
128+
private fun givenActionPermissions(canSendMessage: Boolean): ActionPermissions {
129+
return ActionPermissions(canSendMessage = canSendMessage)
130+
}
131+
}

0 commit comments

Comments
 (0)