From 63ebe5ac1e1e10f313279e02ec84327efcefda5f Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Wed, 25 Sep 2024 13:47:37 +0200 Subject: [PATCH 1/2] Add test for conversation conversion This test respects different API versions and checks if default values are set as expected. - remove deprecated+unused methods - remove comments - remove unnecessary double-bang operator Signed-off-by: Marcel Hibbe --- .../nextcloud/talk/activities/CallActivity.kt | 5 +- .../ConversationInfoActivity.kt | 8 +- .../database/mappers/ConversationMapUtils.kt | 42 ++--- .../talk/models/domain/ConversationModel.kt | 88 +++------- .../models/json/conversations/Conversation.kt | 133 ++++----------- .../dialog/ConversationsListBottomDialog.kt | 2 +- .../nextcloud/talk/utils/ConversationUtils.kt | 19 --- .../talk/json/ConversationConversionTest.kt | 157 ++++++++++++++++++ .../resources/RoomOverallExample_APIv1.json | 66 ++++++++ .../resources/RoomOverallExample_APIv2.json | 51 ++++++ .../resources/RoomOverallExample_APIv4.json | 83 +++++++++ 11 files changed, 436 insertions(+), 218 deletions(-) create mode 100644 app/src/test/java/com/nextcloud/talk/json/ConversationConversionTest.kt create mode 100644 app/src/test/resources/RoomOverallExample_APIv1.json create mode 100644 app/src/test/resources/RoomOverallExample_APIv2.json create mode 100644 app/src/test/resources/RoomOverallExample_APIv4.json diff --git a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.kt b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.kt index 4302e27549..7f9ee8f6b5 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.kt @@ -1745,9 +1745,8 @@ class CallActivity : CallBaseActivity() { ApplicationWideCurrentRoomHolder.getInstance().callStartTime = conversation.callStartTime } - private fun startCallTimeCounter(callStartTime: Long?) { - if (callStartTime != null && - callStartTime != 0L && + private fun startCallTimeCounter(callStartTime: Long) { + if (callStartTime != 0L && hasSpreedFeatureCapability( conversationUser!!.capabilities!!.spreedCapability!!, SpreedFeatures.RECORDING_V1 ) diff --git a/app/src/main/java/com/nextcloud/talk/conversationinfo/ConversationInfoActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationinfo/ConversationInfoActivity.kt index 8ab356befe..2005ebdffa 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationinfo/ConversationInfoActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationinfo/ConversationInfoActivity.kt @@ -356,8 +356,8 @@ class ConversationInfoActivity : binding.webinarInfoView.startTimeButton.setOnClickListener { MaterialDialog(this, BottomSheet(WRAP_CONTENT)).show { val currentTimeCalendar = Calendar.getInstance() - if (conversation!!.lobbyTimer != null && conversation!!.lobbyTimer != 0L) { - currentTimeCalendar.timeInMillis = conversation!!.lobbyTimer!! * DateConstants.SECOND_DIVIDER + if (conversation!!.lobbyTimer != 0L) { + currentTimeCalendar.timeInMillis = conversation!!.lobbyTimer * DateConstants.SECOND_DIVIDER } dateTimePicker( @@ -746,13 +746,13 @@ class ConversationInfoActivity : setupWebinaryView() - if (!ConversationUtils.canLeave(conversation!!)) { + if (!conversation!!.canLeaveConversation) { binding.leaveConversationAction.visibility = GONE } else { binding.leaveConversationAction.visibility = VISIBLE } - if (!ConversationUtils.canDelete(conversation!!, spreedCapabilities)) { + if (!conversation!!.canDeleteConversation) { binding.deleteConversationAction.visibility = GONE } else { binding.deleteConversationAction.visibility = VISIBLE diff --git a/app/src/main/java/com/nextcloud/talk/data/database/mappers/ConversationMapUtils.kt b/app/src/main/java/com/nextcloud/talk/data/database/mappers/ConversationMapUtils.kt index 37d8fbced4..c6c80a485e 100644 --- a/app/src/main/java/com/nextcloud/talk/data/database/mappers/ConversationMapUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/data/database/mappers/ConversationMapUtils.kt @@ -116,36 +116,36 @@ fun Conversation.asEntity(accountId: Long) = ConversationEntity( internalId = "$accountId@$token", accountId = accountId, - token = token!!, - name = name!!, - displayName = displayName!!, - description = description!!, - type = type!!, + token = token, + name = name, + displayName = displayName, + description = description, + type = type, lastPing = lastPing, - participantType = participantType!!, + participantType = participantType, hasPassword = hasPassword, - sessionId = sessionId!!, - actorId = actorId!!, - actorType = actorType!!, + sessionId = sessionId, + actorId = actorId, + actorType = actorType, favorite = favorite, lastActivity = lastActivity, unreadMessages = unreadMessages, unreadMention = unreadMention, lastMessage = lastMessage?.let { LoganSquare.serialize(lastMessage) }, - objectType = objectType!!, - notificationLevel = notificationLevel!!, - conversationReadOnlyState = conversationReadOnlyState!!, - lobbyState = lobbyState!!, - lobbyTimer = lobbyTimer!!, + objectType = objectType, + notificationLevel = notificationLevel, + conversationReadOnlyState = conversationReadOnlyState, + lobbyState = lobbyState, + lobbyTimer = lobbyTimer, lastReadMessage = lastReadMessage, lastCommonReadMessage = lastCommonReadMessage, hasCall = hasCall, callFlag = callFlag, canStartCall = canStartCall, - canLeaveConversation = canLeaveConversation!!, - canDeleteConversation = canDeleteConversation!!, - unreadMentionDirect = unreadMentionDirect!!, - notificationCalls = notificationCalls!!, + canLeaveConversation = canLeaveConversation, + canDeleteConversation = canDeleteConversation, + unreadMentionDirect = unreadMentionDirect, + notificationCalls = notificationCalls, permissions = permissions, messageExpiration = messageExpiration, status = status, @@ -153,9 +153,9 @@ fun Conversation.asEntity(accountId: Long) = statusMessage = statusMessage, statusClearAt = statusClearAt, callRecording = callRecording, - avatarVersion = avatarVersion!!, - hasCustomAvatar = hasCustomAvatar!!, - callStartTime = callStartTime!!, + avatarVersion = avatarVersion, + hasCustomAvatar = hasCustomAvatar, + callStartTime = callStartTime, recordingConsentRequired = recordingConsentRequired, remoteServer = remoteServer, remoteToken = remoteToken diff --git a/app/src/main/java/com/nextcloud/talk/models/domain/ConversationModel.kt b/app/src/main/java/com/nextcloud/talk/models/domain/ConversationModel.kt index 6e361a7110..d653b80986 100644 --- a/app/src/main/java/com/nextcloud/talk/models/domain/ConversationModel.kt +++ b/app/src/main/java/com/nextcloud/talk/models/domain/ConversationModel.kt @@ -16,7 +16,6 @@ import com.nextcloud.talk.models.json.participants.Participant class ConversationModel( var internalId: String, var accountId: Long, - // var roomId: String? = null, var token: String, var name: String, var displayName: String, @@ -70,46 +69,45 @@ class ConversationModel( return ConversationModel( internalId = user.id!!.toString() + "@" + conversation.token, accountId = user.id!!, - // roomId = conversation.roomId, - token = conversation.token!!, - name = conversation.name!!, - displayName = conversation.displayName!!, - description = conversation.description!!, - type = conversation.type.let { ConversationEnums.ConversationType.valueOf(it!!.name) }, + token = conversation.token, + name = conversation.name, + displayName = conversation.displayName, + description = conversation.description, + type = conversation.type.let { ConversationEnums.ConversationType.valueOf(it.name) }, lastPing = conversation.lastPing, - participantType = conversation.participantType.let { Participant.ParticipantType.valueOf(it!!.name) }, + participantType = conversation.participantType.let { Participant.ParticipantType.valueOf(it.name) }, hasPassword = conversation.hasPassword, - sessionId = conversation.sessionId!!, - actorId = conversation.actorId!!, - actorType = conversation.actorType!!, + sessionId = conversation.sessionId, + actorId = conversation.actorId, + actorType = conversation.actorType, password = conversation.password, favorite = conversation.favorite, lastActivity = conversation.lastActivity, unreadMessages = conversation.unreadMessages, unreadMention = conversation.unreadMention, lastMessage = conversation.lastMessage, - objectType = conversation.objectType.let { ConversationEnums.ObjectType.valueOf(it!!.name) }, + objectType = conversation.objectType.let { ConversationEnums.ObjectType.valueOf(it.name) }, notificationLevel = conversation.notificationLevel.let { ConversationEnums.NotificationLevel.valueOf( - it!!.name + it.name ) }, conversationReadOnlyState = conversation.conversationReadOnlyState.let { ConversationEnums.ConversationReadOnlyState.valueOf( - it!!.name + it.name ) }, - lobbyState = conversation.lobbyState.let { ConversationEnums.LobbyState.valueOf(it!!.name) }, - lobbyTimer = conversation.lobbyTimer!!, + lobbyState = conversation.lobbyState.let { ConversationEnums.LobbyState.valueOf(it.name) }, + lobbyTimer = conversation.lobbyTimer, lastReadMessage = conversation.lastReadMessage, lastCommonReadMessage = conversation.lastCommonReadMessage, hasCall = conversation.hasCall, callFlag = conversation.callFlag, canStartCall = conversation.canStartCall, - canLeaveConversation = conversation.canLeaveConversation!!, - canDeleteConversation = conversation.canDeleteConversation!!, - unreadMentionDirect = conversation.unreadMentionDirect!!, - notificationCalls = conversation.notificationCalls!!, + canLeaveConversation = conversation.canLeaveConversation, + canDeleteConversation = conversation.canDeleteConversation, + unreadMentionDirect = conversation.unreadMentionDirect, + notificationCalls = conversation.notificationCalls, permissions = conversation.permissions, messageExpiration = conversation.messageExpiration, status = conversation.status, @@ -117,9 +115,9 @@ class ConversationModel( statusMessage = conversation.statusMessage, statusClearAt = conversation.statusClearAt, callRecording = conversation.callRecording, - avatarVersion = conversation.avatarVersion!!, - hasCustomAvatar = conversation.hasCustomAvatar!!, - callStartTime = conversation.callStartTime!!, + avatarVersion = conversation.avatarVersion, + hasCustomAvatar = conversation.hasCustomAvatar, + callStartTime = conversation.callStartTime, recordingConsentRequired = conversation.recordingConsentRequired, remoteServer = conversation.remoteServer, remoteToken = conversation.remoteToken @@ -127,47 +125,3 @@ class ConversationModel( } } } - -// enum class ConversationType { -// DUMMY, -// ROOM_TYPE_ONE_TO_ONE_CALL, -// ROOM_GROUP_CALL, -// ROOM_PUBLIC_CALL, -// ROOM_SYSTEM, -// FORMER_ONE_TO_ONE, -// NOTE_TO_SELF -// } -// -// enum class ParticipantType { -// DUMMY, -// OWNER, -// MODERATOR, -// USER, -// GUEST, -// USER_FOLLOWING_LINK, -// GUEST_MODERATOR -// } -// -// enum class ObjectType { -// DEFAULT, -// SHARE_PASSWORD, -// FILE, -// ROOM -// } -// -// enum class NotificationLevel { -// DEFAULT, -// ALWAYS, -// MENTION, -// NEVER -// } -// -// enum class ConversationReadOnlyState { -// CONVERSATION_READ_WRITE, -// CONVERSATION_READ_ONLY -// } -// -// enum class LobbyState { -// LOBBY_STATE_ALL_PARTICIPANTS, -// LOBBY_STATE_MODERATORS_ONLY -// } diff --git a/app/src/main/java/com/nextcloud/talk/models/json/conversations/Conversation.kt b/app/src/main/java/com/nextcloud/talk/models/json/conversations/Conversation.kt index 7b22165cc4..65cd280c91 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/conversations/Conversation.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/conversations/Conversation.kt @@ -12,8 +12,6 @@ package com.nextcloud.talk.models.json.conversations import android.os.Parcelable import com.bluelinelabs.logansquare.annotation.JsonField import com.bluelinelabs.logansquare.annotation.JsonObject -import com.nextcloud.talk.data.user.model.User -import com.nextcloud.talk.models.domain.ConversationModel import com.nextcloud.talk.models.json.chat.ChatMessageJson import com.nextcloud.talk.models.json.converters.ConversationObjectTypeConverter import com.nextcloud.talk.models.json.converters.EnumLobbyStateConverter @@ -22,48 +20,45 @@ import com.nextcloud.talk.models.json.converters.EnumParticipantTypeConverter import com.nextcloud.talk.models.json.converters.EnumReadOnlyConversationConverter import com.nextcloud.talk.models.json.converters.EnumRoomTypeConverter import com.nextcloud.talk.models.json.participants.Participant.ParticipantType -import com.nextcloud.talk.utils.ConversationUtils import kotlinx.parcelize.Parcelize @Parcelize @JsonObject data class Conversation( - // @JsonField(name = ["id"]) - // var roomId: String? = null, @JsonField(name = ["token"]) - var token: String? = null, + var token: String = "", @JsonField(name = ["name"]) - var name: String? = null, + var name: String = "", @JsonField(name = ["displayName"]) - var displayName: String? = null, + var displayName: String = "", @JsonField(name = ["description"]) - var description: String? = null, + var description: String = "", @JsonField(name = ["type"], typeConverter = EnumRoomTypeConverter::class) - var type: ConversationEnums.ConversationType? = null, + var type: ConversationEnums.ConversationType = ConversationEnums.ConversationType.DUMMY, @JsonField(name = ["lastPing"]) var lastPing: Long = 0, @JsonField(name = ["participantType"], typeConverter = EnumParticipantTypeConverter::class) - var participantType: ParticipantType? = null, + var participantType: ParticipantType = ParticipantType.DUMMY, @JsonField(name = ["hasPassword"]) var hasPassword: Boolean = false, @JsonField(name = ["sessionId"]) - var sessionId: String? = null, + var sessionId: String = "0", @JsonField(name = ["actorId"]) - var actorId: String? = null, + var actorId: String = "", @JsonField(name = ["actorType"]) - var actorType: String? = null, + var actorType: String = "", - var password: String? = null, + var password: String? = null, //check if this can be removed.Does not belong to api response but is used internally? @JsonField(name = ["isFavorite"]) var favorite: Boolean = false, @@ -81,19 +76,20 @@ data class Conversation( var lastMessage: ChatMessageJson? = null, @JsonField(name = ["objectType"], typeConverter = ConversationObjectTypeConverter::class) - var objectType: ConversationEnums.ObjectType? = null, + var objectType: ConversationEnums.ObjectType = ConversationEnums.ObjectType.DEFAULT, @JsonField(name = ["notificationLevel"], typeConverter = EnumNotificationLevelConverter::class) - var notificationLevel: ConversationEnums.NotificationLevel? = null, + var notificationLevel: ConversationEnums.NotificationLevel = ConversationEnums.NotificationLevel.DEFAULT, @JsonField(name = ["readOnly"], typeConverter = EnumReadOnlyConversationConverter::class) - var conversationReadOnlyState: ConversationEnums.ConversationReadOnlyState? = null, + var conversationReadOnlyState: ConversationEnums.ConversationReadOnlyState = + ConversationEnums.ConversationReadOnlyState.CONVERSATION_READ_WRITE, @JsonField(name = ["lobbyState"], typeConverter = EnumLobbyStateConverter::class) - var lobbyState: ConversationEnums.LobbyState? = null, + var lobbyState: ConversationEnums.LobbyState = ConversationEnums.LobbyState.LOBBY_STATE_ALL_PARTICIPANTS, @JsonField(name = ["lobbyTimer"]) - var lobbyTimer: Long? = null, + var lobbyTimer: Long = 0, @JsonField(name = ["lastReadMessage"]) var lastReadMessage: Int = 0, @@ -111,16 +107,16 @@ data class Conversation( var canStartCall: Boolean = false, @JsonField(name = ["canLeaveConversation"]) - var canLeaveConversation: Boolean? = null, + var canLeaveConversation: Boolean = true, @JsonField(name = ["canDeleteConversation"]) - var canDeleteConversation: Boolean? = null, + var canDeleteConversation: Boolean = false, @JsonField(name = ["unreadMentionDirect"]) - var unreadMentionDirect: Boolean? = null, + var unreadMentionDirect: Boolean = false, @JsonField(name = ["notificationCalls"]) - var notificationCalls: Int? = null, + var notificationCalls: Int = 0, @JsonField(name = ["permissions"]) var permissions: Int = 0, @@ -129,107 +125,38 @@ data class Conversation( var messageExpiration: Int = 0, @JsonField(name = ["status"]) - var status: String? = null, + var status: String? = "", @JsonField(name = ["statusIcon"]) - var statusIcon: String? = null, + var statusIcon: String? = "", @JsonField(name = ["statusMessage"]) - var statusMessage: String? = null, + var statusMessage: String? = "", @JsonField(name = ["statusClearAt"]) - var statusClearAt: Long? = 0, + var statusClearAt: Long? = null, @JsonField(name = ["callRecording"]) var callRecording: Int = 0, @JsonField(name = ["avatarVersion"]) - var avatarVersion: String? = "", + var avatarVersion: String = "", // Be aware that variables with "is" at the beginning will lead to the error: // "@JsonField annotation can only be used on private fields if both getter and setter are present." // Instead, name it with "has" at the beginning: isCustomAvatar -> hasCustomAvatar @JsonField(name = ["isCustomAvatar"]) - var hasCustomAvatar: Boolean? = false, + var hasCustomAvatar: Boolean = false, @JsonField(name = ["callStartTime"]) - var callStartTime: Long? = 0L, + var callStartTime: Long = 0L, @JsonField(name = ["recordingConsent"]) var recordingConsentRequired: Int = 0, @JsonField(name = ["remoteServer"]) - var remoteServer: String? = null, + var remoteServer: String? = "", @JsonField(name = ["remoteToken"]) - var remoteToken: String? = null -) : Parcelable { - @Deprecated("Use ConversationUtil") - val isPublic: Boolean - get() = ConversationEnums.ConversationType.ROOM_PUBLIC_CALL == type - - @Deprecated("Use ConversationUtil") - val isGuest: Boolean - get() = ParticipantType.GUEST == participantType || - ParticipantType.GUEST_MODERATOR == participantType || - ParticipantType.USER_FOLLOWING_LINK == participantType - - @Deprecated("Use ConversationUtil") - val isParticipantOwnerOrModerator: Boolean - get() = ParticipantType.OWNER == participantType || - ParticipantType.GUEST_MODERATOR == participantType || - ParticipantType.MODERATOR == participantType - - @Deprecated("Use ConversationUtil") - fun canModerate(conversationUser: User): Boolean { - return isParticipantOwnerOrModerator && - !ConversationUtils.isLockedOneToOne( - ConversationModel.mapToConversationModel(this, conversationUser), - conversationUser.capabilities?.spreedCapability!! - ) && - type != ConversationEnums.ConversationType.FORMER_ONE_TO_ONE && - !ConversationUtils.isNoteToSelfConversation( - ConversationModel.mapToConversationModel(this, conversationUser) - ) - } - - @Deprecated("Use ConversationUtil") - fun isLobbyViewApplicable(conversationUser: User): Boolean { - return !canModerate(conversationUser) && - ( - type == ConversationEnums.ConversationType.ROOM_GROUP_CALL || - type == ConversationEnums.ConversationType.ROOM_PUBLIC_CALL - ) - } - - @Deprecated("Use ConversationUtil") - fun isNameEditable(conversationUser: User): Boolean { - return canModerate(conversationUser) && ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL != type - } - - @Deprecated("Use ConversationUtil") - fun canLeave(): Boolean { - return if (canLeaveConversation != null) { - // Available since APIv2 - canLeaveConversation!! - } else { - true - } - } - - @Deprecated("Use ConversationUtil") - fun canDelete(conversationUser: User): Boolean { - return if (canDeleteConversation != null) { - // Available since APIv2 - canDeleteConversation!! - } else { - canModerate(conversationUser) - // Fallback for APIv1 - } - } - - @Deprecated("Use ConversationUtil") - fun isNoteToSelfConversation(): Boolean { - return type == ConversationEnums.ConversationType.NOTE_TO_SELF - } -} + var remoteToken: String? = "" +) : Parcelable diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/ConversationsListBottomDialog.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/ConversationsListBottomDialog.kt index 1ca4054ca1..66cff6d7b3 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/ConversationsListBottomDialog.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/ConversationsListBottomDialog.kt @@ -134,7 +134,7 @@ class ConversationsListBottomDialog( ) binding.conversationOperationLeave.visibility = setVisibleIf( - ConversationUtils.canLeave(conversation) && + conversation.canLeaveConversation && // leaving is by api not possible for the last user with moderator permissions. // for now, hide this option for all moderators. !ConversationUtils.canModerate(conversation, currentUser.capabilities!!.spreedCapability!!) diff --git a/app/src/main/java/com/nextcloud/talk/utils/ConversationUtils.kt b/app/src/main/java/com/nextcloud/talk/utils/ConversationUtils.kt index 793ed6eff5..08dbb8587a 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/ConversationUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/ConversationUtils.kt @@ -55,25 +55,6 @@ object ConversationUtils { ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL != conversation.type } - fun canLeave(conversation: ConversationModel): Boolean { - return if (conversation.canLeaveConversation != null) { - // Available since APIv2 - conversation.canLeaveConversation!! - } else { - true - } - } - - fun canDelete(conversation: ConversationModel, spreedCapability: SpreedCapability): Boolean { - return if (conversation.canDeleteConversation != null) { - // Available since APIv2 - conversation.canDeleteConversation!! - } else { - canModerate(conversation, spreedCapability) - // Fallback for APIv1 - } - } - fun isNoteToSelfConversation(currentConversation: ConversationModel?): Boolean { return currentConversation != null && currentConversation.type == ConversationEnums.ConversationType.NOTE_TO_SELF diff --git a/app/src/test/java/com/nextcloud/talk/json/ConversationConversionTest.kt b/app/src/test/java/com/nextcloud/talk/json/ConversationConversionTest.kt new file mode 100644 index 0000000000..4115926d59 --- /dev/null +++ b/app/src/test/java/com/nextcloud/talk/json/ConversationConversionTest.kt @@ -0,0 +1,157 @@ +import com.bluelinelabs.logansquare.LoganSquare +import com.nextcloud.talk.data.database.mappers.asEntity +import com.nextcloud.talk.data.database.mappers.asModel +import com.nextcloud.talk.data.database.model.ConversationEntity +import com.nextcloud.talk.models.json.conversations.ConversationEnums +import com.nextcloud.talk.models.json.conversations.RoomOverall +import com.nextcloud.talk.models.json.participants.Participant +import org.junit.Assert.* +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.Parameterized +import java.io.File + +@RunWith(Parameterized::class) +class ConversationConversionTest( + private val jsonFileName: String +) { + + companion object { + @JvmStatic + @Parameterized.Parameters(name = "{index}: testDeserialization({0})") + fun data(): List { + return listOf( + "RoomOverallExample_APIv1.json", + "RoomOverallExample_APIv2.json", + "RoomOverallExample_APIv4.json" + ) + } + } + + @Test + fun testDeserialization() { + val jsonFile = File("src/test/resources/$jsonFileName") + val jsonString = jsonFile.readText() + + val roomOverall: RoomOverall = LoganSquare.parse(jsonString, RoomOverall::class.java) + assertNotNull(roomOverall) + + val conversationJson = roomOverall.ocs!!.data!! + assertNotNull(conversationJson) + + val conversationEntity = conversationJson.asEntity(1) + assertNotNull(conversationEntity) + + val apiVersion : Int = jsonFileName.substringAfterLast("APIv").first().digitToInt() + + checkConversationEntity(conversationEntity, apiVersion) + + val conversationModel = conversationEntity.asModel() + val conversationEntityConvertedBack = conversationModel.asEntity() + + checkConversationEntity(conversationEntityConvertedBack, apiVersion) + } + + private fun checkConversationEntity( + conversationEntity: ConversationEntity, + apiVersion: Int + ) { + assertEquals("1@juwd77g6", conversationEntity.internalId) + assertEquals(1, conversationEntity.accountId) + + // check if default values are set for the fields when API_V1 is used + if (apiVersion == 1) { + // default values for API_V2 fields + assertEquals(false, conversationEntity.canDeleteConversation) + assertEquals(true, conversationEntity.canLeaveConversation) + + // default values for API_V3 fields + assertEquals("", conversationEntity.description) + assertEquals("", conversationEntity.actorType) + assertEquals("", conversationEntity.actorId) + assertEquals(0, conversationEntity.callFlag) + assertEquals(0, conversationEntity.lastCommonReadMessage) + + // default values for API_V4 fields + assertEquals("", conversationEntity.avatarVersion) + assertEquals(0, conversationEntity.callStartTime) + assertEquals(0, conversationEntity.callRecording) + assertEquals(false, conversationEntity.unreadMentionDirect) + assertEquals("", conversationEntity.status) + assertEquals("", conversationEntity.statusIcon) + assertEquals("", conversationEntity.statusMessage) + assertEquals(null, conversationEntity.statusClearAt) + assertEquals("", conversationEntity.avatarVersion) + assertEquals(0, conversationEntity.callStartTime) + assertEquals(0, conversationEntity.callRecording) + } + + if (apiVersion >= 1) { + assertEquals("juwd77g6", conversationEntity.token) + assertEquals(ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL, conversationEntity.type) + assertEquals("marcel", conversationEntity.name) + assertEquals("Marcel", conversationEntity.displayName) + assertEquals(Participant.ParticipantType.OWNER, conversationEntity.participantType) + assertEquals( + ConversationEnums.ConversationReadOnlyState.CONVERSATION_READ_WRITE, + conversationEntity.conversationReadOnlyState + ) + assertEquals(1727185155, conversationEntity.lastPing) + assertEquals("0", conversationEntity.sessionId) + assertEquals(false, conversationEntity.hasPassword) + assertEquals(false, conversationEntity.hasCall) + assertEquals(true, conversationEntity.canStartCall) + assertEquals(1727098966, conversationEntity.lastActivity) + assertEquals(false, conversationEntity.favorite) + assertEquals(ConversationEnums.NotificationLevel.ALWAYS, conversationEntity.notificationLevel) + assertEquals(ConversationEnums.LobbyState.LOBBY_STATE_ALL_PARTICIPANTS, conversationEntity.lobbyState) + assertEquals(0, conversationEntity.lobbyTimer) + assertEquals(0, conversationEntity.unreadMessages) + assertEquals(false, conversationEntity.unreadMention) + assertEquals(92320, conversationEntity.lastReadMessage) + assertNotNull(conversationEntity.lastMessage) + assertTrue(conversationEntity.lastMessage is String) + assertTrue(conversationEntity.lastMessage!!.contains("token")) + assertEquals(ConversationEnums.ObjectType.DEFAULT, conversationEntity.objectType) + } + + if (apiVersion >= 2) { + assertEquals(false, conversationEntity.canDeleteConversation) + assertEquals(true, conversationEntity.canLeaveConversation) + } + + if (apiVersion >= 3) { + assertEquals("test", conversationEntity.description) + // assertEquals("", conversationEntity.attendeeId) // Not implemented + // assertEquals("", conversationEntity.attendeePin) // Not implemented + assertEquals("users", conversationEntity.actorType) + assertEquals("marcel2", conversationEntity.actorId) + + // assertEquals("", conversationEntity.listable) // Not implemented + assertEquals(0, conversationEntity.callFlag) + // assertEquals("", conversationEntity.sipEnabled) // Not implemented + // assertEquals("", conversationEntity.canEnableSIP) // Not implemented + assertEquals(92320, conversationEntity.lastCommonReadMessage) + } + + if (apiVersion >= 4) { + assertEquals("143a9df3", conversationEntity.avatarVersion) + assertEquals(0, conversationEntity.callStartTime) + assertEquals(0, conversationEntity.callRecording) + assertEquals(false, conversationEntity.unreadMentionDirect) + // assertEquals(, conversationEntity.breakoutRoomMode) // Not implemented + // assertEquals(, conversationEntity.breakoutRoomStatus) // Not implemented + assertEquals("away", conversationEntity.status) + assertEquals("👻", conversationEntity.statusIcon) + assertEquals("buuuuh", conversationEntity.statusMessage) + assertEquals(null, conversationEntity.statusClearAt) + assertEquals("143a9df3", conversationEntity.avatarVersion) + // assertEquals("", conversationEntity.isCustomAvatar) // Not implemented + assertEquals(0, conversationEntity.callStartTime) + assertEquals(0, conversationEntity.callRecording) + // assertEquals("", conversationEntity.recordingConsent) // Not implemented + // assertEquals("", conversationEntity.mentionPermissions) // Not implemented + // assertEquals("", conversationEntity.isArchived) // Not implemented + } + } +} diff --git a/app/src/test/resources/RoomOverallExample_APIv1.json b/app/src/test/resources/RoomOverallExample_APIv1.json new file mode 100644 index 0000000000..993f95c512 --- /dev/null +++ b/app/src/test/resources/RoomOverallExample_APIv1.json @@ -0,0 +1,66 @@ +{ + "ocs": { + "meta": { + "status": "ok", + "statuscode": 200, + "message": "OK" + }, + "data": { + "id": 6410, + "token": "juwd77g6", + "type": 1, + "name": "marcel", + "displayName": "Marcel", + "objectType": "", + "objectId": "", + "participantType": 1, + "participantInCall": false, + "participantFlags": 0, + "readOnly": 0, + "count": 0, + "hasPassword": false, + "hasCall": false, + "canStartCall": true, + "lastActivity": 1727098966, + "lastReadMessage": 92320, + "unreadMessages": 0, + "unreadMention": false, + "isFavorite": false, + "notificationLevel": 1, + "lobbyState": 0, + "lobbyTimer": 0, + "lastPing": 1727185155, + "sessionId": "0", + "participants": { + "marcel": { + "name": "marcel", + "type": 1, + "call": 0, + "sessionId": "tonIuryMpwk5mR2h6lFqPC6M8m6hxdT4YN9X9I1v4i2LOJb9r3FzANx\/7HT0j6r8fzBFPJqnOrT\/mdvHzFlfqQsr6Gxo0\/aLkDfIRL32XlGIzficfLaBNCsyctPxwgHv0fwmJUOS2i0ONdC+QWyTJ4bpYw1Ch9hiybxCgEtss3xy9fbjPwWj3gLvpMpcH0OuNkfEwHqByhpiAb3xuu60\/6j671uwYiGe2Ba7PzLFJ3LVuVRXXTbeaZlVwTAioOu" + }, + "Testuser.Lastname": { + "name": "Testuser", + "type": 1, + "call": 0, + "sessionId": "0" + } + }, + "numGuests": 0, + "guestList": "", + "lastMessage": { + "id": 175430, + "token": "juwd77g6", + "actorType": "users", + "actorId": "marcel", + "actorDisplayName": "Marcel", + "timestamp": 1727182442, + "message": "test", + "messageParameters": [], + "systemMessage": "", + "messageType": "comment", + "isReplyable": true, + "referenceId": "" + } + } + } +} diff --git a/app/src/test/resources/RoomOverallExample_APIv2.json b/app/src/test/resources/RoomOverallExample_APIv2.json new file mode 100644 index 0000000000..9148c6b875 --- /dev/null +++ b/app/src/test/resources/RoomOverallExample_APIv2.json @@ -0,0 +1,51 @@ +{ + "ocs": { + "meta": { + "status": "ok", + "statuscode": 200, + "message": "OK" + }, + "data": { + "id": 6410, + "token": "juwd77g6", + "type": 1, + "name": "marcel", + "displayName": "Marcel", + "objectType": "", + "objectId": "", + "participantType": 1, + "participantFlags": 0, + "readOnly": 0, + "hasPassword": false, + "hasCall": false, + "canStartCall": true, + "lastActivity": 1727098966, + "lastReadMessage": 92320, + "unreadMessages": 0, + "unreadMention": false, + "isFavorite": false, + "canLeaveConversation": true, + "canDeleteConversation": false, + "notificationLevel": 1, + "lobbyState": 0, + "lobbyTimer": 0, + "lastPing": 1727185155, + "sessionId": "0", + "guestList": "", + "lastMessage": { + "id": 175430, + "token": "juwd77g6", + "actorType": "users", + "actorId": "marcel", + "actorDisplayName": "Marcel", + "timestamp": 1727182442, + "message": "test", + "messageParameters": [], + "systemMessage": "", + "messageType": "comment", + "isReplyable": true, + "referenceId": "" + } + } + } +} diff --git a/app/src/test/resources/RoomOverallExample_APIv4.json b/app/src/test/resources/RoomOverallExample_APIv4.json new file mode 100644 index 0000000000..59ef478ca2 --- /dev/null +++ b/app/src/test/resources/RoomOverallExample_APIv4.json @@ -0,0 +1,83 @@ +{ + "ocs": { + "meta": { + "status": "ok", + "statuscode": 200, + "message": "OK" + }, + "data": { + "id": 181, + "token": "juwd77g6", + "type": 1, + "name": "marcel", + "displayName": "Marcel", + "objectType": "", + "objectId": "", + "participantType": 1, + "participantFlags": 0, + "readOnly": 0, + "hasPassword": false, + "hasCall": false, + "callStartTime": 0, + "callRecording": 0, + "canStartCall": true, + "lastActivity": 1727098966, + "lastReadMessage": 92320, + "unreadMessages": 0, + "unreadMention": false, + "unreadMentionDirect": false, + "isFavorite": false, + "canLeaveConversation": true, + "canDeleteConversation": false, + "notificationLevel": 1, + "notificationCalls": 1, + "lobbyState": 0, + "lobbyTimer": 0, + "lastPing": 1727185155, + "sessionId": "0", + "lastMessage": { + "id": 92320, + "token": "3853979093", + "actorType": "users", + "actorId": "marcel", + "actorDisplayName": "Marcel", + "timestamp": 1726673204, + "message": "Test", + "messageParameters": [], + "systemMessage": "", + "messageType": "comment", + "isReplyable": true, + "referenceId": "", + "reactions": {}, + "expirationTimestamp": 0, + "markdown": true + }, + "sipEnabled": 0, + "actorType": "users", + "actorId": "marcel2", + "attendeeId": 5810, + "permissions": 254, + "attendeePermissions": 0, + "callPermissions": 0, + "defaultPermissions": 0, + "canEnableSIP": false, + "attendeePin": "", + "description": "test", + "lastCommonReadMessage": 92320, + "listable": 0, + "callFlag": 0, + "messageExpiration": 0, + "avatarVersion": "143a9df3", + "isCustomAvatar": false, + "breakoutRoomMode": 0, + "breakoutRoomStatus": 0, + "recordingConsent": 0, + "mentionPermissions": 0, + "isArchived": false, + "status": "away", + "statusIcon": "👻", + "statusMessage": "buuuuh", + "statusClearAt": null + } + } +} From 38905ec9cf4ab639df1a716e8bdb1c58a0669721 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Thu, 26 Sep 2024 11:44:34 +0200 Subject: [PATCH 2/2] bump versions for SERVER_VERSION_MIN_SUPPORTED + SERVER_VERSION_SUPPORT_WARNING Signed-off-by: Marcel Hibbe --- .../main/java/com/nextcloud/talk/utils/CapabilitiesUtil.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/utils/CapabilitiesUtil.kt b/app/src/main/java/com/nextcloud/talk/utils/CapabilitiesUtil.kt index 63e55c08db..7329b085a1 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/CapabilitiesUtil.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/CapabilitiesUtil.kt @@ -295,6 +295,6 @@ object CapabilitiesUtil { const val RECORDING_CONSENT_NOT_REQUIRED = 0 const val RECORDING_CONSENT_REQUIRED = 1 const val RECORDING_CONSENT_DEPEND_ON_CONVERSATION = 2 - private const val SERVER_VERSION_MIN_SUPPORTED = 14 - private const val SERVER_VERSION_SUPPORT_WARNING = 18 + private const val SERVER_VERSION_MIN_SUPPORTED = 17 + private const val SERVER_VERSION_SUPPORT_WARNING = 26 }