defmodule DiogramosWeb.CanvasDeleteTest do
use DiogramosWeb.ConnCase, async: true
import Phoenix.LiveViewTest
import Diogramos.AccountsFixtures
import Diogramos.DiagramsFixtures
alias Diogramos.Accounts.Scope
alias Diogramos.Diagrams
setup %{conn: conn} do
owner = user_fixture()
scope = Scope.for_user(owner)
canvas = canvas_fixture(scope, %{title: "Doomed"})
%{conn: log_in_user(conn, owner), owner: owner, scope: scope, canvas: canvas}
end
defp open_manage(lv, canvas) do
lv |> element("button[phx-value-id='#{canvas.id}']") |> render_click()
end
describe "the danger zone" do
test "asks for the slug before it will delete", %{conn: conn, canvas: canvas} do
{:ok, lv, _html} = live(conn, ~p"/canvases")
html = open_manage(lv, canvas)
assert html =~ "Danger zone"
assert html =~ "Type"
assert html =~ canvas.slug
# The button stays disabled until the slug is typed, so a stray
# click can't delete anything.
assert html =~ "disabled"
end
test "deletes when the slug matches", %{conn: conn, scope: scope, canvas: canvas} do
{:ok, lv, _html} = live(conn, ~p"/canvases")
open_manage(lv, canvas)
html =
lv
|> form("#manage-delete-form", %{"confirm" => canvas.slug})
|> render_submit()
assert html =~ "Deleted Doomed."
refute html =~ canvas.slug
refute Diagrams.get_canvas_by_slug(scope, canvas.slug)
end
test "refuses anything that isn't the slug, and keeps the canvas", %{
conn: conn,
scope: scope,
canvas: canvas
} do
{:ok, lv, _html} = live(conn, ~p"/canvases")
open_manage(lv, canvas)
for typed <- ["", " ", "Doomed", canvas.slug <> "x", String.upcase(canvas.slug)] do
html =
lv
|> form("#manage-delete-form", %{"confirm" => typed})
|> render_submit()
assert html =~ "Type #{canvas.slug} exactly to confirm"
assert Diagrams.get_canvas_by_slug(scope, canvas.slug)
end
end
test "surrounding whitespace is forgiven", %{conn: conn, scope: scope, canvas: canvas} do
{:ok, lv, _html} = live(conn, ~p"/canvases")
open_manage(lv, canvas)
# Pasting a slug tends to bring a space with it, and the typed
# confirmation is there to prove intent, not typing accuracy.
lv
|> form("#manage-delete-form", %{"confirm" => " #{canvas.slug} "})
|> render_submit()
refute Diagrams.get_canvas_by_slug(scope, canvas.slug)
end
test "a delete event with no canvas open does nothing", %{
conn: conn,
scope: scope,
canvas: canvas
} do
{:ok, lv, _html} = live(conn, ~p"/canvases")
# The modal was never opened, so there is nothing to confirm
# against -- and the slug alone must not be enough.
render_click(lv, "delete_canvas", %{"confirm" => canvas.slug})
assert Diagrams.get_canvas_by_slug(scope, canvas.slug)
end
end
describe "access" do
test "an editor sees the canvas but is offered no way to manage it", %{
conn: conn,
canvas: canvas
} do
editor = user_fixture()
{:ok, _} = Diagrams.grant_permission("canvas", canvas.id, "user", editor.id, "editor")
{:ok, lv, html} = live(log_in_user(conn, editor), ~p"/canvases")
assert html =~ canvas.title
refute has_element?(lv, "button[phx-value-id='#{canvas.id}']")
end
test "an editor sending the event by hand is refused", %{conn: conn, canvas: canvas} do
editor = user_fixture()
{:ok, _} = Diagrams.grant_permission("canvas", canvas.id, "user", editor.id, "editor")
{:ok, lv, _html} = live(log_in_user(conn, editor), ~p"/canvases")
# The button isn't rendered for them, so this is the interesting
# path: the handler has to refuse it on its own.
html = render_click(lv, "open_manage_modal", %{"id" => to_string(canvas.id)})
assert html =~ "Only the owner can manage collaborators."
refute html =~ "Danger zone"
end
test "an editor's delete event is refused by the context too", %{canvas: canvas} do
editor = user_fixture()
{:ok, _} = Diagrams.grant_permission("canvas", canvas.id, "user", editor.id, "editor")
# Defence in depth: the modal is owner-only, and so is the delete.
assert {:error, :forbidden} =
Diagrams.delete_canvas(Scope.for_user(editor), canvas)
end
end
end
neiam
/diogramos
diogramos
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
Log in to mark this repository.
4.4 KiB · text
History
dc2edab