defmodule LinkifyTest do
use ExUnit.Case, async: true
doctest Linkify
test "default link" do
assert Linkify.link("google.com") ==
"google.com"
end
test "default link iodata" do
assert Linkify.link_to_iodata("google.com") ==
[["", "google.com", ""]]
end
test "default link safe iodata" do
assert Linkify.link_safe("google.com") ==
[
[
{:safe, [""]},
"google.com",
{:safe, ""}
]
]
end
test "does on link existing links" do
text = ~s(google.com)
assert Linkify.link(text) == text
end
test "all kinds of links" do
text = "hello google.com https://ddg.com user@email.com irc:///mIRC"
expected =
"hello google.com https://ddg.com user@email.com irc:///mIRC"
assert Linkify.link(text,
email: true,
extra: true
) == expected
end
test "all kinds of links iodata" do
text = "hello google.com https://ddg.com user@email.com irc:///mIRC"
expected = [
"hello",
" ",
["", "google.com", ""],
" ",
["", "https://ddg.com", ""],
" ",
["", "user@email.com", ""],
" ",
["", "irc:///mIRC", ""]
]
assert Linkify.link_to_iodata(text,
email: true,
extra: true
) == expected
end
test "class attribute" do
assert Linkify.link("google.com", class: "linkified") ==
"google.com"
end
test "class attribute iodata" do
assert Linkify.link_to_iodata("google.com", class: "linkified") ==
[
[
"",
"google.com",
""
]
]
end
test "rel attribute" do
assert Linkify.link("google.com", rel: "noopener noreferrer") ==
"google.com"
end
test "rel attribute iodata" do
assert Linkify.link_to_iodata("google.com", rel: "noopener noreferrer") ==
[
[
"",
"google.com",
""
]
]
end
test "rel as function" do
text = "google.com"
expected = "google.com"
custom_rel = fn url ->
url |> String.split(".") |> List.last()
end
assert Linkify.link(text, rel: custom_rel) == expected
text = "google.com"
expected = "google.com"
custom_rel = fn _ -> nil end
assert Linkify.link(text, rel: custom_rel) == expected
end
test "strip parens" do
assert Linkify.link("(google.com)") ==
"(google.com)"
end
test "strip parens iodata" do
assert Linkify.link_to_iodata("(google.com)") ==
[["(", ["", "google.com", ""], ")"]]
end
test "link_map/2" do
assert Linkify.link_map("google.com", []) ==
{"google.com", []}
end
describe "custom handlers" do
test "mentions handler" do
text = "hello @user, @valid_user and @invalid_user"
valid_users = ["user", "valid_user"]
handler = fn "@" <> user = mention, buffer, _opts, acc ->
if Enum.member?(valid_users, user) do
link = ~s(#{mention})
{link, %{acc | mentions: MapSet.put(acc.mentions, {mention, user})}}
else
{buffer, acc}
end
end
{result_text, %{mentions: mentions}} =
Linkify.link_map(text, %{mentions: MapSet.new()},
mention: true,
mention_handler: handler
)
assert result_text ==
"hello @user, @valid_user and @invalid_user"
assert mentions |> MapSet.to_list() |> Enum.map(&elem(&1, 1)) == valid_users
end
test "hashtags handler" do
text = "#hello #world"
handler = fn hashtag, buffer, opts, acc ->
link = Linkify.Builder.create_hashtag_link(hashtag, buffer, opts)
{link, %{acc | tags: MapSet.put(acc.tags, hashtag)}}
end
{result_text, %{tags: tags}} =
Linkify.link_map(text, %{tags: MapSet.new()},
hashtag: true,
hashtag_handler: handler,
hashtag_prefix: "https://example.com/user/",
rel: false
)
assert result_text ==
"#hello #world"
assert MapSet.to_list(tags) == ["#hello", "#world"]
text = "#cofe
Source"
{_result_text, %{tags: tags}} =
Linkify.link_map(text, %{tags: MapSet.new()},
hashtag: true,
hashtag_handler: handler,
hashtag_prefix: "https://example.com/tag/"
)
assert MapSet.to_list(tags) == ["#cofe"]
text = "#cofe
Source"
{_result_text, %{tags: tags}} =
Linkify.link_map(text, %{tags: MapSet.new()},
hashtag: true,
hashtag_handler: handler,
hashtag_prefix: "https://example.com/tag/"
)
assert MapSet.to_list(tags) == ["#cofe"]
text = "#cofeSource"
{_result_text, %{tags: tags}} =
Linkify.link_map(text, %{tags: MapSet.new()},
hashtag: true,
hashtag_handler: handler,
hashtag_prefix: "https://example.com/tag/"
)
assert MapSet.to_list(tags) == ["#cofe"]
text = "#cofefetch()
"
{_result_text, %{tags: tags}} =
Linkify.link_map(text, %{tags: MapSet.new()},
hashtag: true,
hashtag_handler: handler,
hashtag_prefix: "https://example.com/tag/"
)
assert MapSet.to_list(tags) == ["#cofe"]
text = "#cofe
fetch()" {_result_text, %{tags: tags}} = Linkify.link_map(text, %{tags: MapSet.new()}, hashtag: true, hashtag_handler: handler, hashtag_prefix: "https://example.com/tag/" ) assert MapSet.to_list(tags) == ["#cofe"] end test "mention handler and hashtag prefix" do text = "Hello again, @user.<script></script>\nThis is on another :moominmamma: line. #2hu #epic #phantasmagoric" handler = fn "@" <> user = mention, _, _, _ -> ~s(@#{mention}) end expected = ~s(Hello again, @@user.<script></script>\nThis is on another :moominmamma: line. #2hu #epic #phantasmagoric) assert Linkify.link(text, mention: true, mention_handler: handler, hashtag: true, hashtag_prefix: "/tag/", new_window: true ) == expected end test "mentions handler with hostname/@user links" do text = "hi @user, take a look at this post: https://example.com/@valid_user/posts/9w5AkQp956XIh74apc" valid_users = ["user", "valid_user"] handler = fn "@" <> user = mention, buffer, _opts, acc -> if Enum.member?(valid_users, user) do link = ~s(#{mention}) {link, %{acc | mentions: MapSet.put(acc.mentions, {mention, user})}} else {buffer, acc} end end {result_text, %{mentions: mentions}} = Linkify.link_map(text, %{mentions: MapSet.new()}, mention: true, mention_handler: handler, new_window: true ) assert result_text == "hi @user, take a look at this post: https://example.com/@valid_user/posts/9w5AkQp956XIh74apc" assert mentions |> MapSet.to_list() |> Enum.map(&elem(&1, 1)) == ["user"] end test "mentions handler and extra links" do text = "hi @user, text me asap xmpp:me@cofe.ai, (or contact me at me@cofe.ai), please.
hello world
\n<`em>another @user__test and @user__test google.com paragraph
\n" expected = "hello world
\n<`em>another @user__test and @user__test google.com paragraph
\n" assert Linkify.link(text, mention: true, mention_prefix: "u/") == expected end test "mention @user@example.com" do text = "hey @user@example.com" expected = "hey @user@example.com" assert Linkify.link(text, mention: true, mention_prefix: "https://example.com/user/", new_window: true ) == expected text = "That's @user@example.com's server" expected = "That's @user@example.com's server" assert Linkify.link(text, mention: true, mention_prefix: "https://example.com/user/" ) == expected end test "mentions with symbols before them" do text = "@@example hey! >@@test@example.com" expected = "@@example hey! >@@test@example.com" assert Linkify.link(text, mention: true, mention_prefix: "/users/") == expected end test "invalid mentions" do text = "hey user@example" assert Linkify.link(text, mention: true, mention_prefix: "/users/") == text end end describe "hashtag links" do test "hashtag" do expected = " one #2two three #four." assert Linkify.link(" one #2two three #four.", hashtag: true, hashtag_prefix: "https://example.com/tag/", new_window: true ) == expected end test "must have non-numbers" do expected = "#1ok #42 #7" assert Linkify.link("#1ok #42 #7", hashtag: true, hashtag_prefix: "/t/", rel: false ) == expected end test "support French" do text = "#administrateur·rice·s #ingénieur·e·s" expected = "#administrateur·rice·s #ingénieur·e·s" assert Linkify.link(text, hashtag: true, hashtag_prefix: "/t/", rel: false ) == expected end test "support Telugu" do text = "#చక్రం #కకకకక్ #కకకకాక #కకకక్రకకకక" expected = "#చక్రం #కకకకక్ #కకకకాక #కకకక్రకకకక" assert Linkify.link(text, hashtag: true, hashtag_prefix: "/t/", rel: false ) == expected end test "do not turn urls with hashes into hashtags" do text = "google.com#test #test google.com/#test #tag" expected = "google.com#test #test google.com/#test #tag" assert Linkify.link(text, hashtag: true, rel: false, hashtag_prefix: "https://example.com/tag/" ) == expected end test "works with non-latin characters" do text = "#漢字 #は #тест #ทดสอบ" expected = "#漢字 #は #тест #ทดสอบ" assert Linkify.link(text, rel: false, hashtag: true, hashtag_prefix: "https://example.com/tag/" ) == expected end end describe "links" do test "turning urls into links" do text = "Hey, check out http://www.youtube.com/watch?v=8Zg1-TufF%20zY?x=1&y=2#blabla ." expected = "Hey, check out http://www.youtube.com/watch?v=8Zg1-TufF%20zY?x=1&y=2#blabla ." assert Linkify.link(text, new_window: true) == expected # no scheme text = "Hey, check out www.youtube.com/watch?v=8Zg1-TufF%20zY?x=1&y=2#blabla ." expected = "Hey, check out www.youtube.com/watch?v=8Zg1-TufF%20zY?x=1&y=2#blabla ." assert Linkify.link(text, new_window: true) == expected end test "turn urls with schema into urls" do text = "📌https://google.com" expected = "📌https://google.com" assert Linkify.link(text, rel: false) == expected end test "skip prefix" do assert Linkify.link("http://google.com", strip_prefix: true) == "google.com" assert Linkify.link("http://www.google.com", strip_prefix: true) == "google.com" end test "hostname/@user" do text = "https://example.com/@user" expected = "https://example.com/@user" assert Linkify.link(text, new_window: true) == expected text = "https://example.com:4000/@user" expected = "https://example.com:4000/@user" assert Linkify.link(text, new_window: true) == expected text = "https://example.com:4000/@user" expected = "https://example.com:4000/@user" assert Linkify.link(text, new_window: true) == expected text = "@username" expected = "@username" assert Linkify.link(text, new_window: true) == expected text = "http://www.cs.vu.nl/~ast/intel/" expected = "http://www.cs.vu.nl/~ast/intel/" assert Linkify.link(text) == expected text = "https://forum.zdoom.org/viewtopic.php?f=44&t=57087" expected = "https://forum.zdoom.org/viewtopic.php?f=44&t=57087" assert Linkify.link(text) == expected text = "https://en.wikipedia.org/wiki/Sophia_(Gnosticism)#Mythos_of_the_soul" expected = "https://en.wikipedia.org/wiki/Sophia_(Gnosticism)#Mythos_of_the_soul" assert Linkify.link(text) == expected text = "https://en.wikipedia.org/wiki/Duff's_device" expected = "https://en.wikipedia.org/wiki/Duff's_device" assert Linkify.link(text) == expected end end describe "non http links" do test "xmpp" do text = "xmpp:user@example.com" expected = "xmpp:user@example.com" assert Linkify.link(text, extra: true) == expected end test "wrong xmpp" do text = "xmpp:user.example.com" assert Linkify.link(text, extra: true) == text end test "email" do text = "user@example.com" expected = "user@example.com" assert Linkify.link(text, email: true) == expected end test "magnet" do text = "magnet:?xt=urn:btih:a4104a9d2f5615601c429fe8bab8177c47c05c84&dn=ubuntu-18.04.1.0-live-server-amd64.iso&tr=http%3A%2F%2Ftorrent.ubuntu.com%3A6969%2Fannounce&tr=http%3A%2F%2Fipv6.torrent.ubuntu.com%3A6969%2Fannounce" expected = "magnet:?xt=urn:btih:a4104a9d2f5615601c429fe8bab8177c47c05c84&dn=ubuntu-18.04.1.0-live-server-amd64.iso&tr=http%3A%2F%2Ftorrent.ubuntu.com%3A6969%2Fannounce&tr=http%3A%2F%2Fipv6.torrent.ubuntu.com%3A6969%2Fannounce" assert Linkify.link(text, extra: true) == expected end test "dweb" do text = "dweb://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+v1.0.0/path/to/file.txt" expected = "dweb://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+v1.0.0/path/to/file.txt" assert Linkify.link(text, extra: true) == expected end end describe "TLDs" do test "parse with scheme" do text = "https://google.com" expected = "https://google.com" assert Linkify.link(text) == expected end test "only existing TLDs with scheme" do text = "this url https://google.foobar.blah11blah/ has invalid TLD" expected = "this url https://google.foobar.blah11blah/ has invalid TLD" assert Linkify.link(text) == expected text = "this url https://google.foobar.com/ has valid TLD" expected = "this url https://google.foobar.com/ has valid TLD" assert Linkify.link(text) == expected end test "only existing TLDs without scheme" do text = "this url google.foobar.blah11blah/ has invalid TLD" assert Linkify.link(text) == text text = "this url google.foobar.com/ has valid TLD" expected = "this url google.foobar.com/ has valid TLD" assert Linkify.link(text) == expected end test "only existing TLDs with and without scheme" do text = "this url http://google.foobar.com/ has valid TLD" expected = "this url http://google.foobar.com/ has valid TLD" assert Linkify.link(text) == expected text = "this url google.foobar.com/ has valid TLD" expected = "this url google.foobar.com/ has valid TLD" assert Linkify.link(text) == expected end test "FQDN (with trailing period)" do text = "Check out this article: https://www.wired.com./story/marissa-mayer-startup-sunshine-contacts/" expected = "Check out this article: https://www.wired.com./story/marissa-mayer-startup-sunshine-contacts/" assert Linkify.link(text) == expected end end end