defmodule MicrowavepropWeb.Api.V1.BeaconControllerTest do use MicrowavepropWeb.ConnCase, async: true alias Microwaveprop.Accounts alias Microwaveprop.AccountsFixtures alias Microwaveprop.Beacons alias MicrowavepropWeb.Api.RateLimiter @valid %{ "frequency_mhz" => 10_368.1, "callsign" => "W5HN", "lat" => 32.897, "lon" => -97.038, "power_mw" => 1000.0, "height_ft" => 100, "keying" => "on_off" } setup %{conn: conn} do RateLimiter.reset() user = AccountsFixtures.user_fixture() {:ok, {plaintext, _}} = Accounts.create_api_token(user, %{name: "t"}) %{conn: conn, user: user, plaintext: plaintext} end describe "GET /api/v1/beacons" do test "returns approved beacons only", %{conn: conn, user: user} do {:ok, approved} = Beacons.create_beacon(user, @valid) {:ok, _} = Beacons.approve_beacon(approved) {:ok, _pending} = Beacons.create_beacon(user, Map.put(@valid, "callsign", "K5XX")) body = conn |> get(~p"/api/v1/beacons") |> json_response(200) assert Enum.any?(body["data"], &(&1["callsign"] == "W5HN")) refute Enum.any?(body["data"], &(&1["callsign"] == "K5XX")) end end describe "GET /api/v1/beacons/:id" do test "returns approved beacons to anonymous viewers", %{conn: conn, user: user} do {:ok, b} = Beacons.create_beacon(user, @valid) {:ok, b} = Beacons.approve_beacon(b) body = conn |> get(~p"/api/v1/beacons/#{b.id}") |> json_response(200) assert body["data"]["id"] == b.id end test "404 for anonymous viewers on unapproved beacons", %{conn: conn, user: user} do {:ok, b} = Beacons.create_beacon(user, @valid) conn = get(conn, ~p"/api/v1/beacons/#{b.id}") assert json_response(conn, 404) end test "submitter can view their own unapproved beacon", %{conn: conn, user: user, plaintext: pt} do {:ok, b} = Beacons.create_beacon(user, @valid) body = conn |> put_req_header("authorization", "Bearer " <> pt) |> get(~p"/api/v1/beacons/#{b.id}") |> json_response(200) assert body["data"]["id"] == b.id assert body["data"]["approved"] == false end test "non-owner non-admin gets 404 on another user's unapproved beacon", %{conn: conn, user: user} do {:ok, b} = Beacons.create_beacon(user, @valid) other = AccountsFixtures.user_fixture() {:ok, {other_pt, _}} = Accounts.create_api_token(other, %{name: "t"}) conn = conn |> put_req_header("authorization", "Bearer " <> other_pt) |> get(~p"/api/v1/beacons/#{b.id}") assert json_response(conn, 404) end test "404 on unknown id", %{conn: conn} do conn = get(conn, ~p"/api/v1/beacons/00000000-0000-0000-0000-000000000000") assert json_response(conn, 404) end test "404 on malformed id", %{conn: conn} do conn = get(conn, ~p"/api/v1/beacons/not-a-uuid") assert json_response(conn, 404) end end describe "POST /api/v1/beacons" do test "requires auth", %{conn: conn} do conn = post(conn, ~p"/api/v1/beacons", @valid) assert json_response(conn, 401) end test "creates a beacon under the authenticated user", %{conn: conn, plaintext: pt} do conn = conn |> put_req_header("authorization", "Bearer " <> pt) |> post(~p"/api/v1/beacons", @valid) body = json_response(conn, 201) assert body["data"]["callsign"] == "W5HN" assert body["data"]["approved"] == false end test "422 on invalid payload", %{conn: conn, plaintext: pt} do conn = conn |> put_req_header("authorization", "Bearer " <> pt) |> post(~p"/api/v1/beacons", %{"callsign" => "x"}) assert json_response(conn, 422) end end end