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.<script></script>\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>.<script></script>\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