Non-admin users can now submit beacons but they are held in an unapproved state until an admin approves them. Only approved beacons appear in the public list; pending submissions are shown in a separate admin-only section on /beacons with Approve and Delete actions. The show page surfaces a pending badge and an admin-only Approve button when viewing an unapproved beacon. Also formats EIRP (mW) on the index page without scientific notation.
149 lines
4.9 KiB
Elixir
149 lines
4.9 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 does not see the Submit Beacon button", %{conn: conn} do
|
|
{:ok, _view, html} = live(conn, ~p"/beacons")
|
|
refute 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 =~ "#{beacon.frequency_mhz}"
|
|
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 "redirects anonymous user away from /beacons/new", %{conn: conn} do
|
|
assert {:error, {:redirect, %{to: "/users/log-in"}}} = live(conn, ~p"/beacons/new")
|
|
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
|