Goal: have a personal blog, and try out another point in the 'modular app design with elixir' space. Designing OTP systems with elixir had some interesting ideas.
146 lines
3.6 KiB
Elixir
146 lines
3.6 KiB
Elixir
defmodule Blogex.BlogTest do
|
|
use ExUnit.Case
|
|
|
|
import Blogex.Test.PostBuilder
|
|
alias Blogex.Test.FakeBlog
|
|
|
|
setup do
|
|
Blogex.Test.Setup.with_blog()
|
|
end
|
|
|
|
describe "all_posts/0" do
|
|
test "excludes drafts", %{blog: blog} do
|
|
ids = blog.all_posts() |> Enum.map(& &1.id)
|
|
|
|
assert "draft-post" not in ids
|
|
end
|
|
|
|
test "returns posts newest first", %{blog: blog} do
|
|
dates = blog.all_posts() |> Enum.map(& &1.date)
|
|
|
|
assert dates == Enum.sort(dates, {:desc, Date})
|
|
end
|
|
end
|
|
|
|
describe "recent_posts/1" do
|
|
test "returns at most n posts", %{blog: blog} do
|
|
assert length(blog.recent_posts(2)) == 2
|
|
end
|
|
|
|
test "returns newest posts", %{blog: blog} do
|
|
[first | _] = blog.recent_posts(1)
|
|
|
|
assert first.id == "newest-post"
|
|
end
|
|
end
|
|
|
|
describe "posts_by_tag/1" do
|
|
test "returns only posts with the given tag", %{blog: blog} do
|
|
posts = blog.posts_by_tag("testing")
|
|
|
|
assert [%{id: "middle-post"}] = posts
|
|
end
|
|
|
|
test "returns empty list for unknown tag", %{blog: blog} do
|
|
assert blog.posts_by_tag("nonexistent") == []
|
|
end
|
|
|
|
test "excludes drafts even if tag matches" do
|
|
{:ok, _} = FakeBlog.start([
|
|
build(id: "pub", tags: ["elixir"], published: true),
|
|
build(id: "draft", tags: ["elixir"], published: false)
|
|
])
|
|
|
|
ids = FakeBlog.posts_by_tag("elixir") |> Enum.map(& &1.id)
|
|
|
|
assert "pub" in ids
|
|
refute "draft" in ids
|
|
end
|
|
end
|
|
|
|
describe "all_tags/0" do
|
|
test "returns unique sorted tags from published posts", %{blog: blog} do
|
|
tags = blog.all_tags()
|
|
|
|
assert tags == Enum.sort(tags)
|
|
assert "elixir" in tags
|
|
assert "devops" in tags
|
|
end
|
|
|
|
test "excludes tags only appearing on drafts" do
|
|
{:ok, _} = FakeBlog.start([
|
|
build(tags: ["visible"], published: true),
|
|
build(id: "d", tags: ["hidden"], published: false)
|
|
])
|
|
|
|
refute "hidden" in FakeBlog.all_tags()
|
|
end
|
|
end
|
|
|
|
describe "get_post!/1" do
|
|
test "returns post by id", %{blog: blog} do
|
|
post = blog.get_post!("oldest-post")
|
|
|
|
assert post.id == "oldest-post"
|
|
end
|
|
|
|
test "raises for unknown id", %{blog: blog} do
|
|
assert_raise Blogex.NotFoundError, fn ->
|
|
blog.get_post!("nope")
|
|
end
|
|
end
|
|
|
|
test "raises for draft post id", %{blog: blog} do
|
|
assert_raise Blogex.NotFoundError, fn ->
|
|
blog.get_post!("draft-post")
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "get_post/1" do
|
|
test "returns nil for unknown id", %{blog: blog} do
|
|
assert blog.get_post("nope") == nil
|
|
end
|
|
end
|
|
|
|
describe "paginate/2" do
|
|
setup do
|
|
posts = build_many(25)
|
|
{:ok, _} = FakeBlog.start(posts)
|
|
%{blog: FakeBlog}
|
|
end
|
|
|
|
test "returns the correct page size", %{blog: blog} do
|
|
result = blog.paginate(1, 10)
|
|
|
|
assert length(result.entries) == 10
|
|
end
|
|
|
|
test "calculates total pages", %{blog: blog} do
|
|
result = blog.paginate(1, 10)
|
|
|
|
assert result.total_pages == 3
|
|
assert result.total_entries == 25
|
|
end
|
|
|
|
test "returns fewer entries on last page", %{blog: blog} do
|
|
result = blog.paginate(3, 10)
|
|
|
|
assert length(result.entries) == 5
|
|
end
|
|
|
|
test "page 2 does not overlap with page 1", %{blog: blog} do
|
|
page1_ids = blog.paginate(1, 10).entries |> MapSet.new(& &1.id)
|
|
page2_ids = blog.paginate(2, 10).entries |> MapSet.new(& &1.id)
|
|
|
|
assert MapSet.disjoint?(page1_ids, page2_ids)
|
|
end
|
|
|
|
test "returns empty entries beyond last page", %{blog: blog} do
|
|
result = blog.paginate(99, 10)
|
|
|
|
assert result.entries == []
|
|
end
|
|
end
|
|
end
|