Add LiveView editor dashboard with drafts and scheduled tabs

This commit is contained in:
Willem van den Ende
2026-04-01 21:42:45 +00:00
parent 5395b2de80
commit f1560ff0e7
6 changed files with 309 additions and 1 deletions
@@ -0,0 +1,88 @@
defmodule FirehoseWeb.EditorDashboardLiveTest do
use FirehoseWeb.ConnCase, async: true
import Phoenix.LiveViewTest
setup do
posts = [
%Blogex.Post{
id: "live-post",
title: "Live Post",
author: "Test Author",
body: "<p>Body</p>",
description: "A live post",
date: ~D[2020-01-01],
published: true,
blog: :test_blog,
tags: []
},
%Blogex.Post{
id: "draft-post",
title: "Draft Post",
author: "Test Author",
body: "<p>Body</p>",
description: "A draft post",
date: ~D[2026-03-12],
published: false,
blog: :test_blog,
tags: []
},
%Blogex.Post{
id: "scheduled-post",
title: "Scheduled Post",
author: "Test Author",
body: "<p>Body</p>",
description: "A scheduled post",
date: ~D[2099-06-15],
published: true,
blog: :test_blog,
tags: ["future"]
}
]
{:ok, _} =
Firehose.Test.FakeBlog.start(posts,
blog_id: :test_blog,
title: "Test Blog",
base_path: "/blog/test"
)
Application.put_env(:blogex, :blogs, [Firehose.Test.FakeBlog])
on_exit(fn -> Application.delete_env(:blogex, :blogs) end)
:ok
end
describe "unauthenticated" do
test "redirects to login", %{conn: conn} do
assert {:error, redirect} = live(conn, ~p"/editor/dashboard")
assert {:redirect, %{to: to}} = redirect
assert to =~ "/users/log-in"
end
end
describe "authenticated" do
setup :register_and_log_in_user
test "renders the dashboard", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/editor/dashboard")
assert html =~ "Dashboard"
end
test "shows draft posts", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/editor/dashboard")
assert html =~ "Draft Post"
end
test "shows scheduled posts with days until live", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/editor/dashboard")
assert html =~ "Scheduled Post"
assert html =~ "days"
end
test "does not show live posts", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/editor/dashboard")
refute html =~ "Live Post"
end
end
end
+65
View File
@@ -0,0 +1,65 @@
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