prop/test/microwaveprop_web/live/beacon_live_test.exs
Graham McIntire 8425edbdc4 Add comma separators to MHz frequencies on beacon pages
Formats frequencies like 10368.1 as "10,368.1" on both the
beacon list table and detail page (subtitle, map label, stat field).
2026-04-11 09:37:26 -05:00

171 lines
5.5 KiB
Elixir

defmodule MicrowavepropWeb.BeaconLiveTest do
use MicrowavepropWeb.ConnCase
import Microwaveprop.AccountsFixtures
import Microwaveprop.BeaconsFixtures
import Phoenix.LiveViewTest
alias Microwaveprop.Accounts
defp promote_to_admin(user) do
{:ok, user} = Accounts.admin_update_user(user, %{is_admin: true})
user
end
defp admin_user_fixture do
promote_to_admin(user_fixture())
end
defp approved_beacon_fixture(user, attrs \\ %{}) do
beacon = beacon_fixture(user, attrs)
{:ok, beacon} = Microwaveprop.Beacons.approve_beacon(beacon)
beacon
end
describe "Index (public)" do
test "lists approved beacons without logging in", %{conn: conn} do
beacon = approved_beacon_fixture(user_fixture())
{:ok, _view, html} = live(conn, ~p"/beacons")
assert html =~ "Beacons"
assert html =~ beacon.callsign
end
test "hides unapproved beacons from the public list", %{conn: conn} do
_pending = beacon_fixture(user_fixture(), callsign: "W5PEN")
{:ok, _view, html} = live(conn, ~p"/beacons")
refute html =~ "W5PEN"
end
test "anonymous sees the Submit Beacon button", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/beacons")
assert html =~ "Submit Beacon"
end
test "authenticated user sees the Submit Beacon button", %{conn: conn} do
user = user_fixture()
conn = log_in_user(conn, user)
{:ok, _view, html} = live(conn, ~p"/beacons")
assert html =~ "Submit Beacon"
end
test "admin sees pending beacons section", %{conn: conn} do
pending = beacon_fixture(user_fixture(), callsign: "W5PEN")
conn = log_in_user(conn, admin_user_fixture())
{:ok, _view, html} = live(conn, ~p"/beacons")
assert html =~ "Pending approval"
assert html =~ pending.callsign
end
test "non-admin does not see pending beacons section", %{conn: conn} do
_pending = beacon_fixture(user_fixture(), callsign: "W5PEN")
conn = log_in_user(conn, user_fixture())
{:ok, _view, html} = live(conn, ~p"/beacons")
refute html =~ "Pending approval"
refute html =~ "W5PEN"
end
test "admin can approve a pending beacon", %{conn: conn} do
pending = beacon_fixture(user_fixture(), callsign: "W5PEN")
conn = log_in_user(conn, admin_user_fixture())
{:ok, view, _html} = live(conn, ~p"/beacons")
html =
view
|> element("a[phx-click][data-confirm='Approve this beacon?']")
|> render_click()
assert html =~ "Approved #{pending.callsign}"
assert Microwaveprop.Beacons.get_beacon!(pending.id).approved == true
end
end
describe "Show (public)" do
test "renders beacon details without logging in", %{conn: conn} do
beacon = approved_beacon_fixture(user_fixture())
{:ok, _view, html} = live(conn, ~p"/beacons/#{beacon}")
assert html =~ beacon.callsign
assert html =~ "10,368.1"
end
test "shows pending badge on unapproved beacons", %{conn: conn} do
beacon = beacon_fixture(user_fixture())
{:ok, _view, html} = live(conn, ~p"/beacons/#{beacon}")
assert html =~ "Pending approval"
end
end
describe "Form" do
test "authenticated non-admin can access /beacons/new", %{conn: conn} do
user = user_fixture()
conn = log_in_user(conn, user)
{:ok, _view, html} = live(conn, ~p"/beacons/new")
assert html =~ "New beacon"
end
test "anonymous user can access /beacons/new", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/beacons/new")
assert html =~ "New beacon"
end
test "anonymous submission creates an unapproved beacon with no user_id", %{conn: conn} do
{:ok, form_live, _html} = live(conn, ~p"/beacons/new")
attrs = valid_beacon_attrs(callsign: "W5ANON")
assert {:ok, _view, html} =
form_live
|> form("#beacon-form", beacon: attrs)
|> render_submit()
|> follow_redirect(conn, ~p"/beacons")
assert html =~ "awaiting admin approval"
beacon =
Enum.find(Microwaveprop.Beacons.list_pending_beacons(), fn b -> b.callsign == "W5ANON" end)
assert beacon
assert beacon.user_id == nil
assert beacon.approved == false
end
test "non-admin submission creates an unapproved beacon", %{conn: conn} do
user = user_fixture()
conn = log_in_user(conn, user)
{:ok, form_live, _html} = live(conn, ~p"/beacons/new")
attrs = valid_beacon_attrs()
assert {:ok, _view, _html} =
form_live
|> form("#beacon-form", beacon: attrs)
|> render_submit()
|> follow_redirect(conn, ~p"/beacons")
beacon = List.first(Microwaveprop.Beacons.list_pending_beacons())
assert beacon.callsign == attrs.callsign
assert beacon.approved == false
end
test "admin edits a beacon", %{conn: conn} do
admin = admin_user_fixture()
beacon = beacon_fixture(admin)
conn = log_in_user(conn, admin)
{:ok, form_live, _} = live(conn, ~p"/beacons/#{beacon}/edit")
assert {:ok, _view, html} =
form_live
|> form("#beacon-form", beacon: %{power_mw: 25_000.0})
|> render_submit()
|> follow_redirect(conn, ~p"/beacons")
assert html =~ "Beacon updated"
end
test "non-admin cannot access /beacons/:id/edit", %{conn: conn} do
beacon = beacon_fixture(user_fixture())
conn = log_in_user(conn, user_fixture())
assert {:error, {:redirect, %{to: "/"}}} = live(conn, ~p"/beacons/#{beacon}/edit")
end
end
end