defmodule ToweropsWeb.Admin.MonitoringLiveTest do use ToweropsWeb.ConnCase import Phoenix.LiveViewTest import Towerops.DevicesFixtures import Towerops.JobsFixtures describe "MonitoringLive" do setup [:register_and_log_in_superuser] test "renders monitoring dashboard", %{conn: conn} do {:ok, _view, html} = live(conn, ~p"/admin/monitoring") assert html =~ "Job Monitoring Dashboard" assert html =~ "Active Operations" assert html =~ "Problems" assert html =~ "Health Metrics" end test "subscribes to job lifecycle events", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/admin/monitoring") # Verify PubSub subscription by checking it's alive assert Process.alive?(view.pid) end test "displays active operations section", %{conn: conn} do {:ok, _view, html} = live(conn, ~p"/admin/monitoring") assert html =~ "Active Operations" assert html =~ "No jobs currently executing" end end describe "real-time updates" do setup [:register_and_log_in_superuser] test "displays executing jobs from database", %{conn: conn} do device = device_fixture() _job = oban_job_fixture(%{ worker: "Towerops.Workers.DevicePollerWorker", state: "executing", args: %{"device_id" => device.id}, attempted_at: DateTime.utc_now() }) {:ok, _view, html} = live(conn, ~p"/admin/monitoring") # Should show the device name in executing jobs assert html =~ device.name assert html =~ "Active Operations (1)" end end describe "metrics display" do setup [:register_and_log_in_superuser] test "shows current activity metrics", %{conn: conn} do device = device_fixture() oban_job_fixture(%{ worker: "Towerops.Workers.DevicePollerWorker", state: "executing", args: %{"device_id" => device.id} }) {:ok, _view, html} = live(conn, ~p"/admin/monitoring") assert html =~ "Executing" assert html =~ "1" end end describe "handle_info events" do setup [:register_and_log_in_superuser] test "handles job started event", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/admin/monitoring") send(view.pid, %{event: :started, job_id: 1, worker: "TestWorker"}) assert render(view) end test "handles job completed event", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/admin/monitoring") send(view.pid, %{event: :completed, job_id: 1, worker: "TestWorker"}) assert render(view) end test "handles job failed event", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/admin/monitoring") send(view.pid, %{event: :failed, job_id: 1, worker: "TestWorker"}) assert render(view) end test "handles unknown events gracefully", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/admin/monitoring") send(view.pid, :some_unknown_event) assert render(view) end end defp register_and_log_in_superuser(%{conn: conn}) do user = Towerops.AccountsFixtures.user_fixture(enable_totp: true) user = Towerops.Repo.update!(Ecto.Changeset.change(user, is_superuser: true)) %{conn: log_in_user(conn, user), user: user} end end