berrypod/test/berrypod_web/live/admin/newsletter_test.exs
jamey ad2e6d1e6d add newsletter and email campaigns
Subscribers with double opt-in confirmation, campaign composer with
draft/scheduled/sent lifecycle, admin dashboard with overview stats,
CSV export, and shop signup form wired into page builder blocks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 23:25:28 +00:00

132 lines
3.8 KiB
Elixir

defmodule BerrypodWeb.Admin.NewsletterTest do
use BerrypodWeb.ConnCase, async: true
import Phoenix.LiveViewTest
import Berrypod.AccountsFixtures
import Berrypod.NewsletterFixtures
alias Berrypod.Newsletter
setup %{conn: conn} do
user = user_fixture()
conn = log_in_user(conn, user)
%{conn: conn, user: user}
end
describe "overview tab" do
test "shows newsletter toggle", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/newsletter")
assert has_element?(view, "[role=switch]")
end
test "toggles newsletter enabled", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/newsletter")
refute Newsletter.newsletter_enabled?()
view |> element("[role=switch]") |> render_click()
assert Newsletter.newsletter_enabled?()
end
test "shows subscriber counts", %{conn: conn} do
confirmed_subscriber_fixture(email: "a@example.com")
confirmed_subscriber_fixture(email: "b@example.com")
{:ok, _view, html} = live(conn, ~p"/admin/newsletter")
assert html =~ "2"
assert html =~ "Confirmed"
end
end
describe "subscribers tab" do
test "lists subscribers", %{conn: conn} do
confirmed_subscriber_fixture(email: "listed@example.com")
{:ok, view, _html} = live(conn, ~p"/admin/newsletter?tab=subscribers")
assert has_element?(view, "#subscribers")
assert render(view) =~ "listed@example.com"
end
test "filters by status", %{conn: conn} do
confirmed_subscriber_fixture(email: "confirmed@example.com")
{:ok, view, _html} = live(conn, ~p"/admin/newsletter?tab=subscribers")
# Filter to confirmed only
view |> element("button", "Confirmed") |> render_click()
assert render(view) =~ "confirmed@example.com"
end
test "searches subscribers", %{conn: conn} do
confirmed_subscriber_fixture(email: "findme@example.com")
confirmed_subscriber_fixture(email: "other@example.com")
{:ok, view, _html} = live(conn, ~p"/admin/newsletter?tab=subscribers")
view |> element("form") |> render_change(%{search: "findme"})
html = render(view)
assert html =~ "findme@example.com"
refute html =~ "other@example.com"
end
test "deletes subscriber", %{conn: conn} do
confirmed_subscriber_fixture(email: "deleteme@example.com")
{:ok, view, _html} = live(conn, ~p"/admin/newsletter?tab=subscribers")
assert render(view) =~ "deleteme@example.com"
view |> element("button", "Delete") |> render_click()
refute render(view) =~ "deleteme@example.com"
end
end
describe "campaigns tab" do
test "lists campaigns", %{conn: conn} do
campaign_fixture(subject: "Test campaign")
{:ok, view, _html} = live(conn, ~p"/admin/newsletter?tab=campaigns")
assert render(view) =~ "Test campaign"
end
test "deletes draft campaign", %{conn: conn} do
campaign_fixture(subject: "Delete me")
{:ok, view, _html} = live(conn, ~p"/admin/newsletter?tab=campaigns")
assert render(view) =~ "Delete me"
view |> element("button", "Delete") |> render_click()
refute render(view) =~ "Delete me"
end
test "links to new campaign form", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/newsletter?tab=campaigns")
assert has_element?(view, "a[href='/admin/newsletter/campaigns/new']")
end
end
describe "GET /admin/newsletter/export" do
test "downloads CSV of subscribers", %{conn: conn} do
confirmed_subscriber_fixture(email: "export@example.com")
conn = get(conn, ~p"/admin/newsletter/export")
assert response_content_type(conn, :csv) =~ "text/csv"
assert get_resp_header(conn, "content-disposition") |> hd() =~ "attachment"
assert conn.resp_body =~ "export@example.com"
assert conn.resp_body =~ "email,status"
end
end
end