damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

ReplyTests.swift (15915B)


      1 //
      2 //  ReplyTests.swift
      3 //  damusTests
      4 //
      5 //  Created by William Casarin on 2022-05-08.
      6 //
      7 
      8 import XCTest
      9 @testable import damus
     10 
     11 class ReplyTests: XCTestCase {
     12 
     13     override func setUpWithError() throws {
     14         // Put setup code here. This method is called before the invocation of each test method in the class.
     15     }
     16 
     17     override func tearDownWithError() throws {
     18         // Put teardown code here. This method is called after the invocation of each test method in the class.
     19     }
     20     
     21     func testAtAtEnd() {
     22         let content = "what @"
     23         let blocks = parse_post_blocks(content: content)!.blocks
     24 
     25         XCTAssertEqual(blocks.count, 1)
     26         XCTAssertEqual(blocks[0].asText, "what @")
     27     }
     28     
     29     func testHashtagsInQuote() {
     30         let content = "This is my \"#awesome post\""
     31         let blocks = parse_post_blocks(content: content)!.blocks
     32 
     33         XCTAssertEqual(blocks.count, 3)
     34         XCTAssertEqual(blocks[0].asText, "This is my \"")
     35         XCTAssertEqual(blocks[1].asHashtag, "awesome")
     36         XCTAssertEqual(blocks[2].asText, " post\"")
     37     }
     38     
     39     func testHashtagAtStartWorks() {
     40         let content = "#hashtag"
     41         let blocks = parse_post_blocks(content: content)!.blocks
     42         XCTAssertEqual(blocks.count, 1)
     43         XCTAssertEqual(blocks[0].asHashtag, "hashtag")
     44     }
     45     
     46     func testGroupOfHashtags() {
     47         let content = "#hashtag#what#nope"
     48         let blocks = parse_post_blocks(content: content)!.blocks
     49         XCTAssertEqual(blocks.count, 3)
     50         XCTAssertEqual(blocks[0].asHashtag, "hashtag")
     51         XCTAssertEqual(blocks[1].asHashtag, "what")
     52         XCTAssertEqual(blocks[2].asHashtag, "nope")
     53     }
     54     
     55 //    func testRootReplyWithMention() throws {
     56 //        let content = "this is #[1] a mention"
     57 //        let thread_id = NoteId(hex: "c75e5cbafbefd5de2275f831c2a2386ea05ec5e5a78a5ccf60d467582db48945")!
     58 //        let mentioned_id = NoteId(hex: "5a534797e8cd3b9f4c1cf63e20e48bd0e8bd7f8c4d6353fbd576df000f6f54d3")!
     59 //        let tags = [thread_id.tag, mentioned_id.tag]
     60 //        let ev = NostrEvent(content: content, keypair: test_keypair, tags: tags)!
     61 //        let event_refs = interpret_event_refs(tags: ev.tags)
     62 //
     63 //        XCTAssertEqual(event_refs.count, 2)
     64 //        XCTAssertNotNil(event_refs[0].is_reply)
     65 //        XCTAssertNotNil(event_refs[0].is_thread_id)
     66 //        XCTAssertNotNil(event_refs[0].is_reply)
     67 //        XCTAssertNotNil(event_refs[0].is_direct_reply)
     68 //        XCTAssertEqual(event_refs[0].is_reply, .some(NoteRef(note_id: thread_id)))
     69 //        XCTAssertEqual(event_refs[0].is_thread_id, .some(NoteRef(note_id: thread_id)))
     70 //        XCTAssertNotNil(event_refs[1].is_mention)
     71 //        XCTAssertEqual(event_refs[1].is_mention, .some(NoteRef(note_id: mentioned_id)))
     72 //    }
     73     
     74 //    func testEmptyMention() throws {
     75 //        let content = "this is some & content"
     76 //        let ev = NostrEvent(content: content, keypair: test_keypair, tags: [])!
     77 //        let blocks = parse_note_content(content: .init(note: ev, keypair: test_keypair)).blocks
     78 //        let post_blocks = parse_post_blocks(content: content)!.blocks
     79 //        let post = NostrPost(content: content, kind: NostrKind.text, tags: [])
     80 //        let post_tags = post.make_post_tags(post_blocks: post_blocks, tags: [])
     81 //        let tr = interpret_event_refs(tags: ev.tags)
     82 //
     83 //        XCTAssertNil(tr)
     84 //        XCTAssertEqual(post_tags.blocks.count, 1)
     85 //        XCTAssertEqual(post_tags.tags.count, 0)
     86 //        XCTAssertEqual(post_blocks.count, 1)
     87 //    }
     88 
     89     func testNewlineMentions() throws {
     90         let bech32_pk = "npub1xtscya34g58tk0z605fvr788k263gsu6cy9x0mhnm87echrgufzsevkk5s"
     91         let pk = bech32_pubkey_decode(bech32_pk)!
     92 
     93         let profile = Profile(name: "jb55")
     94         let post = user_tag_attr_string(profile: profile, pubkey: pk)
     95         post.append(.init(string: "\n"))
     96         post.append(user_tag_attr_string(profile: profile, pubkey: pk))
     97         post.append(.init(string: "\n"))
     98 
     99         let post_note = build_post(state: test_damus_state, post: post, action: .posting(.none), uploadedMedias: [], pubkeys: [pk])
    100 
    101         let expected_render = "nostr:\(pk.npub)\nnostr:\(pk.npub)"
    102         XCTAssertEqual(post_note.content, expected_render)
    103 
    104         let blocks = parse_note_content(content: .content(post_note.content,nil))!.blocks
    105         let rendered = blocks.map { $0.asString }.joined(separator: "")
    106 
    107         XCTAssertEqual(rendered, expected_render)
    108 
    109         XCTAssertEqual(blocks.count, 3)
    110         XCTAssertEqual(blocks[0].asMention, Mention<MentionRef>.any(.pubkey(pk)))
    111         XCTAssertEqual(blocks[1].asText, "\n")
    112         XCTAssertEqual(blocks[2].asMention, Mention<MentionRef>.any(.pubkey(pk)))
    113     }
    114     
    115     func testThreadedReply() throws {
    116         let content = "this is some content"
    117         let thread_id = NoteId(hex: "da256fb52146dc565c6c6b9ef906117c665864dc02b14a7b853eca244729c2f2")!
    118         let reply_id = NoteId(hex: "80093e9bdb495728f54cda2bad4aed096877189552b3d41264e73b9a9595be22")!
    119         let tags = [thread_id.tag, reply_id.tag]
    120         let ev = NostrEvent(content: content, keypair: test_keypair, tags: tags)!
    121         let tr = interpret_event_refs(tags: ev.tags)
    122         XCTAssertNotNil(tr)
    123         guard let tr else { return }
    124 
    125         XCTAssertEqual(tr.root.note_id, thread_id)
    126         XCTAssertEqual(tr.reply.note_id, reply_id)
    127     }
    128     
    129     func testRootReply() throws {
    130         let content = "this is a reply"
    131         let thread_id = NoteId(hex: "53f60f5114c06f069ffe9da2bc033e533d09cae44d37a8462154a663771a4ce6")!
    132         let tags = [thread_id.tag]
    133         let ev = NostrEvent(content: content, keypair: test_keypair, tags: tags)!
    134         let tr = interpret_event_refs(tags: ev.tags)
    135 
    136         XCTAssertNotNil(tr)
    137         guard let tr else { return }
    138 
    139         XCTAssertEqual(tr.root.note_id, thread_id)
    140         XCTAssertEqual(tr.reply.note_id, thread_id)
    141         XCTAssertNil(tr.mention)
    142     }
    143 
    144     func testAdjacentComposedMention() throws {
    145         let content = "cc@jb55"
    146 
    147         let profile = Profile(name: "jb55")
    148         let tag = user_tag_attr_string(profile: profile, pubkey: test_pubkey)
    149         let appended = append_user_tag(tag: tag, post: .init(string: content), word_range: .init(2...6))
    150         let new_post = appended.post
    151 
    152         try new_post.testAttributes(conditions: [
    153             { let link = $0[.link] as? String; XCTAssertNil(link) },
    154             { let link = $0[.link] as! String; XCTAssertEqual(link, "damus:nostr:\(test_pubkey.npub)") },
    155             { let link = $0[.link] as? String; XCTAssertNil(link) }
    156         ])
    157 
    158         XCTAssertEqual(new_post.string, "cc @jb55 ")
    159     }
    160 
    161     func testAdjacentEmojiComposedMention() throws {
    162         let content = "😎@jb55"
    163 
    164         let profile = Profile(name: "jb55")
    165         let tag = user_tag_attr_string(profile: profile, pubkey: test_pubkey)
    166         let appended = append_user_tag(tag: tag, post: .init(string: content), word_range: .init(2...6))
    167         let new_post = appended.post
    168 
    169         try new_post.testAttributes(conditions: [
    170             { let link = $0[.link] as? String; XCTAssertNil(link) },
    171             { let link = $0[.link] as! String; XCTAssertEqual(link, "damus:nostr:\(test_pubkey.npub)") },
    172             { let link = $0[.link] as? String; XCTAssertNil(link) }
    173         ])
    174 
    175         XCTAssertEqual(new_post.string, "😎 @jb55 ")
    176     }
    177 
    178     func testComposedMentionNewline() throws {
    179         let content = """
    180         
    181         @jb55
    182         """
    183 
    184         let profile = Profile(name: "jb55")
    185         let tag = user_tag_attr_string(profile: profile, pubkey: test_pubkey)
    186         let appended = append_user_tag(tag: tag, post: .init(string: content), word_range: .init(1...5))
    187         let new_post = appended.post
    188 
    189         try new_post.testAttributes(conditions: [
    190             { let link = $0[.link] as? String; XCTAssertNil(link) },
    191             { let link = $0[.link] as! String; XCTAssertEqual(link, "damus:nostr:\(test_pubkey.npub)") },
    192             { let link = $0[.link] as? String; XCTAssertNil(link) },
    193         ])
    194 
    195         XCTAssertEqual(new_post.string, "\n@jb55 ")
    196     }
    197 
    198     func testComposedMention() throws {
    199         let content = "@jb55"
    200 
    201         let profile = Profile(name: "jb55")
    202         let tag = user_tag_attr_string(profile: profile, pubkey: test_pubkey)
    203         let appended = append_user_tag(tag: tag, post: .init(string: content), word_range: .init(0...4))
    204         let new_post = appended.post
    205 
    206         try new_post.testAttributes(conditions: [
    207             { let link = $0[.link] as! String; XCTAssertEqual(link, "damus:nostr:\(test_pubkey.npub)") },
    208             { let link = $0[.link] as? String; XCTAssertNil(link) },
    209         ])
    210 
    211         XCTAssertEqual(new_post.string, "@jb55 ")
    212     }
    213 
    214     func testAdjacentSpaceComposedMention() throws {
    215         let content = "cc @jb55"
    216 
    217         let profile = Profile(name: "jb55")
    218         let tag = user_tag_attr_string(profile: profile, pubkey: test_pubkey)
    219         let appended = append_user_tag(tag: tag, post: .init(string: content), word_range: .init(3...7))
    220         let new_post = appended.post
    221 
    222         try new_post.testAttributes(conditions: [
    223             { let link = $0[.link] as? String; XCTAssertNil(link) },
    224             { let link = $0[.link] as! String; XCTAssertEqual(link, "damus:nostr:\(test_pubkey.npub)") },
    225             { let link = $0[.link] as? String; XCTAssertNil(link) }
    226         ])
    227 
    228         XCTAssertEqual(new_post.string, "cc @jb55 ")
    229     }
    230 
    231     func testEmptyPostReference() throws {
    232         let parsed = parse_post_blocks(content: "")!.blocks
    233         XCTAssertEqual(parsed.count, 0)
    234     }
    235     
    236     func testBech32MentionAtStart() throws {
    237         let pk = Pubkey(hex: "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245")!
    238         let content = "@\(pk.npub) hello there"
    239         let blocks = parse_post_blocks(content: content)!.blocks
    240 
    241         XCTAssertEqual(blocks.count, 2)
    242         XCTAssertEqual(blocks[0].asMention, .any(.pubkey(pk)))
    243         XCTAssertEqual(blocks[1].asText, " hello there")
    244 
    245     }
    246     
    247     func testBech32MentionAtEnd() throws {
    248         let pk = Pubkey(hex: "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245")!
    249         let content = "this is a @\(pk.npub)"
    250         let blocks = parse_post_blocks(content: content)!.blocks
    251         
    252         XCTAssertEqual(blocks.count, 2)
    253         XCTAssertEqual(blocks[1].asMention, .any(.pubkey(pk)))
    254         XCTAssertEqual(blocks[0].asText, "this is a ")
    255     }
    256     
    257 //    func testNpubMention() throws {
    258 //        let evid = NoteId(hex: "71ba3e5ddaf48103be294aa370e470fb60b6c8bca3fb01706eecd00054c2f588")!
    259 //        let pk = Pubkey(hex: "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245")!
    260 //        let content = "this is a @\(pk.npub) mention"
    261 //        let blocks = parse_post_blocks(content: content)!.blocks
    262 //        let post = NostrPost(content: content, references: [.event(evid)])
    263 //        let ev = post.to_event(keypair: test_keypair_full)!
    264 //
    265 //        XCTAssertEqual(ev.tags.count, 2)
    266 //        XCTAssertEqual(blocks.count, 3)
    267 //        XCTAssertEqual(blocks[1].asMention, .any(.pubkey(pk)))
    268 //        XCTAssertEqual(ev.content, "this is a nostr:npub1xtscya34g58tk0z605fvr788k263gsu6cy9x0mhnm87echrgufzsevkk5s mention")
    269 //    }
    270 //    
    271 //    func testNsecMention() throws {
    272 //        let evid = NoteId(hex: "71ba3e5ddaf48103be294aa370e470fb60b6c8bca3fb01706eecd00054c2f588")!
    273 //        let pk = Pubkey(hex: "ccf95d668650178defca5ac503693b6668eb77895f610178ff8ed9fe5cf9482e")!
    274 //        let nsec = "nsec1jmzdz7d0ldqctdxwm5fzue277ttng2pk28n2u8wntc2r4a0w96ssnyukg7"
    275 //        let content = "this is a @\(nsec) mention"
    276 //        let blocks = parse_post_blocks(content: content)!.blocks
    277 //        let post = NostrPost(content: content, references: [.event(evid)])
    278 //        let ev = post.to_event(keypair: test_keypair_full)!
    279 //
    280 //        XCTAssertEqual(ev.tags.count, 2)
    281 //        XCTAssertEqual(blocks.count, 3)
    282 //        XCTAssertEqual(blocks[1].asMention, .any(.pubkey(pk)))
    283 //        XCTAssertEqual(ev.content, "this is a nostr:npub1enu46e5x2qtcmm72ttzsx6fmve5wkauftassz78l3mvluh8efqhqejf3v4 mention")
    284 //    }
    285     
    286     func testReplyMentions() throws {
    287         let pubkey  = Pubkey(hex: "30c6d1dc7f7c156794fa15055e651b758a61b99f50fcf759de59386050bf6ae2")!
    288         let thread_id = NoteId(hex: "a250fc93570c3e87f9c9b08d6b3ef7b8e05d346df8a52c69e30ffecdb178fb9e")!
    289         let reply_id = NoteId(hex: "9a180a10f16dac9566543ad1fc29616aab272b0cf123ab5d58843e16f4ef03a3")!
    290 
    291         let tags = [
    292             ["e", thread_id.hex()],
    293             ["e", reply_id.hex()],
    294             ["p", pubkey.hex()]
    295         ]
    296 
    297         let post = NostrPost(content: "this is a (@\(pubkey.npub)) mention", tags: tags)
    298         let ev = post.to_event(keypair: test_keypair_full)!
    299         
    300         XCTAssertEqual(ev.content, "this is a (nostr:\(pubkey.npub)) mention")
    301         XCTAssertEqual(ev.tags[2][1].string(), pubkey.description)
    302     }
    303     
    304     func testInvalidPostReference() throws {
    305         let pk = "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e24"
    306         let content = "this is a @\(pk) mention"
    307         let parsed = parse_post_blocks(content: content)!.blocks
    308         XCTAssertEqual(parsed.count, 1)
    309         guard case .text(let txt) = parsed[0] else {
    310             XCTAssert(false)
    311             return
    312         }
    313         XCTAssertEqual(txt, content)
    314     }
    315     
    316     func testInvalidPostReferenceEmptyAt() throws {
    317         let content = "this is a @ mention"
    318         let parsed = parse_post_blocks(content: content)!.blocks
    319         XCTAssertEqual(parsed.count, 1)
    320         guard case .text(let txt) = parsed[0] else {
    321             XCTAssert(false)
    322             return
    323         }
    324         XCTAssertEqual(txt, content)
    325     }
    326     
    327     func testInvalidUriReference() throws {
    328         let id = "6fec2ee6cfff779fe8560976b3d9df782b74577f0caefa7a77c0ed4c3749b5de"
    329         let content = "this is a nostr:z:\(id) event mention"
    330         let parsed = parse_post_blocks(content: content)!.blocks
    331 
    332         XCTAssertNotNil(parsed)
    333         XCTAssertEqual(parsed.count, 1)
    334         
    335         guard case .text(let txt) = parsed[0] else {
    336             XCTAssertTrue(false)
    337             return
    338         }
    339         
    340         XCTAssertEqual(txt, content)
    341     }
    342     
    343     func testParsePostUriPubkeyReference() throws {
    344         let id = Pubkey(hex: "6fec2ee6cfff779fe8560976b3d9df782b74577f0caefa7a77c0ed4c3749b5de")!
    345         let parsed = parse_post_blocks(content: "this is a nostr:\(id.npub) event mention")!.blocks
    346 
    347         XCTAssertNotNil(parsed)
    348         XCTAssertEqual(parsed.count, 3)
    349         XCTAssertEqual(parsed[0].asText, "this is a ")
    350         XCTAssertEqual(parsed[1].asMention, .any(.pubkey(id)))
    351         XCTAssertEqual(parsed[2].asText, " event mention")
    352         
    353         guard case .text(let t1) = parsed[0] else {
    354             XCTAssertTrue(false)
    355             return
    356         }
    357         XCTAssertEqual(t1, "this is a ")
    358         
    359         guard case .text(let t2) = parsed[2] else {
    360             XCTAssertTrue(false)
    361             return
    362         }
    363         XCTAssertEqual(t2, " event mention")
    364     }
    365     
    366     func testParsePostUriReference() throws {
    367         let id = NoteId(hex: "6fec2ee6cfff779fe8560976b3d9df782b74577f0caefa7a77c0ed4c3749b5de")!
    368         let parsed = parse_post_blocks(content: "this is a nostr:\(id.bech32) event mention")!.blocks
    369 
    370         XCTAssertNotNil(parsed)
    371         XCTAssertEqual(parsed.count, 3)
    372         XCTAssertEqual(parsed[0].asText, "this is a ")
    373         XCTAssertEqual(parsed[1].asMention, .any(.note(id)))
    374         XCTAssertEqual(parsed[2].asText, " event mention")
    375 
    376         guard case .text(let t1) = parsed[0] else {
    377             XCTAssertTrue(false)
    378             return
    379         }
    380         XCTAssertEqual(t1, "this is a ")
    381         
    382         guard case .text(let t2) = parsed[2] else {
    383             XCTAssertTrue(false)
    384             return
    385         }
    386         XCTAssertEqual(t2, " event mention")
    387     }
    388 }