fix(chat): restore pending approval guard, tighten encapsulation, drop dormant tracker
This commit is contained in:
1 parent
0af4782da1
commit
7b198fa6d6
6 files changed
+40
-216
No files matched your search
@@ -161,6 +161,36 @@ class ChatApprovalsDelegateTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun handleApprovalPendingResult_dropsMissingRequestId_andDedupesAlreadyShown() {
|
||||
val initialCount = uiState.value.messages.size
|
||||
|
||||
// No request_id -> dropped entirely
|
||||
delegate.handleApprovalPendingResult(
|
||||
mapOf("approvals" to listOf(mapOf("command" to "rm -rf /"))),
|
||||
)
|
||||
assertEquals(initialCount, uiState.value.messages.size)
|
||||
|
||||
// Valid request_id -> surfaced
|
||||
delegate.handleApprovalPendingResult(
|
||||
mapOf("approvals" to listOf(mapOf("command" to "git pull", "request_id" to "r-valid"))),
|
||||
)
|
||||
assertEquals(initialCount + 1, uiState.value.messages.size)
|
||||
assertEquals(
|
||||
"r-valid",
|
||||
uiState.value.messages
|
||||
.last()
|
||||
.approvalInfo
|
||||
?.requestId,
|
||||
)
|
||||
|
||||
// Duplicate request_id -> ignored
|
||||
delegate.handleApprovalPendingResult(
|
||||
mapOf("approvals" to listOf(mapOf("command" to "git pull", "request_id" to "r-valid"))),
|
||||
)
|
||||
assertEquals(initialCount + 1, uiState.value.messages.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun handleApprovalRespondResult_appendsDesktopParitySystemMessage() {
|
||||
delegate.handleApprovalRespondResult(mapOf("resolved" to 1))
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
package com.m57.hermescontrol.ui.chat
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
|
||||
class ChatRpcRequestTrackerTest {
|
||||
private var currentSessionId: String? = "session-a"
|
||||
private val tracker = ChatRpcRequestTracker { currentSessionId }
|
||||
|
||||
@Test
|
||||
fun trackRequest_andRemoveMethod() {
|
||||
tracker.trackRequest("req-1", "session.create")
|
||||
assertEquals("session.create", tracker.removeMethod("req-1"))
|
||||
assertNull(tracker.removeMethod("req-1"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun generationIncrement_detectsStaleGenerations() {
|
||||
val gen1 = tracker.nextSessionGeneration()
|
||||
assertEquals(1L, gen1)
|
||||
|
||||
tracker.trackSessionRequest(
|
||||
id = "req-resume-1",
|
||||
method = "session.resume",
|
||||
generation = gen1,
|
||||
sessionId = "session-a",
|
||||
)
|
||||
assertFalse(tracker.isStaleSessionRequest("req-resume-1"))
|
||||
|
||||
val gen2 = tracker.nextSessionGeneration()
|
||||
assertEquals(2L, gen2)
|
||||
assertTrue(tracker.isStaleSessionRequest("req-resume-1"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun sessionMismatch_marksRequestStale() {
|
||||
val gen = tracker.nextSessionGeneration()
|
||||
tracker.trackSessionRequest(
|
||||
id = "req-2",
|
||||
method = "session.resume",
|
||||
generation = gen,
|
||||
sessionId = "session-a",
|
||||
)
|
||||
assertFalse(tracker.isStaleSessionRequest("req-2"))
|
||||
|
||||
currentSessionId = "session-b"
|
||||
assertTrue(tracker.isStaleSessionRequest("req-2"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun resumeSequence_marksSupersededResumeStale() {
|
||||
val gen = tracker.nextSessionGeneration()
|
||||
val seq1 = tracker.nextResumeSequence()
|
||||
tracker.trackSessionRequest(
|
||||
id = "req-resume-seq1",
|
||||
method = "session.resume",
|
||||
generation = gen,
|
||||
resumeSequence = seq1,
|
||||
sessionId = "session-a",
|
||||
)
|
||||
assertFalse(tracker.isStaleSessionRequest("req-resume-seq1"))
|
||||
|
||||
val seq2 = tracker.nextResumeSequence()
|
||||
assertEquals(2L, seq2)
|
||||
assertTrue(tracker.isStaleSessionRequest("req-resume-seq1"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun hydrationSequence_guardsActiveHydration() {
|
||||
val gen = tracker.nextSessionGeneration()
|
||||
val hyd1 = tracker.nextHydrationSequence()
|
||||
assertTrue(tracker.isCurrentHydration("session-a", gen, hyd1))
|
||||
|
||||
val hyd2 = tracker.nextHydrationSequence()
|
||||
assertFalse(tracker.isCurrentHydration("session-a", gen, hyd1))
|
||||
assertTrue(tracker.isCurrentHydration("session-a", gen, hyd2))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun forgetRequest_removesBothTrackingEntries() {
|
||||
tracker.trackSessionRequest(
|
||||
id = "req-forget",
|
||||
method = "session.resume",
|
||||
generation = tracker.sessionGeneration,
|
||||
sessionId = "session-a",
|
||||
)
|
||||
tracker.forgetRequest("req-forget")
|
||||
assertNull(tracker.removeMethod("req-forget"))
|
||||
assertNull(tracker.removeSessionRequest("req-forget"))
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user