test(chapters): twelve proposals each keep their own summons
Phase 6 of docs/chapter-uploads.md, which asked for three things to be checked rather than assumed. All three already hold, so this is their tests and the record of it. The proposal list already groups: a "Waiting for you" header over the sessions isAwaitingApproval picks out, "Everything else" under them, over a query already ordered newest first. The chapter summary is already `name - N words - N chunks` rather than "Chapter", so twelve rows are twelve distinguishable rows. And isAbout already compares frostSigningSessionId when both rows carry one, falling back to the clock only when either does not. The last of those is the one with a history -- two concurrent sessions broke it once, which is why the column exists -- so it is now tested at twelve, with the answers given in the opposite order to the asking, so that neither the clock nor the list order could produce the right answer by accident. Plus one proposal failing and settling only its own row, which is the transcript's version of why an upload is N sessions and not one. Noted for Phase 8 rather than fixed here: twenty open chapter proposals is roughly 900 KB of unsignedEventJson parsed and summarised on every emission of that query, and summarize then re-splits each chapter's text to count its chunks. Phase 8 replaces that derived count with the session's own item count. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -182,4 +182,42 @@ class TranscriptRequestStateTest {
|
||||
|
||||
assertEquals(setOf(hostKey.id), ChatMessage.answeredRequests(transcript))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `twelve open proposals each keep their own summons`() {
|
||||
// An upload of twelve files opens twelve sessions at once, interleaved in
|
||||
// one stretch of transcript. The clock fallback would have the first
|
||||
// answer drop every later request, which is the failure two concurrent
|
||||
// sessions already had once -- and twelve is where a path that still
|
||||
// falls back to the clock would show.
|
||||
val requests = (1..12).map { n ->
|
||||
line(ChatMessage.TYPE_FROST_APPROVAL_NEEDED, at = 100L + n, session = "session-" + n)
|
||||
}
|
||||
|
||||
// Answered in the opposite order to the asking, so neither the clock nor
|
||||
// the list order could produce the right answer by accident.
|
||||
val answers = listOf(12, 7, 1).map { n ->
|
||||
line(ChatMessage.TYPE_FROST_NONCE, at = 200L + n, session = "session-" + n)
|
||||
}
|
||||
|
||||
val answered = ChatMessage.answeredRequests(requests + answers)
|
||||
|
||||
assertEquals(
|
||||
setOf(requests[11].id, requests[6].id, requests[0].id),
|
||||
answered,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `one proposal failing settles only itself`() {
|
||||
val requests = (1..12).map { n ->
|
||||
line(ChatMessage.TYPE_FROST_APPROVAL_NEEDED, at = 100L + n, session = "session-" + n)
|
||||
}
|
||||
val failure = line(ChatMessage.TYPE_FROST_FAILED, at = 300, session = "session-5")
|
||||
|
||||
// The other eleven chapters are still in front of the group. A batch is
|
||||
// all-or-nothing within a session and nothing across them, which is the
|
||||
// whole reason an upload is N sessions rather than one.
|
||||
assertEquals(setOf(requests[4].id), ChatMessage.settledRequests(requests + listOf(failure)))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user