logo

auto_linker

AutoLinker-shim, based on https://git.pleroma.social/pleroma/auto_linker

auto_linker_test.exs (15144B)


      1 defmodule AutoLinkerTest do
      2   use ExUnit.Case, async: true
      3   doctest AutoLinker
      4 
      5   test "default link" do
      6     assert AutoLinker.link("http://google.com") ==
      7              "<a href=\"http://google.com\" class=\"auto-linker\" target=\"_blank\" rel=\"noopener noreferrer\">http://google.com</a>"
      8   end
      9 
     10   test "markdown" do
     11     assert AutoLinker.link("[google.com](http://google.com)", markdown: true) ==
     12              "<a href='http://google.com' class=\"auto-linker\" target=\"_blank\" rel=\"noopener noreferrer\">google.com</a>"
     13   end
     14 
     15   test "does on link existing links" do
     16     assert AutoLinker.link("<a href='http://google.com'>google.com</a>") ==
     17              "<a href='http://google.com'>google.com</a>"
     18   end
     19 
     20   test "phone number and markdown link" do
     21     assert AutoLinker.link("888 888-8888  [ab](a.com)", phone: true, markdown: true) ==
     22              ~s(<a href="#" class="phone-number" data-phone="8888888888">888 888-8888</a>) <>
     23                ~s(  <a href='a.com' class="auto-linker" target="_blank" rel="noopener noreferrer">ab</a>)
     24   end
     25 
     26   test "all kinds of links" do
     27     text =
     28       "hello http://google.com https://ddg.com 888 888-8888 mailto:user@email.com [google.com](http://google.com)"
     29 
     30     expected =
     31       "hello <a href=\"http://google.com\">http://google.com</a> <a href=\"https://ddg.com\">https://ddg.com</a> 888 888-8888 <a href=\"mailto:user@email.com\">mailto:user@email.com</a> <a href='http://google.com'>google.com</a>"
     32 
     33     assert AutoLinker.link(text,
     34              markdown: true,
     35              scheme: true,
     36              class: false,
     37              new_window: false,
     38              rel: false
     39            ) == expected
     40   end
     41 
     42   test "rel as function" do
     43     text = "http://google.com"
     44 
     45     expected = "<a href=\"http://google.com\" rel=\"com\">http://google.com</a>"
     46 
     47     custom_rel = fn url ->
     48       url |> String.split(".") |> List.last()
     49     end
     50 
     51     assert AutoLinker.link(text,
     52              class: false,
     53              new_window: false,
     54              rel: custom_rel
     55            ) == expected
     56 
     57     text = "http://google.com"
     58 
     59     expected = "<a href=\"http://google.com\">http://google.com</a>"
     60 
     61     custom_rel = fn _ -> nil end
     62 
     63     assert AutoLinker.link(text,
     64              class: false,
     65              new_window: false,
     66              rel: custom_rel
     67            ) == expected
     68   end
     69 
     70   test "link_map/2" do
     71     assert AutoLinker.link_map("http://google.com", []) ==
     72              {"<a href=\"http://google.com\" class=\"auto-linker\" target=\"_blank\" rel=\"noopener noreferrer\">http://google.com</a>",
     73               []}
     74   end
     75 
     76   describe "custom handlers" do
     77     test "mentions handler" do
     78       text = "hello @user, @valid_user and @invalid_user"
     79       valid_users = ["user", "valid_user"]
     80 
     81       handler = fn "@" <> user = mention, buffer, _opts, acc ->
     82         if Enum.member?(valid_users, user) do
     83           link = ~s(<a href="https://example.com/user/#{user}" data-user="#{user}">#{mention}</a>)
     84           {link, %{acc | mentions: MapSet.put(acc.mentions, {mention, user})}}
     85         else
     86           {buffer, acc}
     87         end
     88       end
     89 
     90       {result_text, %{mentions: mentions}} =
     91         AutoLinker.link_map(text, %{mentions: MapSet.new()},
     92           mention: true,
     93           mention_handler: handler
     94         )
     95 
     96       assert result_text ==
     97                "hello <a href=\"https://example.com/user/user\" data-user=\"user\">@user</a>, <a href=\"https://example.com/user/valid_user\" data-user=\"valid_user\">@valid_user</a> and @invalid_user"
     98 
     99       assert mentions |> MapSet.to_list() |> Enum.map(&elem(&1, 1)) == valid_users
    100     end
    101 
    102     test "hashtags handler" do
    103       text = "#hello #world"
    104 
    105       handler = fn hashtag, buffer, opts, acc ->
    106         link = AutoLinker.Builder.create_hashtag_link(hashtag, buffer, opts)
    107         {link, %{acc | tags: MapSet.put(acc.tags, hashtag)}}
    108       end
    109 
    110       {result_text, %{tags: tags}} =
    111         AutoLinker.link_map(text, %{tags: MapSet.new()},
    112           hashtag: true,
    113           hashtag_handler: handler,
    114           hashtag_prefix: "https://example.com/user/",
    115           class: false,
    116           new_window: false,
    117           rel: false
    118         )
    119 
    120       assert result_text ==
    121                "<a href=\"https://example.com/user/hello\">#hello</a> <a href=\"https://example.com/user/world\">#world</a>"
    122 
    123       assert MapSet.to_list(tags) == ["#hello", "#world"]
    124     end
    125 
    126     test "mention handler and hashtag prefix" do
    127       text =
    128         "Hello again, @user.&lt;script&gt;&lt;/script&gt;\nThis is on another :moominmamma: line. #2hu #epic #phantasmagoric"
    129 
    130       handler = fn "@" <> user = mention, _, _, _ ->
    131         ~s(<span class='h-card'><a href='#/user/#{user}'>@<span>#{mention}</span></a></span>)
    132       end
    133 
    134       expected =
    135         "Hello again, <span class='h-card'><a href='#/user/user'>@<span>@user</span></a></span>.&lt;script&gt;&lt;/script&gt;\nThis is on another :moominmamma: line. <a href=\"/tag/2hu\" class=\"auto-linker\" target=\"_blank\" rel=\"noopener noreferrer\">#2hu</a> <a href=\"/tag/epic\" class=\"auto-linker\" target=\"_blank\" rel=\"noopener noreferrer\">#epic</a> <a href=\"/tag/phantasmagoric\" class=\"auto-linker\" target=\"_blank\" rel=\"noopener noreferrer\">#phantasmagoric</a>"
    136 
    137       assert AutoLinker.link(text,
    138                mention: true,
    139                mention_handler: handler,
    140                hashtag: true,
    141                hashtag_prefix: "/tag/"
    142              ) == expected
    143     end
    144   end
    145 
    146   describe "mentions" do
    147     test "simple mentions" do
    148       expected =
    149         ~s{hello <a href="https://example.com/user/user" class="auto-linker" target="_blank" rel="noopener noreferrer">@user</a> and <a href="https://example.com/user/anotherUser" class="auto-linker" target="_blank" rel="noopener noreferrer">@anotherUser</a>.}
    150 
    151       assert AutoLinker.link("hello @user and @anotherUser.",
    152                mention: true,
    153                mention_prefix: "https://example.com/user/"
    154              ) == expected
    155     end
    156 
    157     test "mentions inside html tags" do
    158       text =
    159         "<p><strong>hello world</strong></p>\n<p><`em>another @user__test and @user__test http://google.com paragraph</em></p>\n"
    160 
    161       expected =
    162         "<p><strong>hello world</strong></p>\n<p><`em>another <a href=\"u/user__test\">@user__test</a> and <a href=\"u/user__test\">@user__test</a> <a href=\"http://google.com\">http://google.com</a> paragraph</em></p>\n"
    163 
    164       assert AutoLinker.link(text,
    165                mention: true,
    166                mention_prefix: "u/",
    167                class: false,
    168                rel: false,
    169                new_window: false
    170              ) == expected
    171     end
    172 
    173     test "metion @user@example.com" do
    174       text = "hey @user@example.com"
    175 
    176       expected =
    177         "hey <a href=\"https://example.com/user/user@example.com\" class=\"auto-linker\" target=\"_blank\" rel=\"noopener noreferrer\">@user@example.com</a>"
    178 
    179       assert AutoLinker.link(text,
    180                mention: true,
    181                mention_prefix: "https://example.com/user/"
    182              ) == expected
    183     end
    184   end
    185 
    186   describe "hashtag links" do
    187     test "hashtag" do
    188       expected =
    189         " one <a href=\"https://example.com/tag/2two\" class=\"auto-linker\" target=\"_blank\" rel=\"noopener noreferrer\">#2two</a> three <a href=\"https://example.com/tag/four\" class=\"auto-linker\" target=\"_blank\" rel=\"noopener noreferrer\">#four</a>."
    190 
    191       assert AutoLinker.link(" one #2two three #four.",
    192                hashtag: true,
    193                hashtag_prefix: "https://example.com/tag/"
    194              ) == expected
    195     end
    196 
    197     test "must have non-numbers" do
    198       expected = "<a href=\"/t/1ok\">#1ok</a> #42 #7"
    199 
    200       assert AutoLinker.link("#1ok #42 #7",
    201                hashtag: true,
    202                hashtag_prefix: "/t/",
    203                class: false,
    204                rel: false,
    205                new_window: false
    206              ) == expected
    207     end
    208 
    209     test "support French" do
    210       text = "#administrateur·rice·s #ingénieur·e·s"
    211 
    212       expected =
    213         "<a href=\"/t/administrateur·rice·s\">#administrateur·rice·s</a> <a href=\"/t/ingénieur·e·s\">#ingénieur·e·s</a>"
    214 
    215       assert AutoLinker.link(text,
    216                hashtag: true,
    217                hashtag_prefix: "/t/",
    218                class: false,
    219                rel: false,
    220                new_window: false
    221              ) == expected
    222     end
    223 
    224     test "support Telugu" do
    225       text = "#చక్రం #కకకకక్ #కకకకాక #కకకక్రకకకక"
    226 
    227       expected =
    228         "<a href=\"/t/చక్రం\">#చక్రం</a> <a href=\"/t/కకకకక్\">#కకకకక్</a> <a href=\"/t/కకకకాక\">#కకకకాక</a> <a href=\"/t/కకకక్రకకకక\">#కకకక్రకకకక</a>"
    229 
    230       assert AutoLinker.link(text,
    231                hashtag: true,
    232                hashtag_prefix: "/t/",
    233                class: false,
    234                rel: false,
    235                new_window: false
    236              ) == expected
    237     end
    238 
    239     test "do not turn urls with hashes into hashtags" do
    240       text = "#test http://google.com/#test #tag"
    241 
    242       expected =
    243         "<a href=\"https://example.com/tag/test\">#test</a> <a href=\"http://google.com/#test\">http://google.com/#test</a> <a href=\"https://example.com/tag/tag\">#tag</a>"
    244 
    245       assert AutoLinker.link(text,
    246                scheme: true,
    247                hashtag: true,
    248                class: false,
    249                new_window: false,
    250                rel: false,
    251                hashtag_prefix: "https://example.com/tag/"
    252              ) == expected
    253     end
    254 
    255     test "works with non-latin characters" do
    256       text = "#漢字 #は #тест #ทดสอบ"
    257 
    258       expected =
    259         "<a href=\"https://example.com/tag/漢字\">#漢字</a> <a href=\"https://example.com/tag/は\">#は</a> <a href=\"https://example.com/tag/тест\">#тест</a> <a href=\"https://example.com/tag/ทดสอบ\">#ทดสอบ</a>"
    260 
    261       assert AutoLinker.link(text,
    262                scheme: true,
    263                class: false,
    264                new_window: false,
    265                rel: false,
    266                hashtag: true,
    267                hashtag_prefix: "https://example.com/tag/"
    268              ) == expected
    269     end
    270   end
    271 
    272   describe "links" do
    273     test "turning urls into links" do
    274       text = "Hey, check out http://www.youtube.com/watch?v=8Zg1-TufF%20zY?x=1&y=2#blabla ."
    275 
    276       expected =
    277         "Hey, check out <a href=\"http://www.youtube.com/watch?v=8Zg1-TufF%20zY?x=1&y=2#blabla\" class=\"auto-linker\" target=\"_blank\" rel=\"noopener noreferrer\">http://www.youtube.com/watch?v=8Zg1-TufF%20zY?x=1&y=2#blabla</a> ."
    278 
    279       assert AutoLinker.link(text, scheme: true) == expected
    280 
    281       # no scheme
    282       text = "Hey, check out www.youtube.com/watch?v=8Zg1-TufF%20zY?x=1&y=2#blabla ."
    283       assert AutoLinker.link(text, scheme: true) == text
    284     end
    285 
    286     test "hostname/@user" do
    287       text = "https://example.com/@user"
    288 
    289       expected =
    290         "<a href=\"https://example.com/@user\" class=\"auto-linker\" target=\"_blank\" rel=\"noopener noreferrer\">https://example.com/@user</a>"
    291 
    292       assert AutoLinker.link(text, scheme: true) == expected
    293 
    294       text = "https://example.com:4000/@user"
    295 
    296       expected =
    297         "<a href=\"https://example.com:4000/@user\" class=\"auto-linker\" target=\"_blank\" rel=\"noopener noreferrer\">https://example.com:4000/@user</a>"
    298 
    299       assert AutoLinker.link(text, scheme: true) == expected
    300 
    301       text = "https://example.com:4000/@user"
    302 
    303       expected =
    304         "<a href=\"https://example.com:4000/@user\" class=\"auto-linker\" target=\"_blank\" rel=\"noopener noreferrer\">https://example.com:4000/@user</a>"
    305 
    306       assert AutoLinker.link(text, scheme: true) == expected
    307 
    308       text = "@username"
    309       expected = "@username"
    310       assert AutoLinker.link(text, scheme: true) == expected
    311 
    312       text = "http://www.cs.vu.nl/~ast/intel/"
    313 
    314       expected =
    315         "<a href=\"http://www.cs.vu.nl/~ast/intel/\" class=\"auto-linker\" target=\"_blank\" rel=\"noopener noreferrer\">http://www.cs.vu.nl/~ast/intel/</a>"
    316 
    317       assert AutoLinker.link(text, scheme: true) == expected
    318 
    319       text = "https://forum.zdoom.org/viewtopic.php?f=44&t=57087"
    320 
    321       expected =
    322         "<a href=\"https://forum.zdoom.org/viewtopic.php?f=44&t=57087\" class=\"auto-linker\" target=\"_blank\" rel=\"noopener noreferrer\">https://forum.zdoom.org/viewtopic.php?f=44&t=57087</a>"
    323 
    324       assert AutoLinker.link(text, scheme: true) == expected
    325 
    326       text = "https://en.wikipedia.org/wiki/Sophia_(Gnosticism)#Mythos_of_the_soul"
    327 
    328       expected =
    329         "<a href=\"https://en.wikipedia.org/wiki/Sophia_(Gnosticism)#Mythos_of_the_soul\" class=\"auto-linker\" target=\"_blank\" rel=\"noopener noreferrer\">https://en.wikipedia.org/wiki/Sophia_(Gnosticism)#Mythos_of_the_soul</a>"
    330 
    331       assert AutoLinker.link(text, scheme: true) == expected
    332 
    333       text = "https://en.wikipedia.org/wiki/Duff's_device"
    334 
    335       expected =
    336         "<a href=\"https://en.wikipedia.org/wiki/Duff's_device\" class=\"auto-linker\" target=\"_blank\" rel=\"noopener noreferrer\">https://en.wikipedia.org/wiki/Duff's_device</a>"
    337 
    338       assert AutoLinker.link(text, scheme: true) == expected
    339     end
    340   end
    341 
    342   describe "non http links" do
    343     test "xmpp" do
    344       text = "xmpp:user@example.com"
    345 
    346       expected =
    347         "<a href=\"xmpp:user@example.com\" class=\"auto-linker\">xmpp:user@example.com</a>"
    348 
    349       assert AutoLinker.link(text, new_window: false, rel: false) == expected
    350     end
    351 
    352     test "email" do
    353       text = "mailto:user@example.com"
    354 
    355       expected =
    356         "<a href=\"mailto:user@example.com\" class=\"auto-linker\" target=\"_blank\" rel=\"noopener noreferrer\">mailto:user@example.com</a>"
    357 
    358       assert AutoLinker.link(text) == expected
    359     end
    360 
    361     test "magnet" do
    362       text =
    363         "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"
    364 
    365       expected =
    366         "<a href=\"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\" class=\"auto-linker\">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</a>"
    367 
    368       assert AutoLinker.link(text, extra_prefixes: ["magnet:?"], new_window: false, rel: false) ==
    369                expected
    370     end
    371 
    372     test "dweb" do
    373       text =
    374         "dweb://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+v1.0.0/path/to/file.txt"
    375 
    376       expected =
    377         "<a href=\"dweb://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+v1.0.0/path/to/file.txt\" class=\"auto-linker\">dweb://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+v1.0.0/path/to/file.txt</a>"
    378 
    379       assert AutoLinker.link(text, extra_prefixes: ["dweb://"], new_window: false, rel: false) ==
    380                expected
    381     end
    382   end
    383 end