feat(join): render join_description with auto-linked URLs and Markdown links
This commit is contained in:
parent
b6c2cf58b1
commit
cb5cb68483
2 changed files with 155 additions and 0 deletions
85
test/mv_web/helpers/join_description_renderer_test.exs
Normal file
85
test/mv_web/helpers/join_description_renderer_test.exs
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
defmodule MvWeb.Helpers.JoinDescriptionRendererTest do
|
||||
@moduledoc """
|
||||
Tests for the join-description renderer that auto-links raw URLs and Markdown
|
||||
links while escaping all other content.
|
||||
"""
|
||||
use ExUnit.Case, async: true
|
||||
use ExUnitProperties
|
||||
|
||||
alias MvWeb.Helpers.JoinDescriptionRenderer
|
||||
|
||||
defp html(value) do
|
||||
value
|
||||
|> JoinDescriptionRenderer.render()
|
||||
|> Phoenix.HTML.safe_to_string()
|
||||
end
|
||||
|
||||
describe "render/1" do
|
||||
test "converts a raw URL to an anchor tag" do
|
||||
result = html("Akzeptiere https://example.com/dsgvo")
|
||||
|
||||
assert result =~ ~s(<a href="https://example.com/dsgvo")
|
||||
assert result =~ "https://example.com/dsgvo</a>"
|
||||
assert result =~ "Akzeptiere "
|
||||
end
|
||||
|
||||
test "converts Markdown [text](url) to an anchor tag with the link text" do
|
||||
result = html("[Datenschutzerklärung](https://example.com/dsgvo)")
|
||||
|
||||
assert result =~ ~s(<a href="https://example.com/dsgvo")
|
||||
assert result =~ ">Datenschutzerklärung</a>"
|
||||
end
|
||||
|
||||
test "returns an empty safe string for nil input" do
|
||||
assert JoinDescriptionRenderer.render(nil) == {:safe, ""}
|
||||
end
|
||||
|
||||
test "escapes arbitrary HTML in non-link text" do
|
||||
result = html("<script>alert(1)</script>")
|
||||
|
||||
refute result =~ "<script>"
|
||||
assert result =~ "<script>"
|
||||
end
|
||||
|
||||
test "does not double-link a Markdown link whose URL also looks like a raw URL" do
|
||||
result = html("[Datenschutz](https://example.com/x)")
|
||||
|
||||
# exactly one anchor, no nested anchor for the inner raw URL
|
||||
assert result |> :binary.matches("<a ") |> length() == 1
|
||||
end
|
||||
end
|
||||
|
||||
describe "property: link-free text" do
|
||||
property "preserves non-link text content as HTML-escaped output" do
|
||||
check all(text <- link_free_string()) do
|
||||
result = html(text)
|
||||
|
||||
# No links emitted, and text content equals the HTML-escaped input.
|
||||
refute result =~ "<a "
|
||||
assert result == Phoenix.HTML.html_escape(text) |> Phoenix.HTML.safe_to_string()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "property: well-formed Markdown links" do
|
||||
property "renders every [text](https://...) as a single anchor with verbatim text and url" do
|
||||
check all(
|
||||
label <- string(:alphanumeric, min_length: 1),
|
||||
path <- string(:alphanumeric)
|
||||
) do
|
||||
url = "https://example.com/#{path}"
|
||||
result = html("[#{label}](#{url})")
|
||||
|
||||
assert result =~ ~s(<a href="#{url}">#{label}</a>)
|
||||
assert result |> :binary.matches("<a ") |> length() == 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Printable strings that contain no bare URLs and no Markdown-link opening bracket.
|
||||
defp link_free_string do
|
||||
:printable
|
||||
|> string()
|
||||
|> filter(fn s -> not String.contains?(s, "http") and not String.contains?(s, "[") end)
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue