nip10: simplify and fix reply-to-root bugs

This removes EventRefs alltogether and uses the form we use in Damus
Android.

This simplifies our ThreadReply logic and fixes a reply-to-root bug

Reported-by: NotBiebs <justinbieber@stemstr.app>
Changelog-Fixed: Fix thread bug where a quote isn't picked up as a reply
Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
William Casarin
2024-05-11 09:02:09 -07:00
parent 8dbdff7ff0
commit 52aefc8d64
17 changed files with 139 additions and 499 deletions

View File

@@ -26,36 +26,55 @@ final class NIP10Tests: XCTestCase {
// Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards.
}
func test_root_with_mention_nip10() {
let root_id_hex = "a32d70d331f4bea7a859ac71d85a9b4e0c2d1fa9aaf7237a17f85a6227f52fdb"
let root_id = NoteId(hex: root_id_hex)!
let mention_hex = "e47b7e156acec6881c89a53f1a9e349a982024245e2c398f8a5b4973b7a89ab3"
let mention_id = NoteId(hex: mention_hex)!
let tags =
[["e", root_id_hex,"","root"],
["e", mention_hex,"","mention"],
["p","c4eabae1be3cf657bc1855ee05e69de9f059cb7a059227168b80b89761cbc4e0"],
["p","604e96e099936a104883958b040b47672e0f048c98ac793f37ffe4c720279eb2"],
["p","ffd375eb40eb486656a028edbc83825f58ff0d5c4a1ba22fe7745d284529ed08","","mention"],
["q","e47b7e156acec6881c89a53f1a9e349a982024245e2c398f8a5b4973b7a89ab3"]
]
let note = NdbNote(content: "hi", keypair: test_keypair, kind: 1, tags: tags)!
let thread = ThreadReply(tags: note.tags)
XCTAssertNotNil(thread)
guard let thread else { return }
XCTAssertEqual(thread.root.note_id, root_id)
XCTAssertEqual(thread.reply.note_id, root_id)
XCTAssertEqual(thread.mention?.ref.note_id, mention_id)
}
func test_new_nip10() {
let root_note_id_hex = "7c7d37bc8c04d2ec65cbc7d9275253e6b5cc34b5d10439f158194a3feefa8d52"
let direct_reply_hex = "7c7d37bc8c04d2ec65cbc7d9275253e6b5cc34b5d10439f158194a3feefa8d51"
let reply_hex = "7c7d37bc8c04d2ec65cbc7d9275253e6b5cc34b5d10439f158194a3feefa8d53"
let mention_hex = "7c7d37bc8c04d2ec65cbc7d9275253e6b5cc34b5d10439f158194a3feefa8d54"
let tags = [
["e", mention_hex, "", "mention"],
["e", direct_reply_hex, "", "reply"],
["e", root_note_id_hex, "", "root"],
["e", reply_hex, "", "reply"],
["e", "7c7d37bc8c04d2ec65cbc7d9275253e6b5cc34b5d10439f158194a3feefa8d54", "", "mention"],
]
let root_note_id = NoteId(hex: root_note_id_hex)!
let direct_reply_id = NoteId(hex: direct_reply_hex)!
let reply_id = NoteId(hex: reply_hex)!
let mention_id = NoteId(hex: mention_hex)!
let note = NdbNote(content: "hi", keypair: test_keypair, kind: 1, tags: tags)!
let refs = interp_event_refs_without_mentions_ndb(note.referenced_noterefs)
let tr = interp_event_refs_without_mentions_ndb(note.referenced_noterefs)
XCTAssertEqual(refs.reduce(into: Array<NoteId>(), { xs, r in
if let note_id = r.is_thread_id?.note_id { xs.append(note_id) }
}), [root_note_id])
XCTAssertEqual(refs.reduce(into: Array<NoteId>(), { xs, r in
if let note_id = r.is_direct_reply?.note_id { xs.append(note_id) }
}), [direct_reply_id, reply_id])
XCTAssertEqual(refs.reduce(into: Array<NoteId>(), { xs, r in
if let note_id = r.is_reply?.note_id { xs.append(note_id) }
}), [direct_reply_id, reply_id])
XCTAssertEqual(tr?.root.note_id, root_note_id)
XCTAssertEqual(tr?.reply.note_id, reply_id)
XCTAssertEqual(tr?.mention?.ref.note_id, mention_id)
}
func test_repost_root() {
@@ -66,19 +85,9 @@ final class NIP10Tests: XCTestCase {
let mention_id = NoteId(hex: mention_hex)!
let note = NdbNote(content: "hi", keypair: test_keypair, kind: 1, tags: tags)!
let refs = interp_event_refs_without_mentions_ndb(note.referenced_noterefs)
let tr = note.thread_reply()
XCTAssertEqual(refs.reduce(into: Array<NoteId>(), { xs, r in
if let note_id = r.is_thread_id?.note_id { xs.append(note_id) }
}), [])
XCTAssertEqual(refs.reduce(into: Array<NoteId>(), { xs, r in
if let note_id = r.is_direct_reply?.note_id { xs.append(note_id) }
}), [])
XCTAssertEqual(refs.reduce(into: Array<NoteId>(), { xs, r in
if let note_id = r.is_reply?.note_id { xs.append(note_id) }
}), [])
XCTAssertNil(tr)
}
func test_direct_reply_old_nip10() {
@@ -90,19 +99,14 @@ final class NIP10Tests: XCTestCase {
let root_note_id = NoteId(hex: root_note_id_hex)!
let note = NdbNote(content: "hi", keypair: test_keypair, kind: 1, tags: tags)!
let refs = interp_event_refs_without_mentions_ndb(note.referenced_noterefs)
let tr = note.thread_reply()
XCTAssertEqual(refs.reduce(into: Array<NoteId>(), { xs, r in
if let note_id = r.is_thread_id?.note_id { xs.append(note_id) }
}), [root_note_id])
XCTAssertNotNil(tr)
guard let tr else { return }
XCTAssertEqual(refs.reduce(into: Array<NoteId>(), { xs, r in
if let note_id = r.is_direct_reply?.note_id { xs.append(note_id) }
}), [root_note_id])
XCTAssertEqual(refs.reduce(into: Array<NoteId>(), { xs, r in
if let note_id = r.is_reply?.note_id { xs.append(note_id) }
}), [root_note_id])
XCTAssertEqual(tr.root.note_id, root_note_id)
XCTAssertEqual(tr.reply.note_id, root_note_id)
XCTAssertEqual(tr.is_reply_to_root, true)
}
func test_direct_reply_new_nip10() {
@@ -114,24 +118,14 @@ final class NIP10Tests: XCTestCase {
let root_note_id = NoteId(hex: root_note_id_hex)!
let note = NdbNote(content: "hi", keypair: test_keypair, kind: 1, tags: tags)!
let refs = interp_event_refs_without_mentions_ndb(note.referenced_noterefs)
let tr = note.thread_reply()
XCTAssertNotNil(tr)
guard let tr else { return }
XCTAssertEqual(refs.reduce(into: Array<NoteId>(), { xs, r in
if let note_id = r.is_thread_id?.note_id { xs.append(note_id) }
}), [root_note_id])
XCTAssertEqual(refs.reduce(into: Array<NoteId>(), { xs, r in
if let note_id = r.is_direct_reply?.note_id { xs.append(note_id) }
}), [root_note_id])
XCTAssertEqual(refs.reduce(into: Array<NoteId>(), { xs, r in
if let note_id = r.is_reply?.note_id { xs.append(note_id) }
}), [root_note_id])
let nip10 = note.thread_reply(test_keypair)!
XCTAssertEqual(nip10.is_reply_to_root, true)
XCTAssertEqual(nip10.root.note_id, root_note_id)
XCTAssertEqual(nip10.reply!.note_id, root_note_id)
XCTAssertEqual(tr.root.note_id, root_note_id)
XCTAssertEqual(tr.reply.note_id, root_note_id)
XCTAssertNil(tr.mention)
XCTAssertEqual(tr.is_reply_to_root, true)
}
// seen in the wild by the gleasonator
@@ -143,13 +137,14 @@ final class NIP10Tests: XCTestCase {
let root_note_id = NoteId(hex: root_note_id_hex)!
let note = NdbNote(content: "hi", keypair: test_keypair, kind: 1, tags: tags)!
let refs = interp_event_refs_without_mentions_ndb(note.referenced_noterefs)
let thread_reply = ThreadReply(event_refs: refs)!
let tr = note.thread_reply()
XCTAssertNotNil(tr)
guard let tr else { return }
XCTAssertEqual(thread_reply.mention, nil)
XCTAssertEqual(thread_reply.root.note_id, root_note_id)
XCTAssertEqual(thread_reply.reply!.note_id, root_note_id)
XCTAssertEqual(thread_reply.is_reply_to_root, true)
XCTAssertNil(tr.mention)
XCTAssertEqual(tr.root.note_id, root_note_id)
XCTAssertEqual(tr.reply.note_id, root_note_id)
XCTAssertEqual(tr.is_reply_to_root, true)
}
func test_marker_reply() {
@@ -193,7 +188,6 @@ final class NIP10Tests: XCTestCase {
[
["e", root_hex, "wss://nostr.mutinywallet.com/", "root"],
["e", replying_to_hex, "", "reply"],
//["e", last_reply_hex, "wss://relay.nostrplebs.com"],
["p", "5b0183ab6c3e322bf4d41c6b3aef98562a144847b7499543727c5539a114563e"],
["p", "6e75f7972397ca3295e0f4ca0fbc6eb9cc79be85bafdd56bd378220ca8eee74e"],
])
@@ -218,16 +212,13 @@ final class NIP10Tests: XCTestCase {
let reply_id = NoteId(hex: reply_hex)!
let note = NdbNote(content: "hi", keypair: test_keypair, kind: 1, tags: tags)!
let refs = interp_event_refs_without_mentions_ndb(note.referenced_noterefs)
XCTAssertEqual(refs.reduce(into: Array<NoteId>(), { xs, r in
if let note_id = r.is_thread_id?.note_id { xs.append(note_id) }
}), [root_note_id])
XCTAssertEqual(refs.reduce(into: Array<NoteId>(), { xs, r in
if let note_id = r.is_reply?.note_id { xs.append(note_id) }
}), [reply_id])
let tr = note.thread_reply()
XCTAssertNotNil(tr)
guard let tr else { return }
XCTAssertEqual(tr.root.note_id, root_note_id)
XCTAssertEqual(tr.reply.note_id, reply_id)
XCTAssertEqual(tr.is_reply_to_root, false)
}
func test_deprecated_nip10() {
@@ -245,19 +236,13 @@ final class NIP10Tests: XCTestCase {
let reply_id = NoteId(hex: reply_hex)!
let note = NdbNote(content: "hi", keypair: test_keypair, kind: 1, tags: tags)!
let refs = interp_event_refs_without_mentions_ndb(note.referenced_noterefs)
let tr = note.thread_reply()
XCTAssertNotNil(tr)
guard let tr else { return }
XCTAssertEqual(refs.reduce(into: Array<NoteId>(), { xs, r in
if let note_id = r.is_thread_id?.note_id { xs.append(note_id) }
}), [root_note_id])
XCTAssertEqual(refs.reduce(into: Array<NoteId>(), { xs, r in
if let note_id = r.is_direct_reply?.note_id { xs.append(note_id) }
}), [direct_reply_id, reply_id])
XCTAssertEqual(refs.reduce(into: Array<NoteId>(), { xs, r in
if let note_id = r.is_reply?.note_id { xs.append(note_id) }
}), [direct_reply_id, reply_id])
XCTAssertEqual(tr.root.note_id, root_note_id)
XCTAssertEqual(tr.reply.note_id, reply_id)
XCTAssertEqual(tr.is_reply_to_root, false)
}