defmodule BerrypodWeb.NewsletterControllerTest do use BerrypodWeb.ConnCase, async: true alias Berrypod.Newsletter alias Berrypod.Newsletter.Subscriber alias Berrypod.Repo describe "POST /newsletter/subscribe" do test "subscribes and redirects back", %{conn: conn} do Newsletter.set_newsletter_enabled(true) conn = conn |> put_req_header("referer", "http://localhost:4002/") |> post(~p"/newsletter/subscribe", %{email: "new@example.com"}) assert redirected_to(conn) == "/" assert Phoenix.Flash.get(conn.assigns.flash, :info) =~ "Check your inbox" end test "handles already confirmed subscriber", %{conn: conn} do Newsletter.set_newsletter_enabled(true) # Create a confirmed subscriber directly now = DateTime.utc_now() |> DateTime.truncate(:second) %Subscriber{} |> Subscriber.changeset(%{ email: "confirmed@example.com", status: "confirmed", confirmed_at: now }) |> Repo.insert!() conn = conn |> put_req_header("referer", "http://localhost:4002/about") |> post(~p"/newsletter/subscribe", %{email: "confirmed@example.com"}) assert redirected_to(conn) == "/about" assert Phoenix.Flash.get(conn.assigns.flash, :info) =~ "already subscribed" end test "shows error for invalid email", %{conn: conn} do Newsletter.set_newsletter_enabled(true) conn = conn |> put_req_header("referer", "http://localhost:4002/") |> post(~p"/newsletter/subscribe", %{email: "not-an-email"}) assert redirected_to(conn) == "/" assert Phoenix.Flash.get(conn.assigns.flash, :error) =~ "valid email" end test "redirects to / when no referer", %{conn: conn} do Newsletter.set_newsletter_enabled(true) conn = post(conn, ~p"/newsletter/subscribe", %{email: "test@example.com"}) assert redirected_to(conn) == "/" end end describe "GET /newsletter/confirm/:token" do test "confirms pending subscriber", %{conn: conn} do # Create a pending subscriber with a known raw token raw_token = "test-confirmation-token-abc123" hashed_token = :crypto.hash(:sha256, raw_token) |> Base.encode16(case: :lower) %Subscriber{} |> Subscriber.changeset(%{ email: "pending@example.com", status: "pending", confirmation_token: hashed_token }) |> Repo.insert!() conn = get(conn, "/newsletter/confirm/#{raw_token}") assert conn.status == 200 assert conn.resp_body =~ "subscribed" # Verify the subscriber is now confirmed sub = Repo.get_by!(Subscriber, email: "pending@example.com") assert sub.status == "confirmed" end test "returns error for invalid token", %{conn: conn} do conn = get(conn, "/newsletter/confirm/invalid-token-here") assert conn.status == 400 assert conn.resp_body =~ "invalid" end end end