Validate several ids in constructors (#336)

* Validate ids in constructors.

* Remove redundant `.value` usage in string interpolation.

* Make a distinction between `SessionId` and `UserId` in `TestData`.
This commit is contained in:
Jorge Martin Espinosa
2023-04-18 18:17:13 +02:00
committed by GitHub
parent f98fe8e52c
commit e704870e3f
36 changed files with 193 additions and 199 deletions

View File

@@ -165,7 +165,7 @@ class ConfigureRoomPresenterTests {
presenter.present()
}.test {
val initialState = awaitItem()
val createRoomResult = Result.success(RoomId("!createRoomResult"))
val createRoomResult = Result.success(RoomId("!createRoomResult:domain"))
fakeMatrixClient.givenCreateRoomResult(createRoomResult)

View File

@@ -81,8 +81,8 @@ class CreateRoomRootPresenterTests {
presenter.present()
}.test {
val initialState = awaitItem()
val matrixUser = MatrixUser(UserId("@name:matrix.org"))
val createDmResult = Result.success(RoomId("!createDmResult"))
val matrixUser = MatrixUser(UserId("@name:domain"))
val createDmResult = Result.success(RoomId("!createDmResult:domain"))
fakeMatrixClient.givenFindDmResult(null)
fakeMatrixClient.givenCreateDmResult(createDmResult)
@@ -101,8 +101,8 @@ class CreateRoomRootPresenterTests {
presenter.present()
}.test {
val initialState = awaitItem()
val matrixUser = MatrixUser(UserId("@name:matrix.org"))
val fakeDmResult = FakeMatrixRoom(RoomId("!fakeDmResult"))
val matrixUser = MatrixUser(UserId("@name:domain"))
val fakeDmResult = FakeMatrixRoom(RoomId("!fakeDmResult:domain"))
fakeMatrixClient.givenFindDmResult(fakeDmResult)
@@ -119,8 +119,8 @@ class CreateRoomRootPresenterTests {
presenter.present()
}.test {
val initialState = awaitItem()
val matrixUser = MatrixUser(UserId("@name:matrix.org"))
val createDmResult = Result.success(RoomId("!createDmResult"))
val matrixUser = MatrixUser(UserId("@name:domain"))
val createDmResult = Result.success(RoomId("!createDmResult:domain"))
fakeUserListPresenter.givenState(aUserListState().copy(selectedUsers = persistentListOf(matrixUser)))
fakeMatrixClient.givenFindDmResult(null)

View File

@@ -28,7 +28,7 @@ open class LoginRootStateProvider : PreviewParameterProvider<LoginRootState> {
aLoginRootState().copy(formState = LoginFormState("user", "pass")),
aLoginRootState().copy(formState = LoginFormState("user", "pass"), loggedInState = LoggedInState.LoggingIn),
aLoginRootState().copy(formState = LoginFormState("user", "pass"), loggedInState = LoggedInState.ErrorLoggingIn(Throwable())),
aLoginRootState().copy(formState = LoginFormState("user", "pass"), loggedInState = LoggedInState.LoggedIn(SessionId("1234"))),
aLoginRootState().copy(formState = LoginFormState("user", "pass"), loggedInState = LoggedInState.LoggedIn(SessionId("@user:domain"))),
)
}

View File

@@ -36,9 +36,9 @@ open class MessagesStateProvider : PreviewParameterProvider<MessagesState> {
}
fun aMessagesState() = MessagesState(
roomId = RoomId("!id"),
roomId = RoomId("!id:domain"),
roomName = "Room name",
roomAvatar = AvatarData("!id", "Room name"),
roomAvatar = AvatarData("!id:domain", "Room name"),
composerState = aMessageComposerState().copy(
text = StableCharSequence("Hello"),
isFullScreen = false,

View File

@@ -28,6 +28,7 @@ import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.timeline.MatrixTimeline
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlin.random.Random
fun aTimelineState() = TimelineState(
timelineItems = persistentListOf(),
@@ -78,12 +79,12 @@ internal fun aTimelineItemEvent(
content: TimelineItemEventContent = aTimelineItemContent(),
groupPosition: TimelineItemGroupPosition = TimelineItemGroupPosition.First
): TimelineItem.Event {
val randomId = Math.random().toString()
val randomId = "\$" + Random.nextInt().toString()
return TimelineItem.Event(
id = randomId,
eventId = EventId(randomId),
senderId = UserId("@senderId"),
senderAvatar = AvatarData("@senderId", "sender"),
senderId = UserId("@senderId:domain"),
senderAvatar = AvatarData("@senderId:domain", "sender"),
content = content,
reactionsState = TimelineItemReactions(
persistentListOf(

View File

@@ -38,7 +38,7 @@ open class RoomListStateProvider : PreviewParameterProvider<RoomListState> {
}
internal fun aRoomListState() = RoomListState(
matrixUser = MatrixUser(id = UserId("@id"), username = "User#1", avatarData = AvatarData("@id", "U")),
matrixUser = MatrixUser(id = UserId("@id:domain"), username = "User#1", avatarData = AvatarData("@id:domain", "U")),
roomList = aRoomListRoomSummaryList(),
filter = "filter",
hasNetworkConnection = true,
@@ -55,7 +55,7 @@ internal fun aRoomListRoomSummaryList(): ImmutableList<RoomListRoomSummary> {
timestamp = "14:18",
lastMessage = "A very very very very long message which suites on two lines",
avatarData = AvatarData("!id", "R"),
id = "roomId"
id = "!roomId:domain"
),
RoomListRoomSummary(
name = "Room#2",
@@ -63,8 +63,8 @@ internal fun aRoomListRoomSummaryList(): ImmutableList<RoomListRoomSummary> {
timestamp = "14:16",
lastMessage = "A short message",
avatarData = AvatarData("!id", "Z"),
id = "roomId2"
id = "!roomId2:domain"
),
RoomListRoomSummaryPlaceholders.create("roomId2")
RoomListRoomSummaryPlaceholders.create("!roomId2:domain")
)
}

View File

@@ -249,7 +249,7 @@ internal fun DefaultRoomListTopBarDarkPreview() = ElementPreviewDark { DefaultRo
@Composable
private fun DefaultRoomListTopBarPreview() {
DefaultRoomListTopBar(
matrixUser = MatrixUser(UserId("@id"), "Alice", AvatarData("@id", "Alice")),
matrixUser = MatrixUser(UserId("@id:domain"), "Alice", AvatarData("@id:domain", "Alice")),
scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(rememberTopAppBarState()),
)
}

View File

@@ -34,7 +34,7 @@ object RoomListRoomSummaryPlaceholders {
fun createFakeList(size: Int): List<RoomListRoomSummary> {
return mutableListOf<RoomListRoomSummary>().apply {
repeat(size) {
add(create("\$fakeRoom$it"))
add(create("!fakeRoom$it:domain"))
}
}
}

View File

@@ -34,7 +34,7 @@ open class RoomListRoomSummaryProvider : PreviewParameterProvider<RoomListRoomSu
fun aRoomListRoomSummary() = RoomListRoomSummary(
id = "!roomId",
roomId = RoomId("!roomId"),
roomId = RoomId("!roomId:domain"),
name = "Room name",
hasUnread = false,
timestamp = null,

View File

@@ -232,7 +232,7 @@ class DefaultRoomLastMessageFormatterTests {
fun `Membership change - joined`() {
val otherName = "Someone"
val youContent = RoomMembershipContent(A_USER_ID, MembershipChange.JOINED)
val someoneContent = RoomMembershipContent(UserId("someone_else"), MembershipChange.JOINED)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.JOINED)
val youJoinedRoomEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent)
val youJoinedRoom = formatter.processMessageItem(youJoinedRoomEvent, false)
@@ -240,7 +240,7 @@ class DefaultRoomLastMessageFormatterTests {
val someoneJoinedRoomEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent)
val someoneJoinedRoom = formatter.processMessageItem(someoneJoinedRoomEvent, false)
Truth.assertThat(someoneJoinedRoom).isEqualTo("${someoneContent.userId.value} joined the room")
Truth.assertThat(someoneJoinedRoom).isEqualTo("${someoneContent.userId} joined the room")
}
@Test
@@ -248,7 +248,7 @@ class DefaultRoomLastMessageFormatterTests {
fun `Membership change - left`() {
val otherName = "Someone"
val youContent = RoomMembershipContent(A_USER_ID, MembershipChange.LEFT)
val someoneContent = RoomMembershipContent(UserId("someone_else"), MembershipChange.LEFT)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.LEFT)
val youLeftRoomEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent)
val youLeftRoom = formatter.processMessageItem(youLeftRoomEvent, false)
@@ -256,65 +256,65 @@ class DefaultRoomLastMessageFormatterTests {
val someoneLeftRoomEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent)
val someoneLeftRoom = formatter.processMessageItem(someoneLeftRoomEvent, false)
Truth.assertThat(someoneLeftRoom).isEqualTo("${someoneContent.userId.value} left the room")
Truth.assertThat(someoneLeftRoom).isEqualTo("${someoneContent.userId} left the room")
}
@Test
@Config(qualifiers = "en")
fun `Membership change - banned`() {
val otherName = "Someone"
val youContent = RoomMembershipContent(UserId("someone_else"), MembershipChange.BANNED)
val youKickedContent = RoomMembershipContent(UserId("someone_else"), MembershipChange.KICKED_AND_BANNED)
val someoneContent = RoomMembershipContent(UserId("someone_else"), MembershipChange.BANNED)
val someoneKickedContent = RoomMembershipContent(UserId("someone_else"), MembershipChange.KICKED_AND_BANNED)
val youContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.BANNED)
val youKickedContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.KICKED_AND_BANNED)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.BANNED)
val someoneKickedContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.KICKED_AND_BANNED)
val youBannedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent)
val youBanned = formatter.processMessageItem(youBannedEvent, false)
Truth.assertThat(youBanned).isEqualTo("You banned ${youContent.userId.value}")
Truth.assertThat(youBanned).isEqualTo("You banned ${youContent.userId}")
val youKickBannedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youKickedContent)
val youKickedBanned = formatter.processMessageItem(youKickBannedEvent, false)
Truth.assertThat(youKickedBanned).isEqualTo("You banned ${youContent.userId.value}")
Truth.assertThat(youKickedBanned).isEqualTo("You banned ${youContent.userId}")
val someoneBannedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent)
val someoneBanned = formatter.processMessageItem(someoneBannedEvent, false)
Truth.assertThat(someoneBanned).isEqualTo("$otherName banned ${someoneContent.userId.value}")
Truth.assertThat(someoneBanned).isEqualTo("$otherName banned ${someoneContent.userId}")
val someoneKickBannedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneKickedContent)
val someoneKickBanned = formatter.processMessageItem(someoneKickBannedEvent, false)
Truth.assertThat(someoneKickBanned).isEqualTo("$otherName banned ${someoneContent.userId.value}")
Truth.assertThat(someoneKickBanned).isEqualTo("$otherName banned ${someoneContent.userId}")
}
@Test
@Config(qualifiers = "en")
fun `Membership change - unban`() {
val otherName = "Someone"
val youContent = RoomMembershipContent(UserId("someone_else"), MembershipChange.UNBANNED)
val someoneContent = RoomMembershipContent(UserId("someone_else"), MembershipChange.UNBANNED)
val youContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.UNBANNED)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.UNBANNED)
val youUnbannedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent)
val youUnbanned = formatter.processMessageItem(youUnbannedEvent, false)
Truth.assertThat(youUnbanned).isEqualTo("You unbanned ${youContent.userId.value}")
Truth.assertThat(youUnbanned).isEqualTo("You unbanned ${youContent.userId}")
val someoneUnbannedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent)
val someoneUnbanned = formatter.processMessageItem(someoneUnbannedEvent, false)
Truth.assertThat(someoneUnbanned).isEqualTo("$otherName unbanned ${someoneContent.userId.value}")
Truth.assertThat(someoneUnbanned).isEqualTo("$otherName unbanned ${someoneContent.userId}")
}
@Test
@Config(qualifiers = "en")
fun `Membership change - kicked`() {
val otherName = "Someone"
val youContent = RoomMembershipContent(UserId("someone_else"), MembershipChange.KICKED)
val someoneContent = RoomMembershipContent(UserId("someone_else"), MembershipChange.KICKED)
val youContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.KICKED)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.KICKED)
val youKickedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent)
val youKicked = formatter.processMessageItem(youKickedEvent, false)
Truth.assertThat(youKicked).isEqualTo("You removed ${youContent.userId.value}")
Truth.assertThat(youKicked).isEqualTo("You removed ${youContent.userId}")
val someoneKickedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent)
val someoneKicked = formatter.processMessageItem(someoneKickedEvent, false)
Truth.assertThat(someoneKicked).isEqualTo("$otherName removed ${someoneContent.userId.value}")
Truth.assertThat(someoneKicked).isEqualTo("$otherName removed ${someoneContent.userId}")
}
@Test
@@ -322,7 +322,7 @@ class DefaultRoomLastMessageFormatterTests {
fun `Membership change - invited`() {
val otherName = "Someone"
val youContent = RoomMembershipContent(A_USER_ID, MembershipChange.INVITED)
val someoneContent = RoomMembershipContent(UserId("someone_else"), MembershipChange.INVITED)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.INVITED)
val youWereInvitedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = youContent)
val youWereInvited = formatter.processMessageItem(youWereInvitedEvent, false)
@@ -330,11 +330,11 @@ class DefaultRoomLastMessageFormatterTests {
val youInvitedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = someoneContent)
val youInvited = formatter.processMessageItem(youInvitedEvent, false)
Truth.assertThat(youInvited).isEqualTo("You invited ${someoneContent.userId.value}")
Truth.assertThat(youInvited).isEqualTo("You invited ${someoneContent.userId}")
val someoneInvitedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent)
val someoneInvited = formatter.processMessageItem(someoneInvitedEvent, false)
Truth.assertThat(someoneInvited).isEqualTo("$otherName invited ${someoneContent.userId.value}")
Truth.assertThat(someoneInvited).isEqualTo("$otherName invited ${someoneContent.userId}")
}
@Test
@@ -342,7 +342,7 @@ class DefaultRoomLastMessageFormatterTests {
fun `Membership change - invitation accepted`() {
val otherName = "Someone"
val youContent = RoomMembershipContent(A_USER_ID, MembershipChange.INVITATION_ACCEPTED)
val someoneContent = RoomMembershipContent(UserId("someone_else"), MembershipChange.INVITATION_ACCEPTED)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.INVITATION_ACCEPTED)
val youAcceptedInviteEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent)
val youAcceptedInvite = formatter.processMessageItem(youAcceptedInviteEvent, false)
@@ -350,7 +350,7 @@ class DefaultRoomLastMessageFormatterTests {
val someoneAcceptedInviteEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent)
val someoneAcceptedInvite = formatter.processMessageItem(someoneAcceptedInviteEvent, false)
Truth.assertThat(someoneAcceptedInvite).isEqualTo("${someoneContent.userId.value} accepted the invite")
Truth.assertThat(someoneAcceptedInvite).isEqualTo("${someoneContent.userId} accepted the invite")
}
@Test
@@ -358,7 +358,7 @@ class DefaultRoomLastMessageFormatterTests {
fun `Membership change - invitation rejected`() {
val otherName = "Someone"
val youContent = RoomMembershipContent(A_USER_ID, MembershipChange.INVITATION_REJECTED)
val someoneContent = RoomMembershipContent(UserId("someone_else"), MembershipChange.INVITATION_REJECTED)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.INVITATION_REJECTED)
val youRejectedInviteEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent)
val youRejectedInvite = formatter.processMessageItem(youRejectedInviteEvent, false)
@@ -366,22 +366,22 @@ class DefaultRoomLastMessageFormatterTests {
val someoneRejectedInviteEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent)
val someoneRejectedInvite = formatter.processMessageItem(someoneRejectedInviteEvent, false)
Truth.assertThat(someoneRejectedInvite).isEqualTo("${someoneContent.userId.value} rejected the invitation")
Truth.assertThat(someoneRejectedInvite).isEqualTo("${someoneContent.userId} rejected the invitation")
}
@Test
@Config(qualifiers = "en")
fun `Membership change - invitation revoked`() {
val otherName = "Someone"
val someoneContent = RoomMembershipContent(UserId("someone_else"), MembershipChange.INVITATION_REVOKED)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.INVITATION_REVOKED)
val youRevokedInviteEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = someoneContent)
val youRevokedInvite = formatter.processMessageItem(youRevokedInviteEvent, false)
Truth.assertThat(youRevokedInvite).isEqualTo("You revoked the invitation for ${someoneContent.userId.value} to join the room")
Truth.assertThat(youRevokedInvite).isEqualTo("You revoked the invitation for ${someoneContent.userId} to join the room")
val someoneRevokedInviteEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent)
val someoneRevokedInvite = formatter.processMessageItem(someoneRevokedInviteEvent, false)
Truth.assertThat(someoneRevokedInvite).isEqualTo("$otherName revoked the invitation for ${someoneContent.userId.value} to join the room")
Truth.assertThat(someoneRevokedInvite).isEqualTo("$otherName revoked the invitation for ${someoneContent.userId} to join the room")
}
@Test
@@ -389,7 +389,7 @@ class DefaultRoomLastMessageFormatterTests {
fun `Membership change - knocked`() {
val otherName = "Someone"
val youContent = RoomMembershipContent(A_USER_ID, MembershipChange.KNOCKED)
val someoneContent = RoomMembershipContent(UserId("someone_else"), MembershipChange.KNOCKED)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.KNOCKED)
val youKnockedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent)
val youKnocked = formatter.processMessageItem(youKnockedEvent, false)
@@ -397,22 +397,22 @@ class DefaultRoomLastMessageFormatterTests {
val someoneKnockedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent)
val someoneKnocked = formatter.processMessageItem(someoneKnockedEvent, false)
Truth.assertThat(someoneKnocked).isEqualTo("${someoneContent.userId.value} requested to join")
Truth.assertThat(someoneKnocked).isEqualTo("${someoneContent.userId} requested to join")
}
@Test
@Config(qualifiers = "en")
fun `Membership change - knock accepted`() {
val otherName = "Someone"
val someoneContent = RoomMembershipContent(UserId("someone_else"), MembershipChange.KNOCK_ACCEPTED)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.KNOCK_ACCEPTED)
val youAcceptedKnockEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = someoneContent)
val youAcceptedKnock = formatter.processMessageItem(youAcceptedKnockEvent, false)
Truth.assertThat(youAcceptedKnock).isEqualTo("${someoneContent.userId.value} allowed you to join")
Truth.assertThat(youAcceptedKnock).isEqualTo("${someoneContent.userId} allowed you to join")
val someoneAcceptedKnockEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent)
val someoneAcceptedKnock = formatter.processMessageItem(someoneAcceptedKnockEvent, false)
Truth.assertThat(someoneAcceptedKnock).isEqualTo("$otherName allowed ${someoneContent.userId.value} to join")
Truth.assertThat(someoneAcceptedKnock).isEqualTo("$otherName allowed ${someoneContent.userId} to join")
}
@Test
@@ -420,7 +420,7 @@ class DefaultRoomLastMessageFormatterTests {
fun `Membership change - knock retracted`() {
val otherName = "Someone"
val youContent = RoomMembershipContent(A_USER_ID, MembershipChange.KNOCK_RETRACTED)
val someoneContent = RoomMembershipContent(UserId("someone_else"), MembershipChange.KNOCK_RETRACTED)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.KNOCK_RETRACTED)
val youRetractedKnockEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent)
val youRetractedKnock = formatter.processMessageItem(youRetractedKnockEvent, false)
@@ -428,7 +428,7 @@ class DefaultRoomLastMessageFormatterTests {
val someoneRetractedKnockEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent)
val someoneRetractedKnock = formatter.processMessageItem(someoneRetractedKnockEvent, false)
Truth.assertThat(someoneRetractedKnock).isEqualTo("${someoneContent.userId.value} is no longer interested in joining")
Truth.assertThat(someoneRetractedKnock).isEqualTo("${someoneContent.userId} is no longer interested in joining")
}
@Test
@@ -436,15 +436,15 @@ class DefaultRoomLastMessageFormatterTests {
fun `Membership change - knock denied`() {
val otherName = "Someone"
val youContent = RoomMembershipContent(A_USER_ID, MembershipChange.KNOCK_DENIED)
val someoneContent = RoomMembershipContent(UserId("someone_else"), MembershipChange.KNOCK_DENIED)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.KNOCK_DENIED)
val youDeniedKnockEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = someoneContent)
val youDeniedKnock = formatter.processMessageItem(youDeniedKnockEvent, false)
Truth.assertThat(youDeniedKnock).isEqualTo("You rejected ${someoneContent.userId.value}'s request to join")
Truth.assertThat(youDeniedKnock).isEqualTo("You rejected ${someoneContent.userId}'s request to join")
val someoneDeniedKnockEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent)
val someoneDeniedKnock = formatter.processMessageItem(someoneDeniedKnockEvent, false)
Truth.assertThat(someoneDeniedKnock).isEqualTo("$otherName rejected ${someoneContent.userId.value}'s request to join")
Truth.assertThat(someoneDeniedKnock).isEqualTo("$otherName rejected ${someoneContent.userId}'s request to join")
val someoneDeniedYourKnockEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = youContent)
val someoneDeniedYourKnock = formatter.processMessageItem(someoneDeniedYourKnockEvent, false)
@@ -750,7 +750,7 @@ class DefaultRoomLastMessageFormatterTests {
// endregion
private fun createRoomEvent(sentByYou: Boolean, senderDisplayName: String?, content: EventContent): EventTimelineItem {
val sender = if (sentByYou) A_USER_ID else UserId("someone_else")
val sender = if (sentByYou) A_USER_ID else UserId("@someone_else:domain")
val profile = ProfileTimelineDetails.Ready(senderDisplayName, false, null)
return anEventTimelineItem(content = content, senderProfile = profile, sender = sender)
}

View File

@@ -123,10 +123,10 @@ class DefaultUserListPresenterTests {
}.test {
val initialState = awaitItem()
val userA = aMatrixUser("userA", "A")
val userB = aMatrixUser("userB", "B")
val userABis = aMatrixUser("userA", "A")
val userC = aMatrixUser("userC", "C")
val userA = aMatrixUser("@userA:domain", "A")
val userB = aMatrixUser("@userB:domain", "B")
val userABis = aMatrixUser("@userA:domain", "A")
val userC = aMatrixUser("@userC:domain", "C")
initialState.eventSink(UserListEvents.AddToSelection(userA))
assertThat(awaitItem().selectedUsers).containsExactly(userA)

View File

@@ -18,9 +18,9 @@ package io.element.android.libraries.deeplink
import android.content.Intent
import android.net.Uri
import io.element.android.libraries.matrix.api.core.asRoomId
import io.element.android.libraries.matrix.api.core.asSessionId
import io.element.android.libraries.matrix.api.core.asThreadId
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.api.core.ThreadId
import javax.inject.Inject
class DeeplinkParser @Inject constructor() {
@@ -35,9 +35,9 @@ class DeeplinkParser @Inject constructor() {
if (scheme != SCHEME) return null
if (host != HOST) return null
val pathBits = path.orEmpty().split("/").drop(1)
val sessionId = pathBits.elementAtOrNull(0)?.asSessionId() ?: return null
val roomId = pathBits.elementAtOrNull(1)?.asRoomId()
val threadId = pathBits.elementAtOrNull(2)?.asThreadId()
val sessionId = pathBits.elementAtOrNull(0)?.let(::SessionId) ?: return null
val roomId = pathBits.elementAtOrNull(1)?.let(::RoomId)
val threadId = pathBits.elementAtOrNull(2)?.let(::ThreadId)
return DeeplinkData(
sessionId = sessionId,
roomId = roomId,

View File

@@ -22,7 +22,7 @@ import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.A_SESSION_ID
import io.element.android.libraries.matrix.test.A_THREAD_ID
import io.element.android.tests.testutils.assertNullOrThrow
import io.element.android.tests.testutils.assertThrowsInDebug
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
@@ -59,12 +59,13 @@ class DeeplinkParserTest {
assertThat(sut.getFromIntent(createIntent("elementx://close/@alice:server.org"))).isNull()
// No session Id
assertThat(sut.getFromIntent(createIntent("elementx://open"))).isNull()
// Invalid sessionId
assertNullOrThrow {
assertThrowsInDebug {
// Invalid sessionId
sut.getFromIntent(createIntent("elementx://open/alice:server.org"))
}
// Empty sessionId
assertNullOrThrow {
assertThrowsInDebug {
// Empty sessionId
sut.getFromIntent(createIntent("elementx://open//"))
}
}

View File

@@ -20,10 +20,12 @@ import io.element.android.libraries.matrix.api.BuildConfig
import java.io.Serializable
@JvmInline
value class EventId(val value: String) : Serializable
value class EventId(val value: String) : Serializable {
init {
if (BuildConfig.DEBUG && !MatrixPatterns.isEventId(value)) {
error("`$value` is not a valid event id.\nExample event id: `\$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg`.")
}
}
fun String.asEventId() = if (BuildConfig.DEBUG && !MatrixPatterns.isEventId(this)) {
error("`$this` is not a valid event Id")
} else {
EventId(this)
override fun toString(): String = value
}

View File

@@ -21,13 +21,12 @@ import java.io.Serializable
@JvmInline
value class RoomId(val value: String) : Serializable {
override fun toString(): String {
return value
}
}
fun String.asRoomId() = if (BuildConfig.DEBUG && !MatrixPatterns.isRoomId(this)) {
error("`$this` is not a valid room Id")
} else {
RoomId(this)
init {
if (BuildConfig.DEBUG && !MatrixPatterns.isRoomId(value)) {
error("`$value` is not a valid room id.\n Example room id: `!room_id:domain`.")
}
}
override fun toString(): String = value
}

View File

@@ -16,12 +16,4 @@
package io.element.android.libraries.matrix.api.core
import io.element.android.libraries.matrix.api.BuildConfig
typealias SessionId = UserId
fun String.asSessionId() = if (BuildConfig.DEBUG && !MatrixPatterns.isSessionId(this)) {
error("`$this` is not a valid session Id")
} else {
SessionId(this)
}

View File

@@ -20,15 +20,21 @@ import io.element.android.libraries.matrix.api.BuildConfig
import java.io.Serializable
@JvmInline
value class SpaceId(val value: String) : Serializable
value class SpaceId(val value: String) : Serializable {
init {
if (BuildConfig.DEBUG && !MatrixPatterns.isSpaceId(value)) {
error(
"`$value` is not a valid space id.\n" +
"Space ids are the same as room ids.\n" +
"Example space id: `!space_id:domain`."
)
}
}
override fun toString(): String = value
}
/**
* Value to use when no space is selected by the user.
*/
val MAIN_SPACE = SpaceId("!mainSpace")
fun String.asSpaceId() = if (BuildConfig.DEBUG && !MatrixPatterns.isSpaceId(this)) {
error("`$this` is not a valid space Id")
} else {
SpaceId(this)
}
val MAIN_SPACE = SpaceId("!mainSpace:local")

View File

@@ -20,10 +20,16 @@ import io.element.android.libraries.matrix.api.BuildConfig
import java.io.Serializable
@JvmInline
value class ThreadId(val value: String) : Serializable
value class ThreadId(val value: String) : Serializable {
init {
if (BuildConfig.DEBUG && !MatrixPatterns.isThreadId(value)) {
error(
"`$value` is not a valid thread id.\n" +
"Thread ids are the same as event ids.\n" +
"Example thread id: `\$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg`."
)
}
}
fun String.asThreadId() = if (BuildConfig.DEBUG && !MatrixPatterns.isThreadId(this)) {
error("`$this` is not a valid thread Id")
} else {
ThreadId(this)
override fun toString(): String = value
}

View File

@@ -21,13 +21,12 @@ import java.io.Serializable
@JvmInline
value class UserId(val value: String) : Serializable {
override fun toString(): String {
return value
}
}
fun String.asUserId() = if (BuildConfig.DEBUG && !MatrixPatterns.isUserId(this)) {
error("`$this` is not a valid user Id")
} else {
UserId(this)
init {
if (BuildConfig.DEBUG && !MatrixPatterns.isUserId(value)) {
error("`$value` is not a valid user id.\nExample user id: `@name:domain`.")
}
}
override fun toString(): String = value
}

View File

@@ -20,7 +20,6 @@ import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.matrix.api.MatrixClient
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.core.asRoomId
import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters
import io.element.android.libraries.matrix.api.createroom.RoomPreset
import io.element.android.libraries.matrix.api.createroom.RoomVisibility
@@ -201,7 +200,7 @@ class RustMatrixClient constructor(
invite = createRoomParams.invite?.map { it.value },
avatar = createRoomParams.avatar,
)
val roomId = client.createRoom(rustParams).asRoomId()
val roomId = RoomId(client.createRoom(rustParams))
// Wait to receive the room back from the sync
withTimeout(30_000L) {

View File

@@ -17,7 +17,6 @@
package io.element.android.libraries.matrix.impl.timeline.item.event
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.asEventId
import io.element.android.libraries.matrix.api.timeline.item.event.AudioMessageType
import io.element.android.libraries.matrix.api.timeline.item.event.EmoteMessageType
import io.element.android.libraries.matrix.api.timeline.item.event.FileMessageType
@@ -70,7 +69,7 @@ class EventMessageMapper {
}
MessageContent(
body = message.body(),
inReplyTo = message.inReplyTo()?.eventId?.asEventId(),
inReplyTo = message.inReplyTo()?.eventId?.let(::EventId),
isEdited = message.isEdited(),
type = type
)

View File

@@ -29,8 +29,8 @@ const val A_PASSWORD = "password"
val A_USER_ID = UserId("@alice:server.org")
val A_USER_ID_2 = UserId("@bob:server.org")
val A_SESSION_ID = SessionId(A_USER_ID.value)
val A_SESSION_ID_2 = SessionId(A_USER_ID_2.value)
val A_SESSION_ID: SessionId = A_USER_ID
val A_SESSION_ID_2: SessionId = A_USER_ID_2
val A_SPACE_ID = SpaceId("!aSpaceId:domain")
val A_ROOM_ID = RoomId("!aRoomId:domain")
val A_ROOM_ID_2 = RoomId("!aRoomId2:domain")

View File

@@ -24,9 +24,7 @@ import io.element.android.libraries.architecture.bindings
import io.element.android.libraries.core.log.logger.LoggerTag
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.api.core.asRoomId
import io.element.android.libraries.matrix.api.core.asSessionId
import io.element.android.libraries.matrix.api.core.asThreadId
import io.element.android.libraries.matrix.api.core.ThreadId
import io.element.android.libraries.push.impl.log.notificationLoggerTag
import io.element.android.services.analytics.api.AnalyticsTracker
import io.element.android.services.toolbox.api.systemclock.SystemClock
@@ -51,32 +49,27 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
if (intent == null || context == null) return
context.bindings<NotificationBroadcastReceiverBindings>().inject(this)
Timber.tag(loggerTag.value).v("NotificationBroadcastReceiver received : $intent")
val sessionId = intent.extras?.getString(KEY_SESSION_ID)?.asSessionId() ?: return
val sessionId = intent.extras?.getString(KEY_SESSION_ID)?.let(::SessionId) ?: return
val roomId = intent.getStringExtra(KEY_ROOM_ID)?.let(::RoomId)
when (intent.action) {
actionIds.smartReply ->
handleSmartReply(intent, context)
actionIds.dismissRoom ->
intent.getStringExtra(KEY_ROOM_ID)?.asRoomId()?.let { roomId ->
notificationDrawerManager.clearMessagesForRoom(sessionId, roomId)
}
actionIds.dismissRoom -> if (roomId != null) {
notificationDrawerManager.clearMessagesForRoom(sessionId, roomId)
}
actionIds.dismissSummary ->
notificationDrawerManager.clearAllEvents(sessionId)
actionIds.markRoomRead ->
intent.getStringExtra(KEY_ROOM_ID)?.asRoomId()?.let { roomId ->
notificationDrawerManager.clearMessagesForRoom(sessionId, roomId)
handleMarkAsRead(sessionId, roomId)
}
actionIds.join -> {
intent.getStringExtra(KEY_ROOM_ID)?.asRoomId()?.let { roomId ->
notificationDrawerManager.clearMemberShipNotificationForRoom(sessionId, roomId)
handleJoinRoom(sessionId, roomId)
}
actionIds.markRoomRead -> if (roomId != null) {
notificationDrawerManager.clearMessagesForRoom(sessionId, roomId)
handleMarkAsRead(sessionId, roomId)
}
actionIds.reject -> {
intent.getStringExtra(KEY_ROOM_ID)?.asRoomId()?.let { roomId ->
notificationDrawerManager.clearMemberShipNotificationForRoom(sessionId, roomId)
handleRejectRoom(sessionId, roomId)
}
actionIds.join -> if (roomId != null) {
notificationDrawerManager.clearMemberShipNotificationForRoom(sessionId, roomId)
handleJoinRoom(sessionId, roomId)
}
actionIds.reject -> if (roomId != null) {
notificationDrawerManager.clearMemberShipNotificationForRoom(sessionId, roomId)
handleRejectRoom(sessionId, roomId)
}
}
}
@@ -125,9 +118,9 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
private fun handleSmartReply(intent: Intent, context: Context) {
val message = getReplyMessage(intent)
val sessionId = intent.getStringExtra(KEY_SESSION_ID)?.asSessionId()
val roomId = intent.getStringExtra(KEY_ROOM_ID)?.asRoomId()
val threadId = intent.getStringExtra(KEY_THREAD_ID)?.asThreadId()
val sessionId = intent.getStringExtra(KEY_SESSION_ID)?.let(::SessionId)
val roomId = intent.getStringExtra(KEY_ROOM_ID)?.let(::RoomId)
val threadId = intent.getStringExtra(KEY_THREAD_ID)?.let(::ThreadId)
if (message.isNullOrBlank() || roomId == null) {
// ignore this event

View File

@@ -63,7 +63,7 @@ class PendingIntentFactory @Inject constructor(
fun createDismissSummaryPendingIntent(sessionId: SessionId): PendingIntent {
val intent = Intent(context, NotificationBroadcastReceiver::class.java)
intent.action = actionIds.dismissSummary
intent.data = createIgnoredUri("deleteSummary/${sessionId.value}")
intent.data = createIgnoredUri("deleteSummary/$sessionId")
intent.putExtra(NotificationBroadcastReceiver.KEY_SESSION_ID, sessionId.value)
return PendingIntent.getBroadcast(
context,
@@ -76,7 +76,7 @@ class PendingIntentFactory @Inject constructor(
fun createDismissRoomPendingIntent(sessionId: SessionId, roomId: RoomId): PendingIntent {
val intent = Intent(context, NotificationBroadcastReceiver::class.java)
intent.action = actionIds.dismissRoom
intent.data = createIgnoredUri("deleteRoom/${sessionId.value}/${roomId.value}")
intent.data = createIgnoredUri("deleteRoom/$sessionId/$roomId")
intent.putExtra(NotificationBroadcastReceiver.KEY_SESSION_ID, sessionId.value)
intent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomId.value)
return PendingIntent.getBroadcast(

View File

@@ -78,7 +78,7 @@ class QuickReplyActionFactory @Inject constructor(
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val intent = Intent(context, NotificationBroadcastReceiver::class.java)
intent.action = actionIds.smartReply
intent.data = createIgnoredUri("quickReply/${sessionId.value}/${roomId.value}" + threadId?.let { "/${it.value}" }.orEmpty())
intent.data = createIgnoredUri("quickReply/$sessionId/$roomId" + threadId?.let { "/$it" }.orEmpty())
intent.putExtra(NotificationBroadcastReceiver.KEY_SESSION_ID, sessionId.value)
intent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomId.value)
threadId?.let {

View File

@@ -35,21 +35,21 @@ class NotificationEventQueueTest {
fun `given events when redacting some then marks matching event ids as redacted`() {
val queue = givenQueue(
listOf(
aSimpleNotifiableEvent(eventId = EventId("redacted-id-1")),
aNotifiableMessageEvent(eventId = EventId("redacted-id-2")),
anInviteNotifiableEvent(eventId = EventId("redacted-id-3")),
aSimpleNotifiableEvent(eventId = EventId("kept-id")),
aSimpleNotifiableEvent(eventId = EventId("\$redacted-id-1")),
aNotifiableMessageEvent(eventId = EventId("\$redacted-id-2")),
anInviteNotifiableEvent(eventId = EventId("\$redacted-id-3")),
aSimpleNotifiableEvent(eventId = EventId("\$kept-id")),
)
)
queue.markRedacted(listOf(EventId("redacted-id-1"), EventId("redacted-id-2"), EventId("redacted-id-3")))
queue.markRedacted(listOf(EventId("\$redacted-id-1"), EventId("\$redacted-id-2"), EventId("\$redacted-id-3")))
assertThat(queue.rawEvents()).isEqualTo(
listOf(
aSimpleNotifiableEvent(eventId = EventId("redacted-id-1"), isRedacted = true),
aNotifiableMessageEvent(eventId = EventId("redacted-id-2"), isRedacted = true),
anInviteNotifiableEvent(eventId = EventId("redacted-id-3"), isRedacted = true),
aSimpleNotifiableEvent(eventId = EventId("kept-id"), isRedacted = false),
aSimpleNotifiableEvent(eventId = EventId("\$redacted-id-1"), isRedacted = true),
aNotifiableMessageEvent(eventId = EventId("\$redacted-id-2"), isRedacted = true),
anInviteNotifiableEvent(eventId = EventId("\$redacted-id-3"), isRedacted = true),
aSimpleNotifiableEvent(eventId = EventId("\$kept-id"), isRedacted = false),
)
)
}
@@ -179,8 +179,8 @@ class NotificationEventQueueTest {
@Test
fun `given event when adding new event with edited event id matching the existing event id then updates existing event`() {
val editedEvent = aSimpleNotifiableEvent(eventId = EventId("id-to-edit"))
val updatedEvent = editedEvent.copy(eventId = EventId("1"), editedEventId = EventId("id-to-edit"), title = "updated title", isUpdated = true)
val editedEvent = aSimpleNotifiableEvent(eventId = EventId("\$id-to-edit"))
val updatedEvent = editedEvent.copy(eventId = EventId("\$1"), editedEventId = EventId("\$id-to-edit"), title = "updated title", isUpdated = true)
val queue = givenQueue(listOf(editedEvent))
queue.add(updatedEvent)
@@ -190,8 +190,8 @@ class NotificationEventQueueTest {
@Test
fun `given event when adding new event with edited event id matching the existing event edited id then updates existing event`() {
val editedEvent = aSimpleNotifiableEvent(eventId = EventId("0"), editedEventId = EventId("id-to-edit"))
val updatedEvent = editedEvent.copy(eventId = EventId("1"), editedEventId = EventId("id-to-edit"), title = "updated title", isUpdated = true)
val editedEvent = aSimpleNotifiableEvent(eventId = EventId("\$0"), editedEventId = EventId("\$id-to-edit"))
val updatedEvent = editedEvent.copy(eventId = EventId("\$1"), editedEventId = EventId("\$id-to-edit"), title = "updated title", isUpdated = true)
val queue = givenQueue(listOf(editedEvent))
queue.add(updatedEvent)

View File

@@ -171,10 +171,10 @@ class NotificationFactoryTest {
val roomWithRedactedMessage = mapOf(
A_ROOM_ID to listOf(
ProcessedEvent(ProcessedEvent.Type.KEEP, A_MESSAGE_EVENT.copy(isRedacted = true)),
ProcessedEvent(ProcessedEvent.Type.KEEP, A_MESSAGE_EVENT.copy(eventId = EventId("not-redacted")))
ProcessedEvent(ProcessedEvent.Type.KEEP, A_MESSAGE_EVENT.copy(eventId = EventId("\$not-redacted")))
)
)
val withRedactedRemoved = listOf(A_MESSAGE_EVENT.copy(eventId = EventId("not-redacted")))
val withRedactedRemoved = listOf(A_MESSAGE_EVENT.copy(eventId = EventId("\$not-redacted")))
val expectedNotification = roomGroupMessageCreator.givenCreatesRoomMessageFor(
A_SESSION_ID,
withRedactedRemoved,

View File

@@ -18,7 +18,7 @@ package io.element.android.libraries.push.providers.firebase
import io.element.android.libraries.core.log.logger.LoggerTag
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
import io.element.android.libraries.matrix.api.core.asSessionId
import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.push.providers.api.PusherSubscriber
import io.element.android.libraries.pushstore.api.UserPushStoreFactory
import io.element.android.libraries.sessionstorage.api.SessionStore
@@ -42,7 +42,7 @@ class FirebaseNewTokenHandler @Inject constructor(
firebaseStore.storeFcmToken(firebaseToken)
// Register the pusher for all the sessions
sessionStore.getAllSessions().toUserList()
.mapNotNull { it.asSessionId() }
.map { SessionId(it) }
.forEach { userId ->
val userDataStore = userPushStoreFactory.create(userId)
if (userDataStore.getPushProviderName() == FirebaseConfig.name) {

View File

@@ -16,8 +16,8 @@
package io.element.android.libraries.push.providers.firebase
import io.element.android.libraries.matrix.api.core.asEventId
import io.element.android.libraries.matrix.api.core.asRoomId
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.push.providers.api.PushData
/**
@@ -41,8 +41,8 @@ data class PushDataFirebase(
)
fun PushDataFirebase.toPushData(): PushData? {
val safeEventId = eventId?.asEventId() ?: return null
val safeRoomId = roomId?.asRoomId() ?: return null
val safeEventId = eventId?.let(::EventId) ?: return null
val safeRoomId = roomId?.let(::RoomId) ?: return null
return PushData(
eventId = safeEventId,
roomId = safeRoomId,

View File

@@ -20,7 +20,7 @@ import com.google.common.truth.Truth.assertThat
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.push.providers.api.PushData
import io.element.android.tests.testutils.assertNullOrThrow
import io.element.android.tests.testutils.assertThrowsInDebug
import org.junit.Test
class FirebasePushParserTest {
@@ -52,26 +52,26 @@ class FirebasePushParserTest {
fun `test empty roomId`() {
val pushParser = FirebasePushParser()
assertThat(pushParser.parse(FIREBASE_PUSH_DATA.mutate("room_id", null))).isNull()
assertNullOrThrow { pushParser.parse(FIREBASE_PUSH_DATA.mutate("room_id", "")) }
assertThrowsInDebug { pushParser.parse(FIREBASE_PUSH_DATA.mutate("room_id", "")) }
}
@Test
fun `test invalid roomId`() {
val pushParser = FirebasePushParser()
assertNullOrThrow { pushParser.parse(FIREBASE_PUSH_DATA.mutate("room_id", "aRoomId:domain")) }
assertThrowsInDebug { pushParser.parse(FIREBASE_PUSH_DATA.mutate("room_id", "aRoomId:domain")) }
}
@Test
fun `test empty eventId`() {
val pushParser = FirebasePushParser()
assertThat(pushParser.parse(FIREBASE_PUSH_DATA.mutate("event_id", null))).isNull()
assertNullOrThrow { pushParser.parse(FIREBASE_PUSH_DATA.mutate("event_id", "")) }
assertThrowsInDebug { pushParser.parse(FIREBASE_PUSH_DATA.mutate("event_id", "")) }
}
@Test
fun `test invalid eventId`() {
val pushParser = FirebasePushParser()
assertNullOrThrow { pushParser.parse(FIREBASE_PUSH_DATA.mutate("event_id", "anEventId")) }
assertThrowsInDebug { pushParser.parse(FIREBASE_PUSH_DATA.mutate("event_id", "anEventId")) }
}
companion object {

View File

@@ -16,8 +16,8 @@
package io.element.android.libraries.push.providers.unifiedpush
import io.element.android.libraries.matrix.api.core.asEventId
import io.element.android.libraries.matrix.api.core.asRoomId
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.push.providers.api.PushData
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@@ -56,8 +56,8 @@ data class PushDataUnifiedPushCounts(
)
fun PushDataUnifiedPush.toPushData(clientSecret: String): PushData? {
val safeEventId = notification?.eventId?.asEventId() ?: return null
val safeRoomId = notification.roomId?.asRoomId() ?: return null
val safeEventId = notification?.eventId?.let(::EventId) ?: return null
val safeRoomId = notification.roomId?.let(::RoomId) ?: return null
return PushData(
eventId = safeEventId,
roomId = safeRoomId,

View File

@@ -20,7 +20,7 @@ import com.google.common.truth.Truth.assertThat
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.push.providers.api.PushData
import io.element.android.tests.testutils.assertNullOrThrow
import io.element.android.tests.testutils.assertThrowsInDebug
import org.junit.Test
class UnifiedPushParserTest {
@@ -52,7 +52,7 @@ class UnifiedPushParserTest {
@Test
fun `test empty roomId`() {
val pushParser = UnifiedPushParser()
assertNullOrThrow {
assertThrowsInDebug {
pushParser.parse(UNIFIED_PUSH_DATA.replace(A_ROOM_ID.value, "").toByteArray(), aClientSecret)
}
}
@@ -60,7 +60,7 @@ class UnifiedPushParserTest {
@Test
fun `test invalid roomId`() {
val pushParser = UnifiedPushParser()
assertNullOrThrow {
assertThrowsInDebug {
pushParser.parse(UNIFIED_PUSH_DATA.mutate(A_ROOM_ID.value, "aRoomId:domain"), aClientSecret)
}
}
@@ -68,7 +68,7 @@ class UnifiedPushParserTest {
@Test
fun `test empty eventId`() {
val pushParser = UnifiedPushParser()
assertNullOrThrow {
assertThrowsInDebug {
pushParser.parse(UNIFIED_PUSH_DATA.mutate(AN_EVENT_ID.value, ""), aClientSecret)
}
}
@@ -76,14 +76,14 @@ class UnifiedPushParserTest {
@Test
fun `test invalid eventId`() {
val pushParser = UnifiedPushParser()
assertNullOrThrow {
assertThrowsInDebug {
pushParser.parse(UNIFIED_PUSH_DATA.mutate(AN_EVENT_ID.value, "anEventId"), aClientSecret)
}
}
companion object {
private val UNIFIED_PUSH_DATA =
"{\"notification\":{\"event_id\":\"${AN_EVENT_ID.value}\",\"room_id\":\"${A_ROOM_ID.value}\",\"counts\":{\"unread\":1},\"prio\":\"high\"}}"
"{\"notification\":{\"event_id\":\"$AN_EVENT_ID\",\"room_id\":\"$A_ROOM_ID\",\"counts\":{\"unread\":1},\"prio\":\"high\"}}"
// TODO Check client secret format?
}
}

View File

@@ -22,7 +22,6 @@ import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.ApplicationContext
import io.element.android.libraries.di.SingleIn
import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.api.core.asSessionId
import io.element.android.libraries.pushstore.api.UserPushStore
import io.element.android.libraries.pushstore.api.UserPushStoreFactory
import io.element.android.libraries.sessionstorage.api.observer.SessionListener
@@ -60,6 +59,6 @@ class DefaultUserPushStoreFactory @Inject constructor(
override suspend fun onSessionDeleted(userId: String) {
// Delete the store
userId.asSessionId()?.let { create(it).reset() }
create(SessionId(userId)).reset()
}
}

View File

@@ -26,7 +26,6 @@ import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.ApplicationContext
import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.api.core.asSessionId
import io.element.android.libraries.pushstore.api.clientsecret.PushClientSecretStore
import kotlinx.coroutines.flow.first
import javax.inject.Inject
@@ -58,7 +57,7 @@ class PushClientSecretStoreDataStore @Inject constructor(
val matchingKey = keyValues.keys.find {
keyValues[it] == clientSecret
}
return matchingKey?.name?.asSessionId()
return matchingKey?.name?.let(::SessionId)
}
private fun getPreferenceKeyForUser(userId: SessionId) = stringPreferencesKey(userId.value)

View File

@@ -24,8 +24,8 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.junit.Test
private val A_USER_ID_0 = SessionId("A_USER_ID_0")
private val A_USER_ID_1 = SessionId("A_USER_ID_1")
private val A_USER_ID_0 = SessionId("@A_USER_ID_0:domain")
private val A_USER_ID_1 = SessionId("@A_USER_ID_1:domain")
private const val A_UNKNOWN_SECRET = "A_UNKNOWN_SECRET"

View File

@@ -16,18 +16,17 @@
package io.element.android.tests.testutils
import com.google.common.truth.Truth.assertThat
import org.junit.Assert.assertThrows
/**
* Assert that the lambda throws on debug and returns null on release.
* Assert that the lambda throws only on debug mode.
*/
fun assertNullOrThrow(lambda: () -> Any?) {
fun assertThrowsInDebug(lambda: () -> Any?) {
if (BuildConfig.DEBUG) {
assertThrows(IllegalStateException::class.java) {
lambda()
}
} else {
assertThat(lambda()).isNull()
lambda()
}
}