markdown_test.go (12244B)
1 // GoToSocial 2 // Copyright (C) GoToSocial Authors admin@gotosocial.org 3 // SPDX-License-Identifier: AGPL-3.0-or-later 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package text_test 19 20 import ( 21 "testing" 22 23 "github.com/stretchr/testify/suite" 24 ) 25 26 var withCodeBlock = `# Title 27 28 Below is some JSON. 29 30 ` + "```" + `json 31 { 32 "key": "value", 33 "another_key": [ 34 "value1", 35 "value2" 36 ] 37 } 38 ` + "```" + ` 39 40 that was some JSON :) 41 ` 42 43 const ( 44 simpleMarkdown = "# Title\n\nHere's a simple text in markdown.\n\nHere's a [link](https://example.org)." 45 simpleMarkdownExpected = "<h1>Title</h1><p>Here's a simple text in markdown.</p><p>Here's a <a href=\"https://example.org\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">link</a>.</p>" 46 withCodeBlockExpected = "<h1>Title</h1><p>Below is some JSON.</p><pre><code class=\"language-json\">{\n "key": "value",\n "another_key": [\n "value1",\n "value2"\n ]\n}\n</code></pre><p>that was some JSON :)</p>" 47 withInlineCode = "`Nobody tells you about the <code><del>SECRET CODE</del></code>, do they?`" 48 withInlineCodeExpected = "<p><code>Nobody tells you about the <code><del>SECRET CODE</del></code>, do they?</code></p>" 49 withInlineCode2 = "`Nobody tells you about the </code><del>SECRET CODE</del><code>, do they?`" 50 withInlineCode2Expected = "<p><code>Nobody tells you about the </code><del>SECRET CODE</del><code>, do they?</code></p>" 51 withHashtag = "# Title\n\nhere's a simple status that uses hashtag #Hashtag!" 52 withHashtagExpected = "<h1>Title</h1><p>here's a simple status that uses hashtag <a href=\"http://localhost:8080/tags/Hashtag\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>Hashtag</span></a>!</p>" 53 mdWithHTML = "# Title\n\nHere's a simple text in markdown.\n\nHere's a <a href=\"https://example.org\">link</a>.\n\nHere's an image: <img src=\"https://gts.superseriousbusiness.org/assets/logo.png\" alt=\"The GoToSocial sloth logo.\" width=\"500\" height=\"600\">" 54 mdWithHTMLExpected = "<h1>Title</h1><p>Here's a simple text in markdown.</p><p>Here's a <a href=\"https://example.org\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">link</a>.</p><p>Here's an image: <img src=\"https://gts.superseriousbusiness.org/assets/logo.png\" alt=\"The GoToSocial sloth logo.\" width=\"500\" height=\"600\" crossorigin=\"anonymous\"></p>" 55 mdWithCheekyHTML = "# Title\n\nHere's a simple text in markdown.\n\nHere's a cheeky little script: <script>alert(ahhhh)</script>" 56 mdWithCheekyHTMLExpected = "<h1>Title</h1><p>Here's a simple text in markdown.</p><p>Here's a cheeky little script:</p>" 57 mdWithHashtagInitial = "#welcome #Hashtag" 58 mdWithHashtagInitialExpected = "<p><a href=\"http://localhost:8080/tags/welcome\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>welcome</span></a> <a href=\"http://localhost:8080/tags/Hashtag\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>Hashtag</span></a></p>" 59 mdCodeBlockWithNewlines = "some code coming up\n\n```\n\n\n\n```\nthat was some code" 60 mdCodeBlockWithNewlinesExpected = "<p>some code coming up</p><pre><code>\n\n\n</code></pre><p>that was some code</p>" 61 mdWithFootnote = "fox mulder,fbi.[^1]\n\n[^1]: federated bureau of investigation" 62 mdWithFootnoteExpected = "<p>fox mulder,fbi.[^1]</p><p>[^1]: federated bureau of investigation</p>" 63 mdWithBlockQuote = "get ready, there's a block quote coming:\n\n>line1\n>line2\n>\n>line3\n\n" 64 mdWithBlockQuoteExpected = "<p>get ready, there's a block quote coming:</p><blockquote><p>line1<br>line2</p><p>line3</p></blockquote>" 65 mdHashtagAndCodeBlock = "#Hashtag\n\n```\n#Hashtag\n```" 66 mdHashtagAndCodeBlockExpected = "<p><a href=\"http://localhost:8080/tags/Hashtag\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>Hashtag</span></a></p><pre><code>#Hashtag\n</code></pre>" 67 mdMentionAndCodeBlock = "@the_mighty_zork\n\n```\n@the_mighty_zork\n```" 68 mdMentionAndCodeBlockExpected = "<p><span class=\"h-card\"><a href=\"http://localhost:8080/@the_mighty_zork\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>the_mighty_zork</span></a></span></p><pre><code>@the_mighty_zork\n</code></pre>" 69 mdWithSmartypants = "\"you have to quargle the bleepflorp\" they said with 1/2 of nominal speed and 1/3 of the usual glumping" 70 mdWithSmartypantsExpected = "<p>\"you have to quargle the bleepflorp\" they said with 1/2 of nominal speed and 1/3 of the usual glumping</p>" 71 mdWithAsciiHeart = "hello <3 old friend <3 i loved u </3 :(( you stole my heart" 72 mdWithAsciiHeartExpected = "<p>hello <3 old friend <3 i loved u </3 :(( you stole my heart</p>" 73 mdWithStrikethrough = "I have ~~mdae~~ made an error" 74 mdWithStrikethroughExpected = "<p>I have <del>mdae</del> made an error</p>" 75 mdWithLink = "Check out this code, i heard it was written by a sloth https://github.com/superseriousbusiness/gotosocial" 76 mdWithLinkExpected = "<p>Check out this code, i heard it was written by a sloth <a href=\"https://github.com/superseriousbusiness/gotosocial\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">https://github.com/superseriousbusiness/gotosocial</a></p>" 77 mdObjectInCodeBlock = "@foss_satan@fossbros-anonymous.io this is how to mention a user\n```\n@the_mighty_zork hey bud! nice #ObjectOrientedProgramming software you've been writing lately! :rainbow:\n```\nhope that helps" 78 mdObjectInCodeBlockExpected = "<p><span class=\"h-card\"><a href=\"http://fossbros-anonymous.io/@foss_satan\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>foss_satan</span></a></span> this is how to mention a user</p><pre><code>@the_mighty_zork hey bud! nice #ObjectOrientedProgramming software you've been writing lately! :rainbow:\n</code></pre><p>hope that helps</p>" 79 mdItalicHashtag = "_#hashtag_" 80 mdItalicHashtagExpected = "<p><em><a href=\"http://localhost:8080/tags/Hashtag\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>hashtag</span></a></em></p>" 81 mdItalicHashtags = "_#hashtag #hashtag #hashtag_" 82 mdItalicHashtagsExpected = "<p><em><a href=\"http://localhost:8080/tags/Hashtag\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>hashtag</span></a> <a href=\"http://localhost:8080/tags/Hashtag\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>hashtag</span></a> <a href=\"http://localhost:8080/tags/Hashtag\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>hashtag</span></a></em></p>" 83 // BEWARE: sneaky unicode business going on. 84 // the first ö is one rune, the second ö is an o with a combining diacritic. 85 mdUnnormalizedHashtag = "#hellöthere #hellöthere" 86 mdUnnormalizedHashtagExpected = "<p><a href=\"http://localhost:8080/tags/hell%C3%B6there\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>hellöthere</span></a> <a href=\"http://localhost:8080/tags/hell%C3%B6there\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>hellöthere</span></a></p>" 87 ) 88 89 type MarkdownTestSuite struct { 90 TextStandardTestSuite 91 } 92 93 func (suite *MarkdownTestSuite) TestParseSimple() { 94 formatted := suite.FromMarkdown(simpleMarkdown) 95 suite.Equal(simpleMarkdownExpected, formatted.HTML) 96 } 97 98 func (suite *MarkdownTestSuite) TestParseWithCodeBlock() { 99 formatted := suite.FromMarkdown(withCodeBlock) 100 suite.Equal(withCodeBlockExpected, formatted.HTML) 101 } 102 103 func (suite *MarkdownTestSuite) TestParseWithInlineCode() { 104 formatted := suite.FromMarkdown(withInlineCode) 105 suite.Equal(withInlineCodeExpected, formatted.HTML) 106 } 107 108 func (suite *MarkdownTestSuite) TestParseWithInlineCode2() { 109 formatted := suite.FromMarkdown(withInlineCode2) 110 suite.Equal(withInlineCode2Expected, formatted.HTML) 111 } 112 113 func (suite *MarkdownTestSuite) TestParseWithHashtag() { 114 formatted := suite.FromMarkdown(withHashtag) 115 suite.Equal(withHashtagExpected, formatted.HTML) 116 } 117 118 func (suite *MarkdownTestSuite) TestParseWithHTML() { 119 formatted := suite.FromMarkdown(mdWithHTML) 120 suite.Equal(mdWithHTMLExpected, formatted.HTML) 121 } 122 123 func (suite *MarkdownTestSuite) TestParseWithCheekyHTML() { 124 formatted := suite.FromMarkdown(mdWithCheekyHTML) 125 suite.Equal(mdWithCheekyHTMLExpected, formatted.HTML) 126 } 127 128 func (suite *MarkdownTestSuite) TestParseWithHashtagInitial() { 129 formatted := suite.FromMarkdown(mdWithHashtagInitial) 130 suite.Equal(mdWithHashtagInitialExpected, formatted.HTML) 131 } 132 133 func (suite *MarkdownTestSuite) TestParseCodeBlockWithNewlines() { 134 formatted := suite.FromMarkdown(mdCodeBlockWithNewlines) 135 suite.Equal(mdCodeBlockWithNewlinesExpected, formatted.HTML) 136 } 137 138 func (suite *MarkdownTestSuite) TestParseWithFootnote() { 139 formatted := suite.FromMarkdown(mdWithFootnote) 140 suite.Equal(mdWithFootnoteExpected, formatted.HTML) 141 } 142 143 func (suite *MarkdownTestSuite) TestParseWithBlockquote() { 144 formatted := suite.FromMarkdown(mdWithBlockQuote) 145 suite.Equal(mdWithBlockQuoteExpected, formatted.HTML) 146 } 147 148 func (suite *MarkdownTestSuite) TestParseHashtagWithCodeBlock() { 149 formatted := suite.FromMarkdown(mdHashtagAndCodeBlock) 150 suite.Equal(mdHashtagAndCodeBlockExpected, formatted.HTML) 151 } 152 153 func (suite *MarkdownTestSuite) TestParseMentionWithCodeBlock() { 154 formatted := suite.FromMarkdown(mdMentionAndCodeBlock) 155 suite.Equal(mdMentionAndCodeBlockExpected, formatted.HTML) 156 } 157 158 func (suite *MarkdownTestSuite) TestParseSmartypants() { 159 formatted := suite.FromMarkdown(mdWithSmartypants) 160 suite.Equal(mdWithSmartypantsExpected, formatted.HTML) 161 } 162 163 func (suite *MarkdownTestSuite) TestParseAsciiHeart() { 164 formatted := suite.FromMarkdown(mdWithAsciiHeart) 165 suite.Equal(mdWithAsciiHeartExpected, formatted.HTML) 166 } 167 168 func (suite *MarkdownTestSuite) TestParseStrikethrough() { 169 formatted := suite.FromMarkdown(mdWithStrikethrough) 170 suite.Equal(mdWithStrikethroughExpected, formatted.HTML) 171 } 172 173 func (suite *MarkdownTestSuite) TestParseLink() { 174 formatted := suite.FromMarkdown(mdWithLink) 175 suite.Equal(mdWithLinkExpected, formatted.HTML) 176 } 177 178 func (suite *MarkdownTestSuite) TestParseObjectInCodeBlock() { 179 formatted := suite.FromMarkdown(mdObjectInCodeBlock) 180 suite.Equal(mdObjectInCodeBlockExpected, formatted.HTML) 181 suite.Len(formatted.Mentions, 1) 182 suite.Equal("@foss_satan@fossbros-anonymous.io", formatted.Mentions[0].NameString) 183 suite.Empty(formatted.Tags) 184 suite.Empty(formatted.Emojis) 185 } 186 187 func (suite *MarkdownTestSuite) TestParseItalicHashtag() { 188 formatted := suite.FromMarkdown(mdItalicHashtag) 189 suite.Equal(mdItalicHashtagExpected, formatted.HTML) 190 } 191 192 func (suite *MarkdownTestSuite) TestParseItalicHashtags() { 193 formatted := suite.FromMarkdown(mdItalicHashtags) 194 suite.Equal(mdItalicHashtagsExpected, formatted.HTML) 195 } 196 197 func (suite *MarkdownTestSuite) TestParseUnnormalizedHashtag() { 198 formatted := suite.FromMarkdown(mdUnnormalizedHashtag) 199 suite.Equal(mdUnnormalizedHashtagExpected, formatted.HTML) 200 } 201 202 func TestMarkdownTestSuite(t *testing.T) { 203 suite.Run(t, new(MarkdownTestSuite)) 204 }