Each billing sync (Gaiia, Splynx, VISP, Sonar) already computes subscriber counts and MRR but only stored them in sync messages. Now persists them on the integrations table so the dashboard can aggregate across all billing providers instead of only querying Gaiia network sites (which were never populated). Also fixes SnmpKit Config environment detection to use Mix.env() as fallback when MIX_ENV env var is not set.
165 lines
5.2 KiB
Elixir
165 lines
5.2 KiB
Elixir
defmodule Towerops.DashboardTest do
|
|
use Towerops.DataCase, async: true
|
|
|
|
import Towerops.AccountsFixtures
|
|
import Towerops.DevicesFixtures
|
|
import Towerops.OrganizationsFixtures
|
|
|
|
alias Towerops.Dashboard
|
|
alias Towerops.Integrations
|
|
|
|
setup do
|
|
user = user_fixture()
|
|
org = organization_fixture(user.id)
|
|
|
|
%{org: org, user: user}
|
|
end
|
|
|
|
describe "get_dashboard_summary/1" do
|
|
test "returns correct structure with empty org", %{org: org} do
|
|
summary = Dashboard.get_dashboard_summary(org.id)
|
|
|
|
assert is_map(summary)
|
|
assert Map.has_key?(summary, :health_score)
|
|
assert Map.has_key?(summary, :devices)
|
|
assert Map.has_key?(summary, :alerts)
|
|
assert Map.has_key?(summary, :subscribers)
|
|
assert Map.has_key?(summary, :insights)
|
|
end
|
|
|
|
test "returns device counts", %{org: org} do
|
|
device = device_fixture(%{organization_id: org.id})
|
|
Towerops.Devices.update_device_status(device, :up)
|
|
|
|
summary = Dashboard.get_dashboard_summary(org.id)
|
|
|
|
assert summary.devices.total == 1
|
|
assert summary.devices.up == 1
|
|
assert summary.devices.down == 0
|
|
end
|
|
|
|
test "returns alert count", %{org: org} do
|
|
device = device_fixture(%{organization_id: org.id})
|
|
|
|
{:ok, _alert} =
|
|
Towerops.Alerts.create_alert(%{
|
|
device_id: device.id,
|
|
alert_type: :device_down,
|
|
triggered_at: DateTime.utc_now(),
|
|
message: "Device is down"
|
|
})
|
|
|
|
summary = Dashboard.get_dashboard_summary(org.id)
|
|
assert summary.alerts.active_count == 1
|
|
end
|
|
|
|
test "returns subscriber totals from billing integrations", %{org: org} do
|
|
{:ok, integration} =
|
|
Integrations.create_integration(org.id, %{provider: "gaiia", enabled: true})
|
|
|
|
{:ok, _} = Integrations.update_billing_totals(integration, 100, Decimal.new("5000.00"))
|
|
|
|
summary = Dashboard.get_dashboard_summary(org.id)
|
|
assert summary.subscribers.total == 100
|
|
assert Decimal.equal?(summary.subscribers.total_mrr, Decimal.new("5000.00"))
|
|
end
|
|
|
|
test "returns zero subscribers when no billing integrations", %{org: org} do
|
|
summary = Dashboard.get_dashboard_summary(org.id)
|
|
assert summary.subscribers.total == 0
|
|
end
|
|
|
|
test "returns insight counts by urgency", %{org: org} do
|
|
summary = Dashboard.get_dashboard_summary(org.id)
|
|
assert summary.insights.critical == 0
|
|
assert summary.insights.warning == 0
|
|
assert summary.insights.info == 0
|
|
end
|
|
end
|
|
|
|
describe "compute_health_score/1" do
|
|
test "returns 100 when all devices up, no alerts", %{org: org} do
|
|
device = device_fixture(%{organization_id: org.id})
|
|
Towerops.Devices.update_device_status(device, :up)
|
|
|
|
score = Dashboard.compute_health_score(org.id)
|
|
assert score == 100
|
|
end
|
|
|
|
test "returns lower score when devices down", %{org: org} do
|
|
d1 = device_fixture(%{organization_id: org.id})
|
|
d2 = device_fixture(%{organization_id: org.id})
|
|
Towerops.Devices.update_device_status(d1, :up)
|
|
Towerops.Devices.update_device_status(d2, :down)
|
|
|
|
score = Dashboard.compute_health_score(org.id)
|
|
assert score < 100
|
|
assert score > 0
|
|
end
|
|
|
|
test "returns 100 when no devices exist", %{org: org} do
|
|
score = Dashboard.compute_health_score(org.id)
|
|
assert score == 100
|
|
end
|
|
|
|
test "penalizes for critical alerts", %{org: org} do
|
|
device = device_fixture(%{organization_id: org.id})
|
|
Towerops.Devices.update_device_status(device, :up)
|
|
|
|
{:ok, _} =
|
|
Towerops.Alerts.create_alert(%{
|
|
device_id: device.id,
|
|
alert_type: :device_down,
|
|
triggered_at: DateTime.utc_now(),
|
|
message: "Device down"
|
|
})
|
|
|
|
score = Dashboard.compute_health_score(org.id)
|
|
assert score < 100
|
|
end
|
|
end
|
|
|
|
describe "get_org_subscriber_summary/1" do
|
|
test "returns totals from billing integrations", %{org: org} do
|
|
{:ok, i1} =
|
|
Integrations.create_integration(org.id, %{provider: "gaiia", enabled: true})
|
|
|
|
{:ok, _} = Integrations.update_billing_totals(i1, 50, Decimal.new("2500.00"))
|
|
|
|
{:ok, i2} =
|
|
Integrations.create_integration(org.id, %{provider: "splynx", enabled: true})
|
|
|
|
{:ok, _} = Integrations.update_billing_totals(i2, 30, Decimal.new("1500.00"))
|
|
|
|
result = Dashboard.get_org_subscriber_summary(org.id)
|
|
assert result.total == 80
|
|
assert Decimal.equal?(result.total_mrr, Decimal.new("4000.00"))
|
|
end
|
|
|
|
test "returns zeros when no billing integrations", %{org: org} do
|
|
result = Dashboard.get_org_subscriber_summary(org.id)
|
|
assert result.total == 0
|
|
assert Decimal.equal?(result.total_mrr, Decimal.new(0))
|
|
end
|
|
end
|
|
|
|
describe "list_site_summaries/1" do
|
|
test "returns enriched site data", %{org: org} do
|
|
{:ok, site} =
|
|
Towerops.Sites.create_site(%{
|
|
name: "Test Tower",
|
|
organization_id: org.id
|
|
})
|
|
|
|
device = device_fixture(%{organization_id: org.id, site_id: site.id})
|
|
Towerops.Devices.update_device_status(device, :up)
|
|
|
|
summaries = Dashboard.list_site_summaries(org.id)
|
|
assert summaries != []
|
|
|
|
summary = Enum.find(summaries, &(&1.site_id == site.id))
|
|
assert summary.name == "Test Tower"
|
|
assert summary.device_count >= 1
|
|
end
|
|
end
|
|
end
|