Add comprehensive tests for Monitoring.Check schema

Tests cover:
- Valid and invalid changesets
- All required field validations
- Foreign key constraints
- Status enum values
- Schema field types and associations
- Binary ID usage for primary/foreign keys

All 16 tests passing with good coverage of schema validation logic.
This commit is contained in:
Graham McIntire 2026-01-20 11:59:54 -06:00
parent a2466722b7
commit 638551eb95
No known key found for this signature in database

View file

@ -0,0 +1,209 @@
defmodule Towerops.Monitoring.CheckTest do
use Towerops.DataCase, async: true
import Towerops.AccountsFixtures
alias Towerops.Monitoring.Check
describe "changeset/2" do
setup do
user = user_fixture()
{:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
{:ok, site} =
Towerops.Sites.create_site(%{
name: "Test Site",
organization_id: organization.id
})
{:ok, device} =
Towerops.Devices.create_device(%{
name: "Test Device",
ip_address: "192.168.1.1",
site_id: site.id
})
{:ok, device: device}
end
test "valid changeset with all fields", %{device: device} do
attrs = %{
device_id: device.id,
status: :success,
response_time_ms: 12.5,
checked_at: DateTime.utc_now()
}
changeset = Check.changeset(%Check{}, attrs)
assert changeset.valid?
assert get_change(changeset, :device_id) == device.id
assert get_change(changeset, :status) == :success
assert get_change(changeset, :response_time_ms) == 12.5
assert get_change(changeset, :checked_at)
end
test "valid changeset with failure status", %{device: device} do
attrs = %{
device_id: device.id,
status: :failure,
checked_at: DateTime.utc_now()
}
changeset = Check.changeset(%Check{}, attrs)
assert changeset.valid?
assert get_change(changeset, :status) == :failure
# response_time_ms is optional and can be nil for failures
refute Map.has_key?(changeset.changes, :response_time_ms)
end
test "requires device_id" do
attrs = %{
status: :success,
checked_at: DateTime.utc_now()
}
changeset = Check.changeset(%Check{}, attrs)
refute changeset.valid?
assert "can't be blank" in errors_on(changeset).device_id
end
test "requires status" do
attrs = %{
device_id: Ecto.UUID.generate(),
checked_at: DateTime.utc_now()
}
changeset = Check.changeset(%Check{}, attrs)
refute changeset.valid?
assert "can't be blank" in errors_on(changeset).status
end
test "requires checked_at" do
attrs = %{
device_id: Ecto.UUID.generate(),
status: :success
}
changeset = Check.changeset(%Check{}, attrs)
refute changeset.valid?
assert "can't be blank" in errors_on(changeset).checked_at
end
test "accepts only valid status values", %{device: device} do
# Invalid status value
attrs = %{
device_id: device.id,
status: :invalid_status,
checked_at: DateTime.utc_now()
}
changeset = Check.changeset(%Check{}, attrs)
refute changeset.valid?
assert "is invalid" in errors_on(changeset).status
end
test "validates foreign key constraint on insert", %{device: device} do
# This test requires actual database insert
valid_attrs = %{
device_id: device.id,
status: :success,
checked_at: DateTime.utc_now()
}
changeset = Check.changeset(%Check{}, valid_attrs)
assert {:ok, _check} = Repo.insert(changeset)
# Now try with invalid device_id
invalid_attrs = %{
device_id: Ecto.UUID.generate(),
status: :success,
checked_at: DateTime.utc_now()
}
changeset = Check.changeset(%Check{}, invalid_attrs)
assert {:error, changeset} = Repo.insert(changeset)
assert "does not exist" in errors_on(changeset).device_id
end
test "response_time_ms can be nil", %{device: device} do
attrs = %{
device_id: device.id,
status: :failure,
response_time_ms: nil,
checked_at: DateTime.utc_now()
}
changeset = Check.changeset(%Check{}, attrs)
assert changeset.valid?
end
test "response_time_ms accepts float values", %{device: device} do
attrs = %{
device_id: device.id,
status: :success,
response_time_ms: 123.456,
checked_at: DateTime.utc_now()
}
changeset = Check.changeset(%Check{}, attrs)
assert changeset.valid?
assert get_change(changeset, :response_time_ms) == 123.456
end
test "checked_at accepts DateTime", %{device: device} do
now = DateTime.utc_now()
attrs = %{
device_id: device.id,
status: :success,
checked_at: now
}
changeset = Check.changeset(%Check{}, attrs)
assert changeset.valid?
end
end
describe "schema" do
test "has correct fields" do
fields = Check.__schema__(:fields)
assert :id in fields
assert :device_id in fields
assert :status in fields
assert :response_time_ms in fields
assert :checked_at in fields
assert :inserted_at in fields
end
test "belongs to device" do
assocs = Check.__schema__(:associations)
assert :device in assocs
assoc = Check.__schema__(:association, :device)
assert assoc.queryable == Towerops.Devices.Device
end
test "uses binary_id for primary key" do
assert Check.__schema__(:type, :id) == :binary_id
end
test "uses binary_id for foreign keys" do
assert Check.__schema__(:type, :device_id) == :binary_id
end
test "status is an enum" do
assert {:parameterized, {Ecto.Enum, _}} = Check.__schema__(:type, :status)
end
test "does not have updated_at timestamp" do
fields = Check.__schema__(:fields)
refute :updated_at in fields
end
end
end