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 <dev@mhibbe.de>
This commit is contained in:
Marcel Hibbe 2024-09-25 13:47:37 +02:00
parent 0354501b41
commit ebc2fd2702
No known key found for this signature in database
GPG Key ID: C793F8B59F43CE7B
11 changed files with 436 additions and 218 deletions

View File

@ -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
)

View File

@ -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

View File

@ -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

View File

@ -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
// }

View File

@ -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

View File

@ -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!!)

View File

@ -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

View File

@ -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<String> {
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
}
}
}

View File

@ -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": ""
}
}
}
}

View File

@ -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": ""
}
}
}
}

View File

@ -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
}
}
}