From 8a6381269863fb102b3ed61d2f018016a48c9929 Mon Sep 17 00:00:00 2001
From: Janne Mareike Koschinski <janne@kuschku.de>
Date: Tue, 1 Mar 2022 02:08:01 +0100
Subject: [PATCH] fix: correct issue with backlog loading

---
 build.gradle.kts                              |  2 +-
 .../client/syncables/ClientBacklogManager.kt  | 23 +++++++++++++++++++
 .../client/util/CoroutineKeyedQueue.kt        | 11 ++++++++-
 .../justjanne/libquassel/client/ClientTest.kt | 23 +++++++++++++++++--
 4 files changed, 55 insertions(+), 4 deletions(-)

diff --git a/build.gradle.kts b/build.gradle.kts
index 871c90a..fe4a4e5 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -15,4 +15,4 @@ plugins {
 }
 
 group = "de.justjanne.libquassel"
-version = "0.9.0"
+version = "0.9.1"
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/syncables/ClientBacklogManager.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/syncables/ClientBacklogManager.kt
index 9bb894a..3eafa65 100644
--- a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/syncables/ClientBacklogManager.kt
+++ b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/syncables/ClientBacklogManager.kt
@@ -135,6 +135,29 @@ class ClientBacklogManager(
     super.receiveBacklogFiltered(bufferId, first, last, limit, additional, type, flags, messages)
   }
 
+  override fun receiveBacklogForward(
+    bufferId: BufferId,
+    first: MsgId,
+    last: MsgId,
+    limit: Int,
+    type: Int,
+    flags: Int,
+    messages: QVariantList
+  ) {
+    bufferForwardQueue.resume(
+      BacklogData.BufferForward(
+        bufferId,
+        first,
+        last,
+        limit,
+        MessageType.of(type.toUInt()),
+        MessageFlag.of(flags.toUInt())
+      ),
+      messages
+    )
+    super.receiveBacklogForward(bufferId, first, last, limit, type, flags, messages)
+  }
+
   override fun receiveBacklogAll(first: MsgId, last: MsgId, limit: Int, additional: Int, messages: QVariantList) {
     allQueue.resume(
       BacklogData.All(
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/util/CoroutineKeyedQueue.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/util/CoroutineKeyedQueue.kt
index ae4a2c9..62863cf 100644
--- a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/util/CoroutineKeyedQueue.kt
+++ b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/util/CoroutineKeyedQueue.kt
@@ -9,6 +9,7 @@
 
 package de.justjanne.libquassel.client.util
 
+import org.slf4j.LoggerFactory
 import kotlin.coroutines.Continuation
 import kotlin.coroutines.resume
 import kotlin.coroutines.suspendCoroutine
@@ -22,7 +23,11 @@ class CoroutineKeyedQueue<Key, Value> {
   }
 
   fun resume(key: Key, value: Value) {
-    val continuations = waiting[key].orEmpty().distinct()
+    val queue = waiting[key]
+    if (queue == null) {
+      logger.warn("Trying to resume message with unknown key: $key")
+    }
+    val continuations = queue.orEmpty().distinct()
     for (continuation in continuations) {
       continuation.resume(value)
     }
@@ -30,4 +35,8 @@ class CoroutineKeyedQueue<Key, Value> {
       waiting[it]?.removeAll(continuations)
     }
   }
+
+  companion object {
+    private val logger = LoggerFactory.getLogger(CoroutineKeyedQueue::class.java)
+  }
 }
diff --git a/libquassel-client/src/test/kotlin/de/justjanne/libquassel/client/ClientTest.kt b/libquassel-client/src/test/kotlin/de/justjanne/libquassel/client/ClientTest.kt
index 21b4eae..0d1f3c6 100644
--- a/libquassel-client/src/test/kotlin/de/justjanne/libquassel/client/ClientTest.kt
+++ b/libquassel-client/src/test/kotlin/de/justjanne/libquassel/client/ClientTest.kt
@@ -18,16 +18,21 @@ import de.justjanne.libquassel.protocol.connection.ProtocolVersion
 import de.justjanne.libquassel.protocol.exceptions.HandshakeException
 import de.justjanne.libquassel.protocol.features.FeatureSet
 import de.justjanne.libquassel.protocol.io.CoroutineChannel
+import de.justjanne.libquassel.protocol.models.ids.BufferId
+import de.justjanne.libquassel.protocol.models.ids.MsgId
 import de.justjanne.libquassel.protocol.session.CoreState
 import de.justjanne.testcontainersci.api.providedContainer
 import de.justjanne.testcontainersci.extension.CiContainers
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.withTimeout
 import org.junit.jupiter.api.Assertions.assertTrue
 import org.junit.jupiter.api.Test
 import org.junit.jupiter.api.assertThrows
 import java.net.InetSocketAddress
+import java.time.Duration
 import javax.net.ssl.SSLContext
+import kotlin.test.assertEquals
 
 @ExperimentalCoroutinesApi
 @CiContainers
@@ -36,8 +41,8 @@ class ClientTest {
     QuasselCoreContainer()
   }
 
-  private val username = "kuschku"
-  private val password = "goalielecturetrawl"
+  private val username = "AzureDiamond"
+  private val password = "hunter2"
 
   @Test
   fun testConnect(): Unit = runBlocking {
@@ -91,6 +96,20 @@ class ClientTest {
     }
     session.handshakeHandler.login(username, password)
     session.baseInitHandler.waitForInitDone()
+    withTimeout(Duration.ofSeconds(5).toMillis()) {
+      assertEquals(
+        emptyList(),
+        session.backlogManager.backlog(bufferId = BufferId(1), limit = 5)
+      )
+      assertEquals(
+        emptyList(),
+        session.backlogManager.backlogAll(limit = 5)
+      )
+      assertEquals(
+        emptyList(),
+        session.backlogManager.backlogForward(bufferId = BufferId(1), limit = 5)
+      )
+    }
     channel.close()
   }
 }
-- 
GitLab