168 lines
5.2 KiB
Elixir
168 lines
5.2 KiB
Elixir
defmodule Blogex.BlogIntegrationTest do
|
|
use ExUnit.Case
|
|
|
|
describe "compile-time link validation" do
|
|
test "raises LinkError for invalid blog ID in link" do
|
|
tmp_file = Path.join(System.tmp_dir!(), "test_blog_invalid.ex")
|
|
|
|
File.write!(tmp_file, """
|
|
defmodule TestBlogInvalidBlogId do
|
|
use Blogex.Blog,
|
|
blog_id: :test,
|
|
app: :blogex,
|
|
from: "priv/blog/test/2026/01-02-invalid-post.md",
|
|
title: "Test Blog",
|
|
base_path: "/blog/test"
|
|
end
|
|
""")
|
|
|
|
assert_raise Blogex.LinkError, fn ->
|
|
Code.compile_file(tmp_file, __ENV__.file)
|
|
end
|
|
|
|
File.rm!(tmp_file)
|
|
end
|
|
|
|
test "raises LinkError for invalid slug in link" do
|
|
tmp_file = Path.join(System.tmp_dir!(), "test_blog_invalid_slug.ex")
|
|
|
|
File.write!(tmp_file, """
|
|
defmodule TestBlogInvalidSlug do
|
|
use Blogex.Blog,
|
|
blog_id: :test,
|
|
app: :blogex,
|
|
from: "priv/blog/test/2026/01-02-invalid-post.md",
|
|
title: "Test Blog",
|
|
base_path: "/blog/test"
|
|
end
|
|
""")
|
|
|
|
assert_raise Blogex.LinkError, fn ->
|
|
Code.compile_file(tmp_file, __ENV__.file)
|
|
end
|
|
|
|
File.rm!(tmp_file)
|
|
end
|
|
|
|
test "compiles successfully with valid links" do
|
|
tmp_file = Path.join(System.tmp_dir!(), "test_blog_valid.ex")
|
|
|
|
File.write!(tmp_file, """
|
|
defmodule TestBlogValid do
|
|
use Blogex.Blog,
|
|
blog_id: :test,
|
|
app: :blogex,
|
|
from: "priv/blog/test/2026/01-01-valid-post.md",
|
|
title: "Test Blog",
|
|
base_path: "/blog/test"
|
|
end
|
|
""")
|
|
|
|
[{TestBlogValid, _bytecode}] = Code.compile_file(tmp_file, __ENV__.file)
|
|
assert apply(TestBlogValid, :title, []) == "Test Blog"
|
|
|
|
File.rm!(tmp_file)
|
|
end
|
|
|
|
test "LinkError message includes post context" do
|
|
tmp_file = Path.join(System.tmp_dir!(), "test_blog_msg.ex")
|
|
|
|
File.write!(tmp_file, """
|
|
defmodule TestBlogErrorMsg do
|
|
use Blogex.Blog,
|
|
blog_id: :test,
|
|
app: :blogex,
|
|
from: "priv/blog/test/2026/01-02-invalid-post.md",
|
|
title: "Test Blog",
|
|
base_path: "/blog/test"
|
|
end
|
|
""")
|
|
|
|
exception =
|
|
assert_raise Blogex.LinkError, fn ->
|
|
Code.compile_file(tmp_file, __ENV__.file)
|
|
end
|
|
|
|
msg = Exception.message(exception)
|
|
|
|
assert msg =~ "invalid internal blog links"
|
|
assert msg =~ "invalid-post"
|
|
assert msg =~ "/blog/unknown/broken"
|
|
assert msg =~ "/blog/engineering/My-Post"
|
|
|
|
File.rm!(tmp_file)
|
|
end
|
|
end
|
|
|
|
describe "validation sees compiled post bodies" do
|
|
# `_validate_links/2` runs on `post.body` *after* NimblePublisher rendered
|
|
# the markdown, so validation only works if extraction reads the compiled
|
|
# HTML. This pins that contract against a real compiled body: if
|
|
# extraction ever goes back to scanning markdown syntax only, it fails.
|
|
test "extract_links finds internal links in a compiled post body" do
|
|
tmp_file = Path.join(System.tmp_dir!(), "test_blog_compiled_body.ex")
|
|
|
|
File.write!(tmp_file, """
|
|
defmodule TestBlogCompiledBody do
|
|
use Blogex.Blog,
|
|
blog_id: :test,
|
|
app: :blogex,
|
|
from: "priv/blog/test/2026/01-03-internal-link-post.md",
|
|
title: "Test Blog",
|
|
base_path: "/blog/test"
|
|
end
|
|
""")
|
|
|
|
[{TestBlogCompiledBody, _bytecode}] = Code.compile_file(tmp_file, __ENV__.file)
|
|
|
|
# `apply/3`: the module is compiled at runtime, so a static call would
|
|
# warn ("module is not available") on every test compile.
|
|
[post] = apply(TestBlogCompiledBody, :all_posts, [])
|
|
|
|
# The markdown source is `[hello world](/blog/engineering/hello-world)`.
|
|
assert post.body =~ "/blog/engineering/hello-world"
|
|
|
|
assert "/blog/engineering/hello-world" in Blogex.LinkValidator.extract_links(post.body)
|
|
|
|
File.rm!(tmp_file)
|
|
end
|
|
end
|
|
|
|
describe "show_drafts?/0" do
|
|
# The only path through `Blogex.show_drafts?/0` (blogex.ex): `use Blogex.Blog`
|
|
# compiles a real module over a real draft fixture, so the flag is read by
|
|
# the generated `all_posts/0` rather than asserted in isolation.
|
|
#
|
|
# One test, one compile: compiling the same module name twice would print a
|
|
# "redefining module" warning, and warnings are fatal everywhere in this repo.
|
|
test "drafts are hidden by default and visible when :show_drafts is on" do
|
|
tmp_file = Path.join(System.tmp_dir!(), "test_blog_show_drafts.ex")
|
|
|
|
File.write!(tmp_file, """
|
|
defmodule TestBlogShowDrafts do
|
|
use Blogex.Blog,
|
|
blog_id: :test,
|
|
app: :blogex,
|
|
from: "priv/blog/test/2026/01-03-draft-post.md",
|
|
title: "Test Blog",
|
|
base_path: "/blog/test"
|
|
end
|
|
""")
|
|
|
|
[{TestBlogShowDrafts, _bytecode}] = Code.compile_file(tmp_file, __ENV__.file)
|
|
|
|
on_exit(fn ->
|
|
File.rm!(tmp_file)
|
|
Application.delete_env(:blogex, :show_drafts)
|
|
end)
|
|
|
|
assert apply(TestBlogShowDrafts, :all_posts, []) == []
|
|
|
|
Application.put_env(:blogex, :show_drafts, true)
|
|
|
|
assert [post] = apply(TestBlogShowDrafts, :all_posts, [])
|
|
assert post.title == "Draft Post (test fixture)"
|
|
end
|
|
end
|
|
end
|