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 }