damus

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

NoteContentViewTests.swift (28356B)


      1 //
      2 //  NoteContentViewTests.swift
      3 //  damusTests
      4 //
      5 //  Created by Daniel D’Aquino on 2023-08-02.
      6 //
      7 
      8 import XCTest
      9 import SwiftUI
     10 @testable import damus
     11 
     12 class NoteContentViewTests: XCTestCase {
     13     /*
     14     func testRenderBlocksWithNonLatinHashtags() {
     15         let content = "Damusはかっこいいです #cool #かっこいい"
     16         let note = try XCTUnwrap(NostrEvent(content: content, keypair: test_keypair, tags: [["t", "かっこいい"]]))
     17         let parsed: Blocks = parse_note_content(content: .init(note: note, keypair: test_keypair))
     18 
     19         let testState = test_damus_state
     20         
     21         let text: NoteArtifactsSeparated = render_blocks(blocks: parsed, profiles: testState.profiles, note: note, can_hide_last_previewable_refs: true) 
     22         let attributedText: AttributedString = text.content.attributed
     23         
     24         let runs: AttributedString.Runs = attributedText.runs
     25         let runArray: [AttributedString.Runs.Run] = Array(runs)
     26         print(runArray.description)
     27         XCTAssertEqual(runArray[1].link?.absoluteString, "damus:t:cool", "Latin-character hashtag is missing. Runs description :\(runArray.description)")
     28         XCTAssertEqual(runArray[3].link?.absoluteString.removingPercentEncoding, "damus:t:かっこいい", "Non-latin-character hashtag is missing. Runs description :\(runArray.description)")
     29     }
     30 
     31     func testRenderBlocksWithLeadingAndTrailingWhitespacesTrimmed() throws {
     32         let content = "  \n\n  Hello, \nworld! \n\n   "
     33         let note = try XCTUnwrap(NostrEvent(content: content, keypair: test_keypair))
     34         let parsed: Blocks = parse_note_content(content: .init(note: note, keypair: test_keypair))
     35 
     36         let testState = test_damus_state
     37 
     38         let noteArtifactsSeparated: NoteArtifactsSeparated = render_blocks(blocks: parsed, profiles: testState.profiles, can_hide_last_previewable_refs: true)
     39         let attributedText: AttributedString = noteArtifactsSeparated.content.attributed
     40         let text = attributedText.description
     41 
     42         let runs: AttributedString.Runs = attributedText.runs
     43         let runArray: [AttributedString.Runs.Run] = Array(runs)
     44 
     45         XCTAssertEqual(runArray.count, 1)
     46         XCTAssertTrue(text.contains("Hello, \nworld!"))
     47         XCTAssertFalse(text.contains(content))
     48     }
     49 
     50     func testRenderBlocksWithMediaBlockInMiddleRendered() throws {
     51         let content = "    Check this out: https://damus.io/image.png Isn't this cool?    "
     52         let note = try XCTUnwrap(NostrEvent(content: content, keypair: test_keypair))
     53         let parsed: Blocks = parse_note_content(content: .init(note: note, keypair: test_keypair))
     54 
     55         let testState = test_damus_state
     56 
     57         let noteArtifactsSeparated: NoteArtifactsSeparated = render_blocks(blocks: parsed, profiles: testState.profiles)
     58         let attributedText: AttributedString = noteArtifactsSeparated.content.attributed
     59 
     60         let runs: AttributedString.Runs = attributedText.runs
     61         let runArray: [AttributedString.Runs.Run] = Array(runs)
     62         XCTAssertEqual(runArray.count, 3)
     63         XCTAssertTrue(runArray[0].description.contains("Check this out: "))
     64         XCTAssertTrue(runArray[1].description.contains("https://damus.io/image.png "))
     65         XCTAssertEqual(runArray[1].link?.absoluteString, "https://damus.io/image.png")
     66         XCTAssertTrue(runArray[2].description.contains(" Isn't this cool?"))
     67 
     68         XCTAssertEqual(noteArtifactsSeparated.images.count, 1)
     69         XCTAssertEqual(noteArtifactsSeparated.images[0].absoluteString, "https://damus.io/image.png")
     70     }
     71 
     72     func testRenderBlocksWithInvoiceInMiddleAbbreviated() throws {
     73         let invoiceString = "lnbc100n1p357sl0sp5t9n56wdztun39lgdqlr30xqwksg3k69q4q2rkr52aplujw0esn0qpp5mrqgljk62z20q4nvgr6lzcyn6fhylzccwdvu4k77apg3zmrkujjqdpzw35xjueqd9ejqcfqv3jhxcmjd9c8g6t0dcxqyjw5qcqpjrzjqt56h4gvp5yx36u2uzqa6qwcsk3e2duunfxppzj9vhypc3wfe2wswz607uqq3xqqqsqqqqqqqqqqqlqqyg9qyysgqagx5h20aeulj3gdwx3kxs8u9f4mcakdkwuakasamm9562ffyr9en8yg20lg0ygnr9zpwp68524kmda0t5xp2wytex35pu8hapyjajxqpsql29r"
     74         let content = "    Donations appreciated: \(invoiceString) Pura Vida    "
     75         let note = try XCTUnwrap(NostrEvent(content: content, keypair: test_keypair))
     76         let parsed: Blocks = parse_note_content(content: .init(note: note, keypair: test_keypair))
     77 
     78         let testState = test_damus_state
     79 
     80         let noteArtifactsSeparated: NoteArtifactsSeparated = render_blocks(blocks: parsed, profiles: testState.profiles)
     81         let attributedText: AttributedString = noteArtifactsSeparated.content.attributed
     82 
     83         let runs: AttributedString.Runs = attributedText.runs
     84         let runArray: [AttributedString.Runs.Run] = Array(runs)
     85         XCTAssertEqual(runArray.count, 3)
     86         XCTAssertTrue(runArray[0].description.contains("Donations appreciated: "))
     87         XCTAssertTrue(runArray[1].description.contains("lnbc100n:qpsql29r"))
     88         XCTAssertEqual(runArray[1].link?.absoluteString, "damus:lightning:\(invoiceString)")
     89         XCTAssertTrue(runArray[2].description.contains(" Pura Vida"))
     90     }
     91 
     92     func testRenderBlocksWithNoteIdInMiddleAreRendered() throws {
     93         let noteId = test_note.id.bech32
     94         let content = "    Check this out: nostr:\(noteId) Pura Vida    "
     95         let note = try XCTUnwrap(NostrEvent(content: content, keypair: test_keypair))
     96         let parsed: Blocks = parse_note_content(content: .init(note: note, keypair: test_keypair))
     97 
     98         let testState = test_damus_state
     99 
    100         let noteArtifactsSeparated: NoteArtifactsSeparated = render_blocks(blocks: parsed, profiles: testState.profiles)
    101         let attributedText: AttributedString = noteArtifactsSeparated.content.attributed
    102 
    103         let runs: AttributedString.Runs = attributedText.runs
    104         let runArray: [AttributedString.Runs.Run] = Array(runs)
    105         XCTAssertEqual(runArray.count, 3)
    106         XCTAssertTrue(runArray[0].description.contains("Check this out: "))
    107         XCTAssertTrue(runArray[1].description.contains("note1qqq:qqn2l0z3"))
    108         XCTAssertEqual(runArray[1].link?.absoluteString, "damus:nostr:\(noteId)")
    109         XCTAssertTrue(runArray[2].description.contains(" Pura Vida"))
    110     }
    111 
    112     func testRenderBlocksWithNeventInMiddleAreRendered() throws {
    113         let nevent = "nevent1qqstna2yrezu5wghjvswqqculvvwxsrcvu7uc0f78gan4xqhvz49d9spr3mhxue69uhkummnw3ez6un9d3shjtn4de6x2argwghx6egpr4mhxue69uhkummnw3ez6ur4vgh8wetvd3hhyer9wghxuet5nxnepm"
    114         let content = "    Check this out: nostr:\(nevent) Pura Vida    "
    115         let note = try XCTUnwrap(NostrEvent(content: content, keypair: test_keypair))
    116         let parsed: Blocks = parse_note_content(content: .init(note: note, keypair: test_keypair))
    117 
    118         let testState = test_damus_state
    119 
    120         let noteArtifactsSeparated: NoteArtifactsSeparated = render_blocks(blocks: parsed, profiles: testState.profiles)
    121         let attributedText: AttributedString = noteArtifactsSeparated.content.attributed
    122 
    123         let runs: AttributedString.Runs = attributedText.runs
    124         let runArray: [AttributedString.Runs.Run] = Array(runs)
    125         XCTAssertEqual(runArray.count, 3)
    126         XCTAssertTrue(runArray[0].description.contains("Check this out: "))
    127         XCTAssertTrue(runArray[1].description.contains("nevent1q:t5nxnepm"))
    128         XCTAssertEqual(runArray[1].link?.absoluteString, "damus:nostr:\(nevent)")
    129         XCTAssertTrue(runArray[2].description.contains(" Pura Vida"))
    130     }
    131 
    132     func testRenderBlocksWithPreviewableBlocksAtEndAreHidden() throws {
    133         let noteId = test_note.id.bech32
    134         let invoiceString = "lnbc100n1p357sl0sp5t9n56wdztun39lgdqlr30xqwksg3k69q4q2rkr52aplujw0esn0qpp5mrqgljk62z20q4nvgr6lzcyn6fhylzccwdvu4k77apg3zmrkujjqdpzw35xjueqd9ejqcfqv3jhxcmjd9c8g6t0dcxqyjw5qcqpjrzjqt56h4gvp5yx36u2uzqa6qwcsk3e2duunfxppzj9vhypc3wfe2wswz607uqq3xqqqsqqqqqqqqqqqlqqyg9qyysgqagx5h20aeulj3gdwx3kxs8u9f4mcakdkwuakasamm9562ffyr9en8yg20lg0ygnr9zpwp68524kmda0t5xp2wytex35pu8hapyjajxqpsql29r"
    135         let content = "    Check this out.   \nhttps://hidden.tld/\nhttps://damus.io/hidden1.png\n\(invoiceString)\nhttps://damus.io/hidden2.png\nnostr:\(noteId) "
    136         let note = try XCTUnwrap(NostrEvent(content: content, keypair: test_keypair))
    137         let parsed: Blocks = parse_note_content(content: .init(note: note, keypair: test_keypair))
    138 
    139         let testState = test_damus_state
    140 
    141         let noteArtifactsSeparated: NoteArtifactsSeparated = render_blocks(blocks: parsed, profiles: testState.profiles, can_hide_last_previewable_refs: true)
    142         let attributedText: AttributedString = noteArtifactsSeparated.content.attributed
    143 
    144         let runs: AttributedString.Runs = attributedText.runs
    145         let runArray: [AttributedString.Runs.Run] = Array(runs)
    146         XCTAssertEqual(runArray.count, 1)
    147         XCTAssertTrue(runArray[0].description.contains("Check this out."))
    148         XCTAssertFalse(runArray[0].description.contains("https://hidden.tld/"))
    149         XCTAssertFalse(runArray[0].description.contains("https://damus.io/hidden1.png"))
    150         XCTAssertFalse(runArray[0].description.contains("lnbc100n:qpsql29r"))
    151         XCTAssertFalse(runArray[0].description.contains("https://damus.io/hidden2.png"))
    152         XCTAssertFalse(runArray[0].description.contains("note1qqq:qqn2l0z3"))
    153 
    154         XCTAssertEqual(noteArtifactsSeparated.images.count, 2)
    155         XCTAssertEqual(noteArtifactsSeparated.images[0].absoluteString, "https://damus.io/hidden1.png")
    156         XCTAssertEqual(noteArtifactsSeparated.images[1].absoluteString, "https://damus.io/hidden2.png")
    157 
    158         XCTAssertEqual(noteArtifactsSeparated.media.count, 2)
    159         XCTAssertEqual(noteArtifactsSeparated.media[0].url.absoluteString, "https://damus.io/hidden1.png")
    160         XCTAssertEqual(noteArtifactsSeparated.media[1].url.absoluteString, "https://damus.io/hidden2.png")
    161 
    162         XCTAssertEqual(noteArtifactsSeparated.links.count, 1)
    163         XCTAssertEqual(noteArtifactsSeparated.links[0].absoluteString, "https://hidden.tld/")
    164 
    165         XCTAssertEqual(noteArtifactsSeparated.invoices.count, 1)
    166         XCTAssertEqual(noteArtifactsSeparated.invoices[0].string, invoiceString)
    167     }
    168 
    169     func testRenderBlocksWithMultipleLinksAtEndAreNotHidden() throws {
    170         let noteId = test_note.id.bech32
    171         let invoiceString = "lnbc100n1p357sl0sp5t9n56wdztun39lgdqlr30xqwksg3k69q4q2rkr52aplujw0esn0qpp5mrqgljk62z20q4nvgr6lzcyn6fhylzccwdvu4k77apg3zmrkujjqdpzw35xjueqd9ejqcfqv3jhxcmjd9c8g6t0dcxqyjw5qcqpjrzjqt56h4gvp5yx36u2uzqa6qwcsk3e2duunfxppzj9vhypc3wfe2wswz607uqq3xqqqsqqqqqqqqqqqlqqyg9qyysgqagx5h20aeulj3gdwx3kxs8u9f4mcakdkwuakasamm9562ffyr9en8yg20lg0ygnr9zpwp68524kmda0t5xp2wytex35pu8hapyjajxqpsql29r"
    172         let content = "    Check this out.   \nhttps://nothidden1.tld/\nhttps://nothidden2.tld/\nhttps://damus.io/nothidden1.png\n\(invoiceString)\nhttps://damus.io/nothidden2.png\nnostr:\(noteId) "
    173         let note = try XCTUnwrap(NostrEvent(content: content, keypair: test_keypair))
    174         let parsed: Blocks = parse_note_content(content: .init(note: note, keypair: test_keypair))
    175 
    176         let testState = test_damus_state
    177 
    178         let noteArtifactsSeparated: NoteArtifactsSeparated = render_blocks(blocks: parsed, profiles: testState.profiles, can_hide_last_previewable_refs: true)
    179         let attributedText: AttributedString = noteArtifactsSeparated.content.attributed
    180 
    181         let runs: AttributedString.Runs = attributedText.runs
    182         let runArray: [AttributedString.Runs.Run] = Array(runs)
    183         XCTAssertEqual(runArray.count, 12)
    184         XCTAssertTrue(runArray[0].description.contains("Check this out."))
    185         XCTAssertTrue(runArray[1].description.contains("https://nothidden1.tld/"))
    186         XCTAssertTrue(runArray[3].description.contains("https://nothidden2.tld/"))
    187         XCTAssertTrue(runArray[5].description.contains("https://damus.io/nothidden1.png"))
    188         XCTAssertTrue(runArray[7].description.contains("lnbc100n:qpsql29r"))
    189         XCTAssertTrue(runArray[9].description.contains("https://damus.io/nothidden2.png"))
    190         XCTAssertTrue(runArray[11].description.contains("note1qqq:qqn2l0z3"))
    191 
    192         XCTAssertEqual(noteArtifactsSeparated.images.count, 2)
    193         XCTAssertEqual(noteArtifactsSeparated.images[0].absoluteString, "https://damus.io/nothidden1.png")
    194         XCTAssertEqual(noteArtifactsSeparated.images[1].absoluteString, "https://damus.io/nothidden2.png")
    195 
    196         XCTAssertEqual(noteArtifactsSeparated.media.count, 2)
    197         XCTAssertEqual(noteArtifactsSeparated.media[0].url.absoluteString, "https://damus.io/nothidden1.png")
    198         XCTAssertEqual(noteArtifactsSeparated.media[1].url.absoluteString, "https://damus.io/nothidden2.png")
    199 
    200         XCTAssertEqual(noteArtifactsSeparated.links.count, 2)
    201         XCTAssertEqual(noteArtifactsSeparated.links[0].absoluteString, "https://nothidden1.tld/")
    202         XCTAssertEqual(noteArtifactsSeparated.links[1].absoluteString, "https://nothidden2.tld/")
    203 
    204         XCTAssertEqual(noteArtifactsSeparated.invoices.count, 1)
    205         XCTAssertEqual(noteArtifactsSeparated.invoices[0].string, invoiceString)
    206     }
    207 
    208     func testRenderBlocksWithMultipleEventsAtEndAreNotHidden() throws {
    209         let noteId = test_note.id.bech32
    210         let nevent = "nevent1qqstna2yrezu5wghjvswqqculvvwxsrcvu7uc0f78gan4xqhvz49d9spr3mhxue69uhkummnw3ez6un9d3shjtn4de6x2argwghx6egpr4mhxue69uhkummnw3ez6ur4vgh8wetvd3hhyer9wghxuet5nxnepm"
    211         let invoiceString = "lnbc100n1p357sl0sp5t9n56wdztun39lgdqlr30xqwksg3k69q4q2rkr52aplujw0esn0qpp5mrqgljk62z20q4nvgr6lzcyn6fhylzccwdvu4k77apg3zmrkujjqdpzw35xjueqd9ejqcfqv3jhxcmjd9c8g6t0dcxqyjw5qcqpjrzjqt56h4gvp5yx36u2uzqa6qwcsk3e2duunfxppzj9vhypc3wfe2wswz607uqq3xqqqsqqqqqqqqqqqlqqyg9qyysgqagx5h20aeulj3gdwx3kxs8u9f4mcakdkwuakasamm9562ffyr9en8yg20lg0ygnr9zpwp68524kmda0t5xp2wytex35pu8hapyjajxqpsql29r"
    212         let content = "    Check this out.   \nnostr:\(noteId)\nnostr:\(nevent)\nhttps://damus.io/nothidden1.png\n\(invoiceString)\nhttps://damus.io/nothidden2.png "
    213         let note = try XCTUnwrap(NostrEvent(content: content, keypair: test_keypair))
    214         let parsed: Blocks = parse_note_content(content: .init(note: note, keypair: test_keypair))
    215 
    216         let testState = test_damus_state
    217 
    218         let noteArtifactsSeparated: NoteArtifactsSeparated = render_blocks(blocks: parsed, profiles: testState.profiles, can_hide_last_previewable_refs: true)
    219         let attributedText: AttributedString = noteArtifactsSeparated.content.attributed
    220 
    221         let runs: AttributedString.Runs = attributedText.runs
    222         let runArray: [AttributedString.Runs.Run] = Array(runs)
    223         XCTAssertEqual(runArray.count, 10)
    224         XCTAssertTrue(runArray[0].description.contains("Check this out."))
    225         XCTAssertTrue(runArray[1].description.contains("note1qqq:qqn2l0z3"))
    226         XCTAssertTrue(runArray[3].description.contains("nevent1q:t5nxnepm"))
    227         XCTAssertTrue(runArray[5].description.contains("https://damus.io/nothidden1.png"))
    228         XCTAssertTrue(runArray[7].description.contains("lnbc100n:qpsql29r"))
    229         XCTAssertTrue(runArray[9].description.contains("https://damus.io/nothidden2.png"))
    230 
    231         XCTAssertEqual(noteArtifactsSeparated.images.count, 2)
    232         XCTAssertEqual(noteArtifactsSeparated.images[0].absoluteString, "https://damus.io/nothidden1.png")
    233         XCTAssertEqual(noteArtifactsSeparated.images[1].absoluteString, "https://damus.io/nothidden2.png")
    234 
    235         XCTAssertEqual(noteArtifactsSeparated.media.count, 2)
    236         XCTAssertEqual(noteArtifactsSeparated.media[0].url.absoluteString, "https://damus.io/nothidden1.png")
    237         XCTAssertEqual(noteArtifactsSeparated.media[1].url.absoluteString, "https://damus.io/nothidden2.png")
    238 
    239         XCTAssertEqual(noteArtifactsSeparated.links.count, 0)
    240 
    241         XCTAssertEqual(noteArtifactsSeparated.invoices.count, 1)
    242         XCTAssertEqual(noteArtifactsSeparated.invoices[0].string, invoiceString)
    243     }
    244 
    245     func testRenderBlocksWithPreviewableBlocksAtEndAreNotHiddenWhenMediaBlockPrecedesThem() throws {
    246         let content = "    Check this out: https://damus.io/image.png Isn't this cool?   \nhttps://damus.io/nothidden.png "
    247         let note = try XCTUnwrap(NostrEvent(content: content, keypair: test_keypair))
    248         let parsed: Blocks = parse_note_content(content: .init(note: note, keypair: test_keypair))
    249 
    250         let testState = test_damus_state
    251 
    252         let noteArtifactsSeparated: NoteArtifactsSeparated = render_blocks(blocks: parsed, profiles: testState.profiles, can_hide_last_previewable_refs: true)
    253         let attributedText: AttributedString = noteArtifactsSeparated.content.attributed
    254 
    255         let runs: AttributedString.Runs = attributedText.runs
    256         let runArray: [AttributedString.Runs.Run] = Array(runs)
    257         XCTAssertEqual(runArray.count, 4)
    258         XCTAssertTrue(runArray[0].description.contains("Check this out: "))
    259         XCTAssertTrue(runArray[1].description.contains("https://damus.io/image.png "))
    260         XCTAssertEqual(runArray[1].link?.absoluteString, "https://damus.io/image.png")
    261         XCTAssertTrue(runArray[2].description.contains(" Isn't this cool?"))
    262         XCTAssertTrue(runArray[3].description.contains("https://damus.io/nothidden.png"))
    263         XCTAssertEqual(runArray[3].link?.absoluteString, "https://damus.io/nothidden.png")
    264 
    265         XCTAssertEqual(noteArtifactsSeparated.images.count, 2)
    266         XCTAssertEqual(noteArtifactsSeparated.images[0].absoluteString, "https://damus.io/image.png")
    267         XCTAssertEqual(noteArtifactsSeparated.images[1].absoluteString, "https://damus.io/nothidden.png")
    268     }
    269 
    270     func testRenderBlocksWithPreviewableBlocksAtEndAreNotHiddenWhenInvoicePrecedesThem() throws {
    271         let invoiceString = "lnbc100n1p357sl0sp5t9n56wdztun39lgdqlr30xqwksg3k69q4q2rkr52aplujw0esn0qpp5mrqgljk62z20q4nvgr6lzcyn6fhylzccwdvu4k77apg3zmrkujjqdpzw35xjueqd9ejqcfqv3jhxcmjd9c8g6t0dcxqyjw5qcqpjrzjqt56h4gvp5yx36u2uzqa6qwcsk3e2duunfxppzj9vhypc3wfe2wswz607uqq3xqqqsqqqqqqqqqqqlqqyg9qyysgqagx5h20aeulj3gdwx3kxs8u9f4mcakdkwuakasamm9562ffyr9en8yg20lg0ygnr9zpwp68524kmda0t5xp2wytex35pu8hapyjajxqpsql29r"
    272         let content = "    Donations appreciated: \(invoiceString) Pura Vida   \nhttps://damus.io/nothidden.png "
    273         let note = try XCTUnwrap(NostrEvent(content: content, keypair: test_keypair))
    274         let parsed: Blocks = parse_note_content(content: .init(note: note, keypair: test_keypair))
    275 
    276         let testState = test_damus_state
    277 
    278         let noteArtifactsSeparated: NoteArtifactsSeparated = render_blocks(blocks: parsed, profiles: testState.profiles, can_hide_last_previewable_refs: true)
    279         let attributedText: AttributedString = noteArtifactsSeparated.content.attributed
    280 
    281         let runs: AttributedString.Runs = attributedText.runs
    282         let runArray: [AttributedString.Runs.Run] = Array(runs)
    283         XCTAssertEqual(runArray.count, 4)
    284         XCTAssertTrue(runArray[0].description.contains("Donations appreciated: "))
    285         XCTAssertTrue(runArray[1].description.contains("lnbc100n:qpsql29r"))
    286         XCTAssertEqual(runArray[1].link?.absoluteString, "damus:lightning:\(invoiceString)")
    287         XCTAssertTrue(runArray[2].description.contains(" Pura Vida"))
    288         XCTAssertTrue(runArray[3].description.contains("https://damus.io/nothidden.png"))
    289         XCTAssertEqual(runArray[3].link?.absoluteString, "https://damus.io/nothidden.png")
    290 
    291         XCTAssertEqual(noteArtifactsSeparated.images.count, 1)
    292         XCTAssertEqual(noteArtifactsSeparated.images[0].absoluteString, "https://damus.io/nothidden.png")
    293     }
    294 
    295     func testRenderBlocksWithPreviewableBlocksAtEndAreHiddenWhenHashtagsAreEmbedded() throws {
    296         let noteId = test_note.id.bech32
    297         let invoiceString = "lnbc100n1p357sl0sp5t9n56wdztun39lgdqlr30xqwksg3k69q4q2rkr52aplujw0esn0qpp5mrqgljk62z20q4nvgr6lzcyn6fhylzccwdvu4k77apg3zmrkujjqdpzw35xjueqd9ejqcfqv3jhxcmjd9c8g6t0dcxqyjw5qcqpjrzjqt56h4gvp5yx36u2uzqa6qwcsk3e2duunfxppzj9vhypc3wfe2wswz607uqq3xqqqsqqqqqqqqqqqlqqyg9qyysgqagx5h20aeulj3gdwx3kxs8u9f4mcakdkwuakasamm9562ffyr9en8yg20lg0ygnr9zpwp68524kmda0t5xp2wytex35pu8hapyjajxqpsql29r"
    298         let content = "    Check this out.   \nhttps://hidden.tld/\nhttps://damus.io/hidden1.png\n\(invoiceString)\nhttps://damus.io/hidden2.png\nnostr:\(noteId)#hashtag1 #hashtag2 "
    299         let note = try XCTUnwrap(NostrEvent(content: content, keypair: test_keypair))
    300         let parsed: Blocks = parse_note_content(content: .init(note: note, keypair: test_keypair))
    301 
    302         let testState = test_damus_state
    303 
    304         let noteArtifactsSeparated: NoteArtifactsSeparated = render_blocks(blocks: parsed, profiles: testState.profiles, can_hide_last_previewable_refs: true)
    305         let attributedText: AttributedString = noteArtifactsSeparated.content.attributed
    306 
    307         let runs: AttributedString.Runs = attributedText.runs
    308         let runArray: [AttributedString.Runs.Run] = Array(runs)
    309         XCTAssertEqual(runArray.count, 4)
    310         XCTAssertTrue(runArray[0].description.contains("Check this out."))
    311         XCTAssertFalse(runArray[0].description.contains("https://hidden.tld/"))
    312         XCTAssertFalse(runArray[0].description.contains("https://damus.io/hidden1.png"))
    313         XCTAssertFalse(runArray[0].description.contains("lnbc100n:qpsql29r"))
    314         XCTAssertFalse(runArray[0].description.contains("https://damus.io/hidden2.png"))
    315         XCTAssertFalse(runArray[0].description.contains("note1qqq:qqn2l0z3"))
    316         XCTAssertTrue(runArray[1].description.contains("#hashtag1"))
    317         XCTAssertTrue(runArray[3].description.contains("#hashtag2"))
    318 
    319         XCTAssertEqual(noteArtifactsSeparated.images.count, 2)
    320         XCTAssertEqual(noteArtifactsSeparated.images[0].absoluteString, "https://damus.io/hidden1.png")
    321         XCTAssertEqual(noteArtifactsSeparated.images[1].absoluteString, "https://damus.io/hidden2.png")
    322 
    323         XCTAssertEqual(noteArtifactsSeparated.media.count, 2)
    324         XCTAssertEqual(noteArtifactsSeparated.media[0].url.absoluteString, "https://damus.io/hidden1.png")
    325         XCTAssertEqual(noteArtifactsSeparated.media[1].url.absoluteString, "https://damus.io/hidden2.png")
    326 
    327         XCTAssertEqual(noteArtifactsSeparated.links.count, 1)
    328         XCTAssertEqual(noteArtifactsSeparated.links[0].absoluteString, "https://hidden.tld/")
    329 
    330         XCTAssertEqual(noteArtifactsSeparated.invoices.count, 1)
    331         XCTAssertEqual(noteArtifactsSeparated.invoices[0].string, invoiceString)
    332     }
    333      */
    334 
    335     /// Based on https://github.com/damus-io/damus/issues/1468
    336     /// Tests whether a note content view correctly parses an image block when url in JSON content contains optional escaped slashes
    337     func testParseImageBlockInContentWithEscapedSlashes() throws {
    338         let testJSONWithEscapedSlashes = "{\"tags\":[],\"pubkey\":\"f8e6c64342f1e052480630e27e1016dce35fc3a614e60434fef4aa2503328ca9\",\"content\":\"https:\\/\\/cdn.nostr.build\\/i\\/5c1d3296f66c2630131bf123106486aeaf051ed8466031c0e0532d70b33cddb2.jpg\",\"created_at\":1691864981,\"kind\":1,\"sig\":\"fc0033aa3d4df50b692a5b346fa816fdded698de2045e36e0642a021391468c44ca69c2471adc7e92088131872d4aaa1e90ea6e1ad97f3cc748f4aed96dfae18\",\"id\":\"e8f6eca3b161abba034dac9a02bb6930ecde9fd2fb5d6c5f22a05526e11382cb\"}"
    339         let testNote = NostrEvent.owned_from_json(json: testJSONWithEscapedSlashes)!
    340         let parsed = parse_note_content(content: .init(note: testNote, keypair: test_keypair))!
    341 
    342         XCTAssertTrue((parsed.blocks[0].asURL != nil), "NoteContentView does not correctly parse an image block when url in JSON content contains optional escaped slashes.")
    343     }
    344     
    345     /// Quick test that exercises the direct parsing methods (i.e. not fetching blocks from nostrdb) from `NdbBlockGroup`, and its bridging code with C.
    346     /// The parsing logic itself already has test coverage at the nostrdb level.
    347     func testDirectBlockParsing() {
    348         let kp = test_keypair_full
    349         let dm: NdbNote = NIP04.create_dm("Test", to_pk: kp.pubkey, tags: [], keypair: kp.to_keypair())!
    350         let blocks = try! NdbBlockGroup.from(event: dm, using: test_damus_state.ndb, and: kp.to_keypair())
    351         let blockCount1 = try? blocks.withList({ $0.count })
    352         XCTAssertEqual(blockCount1, 1)
    353         
    354         let post = NostrPost(content: "Test", kind: .text)
    355         let event = post.to_event(keypair: kp)!
    356         let blocks2 = try! NdbBlockGroup.from(event: event, using: test_damus_state.ndb, and: kp.to_keypair())
    357         let blockCount2 = try? blocks2.withList({ $0.count })
    358         XCTAssertEqual(blockCount2, 1)
    359     }
    360     
    361     func testMentionStr_Pubkey_ContainsAbbreviated() throws {
    362         let compatibleText = createCompatibleText(test_pubkey.npub)
    363         
    364         assertCompatibleTextHasExpectedString(compatibleText: compatibleText, expected: "17ldvg64:nq5mhr77")
    365     }
    366     
    367     func testMentionStr_Pubkey_ContainsFullBech32() {
    368         let compatableText = createCompatibleText(test_pubkey.npub)
    369 
    370         assertCompatibleTextHasExpectedString(compatibleText: compatableText, expected: test_pubkey.npub)
    371     }
    372     
    373     func testMentionStr_Nprofile_ContainsAbbreviated() throws {
    374         let compatibleText = createCompatibleText("nprofile1qqsrhuxx8l9ex335q7he0f09aej04zpazpl0ne2cgukyawd24mayt8gpp4mhxue69uhhytnc9e3k7mgpz4mhxue69uhkg6nzv9ejuumpv34kytnrdaksjlyr9p")
    375                 
    376         assertCompatibleTextHasExpectedString(compatibleText: compatibleText, expected: "180cvv07:wsyjh6w6")
    377     }
    378     
    379     func testMentionStr_Nprofile_ContainsFullBech32() throws {
    380         let bech = "nprofile1qqsrhuxx8l9ex335q7he0f09aej04zpazpl0ne2cgukyawd24mayt8gpp4mhxue69uhhytnc9e3k7mgpz4mhxue69uhkg6nzv9ejuumpv34kytnrdaksjlyr9p"
    381         let compatibleText = createCompatibleText(bech)
    382         
    383         assertCompatibleTextHasExpectedString(compatibleText: compatibleText, expected: bech)
    384     }
    385     
    386     func testMentionStr_Note_ContainsAbbreviated() {
    387         let compatibleText = createCompatibleText(test_note.id.bech32)
    388 
    389         assertCompatibleTextHasExpectedString(compatibleText: compatibleText, expected: "note1qqq:qqn2l0z3")
    390     }
    391     
    392     func testMentionStr_Note_ContainsFullBech32() {
    393         let compatibleText = createCompatibleText(test_note.id.bech32)
    394 
    395         assertCompatibleTextHasExpectedString(compatibleText: compatibleText, expected: test_note.id.bech32)
    396     }
    397     
    398     func testMentionStr_Nevent_ContainsAbbreviated() {
    399         let bech = "nevent1qqstna2yrezu5wghjvswqqculvvwxsrcvu7uc0f78gan4xqhvz49d9spr3mhxue69uhkummnw3ez6un9d3shjtn4de6x2argwghx6egpr4mhxue69uhkummnw3ez6ur4vgh8wetvd3hhyer9wghxuet5nxnepm"
    400         let compatibleText = createCompatibleText(bech)
    401 
    402         assertCompatibleTextHasExpectedString(compatibleText: compatibleText, expected: "nevent1q:t5nxnepm")
    403     }
    404     
    405     func testMentionStr_Nevent_ContainsFullBech32() throws {
    406         let bech = "nevent1qqstna2yrezu5wghjvswqqculvvwxsrcvu7uc0f78gan4xqhvz49d9spr3mhxue69uhkummnw3ez6un9d3shjtn4de6x2argwghx6egpr4mhxue69uhkummnw3ez6ur4vgh8wetvd3hhyer9wghxuet5nxnepm"
    407         let compatibleText = createCompatibleText(bech)
    408         
    409         assertCompatibleTextHasExpectedString(compatibleText: compatibleText, expected: bech)
    410     }
    411     
    412     func testMentionStr_Naddr_ContainsAbbreviated() {
    413         let bech = "naddr1qqxnzdesxqmnxvpexqunzvpcqyt8wumn8ghj7un9d3shjtnwdaehgu3wvfskueqzypve7elhmamff3sr5mgxxms4a0rppkmhmn7504h96pfcdkpplvl2jqcyqqq823cnmhuld"
    414         let compatibleText = createCompatibleText(bech)
    415         
    416         assertCompatibleTextHasExpectedString(compatibleText: compatibleText, expected: "naddr1qq:3cnmhuld")
    417     }
    418     
    419     func testMentionStr_Naddr_ContainsFullBech32() {
    420         let bech = "naddr1qqxnzdesxqmnxvpexqunzvpcqyt8wumn8ghj7un9d3shjtnwdaehgu3wvfskueqzypve7elhmamff3sr5mgxxms4a0rppkmhmn7504h96pfcdkpplvl2jqcyqqq823cnmhuld"
    421         let compatibleText = createCompatibleText(bech)
    422         
    423         assertCompatibleTextHasExpectedString(compatibleText: compatibleText, expected: bech)
    424     }
    425 
    426 }
    427 
    428 private func assertCompatibleTextHasExpectedString(compatibleText: CompatibleText, expected: String) {
    429     guard let hasExpected = compatibleText.items.first?.attributed_string()?.description.contains(expected) else {
    430         XCTFail()
    431         return
    432     }
    433     
    434     XCTAssertTrue(hasExpected)
    435 }
    436 
    437 private func createCompatibleText(_ bechString: String) -> CompatibleText {
    438     guard let mentionRef = Bech32Object.parse(bechString)?.toMentionRef() else {
    439         XCTFail("Failed to create MentionRef from Bech32 string")
    440         return CompatibleText()
    441     }
    442     return mention_str(.any(mentionRef), profiles: test_damus_state.profiles)
    443 }