Phase 664: mesh replay and group DM quota voice-note journeys.
Add runVoiceNoteMeshReplayJourney and runVoiceNoteGroupDmQuotaJourney for CI coverage of sparse fetch and per-participant byte limits. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -4,7 +4,7 @@ Agent control plane for Pearcord — send the same IPC messages the UI sends, re
|
||||
|
||||
**Phase 659 (v0.8.638):** Added `runDmPollVoteJourney` to verify DM single-choice idempotent vote apply, multi-select, anonymous poll creation, pre-vote edit guard behavior, close-state vote blocking, DM poll deletion, thread-scoped poll voting in `dm_thread`, and no synthetic unread/mention bump from poll updates; smoke `test:agentctl-dm-poll-phase659`.
|
||||
|
||||
**Phase 664 (v0.8.639):** `runVoiceNoteDmJourney`, `runVoiceNoteLockCancelJourney`, `runVoiceNoteSlowmodeBlockedJourney`; bundle `test:agentctl-phase664-voice-notes`.
|
||||
**Phase 664 (v0.8.639):** `runVoiceNoteDmJourney`, `runVoiceNoteLockCancelJourney`, `runVoiceNoteSlowmodeBlockedJourney`, `runVoiceNoteMeshReplayJourney`, `runVoiceNoteGroupDmQuotaJourney`; bundle `test:agentctl-phase664-voice-notes`.
|
||||
|
||||
**Phase 659 storage (v0.8.639):** Added `runDmPollFixtureExportImportJourney` — export poll/vote fixtures after voting, delete poll row, import round-trip, verify `dmPollEngine` and restored store rows (runs inside `test:agentctl-dm-poll-phase659`).
|
||||
|
||||
|
||||
+43
@@ -2245,6 +2245,49 @@ class HeadlessSession {
|
||||
return this.runVoiceNoteCancelJourney()
|
||||
}
|
||||
|
||||
/** P664-36: 2-peer commit + playback fetch (joiner sparse pull proxy). */
|
||||
async runVoiceNoteMeshReplayJourney () {
|
||||
if (!this.platform) throw new Error('headless not started')
|
||||
await this.registerUser({ username: 'vn_replay', displayName: 'VN Replay' })
|
||||
await this.createGuild({ name: 'VN Replay', publicListing: false })
|
||||
await this.wait({ mode: 'guild' }, 45000)
|
||||
await this.stageVoiceNoteFromBuffer(Buffer.alloc(512, 2), 1100)
|
||||
const sent = await this.sendStagedVoiceNote()
|
||||
const noteId = sent?.voiceNote?.id
|
||||
if (!noteId) throw new Error('expected voiceNote id')
|
||||
this.platform.voiceNotes?.clearBlobCache?.(noteId)
|
||||
const fetched = await this.platform.fetchVoiceNoteBlob(noteId)
|
||||
if (!fetched?.bytes) throw new Error('expected fetched blob bytes')
|
||||
const diag = this.platform.exportVoiceNoteDiagnostics()
|
||||
if (!diag?.fetchProgress) throw new Error('expected fetchProgress in diagnostics')
|
||||
return { noteId, bytes: fetched.bytes, messageId: sent.message.id }
|
||||
}
|
||||
|
||||
/** P664-13: group DM per-participant byte quota. */
|
||||
async runVoiceNoteGroupDmQuotaJourney () {
|
||||
if (!this.platform) throw new Error('headless not started')
|
||||
const { groupDmVoiceNoteMaxBytes, VOICE_NOTE_MAX_BYTES } = require('pearcord-shared')
|
||||
await this.registerUser({ username: 'vn_gquota', displayName: 'VN GQuota' })
|
||||
await this.createGroupDm(['b'.repeat(32), 'c'.repeat(32)], 'VN Group')
|
||||
await this.wait({ mode: 'dm' }, 30000)
|
||||
const v = await this.refreshView()
|
||||
if (!v.dmIsGroup) throw new Error('expected group dm')
|
||||
const participants = v.activeChannel?.participantIds?.length || 3
|
||||
const maxBytes = groupDmVoiceNoteMaxBytes(participants, VOICE_NOTE_MAX_BYTES)
|
||||
let blocked = false
|
||||
try {
|
||||
await this.stageVoiceNoteFromBuffer(Buffer.alloc(maxBytes + 64, 1), 700)
|
||||
} catch (err) {
|
||||
blocked = /exceeds|limit/i.test(err?.message || '')
|
||||
}
|
||||
if (!blocked) throw new Error('expected group dm quota to block oversized note')
|
||||
await this.stageVoiceNoteFromBuffer(Buffer.alloc(Math.min(256 * 1024, maxBytes - 1), 1), 700)
|
||||
const v2 = await this.refreshView()
|
||||
if (!v2.voiceNoteDraft?.id) throw new Error('expected draft under quota')
|
||||
await this.discardStagedVoiceNote()
|
||||
return { maxBytes, participants }
|
||||
}
|
||||
|
||||
/** P664-37: slowmode blocks voice note send. */
|
||||
async runVoiceNoteSlowmodeBlockedJourney () {
|
||||
if (!this.platform) throw new Error('headless not started')
|
||||
|
||||
Reference in New Issue
Block a user