193 lines
4.9 KiB
Elixir
193 lines
4.9 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 "excludes future-dated posts", %{blog: blog} do
|
|
ids = blog.all_posts() |> Enum.map(& &1.id)
|
|
|
|
refute "future-post" in ids
|
|
end
|
|
|
|
test "includes today-dated published posts" do
|
|
{:ok, _} = FakeBlog.start([
|
|
build(id: "today", date: Date.utc_today(), published: true),
|
|
build(id: "tomorrow", date: Date.add(Date.utc_today(), 1), published: true)
|
|
])
|
|
|
|
ids = FakeBlog.all_posts() |> Enum.map(& &1.id)
|
|
|
|
assert "today" in ids
|
|
refute "tomorrow" 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 "excludes future-dated posts", %{blog: blog} do
|
|
posts = blog.recent_posts(100)
|
|
ids = Enum.map(posts, & &1.id)
|
|
|
|
refute "future-post" in ids
|
|
end
|
|
|
|
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 "excludes future-dated posts", %{blog: blog} do
|
|
posts = blog.posts_by_tag("future-only")
|
|
|
|
assert posts == []
|
|
end
|
|
|
|
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 "excludes tags only on future-dated posts", %{blog: blog} do
|
|
refute "future-only" in blog.all_tags()
|
|
end
|
|
|
|
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 "returns a future-dated published post by slug", %{blog: blog} do
|
|
post = blog.get_post!("future-post")
|
|
assert post.id == "future-post"
|
|
end
|
|
|
|
test "returns a draft post by slug", %{blog: blog} do
|
|
post = blog.get_post!("draft-post")
|
|
assert post.id == "draft-post"
|
|
end
|
|
end
|
|
|
|
describe "get_post/1" do
|
|
test "returns nil for unknown id", %{blog: blog} do
|
|
assert blog.get_post("nope") == nil
|
|
end
|
|
|
|
test "returns a future-dated post", %{blog: blog} do
|
|
assert %{id: "future-post"} = blog.get_post("future-post")
|
|
end
|
|
|
|
test "returns a draft post", %{blog: blog} do
|
|
assert %{id: "draft-post"} = blog.get_post("draft-post")
|
|
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
|