From 6608e994b5236fa3786725d4e54e1b81d6a0b190 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20K=C3=BCrten?= <sebastian@mobanisto.de>
Date: Thu, 25 Nov 2021 18:11:26 +0100
Subject: [PATCH] When adding test data, hack GroupCount timestamp

Because the MessageTracker in briar initializes the GroupCount timestamp
to the current time when the contact is being added, we cannot have
realistic test data in the database where the GroupCount timestamp
matches that of the last message in the chat history. This is a dirty
workaround to make this possible.
---
 .../briar/desktop/GroupCountHelper.kt         | 43 +++++++++++++++++++
 .../testdata/DeterministicTestDataCreator.kt  |  8 ----
 .../DeterministicTestDataCreatorImpl.kt       | 28 +++++++-----
 3 files changed, 60 insertions(+), 19 deletions(-)
 create mode 100644 src/test/kotlin/org/briarproject/briar/desktop/GroupCountHelper.kt

diff --git a/src/test/kotlin/org/briarproject/briar/desktop/GroupCountHelper.kt b/src/test/kotlin/org/briarproject/briar/desktop/GroupCountHelper.kt
new file mode 100644
index 0000000000..b753e73b06
--- /dev/null
+++ b/src/test/kotlin/org/briarproject/briar/desktop/GroupCountHelper.kt
@@ -0,0 +1,43 @@
+package org.briarproject.briar.desktop
+
+import org.briarproject.bramble.api.FormatException
+import org.briarproject.bramble.api.client.ClientHelper
+import org.briarproject.bramble.api.contact.ContactId
+import org.briarproject.bramble.api.data.BdfDictionary
+import org.briarproject.bramble.api.data.BdfEntry
+import org.briarproject.bramble.api.db.DbException
+import org.briarproject.bramble.api.db.Transaction
+import org.briarproject.bramble.api.sync.GroupId
+import org.briarproject.briar.api.client.MessageTracker.GroupCount
+import org.briarproject.briar.api.messaging.MessagingManager
+import org.briarproject.briar.client.MessageTrackerConstants
+
+object GroupCountHelper {
+
+    internal fun resetGroupTimestamp(
+        txn: Transaction,
+        contactId: ContactId,
+        messagingManager: MessagingManager,
+        clientHelper: ClientHelper,
+        timestamp: Long,
+    ) {
+        val gc = messagingManager.getGroupCount(txn, contactId)
+        val groupId = messagingManager.getConversationId(txn, contactId)
+        val copy = GroupCount(gc.msgCount, gc.unreadCount, timestamp)
+        storeGroupCount(clientHelper, txn, groupId, copy)
+    }
+
+    @Throws(DbException::class)
+    private fun storeGroupCount(clientHelper: ClientHelper, txn: Transaction, g: GroupId, c: GroupCount) {
+        try {
+            val d = BdfDictionary.of(
+                BdfEntry(MessageTrackerConstants.GROUP_KEY_MSG_COUNT, c.msgCount),
+                BdfEntry(MessageTrackerConstants.GROUP_KEY_UNREAD_COUNT, c.unreadCount),
+                BdfEntry(MessageTrackerConstants.GROUP_KEY_LATEST_MSG, c.latestMsgTime)
+            )
+            clientHelper.mergeGroupMetadata(txn, g, d)
+        } catch (e: FormatException) {
+            throw DbException(e)
+        }
+    }
+}
diff --git a/src/test/kotlin/org/briarproject/briar/desktop/testdata/DeterministicTestDataCreator.kt b/src/test/kotlin/org/briarproject/briar/desktop/testdata/DeterministicTestDataCreator.kt
index bb89f14f70..a896931e16 100644
--- a/src/test/kotlin/org/briarproject/briar/desktop/testdata/DeterministicTestDataCreator.kt
+++ b/src/test/kotlin/org/briarproject/briar/desktop/testdata/DeterministicTestDataCreator.kt
@@ -1,9 +1,5 @@
 package org.briarproject.briar.desktop.testdata
 
