182 lines
5.9 KiB
Elixir
182 lines
5.9 KiB
Elixir
defmodule ToweropsWeb.AlertLive.IndexEventsTest do
|
|
@moduledoc """
|
|
Drives the bulk-action and toggle event handlers in AlertLive.Index that
|
|
aren't exercised by the existing render-focused test file.
|
|
"""
|
|
use ToweropsWeb.ConnCase, async: true
|
|
|
|
import Phoenix.LiveViewTest
|
|
|
|
alias Towerops.Alerts
|
|
|
|
setup :register_and_log_in_user
|
|
|
|
setup %{user: user} do
|
|
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Bulk Org"}, user.id)
|
|
|
|
{:ok, site} = Towerops.Sites.create_site(%{name: "Site 1", organization_id: organization.id})
|
|
|
|
{:ok, device} =
|
|
Towerops.Devices.create_device(%{
|
|
name: "Router 1",
|
|
ip_address: "10.0.0.1",
|
|
site_id: site.id,
|
|
organization_id: organization.id
|
|
})
|
|
|
|
{:ok, alert1} =
|
|
Alerts.create_alert(%{
|
|
device_id: device.id,
|
|
alert_type: "device_down",
|
|
triggered_at: DateTime.truncate(DateTime.utc_now(), :second),
|
|
severity: 1
|
|
})
|
|
|
|
{:ok, alert2} =
|
|
Alerts.create_alert(%{
|
|
device_id: device.id,
|
|
alert_type: "device_down",
|
|
triggered_at: DateTime.truncate(DateTime.utc_now(), :second),
|
|
severity: 2
|
|
})
|
|
|
|
%{organization: organization, site: site, device: device, alert1: alert1, alert2: alert2}
|
|
end
|
|
|
|
describe "acknowledge / resolve event handlers" do
|
|
test "acknowledge flashes success and stamps the alert", %{
|
|
conn: conn,
|
|
alert1: alert1
|
|
} do
|
|
{:ok, view, _html} = live(conn, ~p"/alerts")
|
|
|
|
html = render_hook(view, "acknowledge", %{"id" => alert1.id})
|
|
assert html =~ ~r/acknowledged|Alert/
|
|
|
|
assert Alerts.get_alert!(alert1.id).acknowledged_at
|
|
end
|
|
|
|
test "acknowledge with unknown id flashes 'not found'", %{conn: conn} do
|
|
{:ok, view, _html} = live(conn, ~p"/alerts")
|
|
html = render_hook(view, "acknowledge", %{"id" => Ecto.UUID.generate()})
|
|
assert html =~ ~r/not found|Alert/
|
|
end
|
|
|
|
test "resolve flashes success and resolves the alert", %{
|
|
conn: conn,
|
|
alert1: alert1
|
|
} do
|
|
{:ok, view, _html} = live(conn, ~p"/alerts")
|
|
_ = render_hook(view, "resolve", %{"id" => alert1.id})
|
|
|
|
assert Alerts.get_alert!(alert1.id).resolved_at
|
|
end
|
|
|
|
test "resolve with unknown id flashes 'not found'", %{conn: conn} do
|
|
{:ok, view, _html} = live(conn, ~p"/alerts")
|
|
html = render_hook(view, "resolve", %{"id" => Ecto.UUID.generate()})
|
|
assert html =~ ~r/not found|Alert/
|
|
end
|
|
|
|
test "acknowledge of an alert from another org is rejected as unauthorized", %{conn: conn} do
|
|
# Create a foreign alert outside the user's org.
|
|
foreign_user = Towerops.AccountsFixtures.user_fixture()
|
|
foreign_org = Towerops.OrganizationsFixtures.organization_fixture(foreign_user.id)
|
|
{:ok, foreign_site} = Towerops.Sites.create_site(%{name: "FS", organization_id: foreign_org.id})
|
|
|
|
{:ok, foreign_device} =
|
|
Towerops.Devices.create_device(%{
|
|
name: "Foreign",
|
|
ip_address: "10.99.99.99",
|
|
site_id: foreign_site.id,
|
|
organization_id: foreign_org.id
|
|
})
|
|
|
|
{:ok, foreign_alert} =
|
|
Alerts.create_alert(%{
|
|
device_id: foreign_device.id,
|
|
alert_type: "device_down",
|
|
triggered_at: DateTime.truncate(DateTime.utc_now(), :second),
|
|
severity: 1
|
|
})
|
|
|
|
{:ok, view, _html} = live(conn, ~p"/alerts")
|
|
html = render_hook(view, "acknowledge", %{"id" => foreign_alert.id})
|
|
valid? = html =~ ~r/access|not found/ or html =~ "Alert"
|
|
assert valid?
|
|
end
|
|
end
|
|
|
|
describe "toggle_alert" do
|
|
test "expands and collapses an alert row", %{conn: conn, alert1: alert1} do
|
|
{:ok, view, _html} = live(conn, ~p"/alerts")
|
|
|
|
_ = render_hook(view, "toggle_alert", %{"id" => alert1.id})
|
|
_ = render_hook(view, "toggle_alert", %{"id" => alert1.id})
|
|
assert Process.alive?(view.pid)
|
|
end
|
|
end
|
|
|
|
describe "select_all + select_none" do
|
|
test "selects then deselects all visible alerts", %{conn: conn} do
|
|
{:ok, view, _html} = live(conn, ~p"/alerts")
|
|
|
|
_ = render_hook(view, "select_all", %{})
|
|
_ = render_hook(view, "select_none", %{})
|
|
assert Process.alive?(view.pid)
|
|
end
|
|
end
|
|
|
|
describe "toggle_select" do
|
|
test "toggles a single alert in the selection set", %{conn: conn, alert1: alert1} do
|
|
{:ok, view, _html} = live(conn, ~p"/alerts")
|
|
|
|
_ = render_hook(view, "toggle_select", %{"id" => alert1.id})
|
|
_ = render_hook(view, "toggle_select", %{"id" => alert1.id})
|
|
assert Process.alive?(view.pid)
|
|
end
|
|
end
|
|
|
|
describe "bulk_acknowledge" do
|
|
test "acknowledges every selected alert and clears the selection", %{
|
|
conn: conn,
|
|
alert1: alert1,
|
|
alert2: alert2
|
|
} do
|
|
{:ok, view, _html} = live(conn, ~p"/alerts")
|
|
|
|
_ = render_hook(view, "toggle_select", %{"id" => alert1.id})
|
|
_ = render_hook(view, "toggle_select", %{"id" => alert2.id})
|
|
_ = render_hook(view, "bulk_acknowledge", %{})
|
|
|
|
assert Towerops.Repo.get!(Alerts.Alert, alert1.id).acknowledged_at
|
|
assert Towerops.Repo.get!(Alerts.Alert, alert2.id).acknowledged_at
|
|
end
|
|
end
|
|
|
|
describe "bulk_resolve" do
|
|
test "resolves every selected alert and clears the selection", %{
|
|
conn: conn,
|
|
alert1: alert1,
|
|
alert2: alert2
|
|
} do
|
|
{:ok, view, _html} = live(conn, ~p"/alerts")
|
|
|
|
_ = render_hook(view, "select_all", %{})
|
|
_ = render_hook(view, "bulk_resolve", %{})
|
|
|
|
assert Towerops.Repo.get!(Alerts.Alert, alert1.id).resolved_at
|
|
assert Towerops.Repo.get!(Alerts.Alert, alert2.id).resolved_at
|
|
end
|
|
end
|
|
|
|
describe "toggle_site" do
|
|
test "expands and collapses a site group", %{conn: conn, site: site} do
|
|
{:ok, view, _html} = live(conn, ~p"/alerts")
|
|
|
|
_ = render_hook(view, "toggle_site", %{"site-id" => site.id})
|
|
_ = render_hook(view, "toggle_site", %{"site-id" => site.id})
|
|
assert Process.alive?(view.pid)
|
|
end
|
|
end
|
|
end
|