defmodule ToweropsWeb.Live.Helpers.AccessControlTest do use Towerops.DataCase, async: true import Towerops.AccountsFixtures import Towerops.DevicesFixtures import Towerops.OrganizationsFixtures alias Towerops.Alerts alias ToweropsWeb.Live.Helpers.AccessControl describe "verify_device_access/2" do setup do user1 = user_fixture() user2 = user_fixture() org1 = organization_fixture(user1.id) org2 = organization_fixture(user2.id) site1 = site_fixture(org1.id) site2 = site_fixture(org2.id) device1 = device_fixture(%{site: site1, organization: org1}) device2 = device_fixture(%{site: site2, organization: org2}) %{ org1: org1, org2: org2, site1: site1, site2: site2, device1: device1, device2: device2 } end test "returns {:ok, device} when device belongs to organization", %{ device1: device, org1: org } do assert {:ok, returned_device} = AccessControl.verify_device_access(device.id, org.id) assert returned_device.id == device.id end test "returns {:error, :unauthorized} when device belongs to different organization", %{ device1: device, org2: wrong_org } do assert {:error, :unauthorized} = AccessControl.verify_device_access(device.id, wrong_org.id) end test "returns {:error, :not_found} when device does not exist", %{org1: org} do fake_id = Ecto.UUID.generate() assert {:error, :not_found} = AccessControl.verify_device_access(fake_id, org.id) end end describe "verify_site_access/2" do setup do user1 = user_fixture() user2 = user_fixture() org1 = organization_fixture(user1.id) org2 = organization_fixture(user2.id) site1 = site_fixture(org1.id) site2 = site_fixture(org2.id) %{ org1: org1, org2: org2, site1: site1, site2: site2 } end test "returns {:ok, site} when site belongs to organization", %{ site1: site, org1: org } do assert {:ok, returned_site} = AccessControl.verify_site_access(site.id, org.id) assert returned_site.id == site.id end test "returns {:error, :unauthorized} when site belongs to different organization", %{ site1: site, org2: wrong_org } do assert {:error, :unauthorized} = AccessControl.verify_site_access(site.id, wrong_org.id) end test "returns {:error, :not_found} when site does not exist", %{org1: org} do fake_id = Ecto.UUID.generate() assert {:error, :not_found} = AccessControl.verify_site_access(fake_id, org.id) end end describe "verify_alert_access/2" do setup do user1 = user_fixture() user2 = user_fixture() org1 = organization_fixture(user1.id) org2 = organization_fixture(user2.id) site1 = site_fixture(org1.id) site2 = site_fixture(org2.id) device1 = device_fixture(%{site: site1, organization: org1}) device2 = device_fixture(%{site: site2, organization: org2}) alert1 = alert_fixture(device_id: device1.id) alert2 = alert_fixture(device_id: device2.id) %{ org1: org1, org2: org2, device1: device1, device2: device2, alert1: alert1, alert2: alert2 } end test "returns {:ok, alert} when alert's device belongs to organization", %{ alert1: alert, org1: org } do assert {:ok, returned_alert} = AccessControl.verify_alert_access(alert.id, org.id) assert returned_alert.id == alert.id # Verify preloading worked assert returned_alert.device assert returned_alert.device.site assert returned_alert.device.site.organization end test "returns {:error, :unauthorized} when alert's device belongs to different organization", %{ alert1: alert, org2: wrong_org } do assert {:error, :unauthorized} = AccessControl.verify_alert_access(alert.id, wrong_org.id) end test "returns {:error, :not_found} when alert does not exist", %{org1: org} do fake_id = Ecto.UUID.generate() assert {:error, :not_found} = AccessControl.verify_alert_access(fake_id, org.id) end end # Helper functions to create test data defp alert_fixture(attrs) do {:ok, alert} = attrs |> Enum.into(%{ alert_type: "device_down", message: "Test alert", triggered_at: DateTime.utc_now() }) |> Alerts.create_alert() alert end end