-import org.briarproject.bramble.api.contact.Contact
-import org.briarproject.bramble.api.db.DbException
-import org.briarproject.bramble.api.lifecycle.IoExecutor
-
 interface DeterministicTestDataCreator {
     /**
      * Create fake test data on the IoExecutor
@@ -22,8 +18,4 @@ interface DeterministicTestDataCreator {
         numPrivateGroups: Int,
         numPrivateGroupPosts: Int,
     )
-
-    @IoExecutor
-    @Throws(DbException::class)
-    fun addContact(name: String, alias: String?, avatar: Boolean): Contact
 }
diff --git a/src/test/kotlin/org/briarproject/briar/desktop/testdata/DeterministicTestDataCreatorImpl.kt b/src/test/kotlin/org/briarproject/briar/desktop/testdata/DeterministicTestDataCreatorImpl.kt
index b75891546e..113125fe5e 100644
--- a/src/test/kotlin/org/briarproject/briar/desktop/testdata/DeterministicTestDataCreatorImpl.kt
+++ b/src/test/kotlin/org/briarproject/briar/desktop/testdata/DeterministicTestDataCreatorImpl.kt
@@ -2,6 +2,7 @@ package org.briarproject.briar.desktop.testdata
 
 import mu.KotlinLogging
 import org.briarproject.bramble.api.FormatException
+import org.briarproject.bramble.api.client.ClientHelper
 import org.briarproject.bramble.api.contact.Contact
 import org.briarproject.bramble.api.contact.ContactId
 import org.briarproject.bramble.api.contact.ContactManager
@@ -9,6 +10,7 @@ import org.briarproject.bramble.api.crypto.SecretKey
 import org.briarproject.bramble.api.db.DatabaseComponent
 import org.briarproject.bramble.api.db.DbException
 import org.briarproject.bramble.api.db.Transaction
+import org.briarproject.bramble.api.event.EventBus
 import org.briarproject.bramble.api.identity.AuthorFactory
 import org.briarproject.bramble.api.identity.AuthorId
 import org.briarproject.bramble.api.identity.IdentityManager
@@ -28,6 +30,7 @@ import org.briarproject.bramble.api.system.Clock
 import org.briarproject.briar.api.autodelete.AutoDeleteConstants
 import org.briarproject.briar.api.avatar.AvatarManager
 import org.briarproject.briar.api.avatar.AvatarMessageEncoder
+import org.briarproject.briar.api.conversation.ConversationManager
 import org.briarproject.briar.api.messaging.MessagingManager
 import org.briarproject.briar.api.messaging.PrivateMessageFactory
 import org.briarproject.briar.api.privategroup.GroupMessageFactory
@@ -35,8 +38,10 @@ import org.briarproject.briar.api.privategroup.PrivateGroup
 import org.briarproject.briar.api.privategroup.PrivateGroupFactory
 import org.briarproject.briar.api.privategroup.PrivateGroupManager
 import org.briarproject.briar.api.test.TestAvatarCreator
+import org.briarproject.briar.desktop.GroupCountHelper
 import java.io.IOException
 import java.io.InputStream
+import java.time.LocalDateTime
 import java.time.ZoneOffset
 import java.util.Random
 import java.util.UUID
@@ -56,9 +61,12 @@ class DeterministicTestDataCreatorImpl @Inject internal constructor(
     private val privateGroupManager: PrivateGroupManager,
     private val privateGroupFactory: PrivateGroupFactory,
     private val transportPropertyManager: TransportPropertyManager,
+    private val conversationManager: ConversationManager,
     private val messagingManager: MessagingManager,
     private val testAvatarCreator: TestAvatarCreator,
     private val avatarMessageEncoder: AvatarMessageEncoder,
+    private val clientHelper: ClientHelper,
+    private val eventBus: EventBus,
     @field:IoExecutor @param:IoExecutor private val ioExecutor: Executor
 ) : DeterministicTestDataCreator {
 
@@ -119,7 +127,9 @@ class DeterministicTestDataCreatorImpl @Inject internal constructor(
         for (i in 0 until min(numContacts, conversations.persons.size)) {
             val person = conversations.persons[i]
             val remote = authorFactory.createLocalAuthor(person.name)
-            val contact = addContact(localAuthor.id, remote, null, avatarPercent)
+
+            val date = person.messages.map { it.date }.sorted().last()
+            val contact = addContact(localAuthor.id, remote, null, avatarPercent, date)
             contacts.add(contact)
         }
         return contacts
@@ -130,7 +140,8 @@ class DeterministicTestDataCreatorImpl @Inject internal constructor(
         localAuthorId: AuthorId,
         remote: LocalAuthor,
         alias: String?,
-        avatarPercent: Int
+        avatarPercent: Int,
+        date: LocalDateTime,
     ): Contact {
         // prepare to add contact
         val secretKey = secretKey
@@ -147,7 +158,10 @@ class DeterministicTestDataCreatorImpl @Inject internal constructor(
                 contactManager.setContactAlias(txn, contactId, alias)
             }
             transportPropertyManager.addRemoteProperties(txn, contactId, props)
-            db.getContact(txn, contactId)
+            val contact = db.getContact(txn, contactId)
+            val timestamp = date.toEpochSecond(ZoneOffset.UTC) * 1000
+            GroupCountHelper.resetGroupTimestamp(txn, contactId, messagingManager, clientHelper, timestamp)
+            contact
         }
         if (random.nextInt(100) + 1 <= avatarPercent) addAvatar(contact)
         LOG.info { "Added contact ${remote.name} with transport properties: $props" }
@@ -155,14 +169,6 @@ class DeterministicTestDataCreatorImpl @Inject internal constructor(
         return contact
     }
 
-    @Throws(DbException::class)
-    override fun addContact(name: String, alias: String?, avatar: Boolean): Contact {
-        val localAuthor = identityManager.localAuthor
-        val remote = authorFactory.createLocalAuthor(name)
-        val avatarPercent = if (avatar) 100 else 0
-        return addContact(localAuthor.id, remote, alias, avatarPercent)
-    }
-
     private val secretKey: SecretKey
         get() {
             val b = ByteArray(SecretKey.LENGTH)
-- 
GitLab