2017-09-16 17:17:57 +00:00
// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package markup_test
import (
"strings"
"testing"
2020-04-28 18:05:39 +00:00
"code.gitea.io/gitea/modules/emoji"
2017-09-16 17:17:57 +00:00
. "code.gitea.io/gitea/modules/markup"
2018-02-27 07:09:18 +00:00
"code.gitea.io/gitea/modules/markup/markdown"
2017-09-16 17:17:57 +00:00
"code.gitea.io/gitea/modules/setting"
2018-02-20 12:50:42 +00:00
"code.gitea.io/gitea/modules/util"
2017-09-16 17:17:57 +00:00
"github.com/stretchr/testify/assert"
)
2019-04-16 07:53:57 +00:00
var localMetas = map [ string ] string {
2019-08-14 08:04:55 +00:00
"user" : "gogits" ,
"repo" : "gogs" ,
"repoPath" : "../../integrations/gitea-repositories-meta/user13/repo11.git/" ,
2019-04-16 07:53:57 +00:00
}
2017-09-16 17:17:57 +00:00
func TestRender_Commits ( t * testing . T ) {
setting . AppURL = AppURL
setting . AppSubURL = AppSubURL
test := func ( input , expected string ) {
2019-04-16 07:53:57 +00:00
buffer := RenderString ( ".md" , input , setting . AppSubURL , localMetas )
2019-07-23 18:50:39 +00:00
assert . Equal ( t , strings . TrimSpace ( expected ) , strings . TrimSpace ( buffer ) )
2017-09-16 17:17:57 +00:00
}
2019-08-14 08:04:55 +00:00
var sha = "65f1bf27bc3bf70f64657658635e66094edbcb4d"
2018-02-20 12:50:42 +00:00
var commit = util . URLJoin ( AppSubURL , "commit" , sha )
var subtree = util . URLJoin ( commit , "src" )
2017-09-16 17:17:57 +00:00
var tree = strings . Replace ( subtree , "/commit/" , "/tree/" , - 1 )
2019-08-14 08:04:55 +00:00
test ( sha , ` <p><a href=" ` + commit + ` " rel="nofollow"><code>65f1bf27bc</code></a></p> ` )
test ( sha [ : 7 ] , ` <p><a href=" ` + commit [ : len ( commit ) - ( 40 - 7 ) ] + ` " rel="nofollow"><code>65f1bf2</code></a></p> ` )
test ( sha [ : 39 ] , ` <p><a href=" ` + commit [ : len ( commit ) - ( 40 - 39 ) ] + ` " rel="nofollow"><code>65f1bf27bc</code></a></p> ` )
test ( commit , ` <p><a href=" ` + commit + ` " rel="nofollow"><code>65f1bf27bc</code></a></p> ` )
test ( tree , ` <p><a href=" ` + tree + ` " rel="nofollow"><code>65f1bf27bc/src</code></a></p> ` )
test ( "commit " + sha , ` <p>commit <a href=" ` + commit + ` " rel="nofollow"><code>65f1bf27bc</code></a></p> ` )
2019-04-07 11:18:16 +00:00
test ( "/home/gitea/" + sha , "<p>/home/gitea/" + sha + "</p>" )
2019-08-14 08:04:55 +00:00
test ( "deadbeef" , ` <p>deadbeef</p> ` )
test ( "d27ace93" , ` <p>d27ace93</p> ` )
2017-09-16 17:17:57 +00:00
}
func TestRender_CrossReferences ( t * testing . T ) {
setting . AppURL = AppURL
setting . AppSubURL = AppSubURL
test := func ( input , expected string ) {
2019-04-16 07:53:57 +00:00
buffer := RenderString ( "a.md" , input , setting . AppSubURL , localMetas )
2019-07-23 18:50:39 +00:00
assert . Equal ( t , strings . TrimSpace ( expected ) , strings . TrimSpace ( buffer ) )
2017-09-16 17:17:57 +00:00
}
test (
"gogits/gogs#12345" ,
2020-01-20 04:39:21 +00:00
` <p><a href=" ` + util . URLJoin ( AppURL , "gogits" , "gogs" , "issues" , "12345" ) + ` " class="ref-issue" rel="nofollow">gogits/gogs#12345</a></p> ` )
2018-01-27 12:33:32 +00:00
test (
"go-gitea/gitea#12345" ,
2020-01-20 04:39:21 +00:00
` <p><a href=" ` + util . URLJoin ( AppURL , "go-gitea" , "gitea" , "issues" , "12345" ) + ` " class="ref-issue" rel="nofollow">go-gitea/gitea#12345</a></p> ` )
2019-04-07 11:18:16 +00:00
test (
"/home/gitea/go-gitea/gitea#12345" ,
` <p>/home/gitea/go-gitea/gitea#12345</p> ` )
2017-09-16 17:17:57 +00:00
}
func TestMisc_IsSameDomain ( t * testing . T ) {
setting . AppURL = AppURL
setting . AppSubURL = AppSubURL
var sha = "b6dd6210eaebc915fd5be5579c58cce4da2e2579"
2018-02-20 12:50:42 +00:00
var commit = util . URLJoin ( AppSubURL , "commit" , sha )
2017-09-16 17:17:57 +00:00
assert . True ( t , IsSameDomain ( commit ) )
assert . False ( t , IsSameDomain ( "http://google.com/ncr" ) )
assert . False ( t , IsSameDomain ( "favicon.ico" ) )
}
2018-02-27 07:09:18 +00:00
2019-02-28 12:31:53 +00:00
func TestRender_links ( t * testing . T ) {
setting . AppURL = AppURL
setting . AppSubURL = AppSubURL
test := func ( input , expected string ) {
buffer := RenderString ( "a.md" , input , setting . AppSubURL , nil )
2019-07-23 18:50:39 +00:00
assert . Equal ( t , strings . TrimSpace ( expected ) , strings . TrimSpace ( buffer ) )
2019-02-28 12:31:53 +00:00
}
// Text that should be turned into URL
2019-10-15 01:31:09 +00:00
defaultCustom := setting . Markdown . CustomURLSchemes
setting . Markdown . CustomURLSchemes = [ ] string { "ftp" , "magnet" }
ReplaceSanitizer ( )
CustomLinkURLSchemes ( setting . Markdown . CustomURLSchemes )
2019-02-28 12:31:53 +00:00
test (
"https://www.example.com" ,
` <p><a href="https://www.example.com" rel="nofollow">https://www.example.com</a></p> ` )
test (
"http://www.example.com" ,
` <p><a href="http://www.example.com" rel="nofollow">http://www.example.com</a></p> ` )
test (
"https://example.com" ,
` <p><a href="https://example.com" rel="nofollow">https://example.com</a></p> ` )
test (
"http://example.com" ,
` <p><a href="http://example.com" rel="nofollow">http://example.com</a></p> ` )
test (
"http://foo.com/blah_blah" ,
` <p><a href="http://foo.com/blah_blah" rel="nofollow">http://foo.com/blah_blah</a></p> ` )
test (
"http://foo.com/blah_blah/" ,
` <p><a href="http://foo.com/blah_blah/" rel="nofollow">http://foo.com/blah_blah/</a></p> ` )
test (
"http://www.example.com/wpstyle/?p=364" ,
` <p><a href="http://www.example.com/wpstyle/?p=364" rel="nofollow">http://www.example.com/wpstyle/?p=364</a></p> ` )
test (
"https://www.example.com/foo/?bar=baz&inga=42&quux" ,
2020-04-07 20:08:47 +00:00
` <p><a href="https://www.example.com/foo/?bar=baz&inga=42&quux=" rel="nofollow">https://www.example.com/foo/?bar=baz&inga=42&quux</a></p> ` )
2019-02-28 12:31:53 +00:00
test (
"http://142.42.1.1/" ,
` <p><a href="http://142.42.1.1/" rel="nofollow">http://142.42.1.1/</a></p> ` )
2019-03-07 20:12:01 +00:00
test (
"https://github.com/go-gitea/gitea/?p=aaa/bbb.html#ccc-ddd" ,
2020-04-07 20:08:47 +00:00
` <p><a href="https://github.com/go-gitea/gitea/?p=aaa%2Fbbb.html#ccc-ddd" rel="nofollow">https://github.com/go-gitea/gitea/?p=aaa/bbb.html#ccc-ddd</a></p> ` )
2019-03-07 20:12:01 +00:00
test (
"https://en.wikipedia.org/wiki/URL_(disambiguation)" ,
` <p><a href="https://en.wikipedia.org/wiki/URL_(disambiguation)" rel="nofollow">https://en.wikipedia.org/wiki/URL_(disambiguation)</a></p> ` )
test (
"https://foo_bar.example.com/" ,
` <p><a href="https://foo_bar.example.com/" rel="nofollow">https://foo_bar.example.com/</a></p> ` )
2019-03-27 15:37:54 +00:00
test (
"https://stackoverflow.com/questions/2896191/what-is-go-used-fore" ,
` <p><a href="https://stackoverflow.com/questions/2896191/what-is-go-used-fore" rel="nofollow">https://stackoverflow.com/questions/2896191/what-is-go-used-fore</a></p> ` )
test (
"https://username:password@gitea.com" ,
` <p><a href="https://username:password@gitea.com" rel="nofollow">https://username:password@gitea.com</a></p> ` )
2019-10-15 01:31:09 +00:00
test (
"ftp://gitea.com/file.txt" ,
` <p><a href="ftp://gitea.com/file.txt" rel="nofollow">ftp://gitea.com/file.txt</a></p> ` )
test (
"magnet:?xt=urn:btih:5dee65101db281ac9c46344cd6b175cdcadabcde&dn=download" ,
2020-04-07 20:08:47 +00:00
` <p><a href="magnet:?dn=download&xt=urn%3Abtih%3A5dee65101db281ac9c46344cd6b175cdcadabcde" rel="nofollow">magnet:?xt=urn:btih:5dee65101db281ac9c46344cd6b175cdcadabcde&dn=download</a></p> ` )
2019-02-28 12:31:53 +00:00
// Test that should *not* be turned into URL
test (
"www.example.com" ,
` <p>www.example.com</p> ` )
test (
"example.com" ,
` <p>example.com</p> ` )
test (
"test.example.com" ,
` <p>test.example.com</p> ` )
test (
"http://" ,
` <p>http://</p> ` )
test (
"https://" ,
` <p>https://</p> ` )
test (
"://" ,
` <p>://</p> ` )
test (
"www" ,
` <p>www</p> ` )
2019-10-15 01:31:09 +00:00
test (
"ftps://gitea.com" ,
` <p>ftps://gitea.com</p> ` )
// Restore previous settings
setting . Markdown . CustomURLSchemes = defaultCustom
ReplaceSanitizer ( )
CustomLinkURLSchemes ( setting . Markdown . CustomURLSchemes )
2019-02-28 12:31:53 +00:00
}
2019-04-07 11:18:16 +00:00
func TestRender_email ( t * testing . T ) {
setting . AppURL = AppURL
setting . AppSubURL = AppSubURL
test := func ( input , expected string ) {
buffer := RenderString ( "a.md" , input , setting . AppSubURL , nil )
2019-07-23 18:50:39 +00:00
assert . Equal ( t , strings . TrimSpace ( expected ) , strings . TrimSpace ( buffer ) )
2019-04-07 11:18:16 +00:00
}
// Text that should be turned into email link
test (
"info@gitea.com" ,
` <p><a href="mailto:info@gitea.com" rel="nofollow">info@gitea.com</a></p> ` )
test (
"(info@gitea.com)" ,
` <p>(<a href="mailto:info@gitea.com" rel="nofollow">info@gitea.com</a>)</p> ` )
test (
"[info@gitea.com]" ,
` <p>[<a href="mailto:info@gitea.com" rel="nofollow">info@gitea.com</a>]</p> ` )
test (
"info@gitea.com." ,
` <p><a href="mailto:info@gitea.com" rel="nofollow">info@gitea.com</a>.</p> ` )
2019-04-25 01:53:42 +00:00
test (
"firstname+lastname@gitea.com" ,
` <p><a href="mailto:firstname+lastname@gitea.com" rel="nofollow">firstname+lastname@gitea.com</a></p> ` )
2019-04-07 11:18:16 +00:00
test (
"send email to info@gitea.co.uk." ,
` <p>send email to <a href="mailto:info@gitea.co.uk" rel="nofollow">info@gitea.co.uk</a>.</p> ` )
// Test that should *not* be turned into email links
test (
"\"info@gitea.com\"" ,
` <p>“info@gitea.com”</p> ` )
test (
"/home/gitea/mailstore/info@gitea/com" ,
` <p>/home/gitea/mailstore/info@gitea/com</p> ` )
test (
"git@try.gitea.io:go-gitea/gitea.git" ,
` <p>git@try.gitea.io:go-gitea/gitea.git</p> ` )
2019-04-25 01:53:42 +00:00
test (
"gitea@3" ,
` <p>gitea@3</p> ` )
test (
"gitea@gmail.c" ,
` <p>gitea@gmail.c</p> ` )
test (
"email@domain@domain.com" ,
` <p>email@domain@domain.com</p> ` )
test (
"email@domain..com" ,
` <p>email@domain..com</p> ` )
2019-04-07 11:18:16 +00:00
}
2020-04-28 18:05:39 +00:00
func TestRender_emoji ( t * testing . T ) {
setting . AppURL = AppURL
setting . AppSubURL = AppSubURL
setting . StaticURLPrefix = AppURL
test := func ( input , expected string ) {
expected = strings . Replace ( expected , "&" , "&" , - 1 )
buffer := RenderString ( "a.md" , input , setting . AppSubURL , nil )
assert . Equal ( t , strings . TrimSpace ( expected ) , strings . TrimSpace ( buffer ) )
}
// Make sure we can successfully match every emoji in our dataset with regex
for i := range emoji . GemojiData {
test (
emoji . GemojiData [ i ] . Emoji ,
` <p><span class="emoji" aria-label=" ` + emoji . GemojiData [ i ] . Description + ` "> ` + emoji . GemojiData [ i ] . Emoji + ` </span></p> ` )
}
for i := range emoji . GemojiData {
test (
":" + emoji . GemojiData [ i ] . Aliases [ 0 ] + ":" ,
` <p><span class="emoji" aria-label=" ` + emoji . GemojiData [ i ] . Description + ` "> ` + emoji . GemojiData [ i ] . Emoji + ` </span></p> ` )
}
//Text that should be turned into or recognized as emoji
test (
":gitea:" ,
` <p><span class="emoji" aria-label="gitea"><img src=" ` + setting . StaticURLPrefix + ` /img/emoji/gitea.png"/></span></p> ` )
test (
"Some text with 😄 in the middle" ,
` <p>Some text with <span class="emoji" aria-label="grinning face with smiling eyes">😄</span> in the middle</p> ` )
test (
"Some text with :smile: in the middle" ,
` <p>Some text with <span class="emoji" aria-label="grinning face with smiling eyes">😄</span> in the middle</p> ` )
2020-05-29 16:08:36 +00:00
test (
"Some text with 😄😄 2 emoji next to each other" ,
` <p>Some text with <span class="emoji" aria-label="grinning face with smiling eyes">😄</span><span class="emoji" aria-label="grinning face with smiling eyes">😄</span> 2 emoji next to each other</p> ` )
2020-04-28 18:05:39 +00:00
// should match nothing
test (
"2001:0db8:85a3:0000:0000:8a2e:0370:7334" ,
` <p>2001:0db8:85a3:0000:0000:8a2e:0370:7334</p> ` )
test (
":not exist:" ,
` <p>:not exist:</p> ` )
}
2018-02-27 07:09:18 +00:00
func TestRender_ShortLinks ( t * testing . T ) {
setting . AppURL = AppURL
setting . AppSubURL = AppSubURL
tree := util . URLJoin ( AppSubURL , "src" , "master" )
test := func ( input , expected , expectedWiki string ) {
buffer := markdown . RenderString ( input , tree , nil )
2019-07-23 18:50:39 +00:00
assert . Equal ( t , strings . TrimSpace ( expected ) , strings . TrimSpace ( buffer ) )
2019-04-16 07:53:57 +00:00
buffer = markdown . RenderWiki ( [ ] byte ( input ) , setting . AppSubURL , localMetas )
2019-07-23 18:50:39 +00:00
assert . Equal ( t , strings . TrimSpace ( expectedWiki ) , strings . TrimSpace ( buffer ) )
2018-02-27 07:09:18 +00:00
}
rawtree := util . URLJoin ( AppSubURL , "raw" , "master" )
url := util . URLJoin ( tree , "Link" )
2018-03-05 18:39:12 +00:00
otherURL := util . URLJoin ( tree , "Other-Link" )
2018-06-15 12:42:49 +00:00
encodedURL := util . URLJoin ( tree , "Link%3F" )
2018-02-27 07:09:18 +00:00
imgurl := util . URLJoin ( rawtree , "Link.jpg" )
2018-03-05 18:39:12 +00:00
otherImgurl := util . URLJoin ( rawtree , "Link+Other.jpg" )
2018-06-15 12:42:49 +00:00
encodedImgurl := util . URLJoin ( rawtree , "Link+%23.jpg" )
notencodedImgurl := util . URLJoin ( rawtree , "some" , "path" , "Link+#.jpg" )
2018-02-27 07:09:18 +00:00
urlWiki := util . URLJoin ( AppSubURL , "wiki" , "Link" )
2018-03-05 18:39:12 +00:00
otherURLWiki := util . URLJoin ( AppSubURL , "wiki" , "Other-Link" )
2018-06-15 12:42:49 +00:00
encodedURLWiki := util . URLJoin ( AppSubURL , "wiki" , "Link%3F" )
2018-02-27 07:09:18 +00:00
imgurlWiki := util . URLJoin ( AppSubURL , "wiki" , "raw" , "Link.jpg" )
2018-03-05 18:39:12 +00:00
otherImgurlWiki := util . URLJoin ( AppSubURL , "wiki" , "raw" , "Link+Other.jpg" )
2018-06-15 12:42:49 +00:00
encodedImgurlWiki := util . URLJoin ( AppSubURL , "wiki" , "raw" , "Link+%23.jpg" )
notencodedImgurlWiki := util . URLJoin ( AppSubURL , "wiki" , "raw" , "some" , "path" , "Link+#.jpg" )
2018-02-27 07:09:18 +00:00
favicon := "http://google.com/favicon.ico"
test (
"[[Link]]" ,
` <p><a href=" ` + url + ` " rel="nofollow">Link</a></p> ` ,
` <p><a href=" ` + urlWiki + ` " rel="nofollow">Link</a></p> ` )
test (
"[[Link.jpg]]" ,
` <p><a href=" ` + imgurl + ` " rel="nofollow"><img src=" ` + imgurl + ` " title="Link.jpg" alt="Link.jpg"/></a></p> ` ,
` <p><a href=" ` + imgurlWiki + ` " rel="nofollow"><img src=" ` + imgurlWiki + ` " title="Link.jpg" alt="Link.jpg"/></a></p> ` )
test (
"[[" + favicon + "]]" ,
2020-02-28 20:05:12 +00:00
` <p><a href=" ` + favicon + ` " rel="nofollow"><img src=" ` + favicon + ` " title="favicon.ico" alt=" ` + favicon + ` "/></a></p> ` ,
` <p><a href=" ` + favicon + ` " rel="nofollow"><img src=" ` + favicon + ` " title="favicon.ico" alt=" ` + favicon + ` "/></a></p> ` )
2018-02-27 07:09:18 +00:00
test (
"[[Name|Link]]" ,
` <p><a href=" ` + url + ` " rel="nofollow">Name</a></p> ` ,
` <p><a href=" ` + urlWiki + ` " rel="nofollow">Name</a></p> ` )
test (
"[[Name|Link.jpg]]" ,
` <p><a href=" ` + imgurl + ` " rel="nofollow"><img src=" ` + imgurl + ` " title="Name" alt="Name"/></a></p> ` ,
` <p><a href=" ` + imgurlWiki + ` " rel="nofollow"><img src=" ` + imgurlWiki + ` " title="Name" alt="Name"/></a></p> ` )
test (
"[[Name|Link.jpg|alt=AltName]]" ,
` <p><a href=" ` + imgurl + ` " rel="nofollow"><img src=" ` + imgurl + ` " title="AltName" alt="AltName"/></a></p> ` ,
` <p><a href=" ` + imgurlWiki + ` " rel="nofollow"><img src=" ` + imgurlWiki + ` " title="AltName" alt="AltName"/></a></p> ` )
test (
"[[Name|Link.jpg|title=Title]]" ,
` <p><a href=" ` + imgurl + ` " rel="nofollow"><img src=" ` + imgurl + ` " title="Title" alt="Title"/></a></p> ` ,
` <p><a href=" ` + imgurlWiki + ` " rel="nofollow"><img src=" ` + imgurlWiki + ` " title="Title" alt="Title"/></a></p> ` )
test (
"[[Name|Link.jpg|alt=AltName|title=Title]]" ,
` <p><a href=" ` + imgurl + ` " rel="nofollow"><img src=" ` + imgurl + ` " title="Title" alt="AltName"/></a></p> ` ,
` <p><a href=" ` + imgurlWiki + ` " rel="nofollow"><img src=" ` + imgurlWiki + ` " title="Title" alt="AltName"/></a></p> ` )
test (
"[[Name|Link.jpg|alt=\"AltName\"|title='Title']]" ,
` <p><a href=" ` + imgurl + ` " rel="nofollow"><img src=" ` + imgurl + ` " title="Title" alt="AltName"/></a></p> ` ,
` <p><a href=" ` + imgurlWiki + ` " rel="nofollow"><img src=" ` + imgurlWiki + ` " title="Title" alt="AltName"/></a></p> ` )
test (
2018-03-05 18:39:12 +00:00
"[[Name|Link Other.jpg|alt=\"AltName\"|title='Title']]" ,
` <p><a href=" ` + otherImgurl + ` " rel="nofollow"><img src=" ` + otherImgurl + ` " title="Title" alt="AltName"/></a></p> ` ,
` <p><a href=" ` + otherImgurlWiki + ` " rel="nofollow"><img src=" ` + otherImgurlWiki + ` " title="Title" alt="AltName"/></a></p> ` )
test (
"[[Link]] [[Other Link]]" ,
` <p><a href=" ` + url + ` " rel="nofollow">Link</a> <a href=" ` + otherURL + ` " rel="nofollow">Other Link</a></p> ` ,
` <p><a href=" ` + urlWiki + ` " rel="nofollow">Link</a> <a href=" ` + otherURLWiki + ` " rel="nofollow">Other Link</a></p> ` )
2018-06-15 12:42:49 +00:00
test (
"[[Link?]]" ,
` <p><a href=" ` + encodedURL + ` " rel="nofollow">Link?</a></p> ` ,
` <p><a href=" ` + encodedURLWiki + ` " rel="nofollow">Link?</a></p> ` )
test (
"[[Link]] [[Other Link]] [[Link?]]" ,
` <p><a href=" ` + url + ` " rel="nofollow">Link</a> <a href=" ` + otherURL + ` " rel="nofollow">Other Link</a> <a href=" ` + encodedURL + ` " rel="nofollow">Link?</a></p> ` ,
` <p><a href=" ` + urlWiki + ` " rel="nofollow">Link</a> <a href=" ` + otherURLWiki + ` " rel="nofollow">Other Link</a> <a href=" ` + encodedURLWiki + ` " rel="nofollow">Link?</a></p> ` )
test (
"[[Link #.jpg]]" ,
2020-02-28 20:05:12 +00:00
` <p><a href=" ` + encodedImgurl + ` " rel="nofollow"><img src=" ` + encodedImgurl + ` " title="Link #.jpg" alt="Link #.jpg"/></a></p> ` ,
` <p><a href=" ` + encodedImgurlWiki + ` " rel="nofollow"><img src=" ` + encodedImgurlWiki + ` " title="Link #.jpg" alt="Link #.jpg"/></a></p> ` )
2018-06-15 12:42:49 +00:00
test (
"[[Name|Link #.jpg|alt=\"AltName\"|title='Title']]" ,
` <p><a href=" ` + encodedImgurl + ` " rel="nofollow"><img src=" ` + encodedImgurl + ` " title="Title" alt="AltName"/></a></p> ` ,
` <p><a href=" ` + encodedImgurlWiki + ` " rel="nofollow"><img src=" ` + encodedImgurlWiki + ` " title="Title" alt="AltName"/></a></p> ` )
test (
"[[some/path/Link #.jpg]]" ,
2020-02-28 20:05:12 +00:00
` <p><a href=" ` + notencodedImgurl + ` " rel="nofollow"><img src=" ` + notencodedImgurl + ` " title="Link #.jpg" alt="some/path/Link #.jpg"/></a></p> ` ,
` <p><a href=" ` + notencodedImgurlWiki + ` " rel="nofollow"><img src=" ` + notencodedImgurlWiki + ` " title="Link #.jpg" alt="some/path/Link #.jpg"/></a></p> ` )
2019-03-07 19:13:44 +00:00
test (
"<p><a href=\"https://example.org\">[[foobar]]</a></p>" ,
2019-12-31 01:53:28 +00:00
` <p><a href="https://example.org" rel="nofollow">[[foobar]]</a></p> ` ,
` <p><a href="https://example.org" rel="nofollow">[[foobar]]</a></p> ` )
2018-02-27 07:09:18 +00:00
}