defmodule BDS.Generation.PagefindTest do
use ExUnit.Case, async: true
alias BDS.Generation.Pagefind
defp plan(language, blog_languages), do: %{language: language, blog_languages: blog_languages}
defp index_for(outputs, relative_path) do
{_path, content} = Enum.find(outputs, fn {path, _} -> path == relative_path end)
Jason.decode!(content)
end
defp content_for(outputs, relative_path) do
{_path, content} = Enum.find(outputs, fn {path, _} -> path == relative_path end)
content
end
test "indexes only pages marked with data-pagefind-body and scopes text to that region" do
post_html = """
My First Post
My First Post
Searchable elixir content.
"""
list_html = "Home
list page
"
outputs =
Pagefind.build_outputs(plan("en", ["en"]), [
{"posts/first.html", post_html},
{"index.html", list_html}
])
index = index_for(outputs, "pagefind/index.json")
assert index["language"] == "en"
# Only the marked post page is indexed; the unmarked list page is excluded.
urls = Enum.map(index["pages"], & &1["url"])
assert "/posts/first.html" in urls
refute "/index.html" in urls
page = Enum.find(index["pages"], &(&1["url"] == "/posts/first.html"))
assert page["title"] == "My First Post"
# Body text is scoped to data-pagefind-body — nav/footer text is excluded.
assert page["text"] =~ "Searchable elixir content"
refute page["text"] =~ "ignored-nav-term"
refute page["text"] =~ "footer-term"
end
test "builds a separate index per language scoped by route prefix" do
en_post =
"ENenglish body"
de_post =
"DEdeutscher text"
outputs =
Pagefind.build_outputs(plan("en", ["en", "de"]), [
{"posts/first.html", en_post},
{"de/posts/first.html", de_post}
])
en_index = index_for(outputs, "pagefind/index.json")
de_index = index_for(outputs, "de/pagefind/index.json")
assert en_index["language"] == "en"
assert Enum.map(en_index["pages"], & &1["url"]) == ["/posts/first.html"]
assert de_index["language"] == "de"
assert Enum.map(de_index["pages"], & &1["url"]) == ["/de/posts/first.html"]
end
test "emits a functional PagefindUI script and stylesheet per language" do
outputs =
Pagefind.build_outputs(plan("en", ["en"]), [
{"posts/first.html",
"Tb"}
])
js = content_for(outputs, "pagefind/pagefind-ui.js")
css = content_for(outputs, "pagefind/pagefind-ui.css")
# Real UI defines the PagefindUI global the search runtime instantiates.
assert js =~ "PagefindUI"
refute js =~ "window.bDSPagefind"
# Stylesheet carries real UI selectors, not a one-liner stub.
assert css =~ ".pagefind-ui__results"
end
end