import html import markdown import pytest from wiki.plugins.links.mdx.urlize import makeExtension from wiki.plugins.links.mdx.urlize import UrlizeExtension # Template accepts two strings - href value and link text value. EXPECTED_LINK_TEMPLATE = ( '' '' "" "" " %s" "" "" ) # Template accepts two strings - href value and link text value. EXPECTED_PARAGRAPH_TEMPLATE = "

%s

" % EXPECTED_LINK_TEMPLATE FIXTURE_POSITIVE_MATCHES = [ # Test surrounding begin/end characters. ( "(example.com)", "

(" + EXPECTED_LINK_TEMPLATE % ("http://example.com", "example.com") + ")

", ), ( "", "

<" + EXPECTED_LINK_TEMPLATE % ("http://example.com", "example.com") + ">

", ), # Test protocol specification. ( "http://example.com", EXPECTED_PARAGRAPH_TEMPLATE % ("http://example.com", "http://example.com"), ), ( "https://example.com", EXPECTED_PARAGRAPH_TEMPLATE % ("https://example.com", "https://example.com"), ), ( "ftp://example.com", EXPECTED_PARAGRAPH_TEMPLATE % ("ftp://example.com", "ftp://example.com"), ), ( "ftps://example.com", EXPECTED_PARAGRAPH_TEMPLATE % ("ftps://example.com", "ftps://example.com"), ), ( "example.com", EXPECTED_PARAGRAPH_TEMPLATE % ("http://example.com", "example.com"), ), ( "onion://example.com", EXPECTED_PARAGRAPH_TEMPLATE % ("onion://example.com", "onion://example.com"), ), ( "onion9+.-://example.com", EXPECTED_PARAGRAPH_TEMPLATE % ("onion9+.-://example.com", "onion9+.-://example.com"), ), # Test various supported host variations. ( "10.10.1.1", EXPECTED_PARAGRAPH_TEMPLATE % ("http://10.10.1.1", "10.10.1.1"), ), ( "1122:3344:5566:7788:9900:aabb:ccdd:eeff", EXPECTED_PARAGRAPH_TEMPLATE % ( "http://1122:3344:5566:7788:9900:aabb:ccdd:eeff", "1122:3344:5566:7788:9900:aabb:ccdd:eeff", ), ), ( "1122:3344:5566:7788:9900:AaBb:cCdD:EeFf", EXPECTED_PARAGRAPH_TEMPLATE % ( "http://1122:3344:5566:7788:9900:AaBb:cCdD:EeFf", "1122:3344:5566:7788:9900:AaBb:cCdD:EeFf", ), ), ("::1", EXPECTED_PARAGRAPH_TEMPLATE % ("http://::1", "::1")), ("1::2:3", EXPECTED_PARAGRAPH_TEMPLATE % ("http://1::2:3", "1::2:3")), ("1::", EXPECTED_PARAGRAPH_TEMPLATE % ("http://1::", "1::")), ("::", EXPECTED_PARAGRAPH_TEMPLATE % ("http://::", "::")), ( "example.com", EXPECTED_PARAGRAPH_TEMPLATE % ("http://example.com", "example.com"), ), ( "example.horse", EXPECTED_PARAGRAPH_TEMPLATE % ("http://example.horse", "example.horse"), ), ( "my.long.domain.example.com", EXPECTED_PARAGRAPH_TEMPLATE % ("http://my.long.domain.example.com", "my.long.domain.example.com"), ), # Test port section. ( "10.1.1.1:8000", EXPECTED_PARAGRAPH_TEMPLATE % ("http://10.1.1.1:8000", "10.1.1.1:8000"), ), # Test trailing path specification. ( "http://example.com/", EXPECTED_PARAGRAPH_TEMPLATE % ("http://example.com/", "http://example.com/"), ), ( "http://example.com/my/path", EXPECTED_PARAGRAPH_TEMPLATE % ("http://example.com/my/path", "http://example.com/my/path"), ), ( "http://example.com/my/path?param1=value1¶m2=value2", EXPECTED_PARAGRAPH_TEMPLATE % ( "http://example.com/my/path?param1=value1&param2=value2", "http://example.com/my/path?param1=value1&param2=value2", ), ), # Link positioned somewhere within the text, but around whitespace boundary. ( "This is link myhost.example.com", "

This is link " + EXPECTED_LINK_TEMPLATE % ("http://myhost.example.com", "myhost.example.com") + "

", ), ( "myhost.example.com is the link", "

" + EXPECTED_LINK_TEMPLATE % ("http://myhost.example.com", "myhost.example.com") + " is the link

", ), ( "I have best myhost.example.com link ever", "

I have best " + EXPECTED_LINK_TEMPLATE % ("http://myhost.example.com", "myhost.example.com") + " link ever

", ), ( "I have best\nmyhost.example.com link ever", "

I have best\n" + EXPECTED_LINK_TEMPLATE % ("http://myhost.example.com", "myhost.example.com") + " link ever

", ), ] FIXTURE_NEGATIVE_MATCHES = [ # localhost as part of another word. ("localhosts", "

localhosts

"), ("localhost", "

localhost

"), ("localhost:8000", "

localhost:8000

"), # Incomplete FQDNs. ("example.", "

example.

"), (".example .com", "

.example .com

"), # Invalid FQDNs. ("example-.com", "

example-.com

"), ("-example.com", "

-example.com

"), ("my.-example.com", "

my.-example.com

"), # Invalid IPv6 patterns. ( "1:2:3:4:5:6:7:8:a", # Use :a, because using a number would match as optional port "

1:2:3:4:5:6:7:8:a

", ), ( "1::2::3", "

1::2::3

", ), ( "::::1", "

::::1

", ), ( "1::::", "

1::::

", ), # Invalid IPv4 patterns. ( "1.2.3.4.5", "

1.2.3.4.5

", ), # Invalid protocols. ( "9onion://example.com", "

9onion://example.com

", ), ( "-onion://example.com", "

-onion://example.com

", ), ( "+onion://example.com", "

+onion://example.com

", ), ( ".onion://example.com", "

.onion://example.com

", ), ] class TestUrlizeExtension: def setup_method(self): self.md = markdown.Markdown(extensions=[UrlizeExtension()]) @pytest.mark.parametrize( "markdown_text, expected_output", FIXTURE_POSITIVE_MATCHES ) def test_positive_matches(self, markdown_text, expected_output): assert self.md.convert(markdown_text) == expected_output @pytest.mark.parametrize( "markdown_text, expected_output", FIXTURE_NEGATIVE_MATCHES ) def test_negative_matches(self, markdown_text, expected_output): assert self.md.convert(markdown_text) == expected_output def test_url_with_non_matching_begin_and_end_ignored(self): assert self.md.convert("(example.com>") == "

%s

" % html.escape( "(example.com>" ) assert self.md.convert("%s

" % html.escape( "(example.com" ) assert self.md.convert("example.com)") == "

%s

" % html.escape( "example.com)" ) assert self.md.convert("") == "

%s

" % html.escape( "example.com>" ) def test_makeExtension_return_value(): extension = makeExtension() assert isinstance(extension, UrlizeExtension)