defmodule LinkifyTest do use ExUnit.Case, async: true doctest Linkify test "default link" do assert Linkify.link("google.com") == "google.com" 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 "class attribute" do assert Linkify.link("google.com", class: "linkified") == "google.com" end test "rel attribute" do assert Linkify.link("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 "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"] 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 end describe "mentions" do test "simple mentions" do expected = ~s{hello @user and @anotherUser.} assert Linkify.link("hello @user and @anotherUser.", mention: true, mention_prefix: "https://example.com/user/", new_window: true ) == expected end test "mentions inside html tags" do text = "

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 "metion @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 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 "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 end end