GnunetChatMock.kt (15707B)
1 /* 2 This file is part of GNUnet. 3 Copyright (C) 2021--2025 GNUnet e.V. 4 5 GNUnet is free software: you can redistribute it and/or modify it 6 under the terms of the GNU Affero General Public License as published 7 by the Free Software Foundation, either version 3 of the License, 8 or (at your option) any later version. 9 10 GNUnet is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Affero General Public License for more details. 14 15 You should have received a copy of the GNU Affero General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 SPDX-License-Identifier: AGPL3.0-or-later 19 */ 20 /* 21 * @author t3sserakt 22 * @file GNUnetMessenger/app/src/main/java/org/gnunet/gnunetmessenger/service/mock/GnunetChatMock.kt 23 */ 24 25 package org.gnunet.gnunetmessenger.service.mock 26 27 import org.gnunet.gnunetmessenger.model.ChatAccount 28 import org.gnunet.gnunetmessenger.model.ChatContact 29 import org.gnunet.gnunetmessenger.model.ChatContext 30 import org.gnunet.gnunetmessenger.model.ChatContextType 31 import org.gnunet.gnunetmessenger.model.ChatGroup 32 import org.gnunet.gnunetmessenger.model.ChatHandle 33 import org.gnunet.gnunetmessenger.model.ChatMessage 34 import org.gnunet.gnunetmessenger.model.ChatUri 35 import org.gnunet.gnunetmessenger.model.GnunetReturnValue 36 import org.gnunet.gnunetmessenger.model.MessageKind 37 import org.gnunet.gnunetmessenger.model.MessengerApp 38 import org.gnunet.gnunetmessenger.service.GnunetChat 39 import java.util.UUID 40 41 class GnunetChatMock : GnunetChat { 42 43 private lateinit var messageCallback: (ChatContext, ChatMessage) -> Unit 44 private var uuidCounter: Long = 0 45 46 var lastDestroyedUri: ChatUri? = null 47 private set 48 49 var lastSetUserPointer: Pair<ChatContact?, String?>? = null 50 private set 51 var lastSetGroupPointer: Pair<ChatGroup?, String?>? = null 52 private set 53 54 var lastSetMessageForGroupContact: Triple<ChatGroup?, ChatContact?, ChatMessage?>? = null 55 private set 56 57 override suspend fun awaitReady(handle: ChatHandle) { 58 return 59 } 60 61 override fun startChat( 62 messengerApp: MessengerApp, 63 callback: (ChatContext, ChatMessage) -> Unit 64 ): ChatHandle { 65 println("start chat") 66 messageCallback = callback 67 return ChatHandle(1) 68 } 69 70 override fun iterateAccounts(handle: ChatHandle, callback: (ChatAccount) -> Unit) { 71 val mockAccounts = listOf( 72 ChatAccount(1, "Alice", ""), 73 ChatAccount(2, "Bob", ""), 74 ChatAccount(3, "Charlie", "") 75 ) 76 77 for (account in mockAccounts) { 78 callback(account) 79 } 80 } 81 82 override suspend fun listAccounts(handle: ChatHandle): List<ChatAccount> { 83 return listOf( 84 ChatAccount(1, "Alice", ""), 85 ChatAccount(2, "Bob", ""), 86 ChatAccount(3, "Charlie", "") 87 ) 88 } 89 90 override suspend fun createAccount(handle: ChatHandle, name: String): GnunetReturnValue { 91 println("create account") 92 return GnunetReturnValue.OK 93 } 94 95 override suspend fun connect(handle: ChatHandle, account: ChatAccount) { 96 println("connect") 97 messageCallback( 98 ChatContext(ChatContextType.UNKNOWN, UUID.randomUUID().toString(), false, false), 99 ChatMessage( 100 ChatContext(ChatContextType.UNKNOWN, null, true, false), 101 "", 102 0, 103 null, 104 MessageKind.LOGIN, 105 null 106 ) 107 ) 108 } 109 110 override suspend fun disconnect(handle: ChatHandle) { 111 println("disconnect") 112 uuidCounter = 0 113 messageCallback( 114 ChatContext(ChatContextType.UNKNOWN, UUID.randomUUID().toString(), false, false), 115 ChatMessage( 116 ChatContext(ChatContextType.UNKNOWN, null, false, false), 117 "", 118 0, 119 null, 120 MessageKind.LOGOUT, 121 null 122 ) 123 ) 124 } 125 126 override suspend fun stopChat(handle: ChatHandle) { 127 println("stopChat") 128 } 129 130 override suspend fun getProfileName(handle: ChatHandle): String { 131 return "somename" + (1000..9999).random() 132 } 133 134 override suspend fun setProfileName(handle: ChatHandle, name: String) { 135 println("set profile name") 136 } 137 138 override fun getProfileKey(handle: ChatHandle): String { 139 return "somekey1337" 140 } 141 142 override fun isContactBlocked(contact: ChatContact): Boolean { 143 return true 144 } 145 146 override fun setContactBlocked(contact: ChatContact, isBlocked: Boolean) { 147 println("isblocked:$isBlocked") 148 } 149 150 override fun setAttribute(handle: ChatHandle, key: String, value: String) { 151 println("setting Attribute withj key: ${key} and value ${value}") 152 } 153 154 override fun getAttributes(handle: ChatHandle, callback: (String, String) -> Unit) { 155 val mockAttributes = listOf( 156 "nickname" to "Alice", 157 "location" to "Berlin", 158 "status" to "Online" 159 ) 160 161 for ((key, value) in mockAttributes) { 162 callback(key, value) 163 } 164 } 165 166 override fun lobbyOpen(handle: ChatHandle, callback: (String) -> Unit) { 167 callback("000G006K2TJNMD9VTCYRX7BRVV3HAEPS15E6NHDXKPJA1KAJJEG9AFF884") 168 } 169 170 override suspend fun lobbyJoin(handle: ChatHandle, uri: String) { 171 println("join lobby") 172 } 173 174 override fun setGroupName(group: ChatGroup, name: String) { 175 group.name = name 176 } 177 178 override fun createGroup(handle: ChatHandle, topic: String): ChatGroup { 179 return ChatGroup( 180 ChatContext(ChatContextType.GROUP, null, true, false), 181 topic 182 ) 183 } 184 185 override fun parseUri(uri: String): ChatUri { 186 return ChatUri(uri) 187 } 188 189 override fun destroyUri(uri: ChatUri) { 190 lastDestroyedUri = uri 191 } 192 193 override fun inviteContactToGroup(group: ChatGroup, contact: ChatContact) { 194 println("contact ${contact.name} invited") 195 } 196 197 override fun getUserPointerForContext(context: ChatContext): String? { 198 return context.userPointer 199 } 200 201 override fun setUserPointerForContext(context: ChatContext, userPointer: String) { 202 context.userPointer = userPointer 203 } 204 205 override fun getSenderFromMessage(message: ChatMessage): ChatContact { 206 return ChatContact( 207 ChatContext(ChatContextType.CONTACT, null, true, false), 208 message.sender?.name ?: "" 209 ) 210 } 211 212 override fun getGroupFromContext(context: ChatContext): ChatGroup? { 213 if ("3" == context.userPointer) { 214 val contextDev = ChatContext(ChatContextType.GROUP, null, true, false) 215 return ChatGroup(contextDev, name = "Dev Team") 216 } 217 val contextDev = ChatContext(ChatContextType.GROUP, null, true, false) 218 return ChatGroup(contextDev, name = "GNUnet Team") 219 } 220 221 override fun getMessageForGroupContact(group: ChatGroup, contact: ChatContact): ChatMessage { 222 return ChatMessage( 223 ChatContext(null, null, false, false), 224 "fake-message-for-group", 225 12345L, 226 contact, 227 MessageKind.TEXT, 228 null 229 ) 230 } 231 232 override fun getMessageKind(message: ChatMessage): MessageKind { 233 return MessageKind.TEXT 234 } 235 236 override fun isMessageRecent(message: ChatMessage): GnunetReturnValue { 237 return GnunetReturnValue.OK 238 } 239 240 override fun getMessageTimestamp(message: ChatMessage): Long { 241 return 123456789L 242 } 243 244 override fun setMessageForGroupContact( 245 group: ChatGroup, 246 contact: ChatContact, 247 message: ChatMessage 248 ) { 249 lastSetMessageForGroupContact = Triple(group, contact, message) 250 } 251 252 override fun iterateContacts(handle: ChatHandle, callback: (ChatContact) -> Int) { 253 val contextAlice = ChatContext(ChatContextType.CONTACT, null, false, false) 254 val contextBob = ChatContext(ChatContextType.CONTACT, null, false, false) 255 val contacts = listOf( 256 ChatContact(contextAlice, name = "Alice"), 257 ChatContact(contextBob, name = "Bob") 258 ) 259 for (contact in contacts) { 260 callback(contact) 261 } 262 } 263 264 override fun iterateGroups(handle: ChatHandle, callback: (ChatGroup) -> Int) { 265 println("iterate groups") 266 val contextDev = ChatContext(ChatContextType.GROUP, null, true, false) 267 val contextFriends = ChatContext(ChatContextType.GROUP, null, true, false) 268 val groups = listOf( 269 ChatGroup(contextDev, name = "Dev Team"), 270 ChatGroup(contextFriends, name = "Friends") 271 ) 272 for (group in groups) { 273 callback(group) 274 } 275 276 messageCallback( 277 ChatContext(ChatContextType.CONTACT, null, true, false), 278 ChatMessage( 279 ChatContext(ChatContextType.CONTACT, null, true, false), 280 "", 281 0, 282 ChatContact(ChatContext(ChatContextType.CONTACT, null, true, false), "Mallory"), 283 MessageKind.JOIN, 284 null 285 ) 286 ) 287 288 messageCallback( 289 ChatContext(ChatContextType.CONTACT, "5", true, false), 290 ChatMessage( 291 ChatContext(ChatContextType.CONTACT, null, true, false), 292 "Hi, I am Mallory!", 293 0, 294 ChatContact(ChatContext(ChatContextType.CONTACT, "6", true, false), "Mallory"), 295 MessageKind.TEXT, 296 null 297 ) 298 ) 299 300 messageCallback( 301 ChatContext(ChatContextType.GROUP, "3", true, false), 302 ChatMessage( 303 ChatContext(ChatContextType.GROUP, null, true, false), 304 "", 305 0, 306 ChatContact(ChatContext(ChatContextType.CONTACT, null, true, false), "Flo"), 307 MessageKind.JOIN, 308 null 309 ) 310 ) 311 312 messageCallback( 313 ChatContext(ChatContextType.GROUP, "3", true, false), 314 ChatMessage( 315 ChatContext(ChatContextType.GROUP, null, true, false), 316 "Hi, I am Flo!", 317 0, 318 ChatContact(ChatContext(ChatContextType.CONTACT, "7", true, false), "Flo"), 319 MessageKind.TEXT, 320 null 321 ) 322 ) 323 324 messageCallback( 325 ChatContext(ChatContextType.GROUP, "3", true, false), 326 ChatMessage( 327 ChatContext(ChatContextType.GROUP, null, true, false), 328 "", 329 0, 330 ChatContact(ChatContext(ChatContextType.CONTACT, "1", true, false), "Alice"), 331 MessageKind.JOIN, 332 null 333 ) 334 ) 335 336 messageCallback( 337 ChatContext(ChatContextType.GROUP, "3", true, false), 338 ChatMessage( 339 ChatContext(ChatContextType.GROUP, null, true, false), 340 "Hi, I am Alice!", 341 0, 342 ChatContact(ChatContext(ChatContextType.CONTACT, "1", true, false), "Alice"), 343 MessageKind.TEXT, 344 null 345 ) 346 ) 347 } 348 349 override suspend fun listContacts(handle: ChatHandle): List<ChatContact> { 350 val contextAlice = ChatContext(ChatContextType.CONTACT, null, false, false) 351 val contextBob = ChatContext(ChatContextType.CONTACT, null, false, false) 352 return listOf( 353 ChatContact(contextAlice, name = "Alice"), 354 ChatContact(contextBob, name = "Bob") 355 ) 356 } 357 358 override suspend fun listGroups(handle: ChatHandle): List<ChatGroup> { 359 val contextDev = ChatContext(ChatContextType.GROUP, null, true, false) 360 val contextFriends = ChatContext(ChatContextType.GROUP, null, true, false) 361 return listOf( 362 ChatGroup(contextDev, name = "Dev Team"), 363 ChatGroup(contextFriends, name = "Friends") 364 ) 365 } 366 367 override fun getContactContext(chatContact: ChatContact): ChatContext { 368 return chatContact.chatContext 369 } 370 371 override fun getGroupContext(chatGroup: ChatGroup): ChatContext { 372 return chatGroup.chatContext 373 } 374 375 override fun getContactUserPointer(chatContact: ChatContact): String { 376 return "fake-user-pointer-123" 377 } 378 379 override fun setContactUserPointer(chatContact: ChatContact, userPointer: String) { 380 lastSetUserPointer = Pair(chatContact, userPointer) 381 } 382 383 override fun getGroupUserPointer(chatGroup: ChatGroup): String { 384 return "fake-group-pointer-789" 385 } 386 387 override fun setGroupUserPointer(chatGroup: ChatGroup, userPointer: String) { 388 lastSetGroupPointer = Pair(chatGroup, userPointer) 389 } 390 391 override fun sendText(chatContext: ChatContext, text: String) { 392 println("send text: $text") 393 } 394 395 override fun getContactKey(chatContact: ChatContact): String { 396 return "otherkey42" 397 } 398 399 override fun getContextContact(context: ChatContext): ChatContact { 400 println("get contact for context") 401 return ChatContact(context, "test") 402 } 403 404 override fun deleteContact(chatContact: ChatContact) { 405 println("delete contact") 406 } 407 408 override fun isGroup(context: ChatContext): Boolean { 409 return context.isGroup 410 } 411 412 override fun isPlatform(context: ChatContext): Boolean { 413 return context.isPlatform 414 } 415 416 override fun iterateGroupContacts( 417 chatGroup: ChatGroup, 418 callback: (ChatGroup, ChatContact) -> Int 419 ) { 420 val contextCharlie = ChatContext(ChatContextType.CONTACT, null, true, false) 421 val contacts = listOf( 422 ChatContact(contextCharlie, name = "Charlie") 423 ) 424 for (contact in contacts) { 425 callback(chatGroup, contact) 426 } 427 } 428 429 override suspend fun listGroupContacts(group: ChatGroup): List<ChatContact> { 430 val contextCharlie = ChatContext(ChatContextType.CONTACT, null, true, false) 431 return listOf( 432 ChatContact(contextCharlie, name = "Charlie") 433 ) 434 } 435 436 override fun randomUUID(): String { 437 return uuidCounter++.toString() 438 } 439 440 override fun getContactAttributes( 441 contact: ChatContact, 442 callback: (String, String) -> Unit 443 ) { 444 val mockAttributes = listOf( 445 "nickname" to "Alice", 446 "location" to "Berlin", 447 "status" to "Online" 448 ) 449 450 for ((key, value) in mockAttributes) { 451 callback(key, value) 452 } 453 } 454 455 override fun shareAttributes(handle: ChatHandle, contact: ChatContact, key: String) { 456 println("share ${key} for contact ${contact.name}") 457 } 458 459 override fun unshareAttributes(handle: ChatHandle, contact: ChatContact, key: String) { 460 println("unshare ${key} for contact ${contact.name}") 461 } 462 463 override suspend fun iterateContextMessages(context: ChatContext): List<ChatMessage> { 464 return emptyList() 465 } 466 467 override suspend fun reset() { 468 if (!org.gnunet.gnunetmessenger.BuildConfig.ALLOW_RESET) { 469 println("reset: BLOCKED - Reset not allowed in production builds") 470 throw SecurityException("Reset operation is not allowed in production") 471 } 472 473 println("reset mock service - clearing all state") 474 uuidCounter = 0 475 lastDestroyedUri = null 476 lastSetUserPointer = null 477 lastSetGroupPointer = null 478 lastSetMessageForGroupContact = null 479 messageCallback = { _, _ -> } 480 } 481 }