ndb: switch to nostrdb notes

This is a refactor of the codebase to use a more memory-efficient
representation of notes. It should also be much faster at decoding since
we're using a custom C json parser now.

Changelog-Changed: Improved memory usage and performance when processing events
This commit is contained in:
William Casarin
2023-07-26 08:46:44 -07:00
parent 55bbe8f855
commit cebd1f48ca
110 changed files with 2153 additions and 1799 deletions

View File

@@ -25,20 +25,14 @@ class Bech32Tests: XCTestCase {
// Mark your test throws to produce an unexpected failure when your test encounters an uncaught error.
// Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards.
let pubkey = "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245"
guard let b32_pubkey = bech32_pubkey(pubkey) else {
let pubkey = Pubkey(hex: "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245")!
guard let decoded = try? bech32_decode(pubkey.npub) else {
XCTAssert(false)
return
}
guard let decoded = try? bech32_decode(b32_pubkey) else {
XCTAssert(false)
return
}
let encoded = hex_encode(decoded.data)
XCTAssertEqual(encoded, pubkey)
XCTAssertEqual(decoded.data, pubkey.id)
}
func testPerformanceExample() throws {

View File

@@ -11,96 +11,97 @@ import XCTest
final class DMTests: XCTestCase {
var alice: Keypair {
let sec = "494c680d20f202807a116a6915815bd76a27d62802e7585806f6a2e034cb5cdb"
let pk = "22d925632551a3299022e98de7f9c1087f79a21209f3413ec24ec219b08bd1e4"
let sec = hex_decode_privkey("494c680d20f202807a116a6915815bd76a27d62802e7585806f6a2e034cb5cdb")!
let pk = hex_decode_pubkey("22d925632551a3299022e98de7f9c1087f79a21209f3413ec24ec219b08bd1e4")!
return Keypair(pubkey: pk, privkey: sec)
}
var bob: Keypair {
let sec = "aa8920b05b4bd5c79fce46868ed5ebc82bdb91b211850b14541bfbd13953cfef"
let pk = "5a9a277dca94260688ecf7d63053de8c121b7f01f609d7f84a1eb9cff64e4606"
let sec = hex_decode_privkey("aa8920b05b4bd5c79fce46868ed5ebc82bdb91b211850b14541bfbd13953cfef")!
let pk = hex_decode_pubkey("5a9a277dca94260688ecf7d63053de8c121b7f01f609d7f84a1eb9cff64e4606")!
return Keypair(pubkey: pk, privkey: sec)
}
var charlie: Keypair {
let sec = "4c79130952c9c3b017dad62f37f285853a9c53f2a1184d94594f5b860f30b5a5"
let pk = "51c0d263fbfc4bf850805dccf9a29125071e6fed9619bff3efa9a6b5bbcc54a7"
let sec = hex_decode_privkey("4c79130952c9c3b017dad62f37f285853a9c53f2a1184d94594f5b860f30b5a5")!
let pk = hex_decode_pubkey("51c0d263fbfc4bf850805dccf9a29125071e6fed9619bff3efa9a6b5bbcc54a7")!
return Keypair(pubkey: pk, privkey: sec)
}
var dave: Keypair {
let sec = "630ffd518084334cbb9ecb20d9532ce0658b8123f4ba565c236d0cea9a4a2cfe"
let pk = "b42e44b555013239a0d5dcdb09ebde0857cd8a5a57efbba5a2b6ac78833cb9f0"
let sec = hex_decode_privkey("630ffd518084334cbb9ecb20d9532ce0658b8123f4ba565c236d0cea9a4a2cfe")!
let pk = hex_decode_pubkey("b42e44b555013239a0d5dcdb09ebde0857cd8a5a57efbba5a2b6ac78833cb9f0")!
return Keypair(pubkey: pk, privkey: sec)
}
var fiatjaf: Keypair {
let sec = "5426893eab32191ec17a83a583d5c8f85adaabcab0fa56af277ea0b61f575599"
let pub = "e27258d7be6d84038967334bfd0954f05801b1bcd85b2afa4c03cfd16ae4b0ad"
let sec = hex_decode_privkey("5426893eab32191ec17a83a583d5c8f85adaabcab0fa56af277ea0b61f575599")!
let pub = hex_decode_pubkey("e27258d7be6d84038967334bfd0954f05801b1bcd85b2afa4c03cfd16ae4b0ad")!
return Keypair(pubkey: pub, privkey: sec)
}
/*
func testDMSortOrder() throws {
let notif = NewEventsBits()
let pubkey = "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681"
let pubkey = hex_decode_pubkey("3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681")!
let model = DirectMessagesModel(our_pubkey: pubkey)
let now = UInt32(Date().timeIntervalSince1970)
let alice_to_bob = create_dm("hi bob", to_pk: bob.pubkey, tags: [["p", bob.pubkey]], keypair: alice, created_at: now)!
let debouncer = Debouncer(interval: 3.0)
let alice_to_bob = create_dm("hi bob", to_pk: bob.pubkey, tags: [bob.pubkey.tag], keypair: alice, created_at: now)!
handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [alice_to_bob])
XCTAssertEqual(model.dms.count, 1)
XCTAssertEqual(model.dms[0].pubkey, bob.pubkey)
let bob_to_alice = create_dm("hi alice", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: bob, created_at: now + 1)!
let bob_to_alice = create_dm("hi alice", to_pk: alice.pubkey, tags: [alice.pubkey.tag], keypair: bob, created_at: now + 1)!
handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [bob_to_alice])
XCTAssertEqual(model.dms.count, 1)
XCTAssertEqual(model.dms[0].pubkey, bob.pubkey)
let alice_to_bob_2 = create_dm("hi bob", to_pk: bob.pubkey, tags: [["p", bob.pubkey]], keypair: alice, created_at: now + 2)!
let alice_to_bob_2 = create_dm("hi bob", to_pk: bob.pubkey, tags: [bob.pubkey.tag], keypair: alice, created_at: now + 2)!
handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [alice_to_bob_2])
XCTAssertEqual(model.dms.count, 1)
XCTAssertEqual(model.dms[0].pubkey, bob.pubkey)
let fiatjaf_to_alice = create_dm("hi alice", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: fiatjaf, created_at: now+5)!
let fiatjaf_to_alice = create_dm("hi alice", to_pk: alice.pubkey, tags: [alice.pubkey.tag], keypair: fiatjaf, created_at: now+5)!
handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [fiatjaf_to_alice])
XCTAssertEqual(model.dms.count, 2)
XCTAssertEqual(model.dms[0].pubkey, fiatjaf.pubkey)
let dave_to_alice = create_dm("hi alice", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: dave, created_at: now + 10)!
let dave_to_alice = create_dm("hi alice", to_pk: alice.pubkey, tags: [alice.pubkey.tag], keypair: dave, created_at: now + 10)!
handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [dave_to_alice])
XCTAssertEqual(model.dms.count, 3)
XCTAssertEqual(model.dms[0].pubkey, dave.pubkey)
let bob_to_alice_2 = create_dm("hi alice 2", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: bob, created_at: now + 15)!
let bob_to_alice_2 = create_dm("hi alice 2", to_pk: alice.pubkey, tags: [alice.pubkey.tag], keypair: bob, created_at: now + 15)!
handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [bob_to_alice_2])
XCTAssertEqual(model.dms.count, 3)
XCTAssertEqual(model.dms[0].pubkey, bob.pubkey)
let charlie_to_alice = create_dm("hi alice", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: charlie, created_at: now + 20)!
let charlie_to_alice = create_dm("hi alice", to_pk: alice.pubkey, tags: [alice.pubkey.tag], keypair: charlie, created_at: now + 20)!
handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [charlie_to_alice])
XCTAssertEqual(model.dms.count, 4)
XCTAssertEqual(model.dms[0].pubkey, charlie.pubkey)
let bob_to_alice_3 = create_dm("hi alice 3", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: bob, created_at: now + 25)!
let bob_to_alice_3 = create_dm("hi alice 3", to_pk: alice.pubkey, tags: [alice.pubkey.tag], keypair: bob, created_at: now + 25)!
handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [bob_to_alice_3])
XCTAssertEqual(model.dms.count, 4)
XCTAssertEqual(model.dms[0].pubkey, bob.pubkey)
let charlie_to_alice_2 = create_dm("hi alice 2", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: charlie, created_at: now + 30)!
let charlie_to_alice_2 = create_dm("hi alice 2", to_pk: alice.pubkey, tags: [alice.pubkey.tag], keypair: charlie, created_at: now + 30)!
handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [charlie_to_alice_2])
XCTAssertEqual(model.dms.count, 4)
XCTAssertEqual(model.dms[0].pubkey, charlie.pubkey)
}
*/
}

View File

@@ -20,26 +20,31 @@ final class EventGroupViewTests: XCTestCase {
func testEventAuthorName() {
let damusState = test_damus_state()
XCTAssertEqual(event_author_name(profiles: damusState.profiles, pubkey: "pk1"), "pk1:pk1")
XCTAssertEqual(event_author_name(profiles: damusState.profiles, pubkey: "pk2"), "pk2:pk2")
XCTAssertEqual(event_author_name(profiles: damusState.profiles, pubkey: "anon"), "Anonymous")
XCTAssertEqual(event_author_name(profiles: damusState.profiles, pubkey: test_pubkey), "damus")
XCTAssertEqual(event_author_name(profiles: damusState.profiles, pubkey: test_pubkey_2), "1rppft3m:4qxhsgnj")
XCTAssertEqual(event_author_name(profiles: damusState.profiles, pubkey: ANON_PUBKEY), "Anonymous")
}
func testEventGroupUniquePubkeys() {
let damusState = test_damus_state()
let encodedPost = "{\"id\": \"8ba545ab96959fe0ce7db31bc10f3ac3aa5353bc4428dbf1e56a7be7062516db\",\"pubkey\": \"7e27509ccf1e297e1df164912a43406218f8bd80129424c3ef798ca3ef5c8444\",\"created_at\": 1677013417,\"kind\": 1,\"tags\": [],\"content\": \"hello\",\"sig\": \"93684f15eddf11f42afbdd81828ee9fc35350344d8650c78909099d776e9ad8d959cd5c4bff7045be3b0b255144add43d0feef97940794a1bc9c309791bebe4a\"}"
let pk1 = Keypair(pubkey: "pk1", privkey: nil)
let pk2 = Keypair(pubkey: "pk2", privkey: nil)
let pk3 = Keypair(pubkey: "pk3", privkey: nil)
let repost1 = NostrEvent(content: encodedPost, keypair: pk1, kind: NostrKind.boost.rawValue, tags: [], createdAt: 1)!
let repost2 = NostrEvent(content: encodedPost, keypair: pk2, kind: NostrKind.boost.rawValue, tags: [], createdAt: 1)!
let repost3 = NostrEvent(content: encodedPost, keypair: pk3, kind: NostrKind.boost.rawValue, tags: [], createdAt: 1)!
let pk1 =
hex_decode_pubkey("1723a4dcc6596d84472eb74d579114d8c46b533c81a0ac76620a7605d3ff76e0")!
let pk2 =
hex_decode_pubkey("08c43696702ba1d720e4564b4ad895efdc3716b37468fb288e585368950a428a")!
let pk3 =
hex_decode_pubkey("4e563600925231e9eb35a61842c2c6c19685aa8eefdfad076d6a3f853453a299")!
let repost1 = NostrEvent(content: encodedPost, keypair: .just_pubkey(pk1), kind: NostrKind.boost.rawValue, tags: [], createdAt: 1)!
let repost2 = NostrEvent(content: encodedPost, keypair: .just_pubkey(pk2), kind: NostrKind.boost.rawValue, tags: [], createdAt: 1)!
let repost3 = NostrEvent(content: encodedPost, keypair: .just_pubkey(pk3), kind: NostrKind.boost.rawValue, tags: [], createdAt: 1)!
XCTAssertEqual(event_group_unique_pubkeys(profiles: damusState.profiles, group: .repost(EventGroup(events: []))), [])
XCTAssertEqual(event_group_unique_pubkeys(profiles: damusState.profiles, group: .repost(EventGroup(events: [repost1]))), [pk1.pubkey])
XCTAssertEqual(event_group_unique_pubkeys(profiles: damusState.profiles, group: .repost(EventGroup(events: [repost1, repost2]))), [pk1.pubkey, pk2.pubkey])
XCTAssertEqual(event_group_unique_pubkeys(profiles: damusState.profiles, group: .repost(EventGroup(events: [repost1, repost2, repost3]))), [pk1.pubkey, pk2.pubkey, pk3.pubkey])
XCTAssertEqual(event_group_unique_pubkeys(profiles: damusState.profiles, group: .repost(EventGroup(events: [repost1]))), [pk1])
XCTAssertEqual(event_group_unique_pubkeys(profiles: damusState.profiles, group: .repost(EventGroup(events: [repost1, repost2]))), [pk1, pk2])
XCTAssertEqual(event_group_unique_pubkeys(profiles: damusState.profiles, group: .repost(EventGroup(events: [repost1, repost2, repost3]))), [pk1, pk2, pk3])
}
func testReactingToText() throws {
@@ -48,18 +53,27 @@ final class EventGroupViewTests: XCTestCase {
let encodedPost = "{\"id\": \"8ba545ab96959fe0ce7db31bc10f3ac3aa5353bc4428dbf1e56a7be7062516db\",\"pubkey\": \"7e27509ccf1e297e1df164912a43406218f8bd80129424c3ef798ca3ef5c8444\",\"created_at\": 1677013417,\"kind\": 1,\"tags\": [],\"content\": \"hello\",\"sig\": \"93684f15eddf11f42afbdd81828ee9fc35350344d8650c78909099d776e9ad8d959cd5c4bff7045be3b0b255144add43d0feef97940794a1bc9c309791bebe4a\"}"
let pk1 = Keypair(pubkey: "pk1", privkey: nil)
let pk2 = Keypair(pubkey: "pk2", privkey: nil)
let pk3 = Keypair(pubkey: "pk3", privkey: nil)
let pk1_pk =
hex_decode_pubkey("938afd5f44fdf293546767dcc024b4ec09b9df422fad10d577a846f88f56c8f5")!
let pk2_pk =
hex_decode_pubkey("6b9bb7acbcdf0458a81b9e6d29bb1e23ab9b5d288e9b7fa8cee8dedc9082a466")!
let pk3_pk =
hex_decode_pubkey("b9f00c1f12b0b7a2e3960565af7aba71da9678d90faeb60bc19813f3a28840de")!
let pk1 = Keypair(pubkey: pk1_pk, privkey: nil)
let pk2 = Keypair(pubkey: pk2_pk, privkey: nil)
let pk3 = Keypair(pubkey: pk3_pk, privkey: nil)
let repost1 = NostrEvent(content: encodedPost, keypair: pk1, kind: NostrKind.boost.rawValue, tags: [], createdAt: 1)!
let repost2 = NostrEvent(content: encodedPost, keypair: pk2, kind: NostrKind.boost.rawValue, tags: [], createdAt: 1)!
let repost3 = NostrEvent(content: encodedPost, keypair: pk3, kind: NostrKind.boost.rawValue, tags: [], createdAt: 1)!
XCTAssertEqual(reacting_to_text(profiles: damusState.profiles, our_pubkey: damusState.pubkey, group: .repost(EventGroup(events: [])), ev: test_note, pubkeys: [], locale: enUsLocale), "??")
XCTAssertEqual(reacting_to_text(profiles: damusState.profiles, our_pubkey: damusState.pubkey, group: .repost(EventGroup(events: [repost1])), ev: test_note, pubkeys: [pk1.pubkey], locale: enUsLocale), "pk1:pk1 reposted a note you were tagged in")
XCTAssertEqual(reacting_to_text(profiles: damusState.profiles, our_pubkey: damusState.pubkey, group: .repost(EventGroup(events: [repost1, repost2])), ev: test_note, pubkeys: [pk1.pubkey, pk2.pubkey], locale: enUsLocale), "pk1:pk1 and pk2:pk2 reposted a note you were tagged in")
XCTAssertEqual(reacting_to_text(profiles: damusState.profiles, our_pubkey: damusState.pubkey, group: .repost(EventGroup(events: [repost1, repost2, repost2])), ev: test_note, pubkeys: [pk1.pubkey, pk2.pubkey, pk3.pubkey], locale: enUsLocale), "pk1:pk1 and 2 others reposted a note you were tagged in")
XCTAssertEqual(reacting_to_text(profiles: damusState.profiles, our_pubkey: damusState.pubkey, group: .repost(EventGroup(events: [repost1])), ev: test_note, pubkeys: [pk1.pubkey], locale: enUsLocale), "1jw906h6:6saq3vx4 reposted a note you were tagged in")
XCTAssertEqual(reacting_to_text(profiles: damusState.profiles, our_pubkey: damusState.pubkey, group: .repost(EventGroup(events: [repost1, repost2])), ev: test_note, pubkeys: [pk1.pubkey, pk2.pubkey], locale: enUsLocale), "1jw906h6:6saq3vx4 and 1dwdm0t9:nqtnamhd reposted a note you were tagged in")
XCTAssertEqual(reacting_to_text(profiles: damusState.profiles, our_pubkey: damusState.pubkey, group: .repost(EventGroup(events: [repost1, repost2, repost2])), ev: test_note, pubkeys: [pk1.pubkey, pk2.pubkey, pk3.pubkey], locale: enUsLocale), "1jw906h6:6saq3vx4 and 2 others reposted a note you were tagged in")
Bundle.main.localizations.map { Locale(identifier: $0) }.forEach {
XCTAssertNoThrow(reacting_to_text(profiles: damusState.profiles, our_pubkey: damusState.pubkey, group: .repost(EventGroup(events: [])), ev: test_note, pubkeys: [], locale: $0), "??")

View File

@@ -9,18 +9,9 @@ import XCTest
@testable import damus
final class HashtagTests: XCTestCase {
override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDownWithError() throws {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
func testParseHashtag() {
let parsed = parse_note_content(content: "some hashtag #bitcoin derp", tags: []).blocks
let parsed = parse_note_content(content: .content("some hashtag #bitcoin derp",nil)).blocks
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed.count, 3)
XCTAssertEqual(parsed[0].is_text, "some hashtag ")
@@ -29,8 +20,8 @@ final class HashtagTests: XCTestCase {
}
func testHashtagWithComma() {
let parsed = parse_note_content(content: "some hashtag #bitcoin, cool", tags: []).blocks
let parsed = parse_note_content(content: .content("some hashtag #bitcoin, cool",nil)).blocks
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed.count, 3)
XCTAssertEqual(parsed[0].is_text, "some hashtag ")
@@ -40,7 +31,7 @@ final class HashtagTests: XCTestCase {
func testHashtagWithEmoji() {
let content = "some hashtag #bitcoin☕ cool"
let parsed = parse_note_content(content: content, tags: []).blocks
let parsed = parse_note_content(content: .content(content, nil)).blocks
let post_blocks = parse_post_blocks(content: content)
XCTAssertNotNil(parsed)
@@ -57,7 +48,7 @@ final class HashtagTests: XCTestCase {
func testPowHashtag() {
let content = "pow! #ぽわ〜"
let parsed = parse_note_content(content: content, tags: []).blocks
let parsed = parse_note_content(content: .content(content,nil)).blocks
let post_blocks = parse_post_blocks(content: content)
XCTAssertNotNil(parsed)
@@ -71,8 +62,8 @@ final class HashtagTests: XCTestCase {
}
func testHashtagWithAccents() {
let parsed = parse_note_content(content: "hello from #türkiye", tags: []).blocks
let parsed = parse_note_content(content: .content("hello from #türkiye",nil)).blocks
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed.count, 2)
XCTAssertEqual(parsed[0].is_text, "hello from ")
@@ -80,8 +71,8 @@ final class HashtagTests: XCTestCase {
}
func testHashtagWithNonLatinCharacters() {
let parsed = parse_note_content(content: "this is a #시험 hope it works", tags: []).blocks
let parsed = parse_note_content(content: .content("this is a #시험 hope it works",nil)).blocks
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed.count, 3)
XCTAssertEqual(parsed[0].is_text, "this is a ")
@@ -90,8 +81,8 @@ final class HashtagTests: XCTestCase {
}
func testParseHashtagEnd() {
let parsed = parse_note_content(content: "some hashtag #bitcoin", tags: []).blocks
let parsed = parse_note_content(content: .content("some hashtag #bitcoin",nil)).blocks
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed.count, 2)
XCTAssertEqual(parsed[0].is_text, "some hashtag ")

View File

@@ -20,8 +20,8 @@ final class InvoiceTests: XCTestCase {
func testParseAnyAmountInvoice() throws {
let invstr = "LNBC1P3MR5UJSP5G7SA48YD4JWTTPCHWMY4QYN4UWZQCJQ8NMWKD6QE3HCRVYTDLH9SPP57YM9TSA9NN4M4XU59XMJCXKR7YDV29DDP6LVQUT46ZW6CU3KE9GQDQ9V9H8JXQ8P3MYLZJCQPJRZJQF60PZDVNGGQWQDNERZSQN35L8CVQ3QG2Z5NSZYD0D3Q0JW2TL6VUZA7FYQQWKGQQYQQQQLGQQQQXJQQ9Q9QXPQYSGQ39EM4QJMQFKZGJXZVGL7QJMYNSWA8PGDTAGXXRG5Z92M7VLCGKQK2L2THDF8LM0AUKAURH7FVAWDLRNMVF38W4EYJDNVN9V4Z9CRS5CQCV465C"
let parsed = parse_note_content(content: invstr, tags: []).blocks
let parsed = parse_note_content(content: .content(invstr,nil)).blocks
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed.count, 1)
XCTAssertNotNil(parsed[0].is_invoice)
@@ -38,8 +38,8 @@ final class InvoiceTests: XCTestCase {
let invstr = """
LNBC1P3MR5UJSP5G7SA48YD4JWTTPCHWMY4QYN4UWZQCJQ8NMWKD6QE3HCRVYTDLH9SPP57YM9TSA9NN4M4XU59XMJCXKR7YDV29DDP6LVQUT46ZW6CU3KE9GQDQ9V9H8JXQ8P3MYLZJCQPJRZJQF60PZDVNGGQWQDNERZSQN35L8CVQ3QG2Z5NSZYD0D3Q0JW2TL6VUZA7FYQQWKGQQYQQQQLGQQQQXJQQ9Q9QXPQYSGQ39EM4QJMQFKZGJXZVGL7QJMYNSWA8PGDTAGXXRG5Z92M7VLCGKQK2L2THDF8LM0AUKAURH7FVAWDLRNMVF38W4EYJDNVN9V4Z9CRS5CQCV465C hi there
"""
let parsed = parse_note_content(content: invstr, tags: []).blocks
let parsed = parse_note_content(content: .content(invstr,nil)).blocks
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed.count, 2)
XCTAssertNotNil(parsed[0].is_invoice)
@@ -54,8 +54,8 @@ LNBC1P3MR5UJSP5G7SA48YD4JWTTPCHWMY4QYN4UWZQCJQ8NMWKD6QE3HCRVYTDLH9SPP57YM9TSA9NN
func testParseInvoiceUpper() throws {
let invstr = "LNBC100N1P357SL0SP5T9N56WDZTUN39LGDQLR30XQWKSG3K69Q4Q2RKR52APLUJW0ESN0QPP5MRQGLJK62Z20Q4NVGR6LZCYN6FHYLZCCWDVU4K77APG3ZMRKUJJQDPZW35XJUEQD9EJQCFQV3JHXCMJD9C8G6T0DCXQYJW5QCQPJRZJQT56H4GVP5YX36U2UZQA6QWCSK3E2DUUNFXPPZJ9VHYPC3WFE2WSWZ607UQQ3XQQQSQQQQQQQQQQQLQQYG9QYYSGQAGX5H20AEULJ3GDWX3KXS8U9F4MCAKDKWUAKASAMM9562FFYR9EN8YG20LG0YGNR9ZPWP68524KMDA0T5XP2WYTEX35PU8HAPYJAJXQPSQL29R"
let parsed = parse_note_content(content: invstr, tags: []).blocks
let parsed = parse_note_content(content: .content(invstr,nil)).blocks
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed.count, 1)
XCTAssertNotNil(parsed[0].is_invoice)
@@ -70,8 +70,8 @@ LNBC1P3MR5UJSP5G7SA48YD4JWTTPCHWMY4QYN4UWZQCJQ8NMWKD6QE3HCRVYTDLH9SPP57YM9TSA9NN
func testParseInvoiceWithPrefix() throws {
let invstr = "lightning:lnbc100n1p357sl0sp5t9n56wdztun39lgdqlr30xqwksg3k69q4q2rkr52aplujw0esn0qpp5mrqgljk62z20q4nvgr6lzcyn6fhylzccwdvu4k77apg3zmrkujjqdpzw35xjueqd9ejqcfqv3jhxcmjd9c8g6t0dcxqyjw5qcqpjrzjqt56h4gvp5yx36u2uzqa6qwcsk3e2duunfxppzj9vhypc3wfe2wswz607uqq3xqqqsqqqqqqqqqqqlqqyg9qyysgqagx5h20aeulj3gdwx3kxs8u9f4mcakdkwuakasamm9562ffyr9en8yg20lg0ygnr9zpwp68524kmda0t5xp2wytex35pu8hapyjajxqpsql29r"
let parsed = parse_note_content(content: invstr, tags: []).blocks
let parsed = parse_note_content(content: .content(invstr,nil)).blocks
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed.count, 1)
XCTAssertNotNil(parsed[0].is_invoice)
@@ -79,8 +79,8 @@ LNBC1P3MR5UJSP5G7SA48YD4JWTTPCHWMY4QYN4UWZQCJQ8NMWKD6QE3HCRVYTDLH9SPP57YM9TSA9NN
func testParseInvoiceWithPrefixCapitalized() throws {
let invstr = "LIGHTNING:LNBC100N1P357SL0SP5T9N56WDZTUN39LGDQLR30XQWKSG3K69Q4Q2RKR52APLUJW0ESN0QPP5MRQGLJK62Z20Q4NVGR6LZCYN6FHYLZCCWDVU4K77APG3ZMRKUJJQDPZW35XJUEQD9EJQCFQV3JHXCMJD9C8G6T0DCXQYJW5QCQPJRZJQT56H4GVP5YX36U2UZQA6QWCSK3E2DUUNFXPPZJ9VHYPC3WFE2WSWZ607UQQ3XQQQSQQQQQQQQQQQLQQYG9QYYSGQAGX5H20AEULJ3GDWX3KXS8U9F4MCAKDKWUAKASAMM9562FFYR9EN8YG20LG0YGNR9ZPWP68524KMDA0T5XP2WYTEX35PU8HAPYJAJXQPSQL29R"
let parsed = parse_note_content(content: invstr, tags: []).blocks
let parsed = parse_note_content(content: .content(invstr,nil)).blocks
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed.count, 1)
XCTAssertNotNil(parsed[0].is_invoice)
@@ -88,8 +88,8 @@ LNBC1P3MR5UJSP5G7SA48YD4JWTTPCHWMY4QYN4UWZQCJQ8NMWKD6QE3HCRVYTDLH9SPP57YM9TSA9NN
func testParseInvoice() throws {
let invstr = "lnbc100n1p357sl0sp5t9n56wdztun39lgdqlr30xqwksg3k69q4q2rkr52aplujw0esn0qpp5mrqgljk62z20q4nvgr6lzcyn6fhylzccwdvu4k77apg3zmrkujjqdpzw35xjueqd9ejqcfqv3jhxcmjd9c8g6t0dcxqyjw5qcqpjrzjqt56h4gvp5yx36u2uzqa6qwcsk3e2duunfxppzj9vhypc3wfe2wswz607uqq3xqqqsqqqqqqqqqqqlqqyg9qyysgqagx5h20aeulj3gdwx3kxs8u9f4mcakdkwuakasamm9562ffyr9en8yg20lg0ygnr9zpwp68524kmda0t5xp2wytex35pu8hapyjajxqpsql29r"
let parsed = parse_note_content(content: invstr, tags: []).blocks
let parsed = parse_note_content(content: .content(invstr,nil)).blocks
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed.count, 1)
XCTAssertNotNil(parsed[0].is_invoice)

View File

@@ -19,14 +19,18 @@ class LikeTests: XCTestCase {
}
func testLikeHasNotification() throws {
let liked = NostrEvent(content: "awesome #[0] post", keypair: test_keypair, tags: [["p", "cindy"], ["e", "bob"]])!
let cindy = Pubkey(hex: "9d9181f0aea6500e1f360e07b9f37e25c72169b5158ae78df53f295272b6b71c")!
let bob = Pubkey(hex: "218837fe8c94a66ae33af277bcbda45a0319e7726220cd76171b9dd1a468af91")!
let liked = NostrEvent(content: "awesome #[0] post",
keypair: test_keypair,
tags: [cindy.tag, bob.tag])!
let id = liked.id
let like_ev = make_like_event(keypair: test_keypair_full, liked: liked)!
XCTAssertTrue(like_ev.references(id: test_keypair.pubkey, key: "p"))
XCTAssertTrue(like_ev.references(id: "cindy", key: "p"))
XCTAssertTrue(like_ev.references(id: "bob", key: "e"))
XCTAssertEqual(like_ev.last_refid()!.ref_id, id)
XCTAssertTrue(like_ev.referenced_pubkeys.contains(test_keypair.pubkey))
XCTAssertTrue(like_ev.referenced_pubkeys.contains(cindy))
XCTAssertTrue(like_ev.referenced_pubkeys.contains(bob))
XCTAssertEqual(like_ev.last_refid()!, id)
}
func testToReactionEmoji() {

View File

@@ -19,53 +19,53 @@ final class ListTests: XCTestCase {
}
func testCreateMuteList() throws {
let privkey = "87f313b03f2548e6eaf1c188db47078e08e894252949779b639b28db0891937a"
let pubkey = "4b0c29bf96496130c1253102f6870c0eee05db38a257315858272aa43fd19685"
let to_mute = "2fa2630fea3d2c188c49f2799fcd92f0e9879ea6a36ae60770a5428ed6c19edd"
let privkey = test_keypair_full.privkey
let pubkey = test_keypair_full.pubkey
let to_mute = test_pubkey
let keypair = FullKeypair(pubkey: pubkey, privkey: privkey)
let mutelist = create_or_update_mutelist(keypair: keypair, mprev: nil, to_add: to_mute)!
let mutelist = create_or_update_mutelist(keypair: keypair, mprev: nil, to_add: .pubkey(to_mute))!
XCTAssertEqual(mutelist.pubkey, pubkey)
XCTAssertEqual(mutelist.content, "")
XCTAssertEqual(mutelist.tags.count, 2)
XCTAssertEqual(mutelist.tags[0][0], "d")
XCTAssertEqual(mutelist.tags[0][1], "mute")
XCTAssertEqual(mutelist.tags[1][0], "p")
XCTAssertEqual(mutelist.tags[1][1], to_mute)
XCTAssertEqual(mutelist.tags[0][0].string(), "d")
XCTAssertEqual(mutelist.tags[0][1].string(), "mute")
XCTAssertEqual(mutelist.tags[1][0].string(), "p")
XCTAssertEqual(mutelist.tags[1][1].string(), to_mute.hex())
}
func testCreateAndRemoveMuteList() throws {
let privkey = "87f313b03f2548e6eaf1c188db47078e08e894252949779b639b28db0891937a"
let pubkey = "4b0c29bf96496130c1253102f6870c0eee05db38a257315858272aa43fd19685"
let to_mute = "2fa2630fea3d2c188c49f2799fcd92f0e9879ea6a36ae60770a5428ed6c19edd"
let privkey = test_keypair_full.privkey
let pubkey = test_keypair_full.pubkey
let to_mute = test_pubkey
let keypair = FullKeypair(pubkey: pubkey, privkey: privkey)
let mutelist = create_or_update_mutelist(keypair: keypair, mprev: nil, to_add: to_mute)!
let new = remove_from_mutelist(keypair: keypair, prev: mutelist, to_remove: to_mute)!
let mutelist = create_or_update_mutelist(keypair: keypair, mprev: nil, to_add: .pubkey(to_mute))!
let new = remove_from_mutelist(keypair: keypair, prev: mutelist, to_remove: .pubkey(to_mute))!
XCTAssertEqual(new.pubkey, pubkey)
XCTAssertEqual(new.content, "")
XCTAssertEqual(new.tags.count, 1)
XCTAssertEqual(new.tags[0][0], "d")
XCTAssertEqual(new.tags[0][1], "mute")
XCTAssertEqual(new.tags[0][0].string(), "d")
XCTAssertEqual(new.tags[0][1].string(), "mute")
}
func testAddToExistingMutelist() throws {
let privkey = "87f313b03f2548e6eaf1c188db47078e08e894252949779b639b28db0891937a"
let pubkey = "4b0c29bf96496130c1253102f6870c0eee05db38a257315858272aa43fd19685"
let to_mute = "2fa2630fea3d2c188c49f2799fcd92f0e9879ea6a36ae60770a5428ed6c19edd"
let to_mute_2 = "976b4ab41f8634119b4f21f57ef5836a4bef65d0bf72c7ced67b8b170ba4a38d"
let privkey = test_keypair_full.privkey
let pubkey = test_keypair_full.pubkey
let to_mute = test_pubkey
let to_mute_2 = test_pubkey_2
let keypair = FullKeypair(pubkey: pubkey, privkey: privkey)
let mutelist = create_or_update_mutelist(keypair: keypair, mprev: nil, to_add: to_mute)!
let new = create_or_update_mutelist(keypair: keypair, mprev: mutelist, to_add: to_mute_2)!
let mutelist = create_or_update_mutelist(keypair: keypair, mprev: nil, to_add: .pubkey(to_mute))!
let new = create_or_update_mutelist(keypair: keypair, mprev: mutelist, to_add: .pubkey(to_mute_2))!
XCTAssertEqual(new.pubkey, pubkey)
XCTAssertEqual(new.content, "")
XCTAssertEqual(new.tags.count, 3)
XCTAssertEqual(new.tags[0][0], "d")
XCTAssertEqual(new.tags[0][1], "mute")
XCTAssertEqual(new.tags[1][0], "p")
XCTAssertEqual(new.tags[1][1], to_mute)
XCTAssertEqual(new.tags[2][0], "p")
XCTAssertEqual(new.tags[2][1], to_mute_2)
XCTAssertEqual(new.tags[0][0].string(), "d")
XCTAssertEqual(new.tags[0][1].string(), "mute")
XCTAssertEqual(new.tags[1][0].string(), "p")
XCTAssertEqual(new.tags[1][1].string(), to_mute.hex())
XCTAssertEqual(new.tags[2][0].string(), "p")
XCTAssertEqual(new.tags[2][1].string(), to_mute_2.hex())
}
}

View File

@@ -24,13 +24,14 @@ class ContentParserTests: XCTestCase {
let url = "https://media.tenor.com/5MibLt95scAAAAAC/%ED%98%BC%ED%8C%8C%EB%A7%9D-%ED%94%BC%EC%9E%90.gif"
let content = "gm 🤙\(url)"
let blocks = parse_note_content(content: content, tags: []).blocks
let blocks = parse_note_content(content: .content(content,nil)).blocks
XCTAssertEqual(blocks.count, 2)
XCTAssertEqual(blocks[0], .text("gm 🤙"))
XCTAssertEqual(blocks[1], .url(URL(string: url)!))
}
/*
func test_damus_parse_content_can_parse_mention_without_white_space_at_front() throws {
var bs = note_blocks()
bs.num_blocks = 0;
@@ -38,7 +39,7 @@ class ContentParserTests: XCTestCase {
blocks_init(&bs)
let content = "#[0], #[1],#[2],#[3]#[4],#[5],#[6],#[7], #[8], \n#[9], #[10], #[11], #[12]"
let tagsString = "[[\"p\",\"82341f882b6eabcd2ba7f1ef90aad961cf074af15b9ef44a09f9d2a8fbfbe6a2\"],[\"p\",\"0339bb0d9d818ba126a39385a5edee5651993af7c21f18d4ceb0ba8c9de0d463\"],[\"p\",\"e7424ad457e512fdf4764a56bf6d428a06a13a1006af1fb8e0fe32f6d03265c7\"],[\"p\",\"520830c334a3f79f88cac934580d26f91a7832c6b21fb9625690ea2ed81b5626\"],[\"p\",\"971615b70ad9ec896f8d5ba0f2d01652f1dfe5f9ced81ac9469ca7facefad68b\"],[\"p\",\"2779f3d9f42c7dee17f0e6bcdcf89a8f9d592d19e3b1bbd27ef1cffd1a7f98d1\"],[\"p\",\"17538dc2a62769d09443f18c37cbe358fab5bbf981173542aa7c5ff171ed77c4\"],[\"p\",\"985a7c6b0e75508ad74c4110b2e52dfba6ce26063d80bca218564bd083a72b99\"],[\"p\",\"7fb2a29bd1a41d9a8ca43a19a7dcf3a8522f1bc09b4086253539190e9c29c51a\"],[\"p\",\"b88c7f007bbf3bc2fcaeff9e513f186bab33782c0baa6a6cc12add78b9110ba3\"],[\"p\",\"2f4fa408d85b962d1fe717daae148a4c98424ab2e10c7dd11927e101ed3257b2\"],[\"p\",\"bd1e19980e2c91e6dc657e92c25762ca882eb9272d2579e221f037f93788de91\"],[\"p\",\"32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245\"]]"
let tags = try decoder.decode([[String]].self, from: tagsString.data(using: .utf8)!)
@@ -72,4 +73,5 @@ class ContentParserTests: XCTestCase {
i += 1
}
}
*/
}

View File

@@ -18,37 +18,37 @@ final class NIP19Tests: XCTestCase {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
/*
func test_parse_nprofile() throws {
let res = parse_note_content(content: "nostr:nprofile1qqsrhuxx8l9ex335q7he0f09aej04zpazpl0ne2cgukyawd24mayt8gpp4mhxue69uhhytnc9e3k7mgpz4mhxue69uhkg6nzv9ejuumpv34kytnrdaksjlyr9p", tags: []).blocks
let res = parse_note_content(content: .content("nostr:nprofile1qqsrhuxx8l9ex335q7he0f09aej04zpazpl0ne2cgukyawd24mayt8gpp4mhxue69uhhytnc9e3k7mgpz4mhxue69uhkg6nzv9ejuumpv34kytnrdaksjlyr9p")).blocks
XCTAssertEqual(res.count, 1)
let expected_ref = ReferencedId(ref_id: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d", relay_id: "wss://r.x.com", key: "p")
let expected_mention = Mention(index: nil, type: .pubkey, ref: expected_ref)
XCTAssertEqual(res[0], .mention(expected_mention))
}
*/
func test_parse_npub() throws {
let res = parse_note_content(content: "nostr:npub10elfcs4fr0l0r8af98jlmgdh9c8tcxjvz9qkw038js35mp4dma8qzvjptg ", tags: []).blocks
let res = parse_note_content(content: .content("nostr:npub10elfcs4fr0l0r8af98jlmgdh9c8tcxjvz9qkw038js35mp4dma8qzvjptg ",nil)).blocks
XCTAssertEqual(res.count, 2)
let expected_ref = ReferencedId(ref_id: "7e7e9c42a91bfef19fa929e5fda1b72e0ebc1a4c1141673e2794234d86addf4e", relay_id: nil, key: "p")
let expected_mention = Mention(index: nil, type: .pubkey, ref: expected_ref)
let expected_ref = Pubkey(hex: "7e7e9c42a91bfef19fa929e5fda1b72e0ebc1a4c1141673e2794234d86addf4e")!
let expected_mention: Mention<MentionRef> = Mention(index: nil, ref: .pubkey(expected_ref))
XCTAssertEqual(res[0], .mention(expected_mention))
}
func test_parse_note() throws {
let res = parse_note_content(content: " nostr:note1s4p70596lv50x0zftuses32t6ck8x6wgd4edwacyetfxwns2jtysux7vep", tags: []).blocks
let res = parse_note_content(content: .content(" nostr:note1s4p70596lv50x0zftuses32t6ck8x6wgd4edwacyetfxwns2jtysux7vep",nil)).blocks
XCTAssertEqual(res.count, 2)
let expected_ref = ReferencedId(ref_id: "8543e7d0bafb28f33c495f2198454bd62c7369c86d72d77704cad2674e0a92c9", relay_id: nil, key: "e")
let expected_mention = Mention(index: nil, type: .event, ref: expected_ref)
XCTAssertEqual(res[1], .mention(expected_mention))
let note_id = NoteId(hex:"8543e7d0bafb28f33c495f2198454bd62c7369c86d72d77704cad2674e0a92c9")!
XCTAssertEqual(res[1], .mention(.any(.note(note_id))))
}
func test_mention_with_adjacent() throws {
let res = parse_note_content(content: " nostr:note1s4p70596lv50x0zftuses32t6ck8x6wgd4edwacyetfxwns2jtysux7vep?", tags: []).blocks
let res = parse_note_content(content: .content(" nostr:note1s4p70596lv50x0zftuses32t6ck8x6wgd4edwacyetfxwns2jtysux7vep?",nil)).blocks
XCTAssertEqual(res.count, 3)
let expected_ref = ReferencedId(ref_id: "8543e7d0bafb28f33c495f2198454bd62c7369c86d72d77704cad2674e0a92c9", relay_id: nil, key: "e")
let expected_mention = Mention(index: nil, type: .event, ref: expected_ref)
let note_id = NoteId(hex: "8543e7d0bafb28f33c495f2198454bd62c7369c86d72d77704cad2674e0a92c9")!
XCTAssertEqual(res[0], .text(" "))
XCTAssertEqual(res[1], .mention(expected_mention))
XCTAssertEqual(res[1], .mention(.any(.note(note_id))))
XCTAssertEqual(res[2], .text("?"))
}

View File

@@ -39,7 +39,7 @@ final class NostrScriptTests: XCTestCase {
let data = try load_bool_set_test_wasm().bytes
let pool = RelayPool()
let script = NostrScript(pool: pool, data: data)
let pk = "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245"
let pk = Pubkey(hex: "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245")!
UserSettingsStore.pubkey = pk
let key = pk_setting_key(pk, key: "nozaps")
UserDefaults.standard.set(true, forKey: key)
@@ -103,7 +103,7 @@ final class NostrScriptTests: XCTestCase {
pool.connect(to: ["wss://cache0.primal.net/cache17"])
self.wait(for: [resume_expected], timeout: 10.0)
self.wait(for: [resume_expected], timeout: 5.0)
}
*/

View File

@@ -10,8 +10,10 @@ import XCTest
class NoteContentViewTests: XCTestCase {
func testRenderBlocksWithNonLatinHashtags() {
let parsed: Blocks = parse_note_content(content: "Damusはかっこいいです #cool #かっこいい", tags: [["t", "かっこいい"]])
let content = "Damusはかっこいいです #cool #かっこいい"
let note = NostrEvent(content: content, keypair: test_keypair, tags: [["t", "かっこいい"]])!
let parsed: Blocks = parse_note_content(content: .init(note: note, privkey: test_keypair.privkey))
let testState = test_damus_state()
let text: NoteArtifactsSeparated = render_blocks(blocks: parsed, profiles: testState.profiles)

View File

@@ -32,8 +32,8 @@ class ProfileDatabaseTests: XCTestCase {
}
func testStoreAndRetrieveProfile() async throws {
let id = "test-id"
let id = test_pubkey
let profile = test_profile
// make sure it's not there yet
@@ -58,7 +58,7 @@ class ProfileDatabaseTests: XCTestCase {
}
func testRejectOutdatedProfile() async throws {
let id = "test-id"
let id = test_pubkey
// store a profile
let profile = test_profile
@@ -80,8 +80,8 @@ class ProfileDatabaseTests: XCTestCase {
}
func testUpdateExistingProfile() async throws {
let id = "test-id"
let id = test_pubkey
// store a profile
let profile = test_profile
let profile_last_update = Date.now
@@ -102,7 +102,7 @@ class ProfileDatabaseTests: XCTestCase {
XCTAssertEqual(database.count, 0)
// store a profile
let id = "test-id"
let id = test_pubkey
let profile = test_profile
let profile_last_update = Date.now
try await database.upsert(id: id, profile: profile, last_update: profile_last_update)
@@ -110,7 +110,7 @@ class ProfileDatabaseTests: XCTestCase {
XCTAssertEqual(database.count, 1)
// store another profile
let id2 = "test-id-2"
let id2 = test_pubkey_2
let profile2 = test_profile
let profile_last_update2 = Date.now
try await database.upsert(id: id2, profile: profile2, last_update: profile_last_update2)

View File

@@ -23,13 +23,19 @@ final class ProfileViewTests: XCTestCase {
func testFollowedByString() throws {
let profiles = test_damus_state().profiles
XCTAssertEqual(followedByString(["pk1"], profiles: profiles, locale: enUsLocale), "Followed by pk1:pk1")
XCTAssertEqual(followedByString(["pk1", "pk2"], profiles: profiles, locale: enUsLocale), "Followed by pk1:pk1 & pk2:pk2")
XCTAssertEqual(followedByString(["pk1", "pk2", "pk3"], profiles: profiles, locale: enUsLocale), "Followed by pk1:pk1, pk2:pk2 & pk3:pk3")
XCTAssertEqual(followedByString(["pk1", "pk2", "pk3", "pk4",], profiles: profiles, locale: enUsLocale), "Followed by pk1:pk1, pk2:pk2, pk3:pk3 & 1 other")
XCTAssertEqual(followedByString(["pk1", "pk2", "pk3", "pk4", "pk5"], profiles: profiles, locale: enUsLocale), "Followed by pk1:pk1, pk2:pk2, pk3:pk3 & 2 others")
let pk1 = test_pubkey
let pk2 = test_pubkey_2
let pk3 = Pubkey(hex: "b42e44b555013239a0d5dcdb09ebde0857cd8a5a57efbba5a2b6ac78833cb9f0")!
let pk4 = Pubkey(hex: "cc590e46363d0fa66bb27081368d01f169b8ffc7c614629d4e9eef6c88b38670")!
let pk5 = Pubkey(hex: "f2aa579bb998627e04a8f553842a09446360c9d708c6141dd119c479f6ab9d29")!
let pubkeys = ["pk1", "pk2", "pk3", "pk4", "pk5", "pk6", "pk7", "pk8", "pk9", "pk10"]
XCTAssertEqual(followedByString([pk1], profiles: profiles, locale: enUsLocale), "Followed by damus")
XCTAssertEqual(followedByString([pk1, pk2], profiles: profiles, locale: enUsLocale), "Followed by damus & 1rppft3m:4qxhsgnj")
XCTAssertEqual(followedByString([pk1, pk2, pk3], profiles: profiles, locale: enUsLocale), "Followed by damus, 1rppft3m:4qxhsgnj & 1kshyfd2:cq04aze0")
XCTAssertEqual(followedByString([pk1, pk2, pk3, pk4,], profiles: profiles, locale: enUsLocale), "Followed by damus, 1rppft3m:4qxhsgnj, 1kshyfd2:cq04aze0 & 1 other")
XCTAssertEqual(followedByString([pk1, pk2, pk3, pk4, pk5], profiles: profiles, locale: enUsLocale), "Followed by damus, 1rppft3m:4qxhsgnj, 1kshyfd2:cq04aze0 & 2 others")
let pubkeys = [pk1, pk2, pk3, pk4, pk5, pk1, pk2, pk3, pk4, pk5]
Bundle.main.localizations.map { Locale(identifier: $0) }.forEach {
for count in 1...10 {
XCTAssertNoThrow(followedByString(pubkeys.prefix(count).map { $0 }, profiles: profiles, locale: $0))

View File

@@ -19,11 +19,13 @@ class ReplyTests: XCTestCase {
}
func testMentionIsntReply() throws {
let evid = NoteId(hex: "4090a9017a2beac3f17795d1aafb80d9f2b9eda97e4738501082ed5c927be014")!
let content = "this is #[0] a mention"
let tags = [["e", "event_id"]]
let blocks = parse_note_content(content: content, tags: tags).blocks
let event_refs = interpret_event_refs(blocks: blocks, tags: tags)
let tags = [evid.tag]
let ev = NostrEvent(content: content, keypair: test_keypair, tags: tags)!
let blocks = parse_note_content(content: .init(note: ev, privkey: test_keypair.privkey)).blocks
let event_refs = interpret_event_refs(blocks: blocks, tags: ev.tags)
XCTAssertEqual(event_refs.count, 1)
let ref = event_refs[0]
@@ -31,14 +33,13 @@ class ReplyTests: XCTestCase {
XCTAssertNil(ref.is_reply)
XCTAssertNil(ref.is_thread_id)
XCTAssertNil(ref.is_direct_reply)
XCTAssertEqual(ref.is_mention?.type, .event)
XCTAssertEqual(ref.is_mention?.ref.ref_id, "event_id")
XCTAssertEqual(ref.is_mention, .some(.init(note_id: evid)))
}
func testUrlAnchorsAreNotHashtags() {
let content = "this is my link: https://jb55.com/index.html#buybitcoin this is not a hashtag!"
let blocks = parse_post_blocks(content: content)
XCTAssertEqual(blocks.count, 3)
XCTAssertEqual(blocks[0].is_text, "this is my link: ")
XCTAssertEqual(blocks[1].is_url, URL(string: "https://jb55.com/index.html#buybitcoin")!)
@@ -93,30 +94,32 @@ class ReplyTests: XCTestCase {
func testRootReplyWithMention() throws {
let content = "this is #[1] a mention"
let tags = [["e", "thread_id"], ["e", "mentioned_id"]]
let blocks = parse_note_content(content: content, tags: tags).blocks
let event_refs = interpret_event_refs(blocks: blocks, tags: tags)
let thread_id = NoteId(hex: "c75e5cbafbefd5de2275f831c2a2386ea05ec5e5a78a5ccf60d467582db48945")!
let mentioned_id = NoteId(hex: "5a534797e8cd3b9f4c1cf63e20e48bd0e8bd7f8c4d6353fbd576df000f6f54d3")!
let tags = [thread_id.tag, mentioned_id.tag]
let ev = NostrEvent(content: content, keypair: test_keypair, tags: tags)!
let blocks = parse_note_content(content: .init(note: ev, privkey: test_keypair.privkey)).blocks
let event_refs = interpret_event_refs(blocks: blocks, tags: ev.tags)
XCTAssertEqual(event_refs.count, 2)
XCTAssertNotNil(event_refs[0].is_reply)
XCTAssertNotNil(event_refs[0].is_thread_id)
XCTAssertNotNil(event_refs[0].is_reply)
XCTAssertNotNil(event_refs[0].is_direct_reply)
XCTAssertEqual(event_refs[0].is_reply?.ref_id, "thread_id")
XCTAssertEqual(event_refs[0].is_thread_id?.ref_id, "thread_id")
XCTAssertEqual(event_refs[0].is_reply, .some(NoteRef(note_id: thread_id)))
XCTAssertEqual(event_refs[0].is_thread_id, .some(NoteRef(note_id: thread_id)))
XCTAssertNotNil(event_refs[1].is_mention)
XCTAssertEqual(event_refs[1].is_mention?.type, .event)
XCTAssertEqual(event_refs[1].is_mention?.ref.ref_id, "mentioned_id")
XCTAssertEqual(event_refs[1].is_mention, .some(NoteRef(note_id: mentioned_id)))
}
func testEmptyMention() throws {
let content = "this is some & content"
let tags: [[String]] = []
let blocks = parse_note_content(content: content, tags: tags).blocks
let ev = NostrEvent(content: content, keypair: test_keypair, tags: [])!
let blocks = parse_note_content(content: .init(note: ev, privkey: test_keypair.privkey)).blocks
let post_blocks = parse_post_blocks(content: content)
let post_tags = make_post_tags(post_blocks: post_blocks, tags: tags)
let event_refs = interpret_event_refs(blocks: blocks, tags: tags)
let post_tags = make_post_tags(post_blocks: post_blocks, tags: [])
let event_refs = interpret_event_refs(blocks: blocks, tags: ev.tags)
XCTAssertEqual(event_refs.count, 0)
XCTAssertEqual(post_tags.blocks.count, 1)
XCTAssertEqual(post_tags.tags.count, 0)
@@ -126,16 +129,15 @@ class ReplyTests: XCTestCase {
func testManyMentions() throws {
let content = "#[10]"
let tags: [[String]] = [[],[],[],[],[],[],[],[],[],[],["p", "3e999f94e2cb34ef44a64b351141ac4e51b5121b2d31aed4a6c84602a1144692"]]
let blocks = parse_note_content(content: content, tags: tags).blocks
let ev = NostrEvent(content: content, keypair: test_keypair, tags: tags)!
let blocks = parse_note_content(content: .init(note: ev, privkey: test_keypair.privkey)).blocks
let mentions = blocks.filter { $0.is_mention != nil }
XCTAssertEqual(mentions.count, 1)
}
func testNewlineMentions() throws {
let pk = "npub1xtscya34g58tk0z605fvr788k263gsu6cy9x0mhnm87echrgufzsevkk5s"
guard let hex_pk = bech32_pubkey_decode(pk) else {
return
}
let bech32_pk = "npub1xtscya34g58tk0z605fvr788k263gsu6cy9x0mhnm87echrgufzsevkk5s"
let pk = bech32_pubkey_decode(bech32_pk)!
let profile = Profile(name: "jb55")
let post = user_tag_attr_string(profile: profile, pubkey: pk)
@@ -143,50 +145,55 @@ class ReplyTests: XCTestCase {
post.append(user_tag_attr_string(profile: profile, pubkey: pk))
post.append(.init(string: "\n"))
let post_note = build_post(post: post, action: .posting(.none), uploadedMedias: [], references: [.p(hex_pk)])
let post_note = build_post(post: post, action: .posting(.none), uploadedMedias: [], references: [.pubkey(pk)])
let expected_render = "nostr:\(pk)\nnostr:\(pk)"
let expected_render = "nostr:\(pk.npub)\nnostr:\(pk.npub)"
XCTAssertEqual(post_note.content, expected_render)
let blocks = parse_note_content(content: post_note.content, tags: []).blocks
let blocks = parse_note_content(content: .content(post_note.content,nil)).blocks
let rendered = render_blocks(blocks: blocks)
XCTAssertEqual(rendered, expected_render)
XCTAssertEqual(blocks.count, 3)
XCTAssertEqual(blocks[0].is_mention, .pubkey(hex_pk))
XCTAssertEqual(blocks[0].is_mention, .any(.pubkey(pk)))
XCTAssertEqual(blocks[1].is_text, "\n")
XCTAssertEqual(blocks[2].is_mention, .pubkey(hex_pk))
XCTAssertEqual(blocks[2].is_mention, .any(.pubkey(pk)))
}
func testThreadedReply() throws {
let content = "this is some content"
let tags = [["e", "thread_id"], ["e", "reply_id"]]
let blocks = parse_note_content(content: content, tags: tags).blocks
let event_refs = interpret_event_refs(blocks: blocks, tags: tags)
let thread_id = NoteId(hex: "da256fb52146dc565c6c6b9ef906117c665864dc02b14a7b853eca244729c2f2")!
let reply_id = NoteId(hex: "80093e9bdb495728f54cda2bad4aed096877189552b3d41264e73b9a9595be22")!
let tags = [thread_id.tag, reply_id.tag]
let ev = NostrEvent(content: content, keypair: test_keypair, tags: tags)!
let blocks = parse_note_content(content: .init(note: ev, privkey: test_keypair.privkey)).blocks
let event_refs = interpret_event_refs(blocks: blocks, tags: ev.tags)
XCTAssertEqual(event_refs.count, 2)
let r1 = event_refs[0]
let r2 = event_refs[1]
XCTAssertEqual(r1.is_thread_id!.ref_id, "thread_id")
XCTAssertEqual(r2.is_reply!.ref_id, "reply_id")
XCTAssertEqual(r2.is_direct_reply!.ref_id, "reply_id")
XCTAssertEqual(r1.is_thread_id, .some(.note_id(thread_id)))
XCTAssertEqual(r2.is_reply, .some(.note_id(reply_id)))
XCTAssertEqual(r2.is_direct_reply, .some(.note_id(reply_id)))
XCTAssertNil(r1.is_direct_reply)
}
func testRootReply() throws {
let content = "this is a reply"
let tags = [["e", "thread_id"]]
let blocks = parse_note_content(content: content, tags: tags).blocks
let event_refs = interpret_event_refs(blocks: blocks, tags: tags)
let thread_id = NoteId(hex: "53f60f5114c06f069ffe9da2bc033e533d09cae44d37a8462154a663771a4ce6")!
let tags = [thread_id.tag]
let ev = NostrEvent(content: content, keypair: test_keypair, tags: tags)!
let blocks = parse_note_content(content: .content(ev.content,nil)).blocks
let event_refs = interpret_event_refs(blocks: blocks, tags: ev.tags)
XCTAssertEqual(event_refs.count, 1)
let r = event_refs[0]
XCTAssertEqual(r.is_direct_reply!.ref_id, "thread_id")
XCTAssertEqual(r.is_reply!.ref_id, "thread_id")
XCTAssertEqual(r.is_thread_id!.ref_id, "thread_id")
XCTAssertEqual(r.is_direct_reply, .some(.note_id(thread_id)))
XCTAssertEqual(r.is_reply, .some(.note_id(thread_id)))
XCTAssertEqual(r.is_thread_id, .some(.note_id(thread_id)))
XCTAssertNil(r.is_mention)
}
@@ -194,13 +201,13 @@ class ReplyTests: XCTestCase {
let content = "cc@jb55"
let profile = Profile(name: "jb55")
let tag = user_tag_attr_string(profile: profile, pubkey: "pk")
let tag = user_tag_attr_string(profile: profile, pubkey: test_pubkey)
let appended = append_user_tag(tag: tag, post: .init(string: content), word_range: .init(2...6))
let new_post = appended.post
try new_post.testAttributes(conditions: [
{ let link = $0[.link] as? String; XCTAssertNil(link) },
{ let link = $0[.link] as! String; XCTAssertEqual(link, "damus:nostr:pk") },
{ let link = $0[.link] as! String; XCTAssertEqual(link, "damus:nostr:\(test_pubkey.npub)") },
{ let link = $0[.link] as? String; XCTAssertNil(link) }
])
@@ -211,13 +218,13 @@ class ReplyTests: XCTestCase {
let content = "😎@jb55"
let profile = Profile(name: "jb55")
let tag = user_tag_attr_string(profile: profile, pubkey: "pk")
let tag = user_tag_attr_string(profile: profile, pubkey: test_pubkey)
let appended = append_user_tag(tag: tag, post: .init(string: content), word_range: .init(2...6))
let new_post = appended.post
try new_post.testAttributes(conditions: [
{ let link = $0[.link] as? String; XCTAssertNil(link) },
{ let link = $0[.link] as! String; XCTAssertEqual(link, "damus:nostr:pk") },
{ let link = $0[.link] as! String; XCTAssertEqual(link, "damus:nostr:\(test_pubkey.npub)") },
{ let link = $0[.link] as? String; XCTAssertNil(link) }
])
@@ -231,13 +238,13 @@ class ReplyTests: XCTestCase {
"""
let profile = Profile(name: "jb55")
let tag = user_tag_attr_string(profile: profile, pubkey: "pk")
let tag = user_tag_attr_string(profile: profile, pubkey: test_pubkey)
let appended = append_user_tag(tag: tag, post: .init(string: content), word_range: .init(1...5))
let new_post = appended.post
try new_post.testAttributes(conditions: [
{ let link = $0[.link] as? String; XCTAssertNil(link) },
{ let link = $0[.link] as! String; XCTAssertEqual(link, "damus:nostr:pk") },
{ let link = $0[.link] as! String; XCTAssertEqual(link, "damus:nostr:\(test_pubkey.npub)") },
{ let link = $0[.link] as? String; XCTAssertNil(link) },
])
@@ -248,12 +255,12 @@ class ReplyTests: XCTestCase {
let content = "@jb55"
let profile = Profile(name: "jb55")
let tag = user_tag_attr_string(profile: profile, pubkey: "pk")
let tag = user_tag_attr_string(profile: profile, pubkey: test_pubkey)
let appended = append_user_tag(tag: tag, post: .init(string: content), word_range: .init(0...4))
let new_post = appended.post
try new_post.testAttributes(conditions: [
{ let link = $0[.link] as! String; XCTAssertEqual(link, "damus:nostr:pk") },
{ let link = $0[.link] as! String; XCTAssertEqual(link, "damus:nostr:\(test_pubkey.npub)") },
{ let link = $0[.link] as? String; XCTAssertNil(link) },
])
@@ -264,13 +271,13 @@ class ReplyTests: XCTestCase {
let content = "cc @jb55"
let profile = Profile(name: "jb55")
let tag = user_tag_attr_string(profile: profile, pubkey: "pk")
let tag = user_tag_attr_string(profile: profile, pubkey: test_pubkey)
let appended = append_user_tag(tag: tag, post: .init(string: content), word_range: .init(3...7))
let new_post = appended.post
try new_post.testAttributes(conditions: [
{ let link = $0[.link] as? String; XCTAssertNil(link) },
{ let link = $0[.link] as! String; XCTAssertEqual(link, "damus:nostr:pk") },
{ let link = $0[.link] as! String; XCTAssertEqual(link, "damus:nostr:\(test_pubkey.npub)") },
{ let link = $0[.link] as? String; XCTAssertNil(link) }
])
@@ -279,15 +286,19 @@ class ReplyTests: XCTestCase {
func testNoReply() throws {
let content = "this is a #[0] reply"
let blocks = parse_note_content(content: content, tags: []).blocks
let event_refs = interpret_event_refs(blocks: blocks, tags: [])
let ev = NostrEvent(content: content, keypair: test_keypair, tags: [])!
let blocks = parse_note_content(content: .init(note: ev, privkey: test_keypair.privkey)).blocks
let event_refs = interpret_event_refs(blocks: blocks, tags:ev.tags)
XCTAssertEqual(event_refs.count, 0)
}
func testParseMention() throws {
let parsed = parse_note_content(content: "this is #[0] a mention", tags: [["e", "event_id"]]).blocks
let note_id = NoteId(hex: "53f60f5114c06f069ffe9da2bc033e533d09cae44d37a8462154a663771a4ce6")!
let tags = [note_id.tag]
let ev = NostrEvent(content: "this is #[0] a mention", keypair: test_keypair, tags: tags)!
let parsed = parse_note_content(content: .init(note: ev, privkey: test_keypair.privkey)).blocks
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed.count, 3)
XCTAssertEqual(parsed[0].is_text, "this is ")
@@ -301,76 +312,71 @@ class ReplyTests: XCTestCase {
}
func testBech32MentionAtStart() throws {
let pk = "npub1xtscya34g58tk0z605fvr788k263gsu6cy9x0mhnm87echrgufzsevkk5s"
let hex_pk = "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245"
let content = "@\(pk) hello there"
let pk = Pubkey(hex: "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245")!
let content = "@\(pk.npub) hello there"
let blocks = parse_post_blocks(content: content)
XCTAssertEqual(blocks.count, 2)
XCTAssertEqual(blocks[0].is_mention, .pubkey(hex_pk))
XCTAssertEqual(blocks[0].is_mention, .any(.pubkey(pk)))
XCTAssertEqual(blocks[1].is_text, " hello there")
}
func testBech32MentionAtEnd() throws {
let pk = "npub1xtscya34g58tk0z605fvr788k263gsu6cy9x0mhnm87echrgufzsevkk5s"
let hex_pk = "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245"
let content = "this is a @\(pk)"
let pk = Pubkey(hex: "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245")!
let content = "this is a @\(pk.npub)"
let blocks = parse_post_blocks(content: content)
XCTAssertEqual(blocks.count, 2)
XCTAssertEqual(blocks[1].is_mention, .pubkey(hex_pk))
XCTAssertEqual(blocks[1].is_mention, .any(.pubkey(pk)))
XCTAssertEqual(blocks[0].is_text, "this is a ")
}
func testNpubMention() throws {
let evid = "0000000000000000000000000000000000000000000000000000000000000005"
let pk = "npub1xtscya34g58tk0z605fvr788k263gsu6cy9x0mhnm87echrgufzsevkk5s"
let hex_pk = "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245"
let content = "this is a @\(pk) mention"
let reply_ref = ReferencedId(ref_id: evid, relay_id: nil, key: "e")
let evid = NoteId(hex: "71ba3e5ddaf48103be294aa370e470fb60b6c8bca3fb01706eecd00054c2f588")!
let pk = Pubkey(hex: "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245")!
let content = "this is a @\(pk.npub) mention"
let blocks = parse_post_blocks(content: content)
let post = NostrPost(content: content, references: [reply_ref])
let post = NostrPost(content: content, references: [.event(evid)])
let ev = post_to_event(post: post, keypair: test_keypair_full)!
XCTAssertEqual(ev.tags.count, 2)
XCTAssertEqual(blocks.count, 3)
XCTAssertEqual(blocks[1].is_mention, .pubkey(hex_pk))
XCTAssertEqual(blocks[1].is_mention, .any(.pubkey(pk)))
XCTAssertEqual(ev.content, "this is a nostr:npub1xtscya34g58tk0z605fvr788k263gsu6cy9x0mhnm87echrgufzsevkk5s mention")
}
func testNsecMention() throws {
let evid = "0000000000000000000000000000000000000000000000000000000000000005"
let pk = "nsec1jmzdz7d0ldqctdxwm5fzue277ttng2pk28n2u8wntc2r4a0w96ssnyukg7"
let hex_pk = "ccf95d668650178defca5ac503693b6668eb77895f610178ff8ed9fe5cf9482e"
let content = "this is a @\(pk) mention"
let reply_ref = ReferencedId(ref_id: evid, relay_id: nil, key: "e")
let evid = NoteId(hex: "71ba3e5ddaf48103be294aa370e470fb60b6c8bca3fb01706eecd00054c2f588")!
let pk = Pubkey(hex: "ccf95d668650178defca5ac503693b6668eb77895f610178ff8ed9fe5cf9482e")!
let nsec = "nsec1jmzdz7d0ldqctdxwm5fzue277ttng2pk28n2u8wntc2r4a0w96ssnyukg7"
let content = "this is a @\(nsec) mention"
let blocks = parse_post_blocks(content: content)
let post = NostrPost(content: content, references: [reply_ref])
let post = NostrPost(content: content, references: [.event(evid)])
let ev = post_to_event(post: post, keypair: test_keypair_full)!
XCTAssertEqual(ev.tags.count, 2)
XCTAssertEqual(blocks.count, 3)
XCTAssertEqual(blocks[1].is_mention, .pubkey(hex_pk))
XCTAssertEqual(blocks[1].is_mention, .any(.pubkey(pk)))
XCTAssertEqual(ev.content, "this is a nostr:npub1enu46e5x2qtcmm72ttzsx6fmve5wkauftassz78l3mvluh8efqhqejf3v4 mention")
}
func testReplyMentions() throws {
let privkey = "0fc2092231f958f8d57d66f5e238bb45b6a2571f44c0ce024bbc6f3a9c8a15fe"
let pubkey = "30c6d1dc7f7c156794fa15055e651b758a61b99f50fcf759de59386050bf6ae2"
let npub = "npub1xrrdrhrl0s2k0986z5z4uegmwk9xrwvl2r70wkw7tyuxq59ldt3qh09eay"
let pubkey = Pubkey(hex: "30c6d1dc7f7c156794fa15055e651b758a61b99f50fcf759de59386050bf6ae2")!
let thread_id = NoteId(hex: "a250fc93570c3e87f9c9b08d6b3ef7b8e05d346df8a52c69e30ffecdb178fb9e")!
let reply_id = NoteId(hex: "9a180a10f16dac9566543ad1fc29616aab272b0cf123ab5d58843e16f4ef03a3")!
let refs = [
ReferencedId(ref_id: "thread_id", relay_id: nil, key: "e"),
ReferencedId(ref_id: "reply_id", relay_id: nil, key: "e"),
ReferencedId(ref_id: pubkey, relay_id: nil, key: "p"),
let refs: [RefId] = [
.event(thread_id),
.event(reply_id),
.pubkey(pubkey)
]
let post = NostrPost(content: "this is a (@\(npub)) mention", references: refs)
let post = NostrPost(content: "this is a (@\(pubkey.npub)) mention", references: refs)
let ev = post_to_event(post: post, keypair: test_keypair_full)!
XCTAssertEqual(ev.content, "this is a (nostr:\(npub)) mention")
XCTAssertEqual(ev.tags[2][1], pubkey)
XCTAssertEqual(ev.content, "this is a (nostr:\(pubkey.npub)) mention")
XCTAssertEqual(ev.tags[2][1].string(), pubkey.description)
}
func testInvalidPostReference() throws {
@@ -413,14 +419,13 @@ class ReplyTests: XCTestCase {
}
func testParsePostUriPubkeyReference() throws {
let id = "6fec2ee6cfff779fe8560976b3d9df782b74577f0caefa7a77c0ed4c3749b5de"
let npub = try XCTUnwrap(bech32_pubkey(id))
let parsed = parse_post_blocks(content: "this is a nostr:\(npub) event mention")
let id = Pubkey(hex: "6fec2ee6cfff779fe8560976b3d9df782b74577f0caefa7a77c0ed4c3749b5de")!
let parsed = parse_post_blocks(content: "this is a nostr:\(id.npub) event mention")
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed.count, 3)
XCTAssertEqual(parsed[0].is_text, "this is a ")
XCTAssertEqual(parsed[1].is_mention, .pubkey(id))
XCTAssertEqual(parsed[1].is_mention, .any(.pubkey(id)))
XCTAssertEqual(parsed[2].is_text, " event mention")
guard case .text(let t1) = parsed[0] else {
@@ -437,14 +442,13 @@ class ReplyTests: XCTestCase {
}
func testParsePostUriReference() throws {
let id = "6fec2ee6cfff779fe8560976b3d9df782b74577f0caefa7a77c0ed4c3749b5de"
let note_id = try XCTUnwrap(bech32_note_id(id))
let parsed = parse_post_blocks(content: "this is a nostr:\(note_id) event mention")
let id = NoteId(hex: "6fec2ee6cfff779fe8560976b3d9df782b74577f0caefa7a77c0ed4c3749b5de")!
let parsed = parse_post_blocks(content: "this is a nostr:\(id.bech32) event mention")
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed.count, 3)
XCTAssertEqual(parsed[0].is_text, "this is a ")
XCTAssertEqual(parsed[1].is_mention, .note(id))
XCTAssertEqual(parsed[1].is_mention, .any(.note(id)))
XCTAssertEqual(parsed[2].is_text, " event mention")
guard case .text(let t1) = parsed[0] else {
@@ -461,8 +465,8 @@ class ReplyTests: XCTestCase {
}
func testParseInvalidMention() throws {
let parsed = parse_note_content(content: "this is #[0] a mention", tags: []).blocks
let parsed = parse_note_content(content: .content("this is #[0] a mention",nil)).blocks
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed.count, 3)
XCTAssertEqual(parsed[0].is_text, "this is ")

View File

@@ -83,8 +83,8 @@ final class UserSearchCacheTests: XCTestCase {
func testUpdateOwnContactsPetnames() throws {
let keypair = try XCTUnwrap(keypair)
let damus = "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681"
let jb55 = "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245"
let damus = Pubkey(hex: "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681")!
let jb55 = Pubkey(hex: "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245")!
var pubkeysToPetnames = [Pubkey: String]()
pubkeysToPetnames[damus] = "damus"
@@ -127,8 +127,8 @@ final class UserSearchCacheTests: XCTestCase {
let relayJson = encode_json(relays)!
let tags = pubkeysToPetnames.enumerated().map {
["p", $0.element.key, "", $0.element.value]
let tags: [[String]] = pubkeysToPetnames.enumerated().map {
["p", $0.element.key.description, "", $0.element.value]
}
return NostrEvent(content: relayJson, keypair: keypair.to_keypair(), kind: NostrKind.contacts.rawValue, tags: tags)!

View File

@@ -36,8 +36,8 @@ final class WalletConnectTests: XCTestCase {
}
func testDoesNWCParse() {
let pk = "9d088f4760422443d4699b485e2ac66e565a2f5da1198c55ddc5679458e3f67a"
let sec = "ff2eefd57196d42089e1b42acc39916d7ecac52e0625bd70597bbd5be14aff18"
let pk = Pubkey(hex: "9d088f4760422443d4699b485e2ac66e565a2f5da1198c55ddc5679458e3f67a")!
let sec = Privkey(hex: "ff2eefd57196d42089e1b42acc39916d7ecac52e0625bd70597bbd5be14aff18")!
let relay = "wss://relay.getalby.com/v1"
let str = "nostrwalletconnect://\(pk)?relay=\(relay)&secret=\(sec)&lud16=jb55@jb55.com"

View File

@@ -60,16 +60,18 @@ final class ZapTests: XCTestCase {
return
}
guard let zap = Zap.from_zap_event(zap_ev: ev, zapper: "9630f464cca6a5147aa8a35f0bcdd3ce485324e732fd39e09233b1d848238f31", our_privkey: nil) else {
let zapper = Pubkey(hex: "9630f464cca6a5147aa8a35f0bcdd3ce485324e732fd39e09233b1d848238f31")!
guard let zap = Zap.from_zap_event(zap_ev: ev, zapper: zapper, our_privkey: nil) else {
XCTAssert(false)
return
}
XCTAssertEqual(zap.zapper, "9630f464cca6a5147aa8a35f0bcdd3ce485324e732fd39e09233b1d848238f31")
XCTAssertEqual(zap.target, ZapTarget.profile("32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245"))
let profile = Pubkey(hex: "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245")!
XCTAssertEqual(zap.zapper, zapper)
XCTAssertEqual(zap.target, ZapTarget.profile(profile))
XCTAssertEqual(zap_notification_title(zap), "Zap")
XCTAssertEqual(zap_notification_body(profiles: Profiles(user_search_cache: UserSearchCache()), zap: zap), "You received 1k sats from 107jk7ht:2qlu3nfm")
XCTAssertEqual(zap_notification_body(profiles: Profiles(user_search_cache: UserSearchCache()), zap: zap), "You received 1k sats from 107jk7ht:2quqncxg")
}
}

View File

@@ -18,12 +18,14 @@ class damusTests: XCTestCase {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
func testExample() throws {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
// Any test you write for XCTest can be annotated as throws and async.
// Mark your test throws to produce an unexpected failure when your test encounters an uncaught error.
// Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards.
func testIdEquality() throws {
let pubkey = test_pubkey
let ev = test_note
let pubkey_same = Pubkey(Data([0xf7, 0xda, 0xc4, 0x6a, 0xa2, 0x70, 0xf7, 0x28, 0x76, 0x06, 0xa2, 0x2b, 0xeb, 0x4d, 0x77, 0x25, 0x57, 0x3a, 0xfa, 0x0e, 0x02, 0x8c, 0xdf, 0xac, 0x39, 0xa4, 0xcb, 0x23, 0x31, 0x53, 0x7f, 0x66]))
XCTAssertEqual(pubkey.hashValue, pubkey_same.hashValue)
XCTAssertEqual(pubkey, pubkey_same)
}
func testPerformanceExample() throws {
@@ -71,8 +73,8 @@ class damusTests: XCTestCase {
[my website](https://jb55.com)
"""
let parsed = parse_note_content(content: md, tags: []).blocks
let parsed = parse_note_content(content: .content(md, nil)).blocks
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed.count, 3)
XCTAssertNotNil(parsed[0].is_text)
@@ -96,7 +98,7 @@ class damusTests: XCTestCase {
}
func testParseUrlUpper() {
let parsed = parse_note_content(content: "a HTTPS://jb55.COM b", tags: []).blocks
let parsed = parse_note_content(content: .content("a HTTPS://jb55.COM b", nil)).blocks
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed.count, 3)
@@ -106,10 +108,8 @@ class damusTests: XCTestCase {
func testBech32Url() {
let parsed = decode_nostr_uri("nostr:npub1xtscya34g58tk0z605fvr788k263gsu6cy9x0mhnm87echrgufzsevkk5s")
let hexpk = "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245"
let expected: NostrLink = .ref(ReferencedId(ref_id: hexpk, relay_id: nil, key: "p"))
XCTAssertEqual(parsed, expected)
let pk = Pubkey(hex:"32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245")!
XCTAssertEqual(parsed, .ref(.pubkey(pk)))
}
func testSaveRelayFilters() {
@@ -120,10 +120,9 @@ class damusTests: XCTestCase {
filters.insert(filter1)
filters.insert(filter2)
let pubkey = "test_pubkey"
save_relay_filters(pubkey, filters: filters)
let loaded_filters = load_relay_filters(pubkey)!
save_relay_filters(test_pubkey, filters: filters)
let loaded_filters = load_relay_filters(test_pubkey)!
XCTAssertEqual(loaded_filters.count, 2)
XCTAssertTrue(loaded_filters.contains(filter1))
XCTAssertTrue(loaded_filters.contains(filter2))
@@ -131,7 +130,7 @@ class damusTests: XCTestCase {
}
func testParseUrl() {
let parsed = parse_note_content(content: "a https://jb55.com b", tags: []).blocks
let parsed = parse_note_content(content: .content("a https://jb55.com b", nil)).blocks
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed.count, 3)
@@ -139,7 +138,7 @@ class damusTests: XCTestCase {
}
func testParseUrlEnd() {
let parsed = parse_note_content(content: "a https://jb55.com", tags: []).blocks
let parsed = parse_note_content(content: .content("a https://jb55.com", nil)).blocks
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed.count, 2)
@@ -148,7 +147,7 @@ class damusTests: XCTestCase {
}
func testParseUrlStart() {
let parsed = parse_note_content(content: "https://jb55.com br", tags: []).blocks
let parsed = parse_note_content(content: .content("https://jb55.com br",nil)).blocks
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed.count, 2)
@@ -158,44 +157,49 @@ class damusTests: XCTestCase {
func testNoParseUrlWithOnlyWhitespace() {
let testString = "https:// "
let parsed = parse_note_content(content: testString, tags: []).blocks
let parsed = parse_note_content(content: .content(testString,nil)).blocks
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed[0].is_text, testString)
}
func testNoParseUrlTrailingCharacters() {
let testString = "https://foo.bar, "
let parsed = parse_note_content(content: testString, tags: []).blocks
let parsed = parse_note_content(content: .content(testString,nil)).blocks
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed[0].is_url?.absoluteString, "https://foo.bar")
}
/*
func testParseMentionBlank() {
let parsed = parse_note_content(content: "", tags: [["e", "event_id"]]).blocks
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed.count, 0)
}
*/
func testMakeHashtagPost() {
let post = NostrPost(content: "#damus some content #bitcoin derp #かっこいい wow", references: [])
let ev = post_to_event(post: post, keypair: test_keypair_full)!
XCTAssertEqual(ev.tags.count, 3)
XCTAssertEqual(ev.content, "#damus some content #bitcoin derp #かっこいい wow")
XCTAssertEqual(ev.tags[0][0], "t")
XCTAssertEqual(ev.tags[0][1], "damus")
XCTAssertEqual(ev.tags[1][0], "t")
XCTAssertEqual(ev.tags[1][1], "bitcoin")
XCTAssertEqual(ev.tags[2][0], "t")
XCTAssertEqual(ev.tags[2][1], "かっこいい")
XCTAssertEqual(ev.tags[0][0].string(), "t")
XCTAssertEqual(ev.tags[0][1].string(), "damus")
XCTAssertEqual(ev.tags[1][0].string(), "t")
XCTAssertEqual(ev.tags[1][1].string(), "bitcoin")
XCTAssertEqual(ev.tags[2][0].string(), "t")
XCTAssertEqual(ev.tags[2][1].string(), "かっこいい")
}
func testParseMentionOnlyText() {
let parsed = parse_note_content(content: "there is no mention here", tags: [["e", "event_id"]]).blocks
let tags = [["e", "event_id"]]
let ev = NostrEvent(content: "there is no mention here", keypair: test_keypair, tags: tags)!
let parsed = parse_note_content(content: .init(note: ev, privkey: test_keypair.privkey)).blocks
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed.count, 1)
XCTAssertEqual(parsed[0].is_text, "there is no mention here")