defmodule Firehose.Test.FakeBlog do @moduledoc """ A test double that implements the blog module interface, backed by an Agent so tests can control the post data. """ use Agent @defaults [ blog_id: :test_blog, title: "Test Blog", description: "A blog for tests", base_path: "/blog/test" ] def start(posts \\ [], opts \\ []) do opts = Keyword.merge(@defaults, opts) state = %{ posts: posts, blog_id: opts[:blog_id], title: opts[:title], description: opts[:description], base_path: opts[:base_path] } case Agent.start(fn -> state end, name: __MODULE__) do {:ok, pid} -> {:ok, pid} {:error, {:already_started, pid}} -> Agent.update(__MODULE__, fn _ -> state end) {:ok, pid} end end defp get(key), do: Agent.get(__MODULE__, &Map.fetch!(&1, key)) def blog_id, do: get(:blog_id) def title, do: get(:title) def description, do: get(:description) def base_path, do: get(:base_path) def all_posts_unfiltered do get(:posts) |> Enum.sort_by(& &1.date, {:desc, Date}) end def unfiltered_posts do all_posts_unfiltered() end def all_posts do get(:posts) |> Enum.filter(& &1.published) |> Enum.sort_by(& &1.date, {:desc, Date}) end def all_tags do all_posts() |> Enum.flat_map(& &1.tags) |> Enum.uniq() |> Enum.sort() end end