From ce650b06fbebbad518d2447391be29947ee9dfcf Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 20 Sep 2024 11:23:42 +0200 Subject: [PATCH 1/2] Include sender name in notification for invite content. --- .../DefaultNotifiableEventResolver.kt | 9 +- .../impl/src/main/res/values/localazy.xml | 2 + .../DefaultNotifiableEventResolverTest.kt | 82 +++++++++++++++++-- 3 files changed, 84 insertions(+), 9 deletions(-) diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt index 19f9e1f356..283b28ab31 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt @@ -112,6 +112,7 @@ class DefaultNotifiableEventResolver @Inject constructor( ) } is NotificationContent.Invite -> { + val senderDisambiguatedDisplayName = getDisambiguatedDisplayName(content.senderId) InviteNotifiableEvent( sessionId = userId, roomId = roomId, @@ -124,8 +125,7 @@ class DefaultNotifiableEventResolver @Inject constructor( soundName = null, isRedacted = false, isUpdated = false, - // TODO We could use the senderId here - description = descriptionFromRoomMembershipInvite(isDirect), + description = descriptionFromRoomMembershipInvite(senderDisambiguatedDisplayName, isDirect), // TODO check if type is needed anymore type = null, // TODO check if title is needed anymore @@ -278,12 +278,13 @@ class DefaultNotifiableEventResolver @Inject constructor( } private fun descriptionFromRoomMembershipInvite( + senderDisambiguatedDisplayName: String, isDirectRoom: Boolean ): String { return if (isDirectRoom) { - stringProvider.getString(R.string.notification_invite_body) + stringProvider.getString(R.string.notification_invite_body_with_sender, senderDisambiguatedDisplayName) } else { - stringProvider.getString(R.string.notification_room_invite_body) + stringProvider.getString(R.string.notification_room_invite_body_with_sender, senderDisambiguatedDisplayName) } } diff --git a/libraries/push/impl/src/main/res/values/localazy.xml b/libraries/push/impl/src/main/res/values/localazy.xml index 5fed2718a1..f3d1e5392f 100644 --- a/libraries/push/impl/src/main/res/values/localazy.xml +++ b/libraries/push/impl/src/main/res/values/localazy.xml @@ -23,6 +23,7 @@ "%d invitations" "Invited you to chat" + "%1$s invited you to chat" "Mentioned you: %1$s" "New Messages" @@ -33,6 +34,7 @@ "Mark as read" "Quick reply" "Invited you to join the room" + "%1$s invited you to join the room" "Me" "%1$s mentioned or replied" "You are viewing the notification! Click me!" diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolverTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolverTest.kt index e41d26b943..7dc0eab13b 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolverTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolverTest.kt @@ -404,7 +404,7 @@ class DefaultNotifiableEventResolverTest { roomName = null, noisy = false, title = null, - description = "Invited you to join the room", + description = "Bob invited you to join the room", type = null, timestamp = A_TIMESTAMP, soundName = null, @@ -416,7 +416,7 @@ class DefaultNotifiableEventResolverTest { } @Test - fun `resolve invite invite direct`() = runTest { + fun `resolve invite direct`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( createNotificationData( @@ -438,7 +438,77 @@ class DefaultNotifiableEventResolverTest { roomName = null, noisy = false, title = null, - description = "Invited you to chat", + description = "Bob invited you to chat", + type = null, + timestamp = A_TIMESTAMP, + soundName = null, + isRedacted = false, + isUpdated = false, + ) + ) + assertThat(result).isEqualTo(expectedResult) + } + + @Test + fun `resolve invite direct, no display name`() = runTest { + val sut = createDefaultNotifiableEventResolver( + notificationResult = Result.success( + createNotificationData( + content = NotificationContent.Invite( + senderId = A_USER_ID_2, + ), + isDirect = true, + senderDisplayName = null, + ) + ) + ) + val result = sut.resolveEvent(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID) + val expectedResult = ResolvedPushEvent.Event( + InviteNotifiableEvent( + sessionId = A_SESSION_ID, + roomId = A_ROOM_ID, + eventId = AN_EVENT_ID, + editedEventId = null, + canBeReplaced = true, + roomName = null, + noisy = false, + title = null, + description = "@bob:server.org invited you to chat", + type = null, + timestamp = A_TIMESTAMP, + soundName = null, + isRedacted = false, + isUpdated = false, + ) + ) + assertThat(result).isEqualTo(expectedResult) + } + + @Test + fun `resolve invite direct, ambiguous display name`() = runTest { + val sut = createDefaultNotifiableEventResolver( + notificationResult = Result.success( + createNotificationData( + content = NotificationContent.Invite( + senderId = A_USER_ID_2, + ), + isDirect = false, + senderIsNameAmbiguous = true, + ) + ) + ) + val result = sut.resolveEvent(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID) + val expectedResult = ResolvedPushEvent.Event( + InviteNotifiableEvent( + sessionId = A_SESSION_ID, + roomId = A_ROOM_ID, + eventId = AN_EVENT_ID, + editedEventId = null, + canBeReplaced = true, + roomName = null, + noisy = false, + title = null, + description = "Bob (@bob:server.org) invited you to join the room", type = null, timestamp = A_TIMESTAMP, soundName = null, @@ -755,13 +825,15 @@ class DefaultNotifiableEventResolverTest { isDirect: Boolean = false, hasMention: Boolean = false, timestamp: Long = A_TIMESTAMP, + senderDisplayName: String? = "Bob", + senderIsNameAmbiguous: Boolean = false, ): NotificationData { return NotificationData( eventId = AN_EVENT_ID, roomId = A_ROOM_ID, senderAvatarUrl = null, - senderDisplayName = "Bob", - senderIsNameAmbiguous = false, + senderDisplayName = senderDisplayName, + senderIsNameAmbiguous = senderIsNameAmbiguous, roomAvatarUrl = null, roomDisplayName = null, isDirect = isDirect, From 6fc801ede6d00416c7422e625dd8f3d64fc71452 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 20 Sep 2024 12:36:51 +0200 Subject: [PATCH 2/2] Use aNotificationData and aNotifiableMessageEvent And cleanup existing tests. --- .../features/roomdetails/MatrixRoomFixture.kt | 6 +- .../roomdetails/RoomDetailsPresenterTest.kt | 10 +- .../android/libraries/matrix/test/TestData.kt | 4 + .../test/notification/NotificationData.kt | 22 +- .../DefaultNotifiableEventResolverTest.kt | 205 +++++++----------- .../DefaultRoomGroupMessageCreatorTest.kt | 2 +- .../NotificationDataFactoryTest.kt | 4 +- .../fixtures/NotifiableEventFixture.kt | 30 ++- 8 files changed, 134 insertions(+), 149 deletions(-) diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/MatrixRoomFixture.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/MatrixRoomFixture.kt index 8ff03a69b9..d4d973d834 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/MatrixRoomFixture.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/MatrixRoomFixture.kt @@ -11,8 +11,10 @@ import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.StateEventType +import io.element.android.libraries.matrix.test.AN_AVATAR_URL import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_ROOM_NAME +import io.element.android.libraries.matrix.test.A_ROOM_TOPIC import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService import io.element.android.libraries.matrix.test.room.FakeMatrixRoom import io.element.android.libraries.matrix.test.room.aRoomInfo @@ -22,8 +24,8 @@ fun aMatrixRoom( roomId: RoomId = A_ROOM_ID, displayName: String = A_ROOM_NAME, rawName: String? = displayName, - topic: String? = "A topic", - avatarUrl: String? = "https://matrix.org/avatar.jpg", + topic: String? = A_ROOM_TOPIC, + avatarUrl: String? = AN_AVATAR_URL, isEncrypted: Boolean = true, isPublic: Boolean = true, isDirect: Boolean = false, diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/RoomDetailsPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/RoomDetailsPresenterTest.kt index 5b64e41a58..84f6f5f341 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/RoomDetailsPresenterTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/RoomDetailsPresenterTest.kt @@ -33,7 +33,10 @@ import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.StateEventType +import io.element.android.libraries.matrix.test.AN_AVATAR_URL import io.element.android.libraries.matrix.test.AN_EVENT_ID +import io.element.android.libraries.matrix.test.A_ROOM_NAME +import io.element.android.libraries.matrix.test.A_ROOM_TOPIC import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.A_USER_ID_2 import io.element.android.libraries.matrix.test.FakeMatrixClient @@ -129,7 +132,12 @@ class RoomDetailsPresenterTest { @Test fun `present - initial state is updated with roomInfo if it exists`() = runTest { - val roomInfo = aRoomInfo(name = "A room name", topic = "A topic", avatarUrl = "https://matrix.org/avatar.jpg", pinnedEventIds = listOf(AN_EVENT_ID)) + val roomInfo = aRoomInfo( + name = A_ROOM_NAME, + topic = A_ROOM_TOPIC, + avatarUrl = AN_AVATAR_URL, + pinnedEventIds = listOf(AN_EVENT_ID), + ) val room = aMatrixRoom( canInviteResult = { Result.success(true) }, canUserJoinCallResult = { Result.success(true) }, diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt index d7dfc2dcb3..83a9b8e5dd 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt @@ -22,6 +22,7 @@ import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.RoomNotificationSettings const val A_USER_NAME = "alice" +const val A_USER_NAME_2 = "Bob" const val A_PASSWORD = "password" const val A_PASSPHRASE = "passphrase" const val A_SECRET = "secret" @@ -55,6 +56,7 @@ val A_UNIQUE_ID = UniqueId("aUniqueId") val A_UNIQUE_ID_2 = UniqueId("aUniqueId2") const val A_ROOM_NAME = "A room name" +const val A_ROOM_TOPIC = "A room topic" const val A_ROOM_RAW_NAME = "A room raw name" const val A_MESSAGE = "Hello world!" const val A_REPLY = "OK, I'll be there!" @@ -80,3 +82,5 @@ val AN_EXCEPTION = Exception(A_FAILURE_REASON) const val A_RECOVERY_KEY = "1234 5678" val A_SERVER_LIST = listOf("server1", "server2") + +const val A_TIMESTAMP = 567L diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/notification/NotificationData.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/notification/NotificationData.kt index 7305db9103..b79076ef10 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/notification/NotificationData.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/notification/NotificationData.kt @@ -11,10 +11,18 @@ import io.element.android.libraries.matrix.api.notification.NotificationContent import io.element.android.libraries.matrix.api.notification.NotificationData import io.element.android.libraries.matrix.test.AN_EVENT_ID import io.element.android.libraries.matrix.test.A_ROOM_ID +import io.element.android.libraries.matrix.test.A_ROOM_NAME +import io.element.android.libraries.matrix.test.A_TIMESTAMP +import io.element.android.libraries.matrix.test.A_USER_NAME_2 fun aNotificationData( - senderDisplayName: String?, - senderIsNameAmbiguous: Boolean, + content: NotificationContent = NotificationContent.MessageLike.RoomEncrypted, + isDirect: Boolean = false, + hasMention: Boolean = false, + timestamp: Long = A_TIMESTAMP, + senderDisplayName: String? = A_USER_NAME_2, + senderIsNameAmbiguous: Boolean = false, + roomDisplayName: String? = A_ROOM_NAME ): NotificationData { return NotificationData( eventId = AN_EVENT_ID, @@ -23,13 +31,13 @@ fun aNotificationData( senderDisplayName = senderDisplayName, senderIsNameAmbiguous = senderIsNameAmbiguous, roomAvatarUrl = null, - roomDisplayName = null, - isDirect = false, + roomDisplayName = roomDisplayName, + isDirect = isDirect, isDm = false, isEncrypted = false, isNoisy = false, - timestamp = 0L, - content = NotificationContent.MessageLike.RoomEncrypted, - hasMention = false, + timestamp = timestamp, + content = content, + hasMention = hasMention, ) } diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolverTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolverTest.kt index 7dc0eab13b..de74d1d7a9 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolverTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolverTest.kt @@ -9,7 +9,6 @@ package io.element.android.libraries.push.impl.notifications import android.content.Context import com.google.common.truth.Truth.assertThat -import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.media.MediaSource import io.element.android.libraries.matrix.api.notification.CallNotifyType import io.element.android.libraries.matrix.api.notification.NotificationContent @@ -33,13 +32,18 @@ import io.element.android.libraries.matrix.test.AN_EVENT_ID_2 import io.element.android.libraries.matrix.test.AN_EXCEPTION import io.element.android.libraries.matrix.test.A_REDACTION_REASON import io.element.android.libraries.matrix.test.A_ROOM_ID +import io.element.android.libraries.matrix.test.A_ROOM_NAME import io.element.android.libraries.matrix.test.A_SESSION_ID +import io.element.android.libraries.matrix.test.A_TIMESTAMP import io.element.android.libraries.matrix.test.A_USER_ID_2 +import io.element.android.libraries.matrix.test.A_USER_NAME_2 import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.FakeMatrixClientProvider import io.element.android.libraries.matrix.test.notification.FakeNotificationService +import io.element.android.libraries.matrix.test.notification.aNotificationData import io.element.android.libraries.matrix.test.permalink.FakePermalinkParser import io.element.android.libraries.push.impl.notifications.fake.FakeNotificationMediaRepo +import io.element.android.libraries.push.impl.notifications.fixtures.aNotifiableMessageEvent import io.element.android.libraries.push.impl.notifications.model.FallbackNotifiableEvent import io.element.android.libraries.push.impl.notifications.model.InviteNotifiableEvent import io.element.android.libraries.push.impl.notifications.model.NotifiableMessageEvent @@ -88,17 +92,17 @@ class DefaultNotifiableEventResolverTest { fun `resolve event message text`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.MessageLike.RoomMessage( senderId = A_USER_ID_2, messageType = TextMessageType(body = "Hello world", formatted = null) - ) + ), ) ) ) val result = sut.resolveEvent(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID) val expectedResult = ResolvedPushEvent.Event( - createNotifiableMessageEvent(body = "Hello world") + aNotifiableMessageEvent(body = "Hello world") ) assertThat(result).isEqualTo(expectedResult) } @@ -108,7 +112,7 @@ class DefaultNotifiableEventResolverTest { fun `resolve event message with mention`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.MessageLike.RoomMessage( senderId = A_USER_ID_2, messageType = TextMessageType(body = "Hello world", formatted = null) @@ -119,7 +123,7 @@ class DefaultNotifiableEventResolverTest { ) val result = sut.resolveEvent(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID) val expectedResult = ResolvedPushEvent.Event( - createNotifiableMessageEvent(body = "Hello world", hasMentionOrReply = true) + aNotifiableMessageEvent(body = "Hello world", hasMentionOrReply = true) ) assertThat(result).isEqualTo(expectedResult) } @@ -128,7 +132,7 @@ class DefaultNotifiableEventResolverTest { fun `resolve HTML formatted event message text takes plain text version`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.MessageLike.RoomMessage( senderId = A_USER_ID_2, messageType = TextMessageType( @@ -138,13 +142,13 @@ class DefaultNotifiableEventResolverTest { format = MessageFormat.HTML, ) ) - ) + ), ) ) ) val result = sut.resolveEvent(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID) val expectedResult = ResolvedPushEvent.Event( - createNotifiableMessageEvent(body = "Hello world") + aNotifiableMessageEvent(body = "Hello world") ) assertThat(result).isEqualTo(expectedResult) } @@ -153,7 +157,7 @@ class DefaultNotifiableEventResolverTest { fun `resolve incorrectly formatted event message text uses fallback`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.MessageLike.RoomMessage( senderId = A_USER_ID_2, messageType = TextMessageType( @@ -163,13 +167,13 @@ class DefaultNotifiableEventResolverTest { format = MessageFormat.UNKNOWN, ) ) - ) + ), ) ) ) val result = sut.resolveEvent(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID) val expectedResult = ResolvedPushEvent.Event( - createNotifiableMessageEvent(body = "Hello world") + aNotifiableMessageEvent(body = "Hello world") ) assertThat(result).isEqualTo(expectedResult) } @@ -178,17 +182,17 @@ class DefaultNotifiableEventResolverTest { fun `resolve event message audio`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.MessageLike.RoomMessage( senderId = A_USER_ID_2, messageType = AudioMessageType(body = "Audio", MediaSource("url"), null) - ) + ), ) ) ) val result = sut.resolveEvent(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID) val expectedResult = ResolvedPushEvent.Event( - createNotifiableMessageEvent(body = "Audio") + aNotifiableMessageEvent(body = "Audio") ) assertThat(result).isEqualTo(expectedResult) } @@ -197,17 +201,17 @@ class DefaultNotifiableEventResolverTest { fun `resolve event message video`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.MessageLike.RoomMessage( senderId = A_USER_ID_2, messageType = VideoMessageType(body = "Video", null, null, MediaSource("url"), null) - ) + ), ) ) ) val result = sut.resolveEvent(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID) val expectedResult = ResolvedPushEvent.Event( - createNotifiableMessageEvent(body = "Video") + aNotifiableMessageEvent(body = "Video") ) assertThat(result).isEqualTo(expectedResult) } @@ -216,17 +220,17 @@ class DefaultNotifiableEventResolverTest { fun `resolve event message voice`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.MessageLike.RoomMessage( senderId = A_USER_ID_2, messageType = VoiceMessageType(body = "Voice", MediaSource("url"), null, null) - ) + ), ) ) ) val result = sut.resolveEvent(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID) val expectedResult = ResolvedPushEvent.Event( - createNotifiableMessageEvent(body = "Voice message") + aNotifiableMessageEvent(body = "Voice message") ) assertThat(result).isEqualTo(expectedResult) } @@ -235,17 +239,17 @@ class DefaultNotifiableEventResolverTest { fun `resolve event message image`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.MessageLike.RoomMessage( senderId = A_USER_ID_2, messageType = ImageMessageType("Image", null, null, MediaSource("url"), null), - ) + ), ) ) ) val result = sut.resolveEvent(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID) val expectedResult = ResolvedPushEvent.Event( - createNotifiableMessageEvent(body = "Image") + aNotifiableMessageEvent(body = "Image") ) assertThat(result).isEqualTo(expectedResult) } @@ -254,17 +258,17 @@ class DefaultNotifiableEventResolverTest { fun `resolve event message sticker`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.MessageLike.RoomMessage( senderId = A_USER_ID_2, messageType = StickerMessageType("Sticker", MediaSource("url"), null), - ) + ), ) ) ) val result = sut.resolveEvent(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID) val expectedResult = ResolvedPushEvent.Event( - createNotifiableMessageEvent(body = "Sticker") + aNotifiableMessageEvent(body = "Sticker") ) assertThat(result).isEqualTo(expectedResult) } @@ -273,17 +277,17 @@ class DefaultNotifiableEventResolverTest { fun `resolve event message file`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.MessageLike.RoomMessage( senderId = A_USER_ID_2, messageType = FileMessageType("File", MediaSource("url"), null), - ) + ), ) ) ) val result = sut.resolveEvent(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID) val expectedResult = ResolvedPushEvent.Event( - createNotifiableMessageEvent(body = "File") + aNotifiableMessageEvent(body = "File") ) assertThat(result).isEqualTo(expectedResult) } @@ -292,17 +296,17 @@ class DefaultNotifiableEventResolverTest { fun `resolve event message location`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.MessageLike.RoomMessage( senderId = A_USER_ID_2, messageType = LocationMessageType("Location", "geo:1,2", null), - ) + ), ) ) ) val result = sut.resolveEvent(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID) val expectedResult = ResolvedPushEvent.Event( - createNotifiableMessageEvent(body = "Location") + aNotifiableMessageEvent(body = "Location") ) assertThat(result).isEqualTo(expectedResult) } @@ -311,17 +315,17 @@ class DefaultNotifiableEventResolverTest { fun `resolve event message notice`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.MessageLike.RoomMessage( senderId = A_USER_ID_2, messageType = NoticeMessageType("Notice", null), - ) + ), ) ) ) val result = sut.resolveEvent(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID) val expectedResult = ResolvedPushEvent.Event( - createNotifiableMessageEvent(body = "Notice") + aNotifiableMessageEvent(body = "Notice") ) assertThat(result).isEqualTo(expectedResult) } @@ -330,17 +334,17 @@ class DefaultNotifiableEventResolverTest { fun `resolve event message emote`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.MessageLike.RoomMessage( senderId = A_USER_ID_2, messageType = EmoteMessageType("is happy", null), - ) + ), ) ) ) val result = sut.resolveEvent(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID) val expectedResult = ResolvedPushEvent.Event( - createNotifiableMessageEvent(body = "* Bob is happy") + aNotifiableMessageEvent(body = "* Bob is happy") ) assertThat(result).isEqualTo(expectedResult) } @@ -349,17 +353,17 @@ class DefaultNotifiableEventResolverTest { fun `resolve poll`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.MessageLike.Poll( senderId = A_USER_ID_2, question = "A question" - ) + ), ) ) ) val result = sut.resolveEvent(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID) val expectedResult = ResolvedPushEvent.Event( - createNotifiableMessageEvent(body = "Poll: A question") + aNotifiableMessageEvent(body = "Poll: A question") ) assertThat(result).isEqualTo(expectedResult) } @@ -368,7 +372,7 @@ class DefaultNotifiableEventResolverTest { fun `resolve RoomMemberContent invite room`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.StateEvent.RoomMemberContent( userId = A_USER_ID_2, membershipState = RoomMembershipState.INVITE @@ -385,7 +389,7 @@ class DefaultNotifiableEventResolverTest { fun `resolve invite room`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.Invite( senderId = A_USER_ID_2, ), @@ -401,7 +405,7 @@ class DefaultNotifiableEventResolverTest { eventId = AN_EVENT_ID, editedEventId = null, canBeReplaced = true, - roomName = null, + roomName = A_ROOM_NAME, noisy = false, title = null, description = "Bob invited you to join the room", @@ -419,7 +423,7 @@ class DefaultNotifiableEventResolverTest { fun `resolve invite direct`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.Invite( senderId = A_USER_ID_2, ), @@ -435,7 +439,7 @@ class DefaultNotifiableEventResolverTest { eventId = AN_EVENT_ID, editedEventId = null, canBeReplaced = true, - roomName = null, + roomName = A_ROOM_NAME, noisy = false, title = null, description = "Bob invited you to chat", @@ -453,7 +457,7 @@ class DefaultNotifiableEventResolverTest { fun `resolve invite direct, no display name`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.Invite( senderId = A_USER_ID_2, ), @@ -470,7 +474,7 @@ class DefaultNotifiableEventResolverTest { eventId = AN_EVENT_ID, editedEventId = null, canBeReplaced = true, - roomName = null, + roomName = A_ROOM_NAME, noisy = false, title = null, description = "@bob:server.org invited you to chat", @@ -488,7 +492,7 @@ class DefaultNotifiableEventResolverTest { fun `resolve invite direct, ambiguous display name`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.Invite( senderId = A_USER_ID_2, ), @@ -505,7 +509,7 @@ class DefaultNotifiableEventResolverTest { eventId = AN_EVENT_ID, editedEventId = null, canBeReplaced = true, - roomName = null, + roomName = A_ROOM_NAME, noisy = false, title = null, description = "Bob (@bob:server.org) invited you to join the room", @@ -523,7 +527,7 @@ class DefaultNotifiableEventResolverTest { fun `resolve RoomMemberContent other`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.StateEvent.RoomMemberContent( userId = A_USER_ID_2, membershipState = RoomMembershipState.JOIN @@ -539,7 +543,7 @@ class DefaultNotifiableEventResolverTest { fun `resolve RoomEncrypted`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.MessageLike.RoomEncrypted ) ) @@ -565,8 +569,8 @@ class DefaultNotifiableEventResolverTest { fun `resolve CallInvite`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( - content = NotificationContent.MessageLike.CallInvite(A_USER_ID_2) + aNotificationData( + content = NotificationContent.MessageLike.CallInvite(A_USER_ID_2), ) ) ) @@ -581,11 +585,11 @@ class DefaultNotifiableEventResolverTest { senderId = A_USER_ID_2, noisy = false, timestamp = A_TIMESTAMP, - senderDisambiguatedDisplayName = "Bob", + senderDisambiguatedDisplayName = A_USER_NAME_2, body = "Call in progress (unsupported)", imageUriString = null, threadId = null, - roomName = null, + roomName = A_ROOM_NAME, roomAvatarPath = null, senderAvatarPath = null, soundName = null, @@ -603,7 +607,7 @@ class DefaultNotifiableEventResolverTest { val timestamp = DefaultSystemClock().epochMillis() val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.MessageLike.CallNotify( A_USER_ID_2, CallNotifyType.RING @@ -618,14 +622,14 @@ class DefaultNotifiableEventResolverTest { roomId = A_ROOM_ID, eventId = AN_EVENT_ID, senderId = A_USER_ID_2, - roomName = null, + roomName = A_ROOM_NAME, editedEventId = null, description = "Incoming call", timestamp = timestamp, canBeReplaced = true, isRedacted = false, isUpdated = false, - senderDisambiguatedDisplayName = "Bob", + senderDisambiguatedDisplayName = A_USER_NAME_2, senderAvatarUrl = null, callNotifyType = CallNotifyType.RING, ) @@ -638,7 +642,7 @@ class DefaultNotifiableEventResolverTest { fun `resolve CallNotify - ring but timed out displays the same as notify`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.MessageLike.CallNotify( A_USER_ID_2, CallNotifyType.RING @@ -654,12 +658,12 @@ class DefaultNotifiableEventResolverTest { editedEventId = null, noisy = true, timestamp = 0L, - senderDisambiguatedDisplayName = "Bob", - senderId = UserId("@bob:server.org"), + senderDisambiguatedDisplayName = A_USER_NAME_2, + senderId = A_USER_ID_2, body = "☎\uFE0F Incoming call", roomId = A_ROOM_ID, threadId = null, - roomName = null, + roomName = A_ROOM_NAME, canBeReplaced = false, isRedacted = false, imageUriString = null, @@ -674,11 +678,11 @@ class DefaultNotifiableEventResolverTest { fun `resolve CallNotify - notify`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.MessageLike.CallNotify( A_USER_ID_2, CallNotifyType.NOTIFY - ) + ), ) ) ) @@ -689,12 +693,12 @@ class DefaultNotifiableEventResolverTest { editedEventId = null, noisy = true, timestamp = A_TIMESTAMP, - senderDisambiguatedDisplayName = "Bob", - senderId = UserId("@bob:server.org"), + senderDisambiguatedDisplayName = A_USER_NAME_2, + senderId = A_USER_ID_2, body = "☎\uFE0F Incoming call", roomId = A_ROOM_ID, threadId = null, - roomName = null, + roomName = A_ROOM_NAME, canBeReplaced = false, isRedacted = false, imageUriString = null, @@ -709,7 +713,7 @@ class DefaultNotifiableEventResolverTest { fun `resolve RoomRedaction`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.MessageLike.RoomRedaction( AN_EVENT_ID_2, A_REDACTION_REASON, @@ -731,7 +735,7 @@ class DefaultNotifiableEventResolverTest { fun `resolve RoomRedaction with null redactedEventId should return null`() = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = NotificationContent.MessageLike.RoomRedaction( null, A_REDACTION_REASON, @@ -782,7 +786,7 @@ class DefaultNotifiableEventResolverTest { private fun testNull(content: NotificationContent) = runTest { val sut = createDefaultNotifiableEventResolver( notificationResult = Result.success( - createNotificationData( + aNotificationData( content = content ) ) @@ -819,61 +823,4 @@ class DefaultNotifiableEventResolverTest { ), ) } - - private fun createNotificationData( - content: NotificationContent, - isDirect: Boolean = false, - hasMention: Boolean = false, - timestamp: Long = A_TIMESTAMP, - senderDisplayName: String? = "Bob", - senderIsNameAmbiguous: Boolean = false, - ): NotificationData { - return NotificationData( - eventId = AN_EVENT_ID, - roomId = A_ROOM_ID, - senderAvatarUrl = null, - senderDisplayName = senderDisplayName, - senderIsNameAmbiguous = senderIsNameAmbiguous, - roomAvatarUrl = null, - roomDisplayName = null, - isDirect = isDirect, - isEncrypted = false, - isNoisy = false, - timestamp = timestamp, - content = content, - hasMention = hasMention, - isDm = false, - ) - } - - private fun createNotifiableMessageEvent( - body: String, - hasMentionOrReply: Boolean = false, - ): NotifiableMessageEvent { - return NotifiableMessageEvent( - sessionId = A_SESSION_ID, - roomId = A_ROOM_ID, - eventId = AN_EVENT_ID, - editedEventId = null, - canBeReplaced = false, - senderId = A_USER_ID_2, - noisy = false, - timestamp = A_TIMESTAMP, - senderDisambiguatedDisplayName = "Bob", - body = body, - imageUriString = null, - threadId = null, - roomName = null, - roomAvatarPath = null, - senderAvatarPath = null, - soundName = null, - outGoingMessage = false, - outGoingMessageFailed = false, - isRedacted = false, - isUpdated = false, - hasMentionOrReply = hasMentionOrReply, - ) - } } - -private const val A_TIMESTAMP = 567L diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultRoomGroupMessageCreatorTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultRoomGroupMessageCreatorTest.kt index 1030331134..dbb60296b1 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultRoomGroupMessageCreatorTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultRoomGroupMessageCreatorTest.kt @@ -13,6 +13,7 @@ import androidx.core.app.NotificationCompat import com.google.common.truth.Truth.assertThat import io.element.android.libraries.matrix.api.media.MediaSource import io.element.android.libraries.matrix.test.A_ROOM_ID +import io.element.android.libraries.matrix.test.A_TIMESTAMP import io.element.android.libraries.matrix.ui.components.aMatrixUser import io.element.android.libraries.matrix.ui.media.MediaRequestData import io.element.android.libraries.push.impl.notifications.factories.createNotificationCreator @@ -27,7 +28,6 @@ import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner import org.robolectric.RuntimeEnvironment -private const val A_TIMESTAMP = 6480L private const val A_ROOM_AVATAR = "mxc://roomAvatar" private const val A_USER_AVATAR_1 = "mxc://userAvatar1" private const val A_USER_AVATAR_2 = "mxc://userAvatar2" diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDataFactoryTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDataFactoryTest.kt index 4221c2b287..8a0a50e924 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDataFactoryTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDataFactoryTest.kt @@ -100,7 +100,7 @@ class NotificationDataFactoryTest { null, ), roomId = A_ROOM_ID, - summaryLine = "room-name: sender-name message-body", + summaryLine = "A room name: Bob Hello world!", messageCount = events.size, latestTimestamp = events.maxOf { it.timestamp }, shouldBing = events.any { it.noisy } @@ -152,7 +152,7 @@ class NotificationDataFactoryTest { null, ), roomId = A_ROOM_ID, - summaryLine = "room-name: sender-name message-body", + summaryLine = "A room name: Bob Hello world!", messageCount = withRedactedRemoved.size, latestTimestamp = withRedactedRemoved.maxOf { it.timestamp }, shouldBing = withRedactedRemoved.any { it.noisy } diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/fixtures/NotifiableEventFixture.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/fixtures/NotifiableEventFixture.kt index 2cfde0e72b..faba6a6c65 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/fixtures/NotifiableEventFixture.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/fixtures/NotifiableEventFixture.kt @@ -16,9 +16,13 @@ import io.element.android.libraries.matrix.api.notification.CallNotifyType import io.element.android.libraries.matrix.api.timeline.item.event.EventType import io.element.android.libraries.matrix.test.AN_AVATAR_URL import io.element.android.libraries.matrix.test.AN_EVENT_ID +import io.element.android.libraries.matrix.test.A_MESSAGE import io.element.android.libraries.matrix.test.A_ROOM_ID +import io.element.android.libraries.matrix.test.A_ROOM_NAME import io.element.android.libraries.matrix.test.A_SESSION_ID +import io.element.android.libraries.matrix.test.A_TIMESTAMP import io.element.android.libraries.matrix.test.A_USER_ID_2 +import io.element.android.libraries.matrix.test.A_USER_NAME_2 import io.element.android.libraries.push.impl.notifications.model.InviteNotifiableEvent import io.element.android.libraries.push.impl.notifications.model.NotifiableMessageEvent import io.element.android.libraries.push.impl.notifications.model.NotifiableRingingCallEvent @@ -56,7 +60,7 @@ fun anInviteNotifiableEvent( sessionId = sessionId, eventId = eventId, roomId = roomId, - roomName = "a room name", + roomName = A_ROOM_NAME, editedEventId = null, noisy = false, title = "title", @@ -69,28 +73,40 @@ fun anInviteNotifiableEvent( ) fun aNotifiableMessageEvent( + body: String = A_MESSAGE, sessionId: SessionId = A_SESSION_ID, roomId: RoomId = A_ROOM_ID, eventId: EventId = AN_EVENT_ID, threadId: ThreadId? = null, isRedacted: Boolean = false, - timestamp: Long = 0, + hasMentionOrReply: Boolean = false, + timestamp: Long = A_TIMESTAMP, type: String = EventType.MESSAGE, + senderId: UserId = A_USER_ID_2, + senderDisambiguatedDisplayName: String = A_USER_NAME_2, + roomName: String? = A_ROOM_NAME, ) = NotifiableMessageEvent( sessionId = sessionId, eventId = eventId, editedEventId = null, noisy = false, timestamp = timestamp, - senderDisambiguatedDisplayName = "sender-name", - senderId = UserId("@sending-id:domain.com"), - body = "message-body", + senderDisambiguatedDisplayName = senderDisambiguatedDisplayName, + senderId = senderId, + body = body, roomId = roomId, threadId = threadId, - roomName = "room-name", + roomName = roomName, canBeReplaced = false, isRedacted = isRedacted, imageUriString = null, + roomAvatarPath = null, + senderAvatarPath = null, + soundName = null, + outGoingMessage = false, + outGoingMessageFailed = false, + isUpdated = false, + hasMentionOrReply = hasMentionOrReply, type = type, ) @@ -108,7 +124,7 @@ fun aNotifiableCallEvent( sessionId = sessionId, eventId = eventId, roomId = roomId, - roomName = "a room name", + roomName = A_ROOM_NAME, editedEventId = null, description = "description", timestamp = timestamp,