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.
223 lines
8.4 KiB
Elixir
223 lines
8.4 KiB
Elixir
defmodule Towerops.IntegrationsTest do
|
|
use Towerops.DataCase, async: true
|
|
|
|
import Towerops.AccountsFixtures
|
|
import Towerops.OrganizationsFixtures
|
|
|
|
alias Towerops.Integrations
|
|
alias Towerops.Integrations.Integration
|
|
|
|
setup do
|
|
user = user_fixture()
|
|
organization = organization_fixture(user.id)
|
|
%{organization: organization}
|
|
end
|
|
|
|
describe "list_integrations/1" do
|
|
test "returns all integrations for an organization", %{organization: org} do
|
|
{:ok, _} = Integrations.create_integration(org.id, %{provider: "preseem"})
|
|
integrations = Integrations.list_integrations(org.id)
|
|
assert length(integrations) == 1
|
|
end
|
|
|
|
test "does not return integrations from other orgs", %{organization: org} do
|
|
user2 = user_fixture()
|
|
org2 = organization_fixture(user2.id)
|
|
{:ok, _} = Integrations.create_integration(org2.id, %{provider: "preseem"})
|
|
assert Integrations.list_integrations(org.id) == []
|
|
end
|
|
end
|
|
|
|
describe "get_integration/2" do
|
|
test "returns integration by org and provider", %{organization: org} do
|
|
{:ok, created} = Integrations.create_integration(org.id, %{provider: "preseem"})
|
|
assert {:ok, fetched} = Integrations.get_integration(org.id, "preseem")
|
|
assert fetched.id == created.id
|
|
end
|
|
|
|
test "returns error when not found", %{organization: org} do
|
|
assert {:error, :not_found} = Integrations.get_integration(org.id, "preseem")
|
|
end
|
|
end
|
|
|
|
describe "get_integration!/2" do
|
|
test "returns integration by org and provider", %{organization: org} do
|
|
{:ok, created} = Integrations.create_integration(org.id, %{provider: "preseem"})
|
|
fetched = Integrations.get_integration!(org.id, "preseem")
|
|
assert fetched.id == created.id
|
|
end
|
|
|
|
test "raises when not found", %{organization: org} do
|
|
assert_raise Ecto.NoResultsError, fn ->
|
|
Integrations.get_integration!(org.id, "preseem")
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "create_integration/2" do
|
|
test "creates with valid attrs", %{organization: org} do
|
|
attrs = %{provider: "preseem", credentials: %{"api_key" => "test-123"}, enabled: true}
|
|
assert {:ok, %Integration{} = integration} = Integrations.create_integration(org.id, attrs)
|
|
assert integration.provider == "preseem"
|
|
assert integration.credentials == %{"api_key" => "test-123"}
|
|
assert integration.enabled == true
|
|
assert integration.organization_id == org.id
|
|
end
|
|
|
|
test "rejects duplicate provider per org", %{organization: org} do
|
|
{:ok, _} = Integrations.create_integration(org.id, %{provider: "preseem"})
|
|
assert {:error, changeset} = Integrations.create_integration(org.id, %{provider: "preseem"})
|
|
assert "has already been taken" in errors_on(changeset).provider
|
|
end
|
|
end
|
|
|
|
describe "update_integration/2" do
|
|
test "updates credentials", %{organization: org} do
|
|
{:ok, integration} =
|
|
Integrations.create_integration(org.id, %{
|
|
provider: "preseem",
|
|
credentials: %{"api_key" => "old-key"}
|
|
})
|
|
|
|
assert {:ok, updated} =
|
|
Integrations.update_integration(integration, %{credentials: %{"api_key" => "new-key"}})
|
|
|
|
assert updated.credentials == %{"api_key" => "new-key"}
|
|
end
|
|
|
|
test "updates enabled flag", %{organization: org} do
|
|
{:ok, integration} =
|
|
Integrations.create_integration(org.id, %{provider: "preseem", enabled: false})
|
|
|
|
assert {:ok, updated} = Integrations.update_integration(integration, %{enabled: true})
|
|
assert updated.enabled == true
|
|
end
|
|
end
|
|
|
|
describe "update_sync_status/2" do
|
|
test "updates last_synced_at and last_sync_status", %{organization: org} do
|
|
{:ok, integration} = Integrations.create_integration(org.id, %{provider: "preseem"})
|
|
assert integration.last_sync_status == "never"
|
|
assert integration.last_synced_at == nil
|
|
|
|
assert {:ok, updated} = Integrations.update_sync_status(integration, "success")
|
|
assert updated.last_sync_status == "success"
|
|
assert updated.last_synced_at
|
|
end
|
|
end
|
|
|
|
describe "delete_integration/1" do
|
|
test "deletes the integration", %{organization: org} do
|
|
{:ok, integration} = Integrations.create_integration(org.id, %{provider: "preseem"})
|
|
assert {:ok, _} = Integrations.delete_integration(integration)
|
|
assert {:error, :not_found} = Integrations.get_integration(org.id, "preseem")
|
|
end
|
|
end
|
|
|
|
describe "change_integration/2" do
|
|
test "returns a changeset", %{organization: org} do
|
|
{:ok, integration} = Integrations.create_integration(org.id, %{provider: "preseem"})
|
|
assert %Ecto.Changeset{} = Integrations.change_integration(integration)
|
|
end
|
|
end
|
|
|
|
describe "update_billing_totals/3" do
|
|
test "persists subscriber_count and total_mrr on integration", %{organization: org} do
|
|
{:ok, integration} =
|
|
Integrations.create_integration(org.id, %{provider: "gaiia", enabled: true})
|
|
|
|
assert {:ok, updated} =
|
|
Integrations.update_billing_totals(integration, 42, Decimal.new("3500.00"))
|
|
|
|
assert updated.subscriber_count == 42
|
|
assert Decimal.equal?(updated.total_mrr, Decimal.new("3500.00"))
|
|
end
|
|
|
|
test "overwrites previous billing totals", %{organization: org} do
|
|
{:ok, integration} =
|
|
Integrations.create_integration(org.id, %{provider: "splynx", enabled: true})
|
|
|
|
{:ok, _} = Integrations.update_billing_totals(integration, 10, Decimal.new("500.00"))
|
|
integration = Repo.reload!(integration)
|
|
{:ok, updated} = Integrations.update_billing_totals(integration, 20, Decimal.new("1000.00"))
|
|
|
|
assert updated.subscriber_count == 20
|
|
assert Decimal.equal?(updated.total_mrr, Decimal.new("1000.00"))
|
|
end
|
|
end
|
|
|
|
describe "get_billing_summary/1" do
|
|
test "sums across multiple billing integrations", %{organization: org} do
|
|
{:ok, i1} =
|
|
Integrations.create_integration(org.id, %{provider: "gaiia", enabled: true})
|
|
|
|
{:ok, _} = Integrations.update_billing_totals(i1, 100, Decimal.new("5000.00"))
|
|
|
|
user2 = user_fixture()
|
|
org2 = organization_fixture(user2.id)
|
|
|
|
{:ok, i2} =
|
|
Integrations.create_integration(org2.id, %{provider: "splynx", enabled: true})
|
|
|
|
{:ok, _} = Integrations.update_billing_totals(i2, 50, Decimal.new("2500.00"))
|
|
|
|
# Only org's integrations
|
|
summary = Integrations.get_billing_summary(org.id)
|
|
assert summary.total_subscribers == 100
|
|
assert Decimal.equal?(summary.total_mrr, Decimal.new("5000.00"))
|
|
end
|
|
|
|
test "excludes disabled integrations", %{organization: org} do
|
|
{:ok, i1} =
|
|
Integrations.create_integration(org.id, %{provider: "gaiia", enabled: true})
|
|
|
|
{:ok, _} = Integrations.update_billing_totals(i1, 100, Decimal.new("5000.00"))
|
|
|
|
{:ok, i2} =
|
|
Integrations.create_integration(org.id, %{provider: "splynx", enabled: false})
|
|
|
|
{:ok, _} = Integrations.update_billing_totals(i2, 50, Decimal.new("2500.00"))
|
|
|
|
summary = Integrations.get_billing_summary(org.id)
|
|
assert summary.total_subscribers == 100
|
|
assert Decimal.equal?(summary.total_mrr, Decimal.new("5000.00"))
|
|
end
|
|
|
|
test "excludes non-billing integrations", %{organization: org} do
|
|
{:ok, i1} =
|
|
Integrations.create_integration(org.id, %{provider: "gaiia", enabled: true})
|
|
|
|
{:ok, _} = Integrations.update_billing_totals(i1, 100, Decimal.new("5000.00"))
|
|
|
|
{:ok, _} =
|
|
Integrations.create_integration(org.id, %{
|
|
provider: "preseem",
|
|
enabled: true
|
|
})
|
|
|
|
summary = Integrations.get_billing_summary(org.id)
|
|
assert summary.total_subscribers == 100
|
|
assert Decimal.equal?(summary.total_mrr, Decimal.new("5000.00"))
|
|
end
|
|
|
|
test "returns zeros when no billing integrations", %{organization: org} do
|
|
summary = Integrations.get_billing_summary(org.id)
|
|
assert summary.total_subscribers == 0
|
|
assert Decimal.equal?(summary.total_mrr, Decimal.new(0))
|
|
end
|
|
end
|
|
|
|
describe "list_enabled_integrations/1" do
|
|
test "returns only enabled integrations for a provider", %{organization: org} do
|
|
{:ok, _} = Integrations.create_integration(org.id, %{provider: "preseem", enabled: true})
|
|
|
|
user2 = user_fixture()
|
|
org2 = organization_fixture(user2.id)
|
|
{:ok, _} = Integrations.create_integration(org2.id, %{provider: "preseem", enabled: false})
|
|
|
|
enabled = Integrations.list_enabled_integrations("preseem")
|
|
assert length(enabled) == 1
|
|
assert hd(enabled).organization_id == org.id
|
|
end
|
|
end
|
|
end
|