defmodule AutoLinkerTest do use ExUnit.Case, async: true doctest AutoLinker test "phone number" do assert AutoLinker.link(", work (555) 555-5555", phone: true) == ~s{, work (555) 555-5555} end test "default link" do assert AutoLinker.link("google.com") == "google.com" end test "markdown" do assert AutoLinker.link("[google.com](http://google.com)", markdown: true) == "google.com" end test "does on link existing links" do assert AutoLinker.link("google.com") == "google.com" end test "phone number and markdown link" do assert AutoLinker.link("888 888-8888 [ab](a.com)", phone: true, markdown: true) == "888 888-8888" <> " ab" end test "all kinds of links" do text = "hello google.com https://ddg.com 888 888-8888 user@email.com [google.com](http://google.com) irc:///mIRC" expected = "hello google.com ddg.com 888 888-8888 user@email.com google.com irc:///mIRC" assert AutoLinker.link(text, phone: true, markdown: true, email: true, scheme: true, extra: true, class: false, new_window: false, rel: false ) == expected end test "rel as function" do text = "google.com" expected = "google.com" custom_rel = fn url -> url |> String.split(".") |> List.last() end assert AutoLinker.link(text, class: false, new_window: false, rel: custom_rel ) == expected 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}} = AutoLinker.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 = AutoLinker.Builder.create_hashtag_link(hashtag, buffer, opts) {link, %{acc | tags: MapSet.put(acc.tags, hashtag)}} end {result_text, %{tags: tags}} = AutoLinker.link_map(text, %{tags: MapSet.new()}, hashtag: true, hashtag_handler: handler, hashtag_prefix: "https://example.com/user/", class: false, new_window: false, 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 = "Hello again, @@user.<script></script>\nThis is on another :moominmamma: line. #2hu #epic #phantasmagoric" assert AutoLinker.link(text, mention: true, mention_handler: handler, hashtag: true, hashtag_prefix: "/tag/" ) == expected end end describe "mentions" do test "simple mentions" do expected = ~s{hello @user and @anotherUser.} assert AutoLinker.link("hello @user and @anotherUser.", mention: true, mention_prefix: "https://example.com/user/" ) == expected end test "metion @user@example.com" do text = "hey @user@example.com" expected = "hey @user@example.com" assert AutoLinker.link(text, mention: true, mention_prefix: "https://example.com/user/" ) == expected end end describe "hashtag links" do test "hashtag" do expected = " one #2two three #four." assert AutoLinker.link(" one #2two three #four.", hashtag: true, hashtag_prefix: "https://example.com/tag/" ) == expected end test "must have non-numbers" do expected = "#1ok #42 #7" assert AutoLinker.link("#1ok #42 #7", hashtag: true, hashtag_prefix: "/t/", class: false, rel: false, new_window: false ) == expected end test "support French" do text = "#administrateur·rice·s #ingénieur·e·s" expected = "#administrateur·rice·s #ingénieur·e·s" assert AutoLinker.link(text, hashtag: true, hashtag_prefix: "/t/", class: false, rel: false, new_window: 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 AutoLinker.link(text, scheme: true, hashtag: true, class: false, new_window: false, rel: false, hashtag_prefix: "https://example.com/tag/" ) == expected end test "works with non-latin characters" do text = "#漢字 #は #тест #ทดสอบ" expected = "#漢字 #は #тест #ทดสอบ" assert AutoLinker.link(text, scheme: true, class: false, new_window: false, 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 youtube.com/watch?v=8Zg1-TufF%20zY?x=1&y=2#blabla ." assert AutoLinker.link(text, scheme: true) == expected # no scheme text = "Hey, check out www.youtube.com/watch?v=8Zg1-TufF%20zY?x=1&y=2#blabla ." assert AutoLinker.link(text, scheme: true) == expected end test "hostname/@user" do text = "https://example.com/@user" expected = "example.com/@user" assert AutoLinker.link(text, scheme: true) == expected text = "https://example.com:4000/@user" expected = "example.com:4000/@user" assert AutoLinker.link(text, scheme: true) == expected text = "https://example.com:4000/@user" expected = "example.com:4000/@user" assert AutoLinker.link(text, scheme: true) == expected text = "@username" expected = "@username" assert AutoLinker.link(text, scheme: true) == expected text = "http://www.cs.vu.nl/~ast/intel/" expected = "cs.vu.nl/~ast/intel/" assert AutoLinker.link(text, scheme: true) == expected text = "https://forum.zdoom.org/viewtopic.php?f=44&t=57087" expected = "forum.zdoom.org/viewtopic.php?f=44&t=57087" assert AutoLinker.link(text, scheme: true) == expected text = "https://en.wikipedia.org/wiki/Sophia_(Gnosticism)#Mythos_of_the_soul" expected = "en.wikipedia.org/wiki/Sophia_(Gnosticism)#Mythos_of_the_soul" assert AutoLinker.link(text, scheme: true) == expected text = "https://en.wikipedia.org/wiki/Duff's_device" expected = "en.wikipedia.org/wiki/Duff's_device" assert AutoLinker.link(text, scheme: true) == expected end end describe "non http links" do test "xmpp" do text = "xmpp:user@example.com" expected = "xmpp:user@example.com" assert AutoLinker.link(text, extra: true, new_window: false, rel: false) == expected end test "email" do text = "user@example.com" expected = "user@example.com" assert AutoLinker.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 AutoLinker.link(text, extra: true, new_window: false, rel: false) == 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 AutoLinker.link(text, extra: true, new_window: false, rel: false) == expected end end describe "TLDs" do test "parse with scheme" do text = "https://google.com" expected = "google.com" assert AutoLinker.link(text, scheme: true) == 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 AutoLinker.link(text, scheme: true) == expected text = "this url https://google.foobar.com/ has valid TLD" expected = "this url google.foobar.com/ has valid TLD" assert AutoLinker.link(text, scheme: true) == expected end test "only existing TLDs without scheme" do text = "this url google.foobar.blah11blah/ has invalid TLD" expected = "this url google.foobar.blah11blah/ has invalid TLD" assert AutoLinker.link(text, scheme: false) == expected text = "this url google.foobar.com/ has valid TLD" expected = "this url google.foobar.com/ has valid TLD" assert AutoLinker.link(text, scheme: false) == expected end test "only existing TLDs with and without scheme" do text = "this url http://google.foobar.com/ has valid TLD" expected = "this url google.foobar.com/ has valid TLD" assert AutoLinker.link(text, scheme: true) == expected text = "this url google.foobar.com/ has valid TLD" expected = "this url google.foobar.com/ has valid TLD" assert AutoLinker.link(text, scheme: true) == expected end end end