From 5cb84e16dc589fa378baaae49309a01f7b138b13 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 28 Jul 2026 19:17:57 +0000 Subject: [PATCH] test: cover the version-note guard path in observeNotes dedup Add coverage for a real consumeBaseReplaceable call the suite was missing: observers are also notified with the "version" note (getOrCreateNote(event.id), a regular Note carrying the AddressableEvent), which the addressable-list guard must drop while still listing the AddressableNote for the same event. Confirmed the concurrency the stress tests exercise is real, not theoretical: relay events are verified+consumed inline on per-relay socket dispatchers, so distinct relays drive new()/remove() on the same note instance concurrently. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Ah1aCniyjnzc27x4pwq2Df --- .../observables/NoteListMatchingFilterTest.kt | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/commons/src/jvmTest/kotlin/com/vitorpamplona/amethyst/commons/model/observables/NoteListMatchingFilterTest.kt b/commons/src/jvmTest/kotlin/com/vitorpamplona/amethyst/commons/model/observables/NoteListMatchingFilterTest.kt index a4711101de..a77efc8318 100644 --- a/commons/src/jvmTest/kotlin/com/vitorpamplona/amethyst/commons/model/observables/NoteListMatchingFilterTest.kt +++ b/commons/src/jvmTest/kotlin/com/vitorpamplona/amethyst/commons/model/observables/NoteListMatchingFilterTest.kt @@ -186,6 +186,27 @@ class NoteListMatchingFilterTest { assertNull(firstViolation.get(), "an emission carried a duplicate idHex: ${firstViolation.get()}") } + @Test + fun ignoresTheVersionNoteThatHoldsAnAddressableEvent() { + // consumeBaseReplaceable also notifies observers with the "version" note: + // getOrCreateNote(event.id), a regular Note (not AddressableNote) carrying + // the AddressableEvent. It must never enter the addressable list. + var last: List = emptyList() + val subject = newFilter { last = it } + subject.init() + + val event = appDefinition("nostr-dvm-labeler", 1000) + val versionNote = Note(event.id).apply { this.event = event } + subject.new(event, versionNote) + + assertEquals(emptyList(), last) + + // The addressable note for the same event, however, is listed. + val addressable = noteFor("nostr-dvm-labeler").apply { this.event = event } + subject.new(event, addressable) + assertEquals(listOf(addressable.idHex), last.map { it.idHex }) + } + @Test fun removeDropsTheNoteEvenAfterCreatedAtChanged() { var last: List = emptyList()