defmodule MicrowavepropWeb.RoverLocationsLiveTest do use MicrowavepropWeb.ConnCase, async: true import Phoenix.LiveViewTest alias Microwaveprop.Rover alias Microwaveprop.Rover.Location describe "anonymous visitor" do test "can view the locations page", %{conn: conn} do {:ok, _lv, html} = live(conn, ~p"/rover-locations") assert html =~ "Rover Locations" assert html =~ "Sign in" end test "shows existing locations from any user", %{conn: conn} do user = Microwaveprop.AccountsFixtures.user_fixture() {:ok, _} = Rover.create_location(user, %{ lat: 32.5, lon: -97.5, status: :ideal, notes: "great hill" }) {:ok, _lv, html} = live(conn, ~p"/rover-locations") assert html =~ "Ideal" assert html =~ "great hill" end test "Add button is disabled for anonymous users", %{conn: conn} do {:ok, _lv, html} = live(conn, ~p"/rover-locations") assert html =~ ~s(disabled) assert html =~ "Add location" end test "status filter narrows the visible rows", %{conn: conn} do user = Microwaveprop.AccountsFixtures.user_fixture() {:ok, _} = Rover.create_location(user, %{lat: 32.0, lon: -97.0, status: :ideal, notes: "ideal-spot"}) {:ok, _} = Rover.create_location(user, %{lat: 33.0, lon: -98.0, status: :off_limits, notes: "no-go-spot"}) {:ok, lv, html} = live(conn, ~p"/rover-locations") assert html =~ "ideal-spot" assert html =~ "no-go-spot" html = lv |> form("form[phx-change=filter_status]", %{"value" => "ideal"}) |> render_change() assert html =~ "ideal-spot" refute html =~ "no-go-spot" html = lv |> form("form[phx-change=filter_status]", %{"value" => "off_limits"}) |> render_change() refute html =~ "ideal-spot" assert html =~ "no-go-spot" end end describe "logged-in user" do setup :register_and_log_in_user test "can add a new location", %{conn: conn} do {:ok, lv, _html} = live(conn, ~p"/rover-locations") lv |> element("button", "Add location") |> render_click() lv |> form("#location-form", location: %{lat: "32.5", lon: "-97.5", status: "ideal", notes: "test note"} ) |> render_submit() html = render(lv) assert html =~ "test note" end test "typing a grid populates lat/lon", %{conn: conn} do {:ok, lv, _html} = live(conn, ~p"/rover-locations") lv |> element("button", "Add location") |> render_click() html = lv |> form("#location-form", location: %{ grid: "EM12kp", lat: "", lon: "", status: "ideal", notes: "" } ) |> render_change(%{"_target" => ["location", "grid"]}) # EM12kp center: lat 32.645833, lon -97.125 assert html =~ ~s(value="32.645833") assert html =~ ~s(value="-97.125") end test "typing lat/lon populates the grid field", %{conn: conn} do {:ok, lv, _html} = live(conn, ~p"/rover-locations") lv |> element("button", "Add location") |> render_click() html = lv |> form("#location-form", location: %{ grid: "", lat: "32.5", lon: "-97.5", status: "ideal", notes: "" } ) |> render_change(%{"_target" => ["location", "lat"]}) assert html =~ ~s(value="EM12gm") end test "the location cell links to the show page", %{conn: conn, user: user} do {:ok, loc} = Rover.create_location(user, %{ lat: 32.5, lon: -97.5, status: :ideal, notes: "rooftop spot" }) {:ok, lv, _html} = live(conn, ~p"/rover-locations") assert has_element?(lv, "a[href='/rover-locations/#{loc.id}']") end test "edit/delete buttons appear only on the owner's row", %{conn: conn, user: user} do other = Microwaveprop.AccountsFixtures.user_fixture() {:ok, mine} = Rover.create_location(user, %{lat: 32.0, lon: -97.0, status: :ideal}) {:ok, theirs} = Rover.create_location(other, %{lat: 33.0, lon: -98.0, status: :off_limits}) {:ok, lv, _html} = live(conn, ~p"/rover-locations") assert has_element?(lv, "button[phx-click=edit][phx-value-id='#{mine.id}']", "Edit") assert has_element?(lv, "button[phx-click=delete][phx-value-id='#{mine.id}']", "Delete") refute has_element?(lv, "button[phx-click=edit][phx-value-id='#{theirs.id}']", "Edit") refute has_element?(lv, "button[phx-click=delete][phx-value-id='#{theirs.id}']", "Delete") end end describe "admin" do test "sees edit/delete on every row and can delete a stranger's location", %{conn: conn} do admin = Microwaveprop.AccountsFixtures.user_fixture() {:ok, admin} = Microwaveprop.Accounts.admin_update_user(admin, %{is_admin: true}) other = Microwaveprop.AccountsFixtures.user_fixture() {:ok, theirs} = Rover.create_location(other, %{lat: 33.0, lon: -98.0, status: :ideal}) conn = log_in_user(conn, admin) {:ok, lv, _html} = live(conn, ~p"/rover-locations") assert has_element?(lv, "button[phx-click=edit][phx-value-id='#{theirs.id}']", "Edit") assert has_element?(lv, "button[phx-click=delete][phx-value-id='#{theirs.id}']", "Delete") lv |> element("button[phx-click=delete][phx-value-id='#{theirs.id}']") |> render_click() refute Microwaveprop.Repo.get(Location, theirs.id) end test "can edit a stranger's location", %{conn: conn} do admin = Microwaveprop.AccountsFixtures.user_fixture() {:ok, admin} = Microwaveprop.Accounts.admin_update_user(admin, %{is_admin: true}) other = Microwaveprop.AccountsFixtures.user_fixture() {:ok, theirs} = Rover.create_location(other, %{ lat: 33.0, lon: -98.0, status: :ideal, notes: "old" }) conn = log_in_user(conn, admin) {:ok, lv, _html} = live(conn, ~p"/rover-locations") lv |> element("button[phx-click=edit][phx-value-id='#{theirs.id}']") |> render_click() lv |> form("#location-form", location: %{ lat: "33.0", lon: "-98.0", status: "off_limits", notes: "admin override" } ) |> render_submit() updated = Microwaveprop.Repo.get(Location, theirs.id) assert updated.notes == "admin override" assert updated.status == :off_limits end end end