diff --git a/gso/services/netbox_client.py b/gso/services/netbox_client.py index 5531ab8dc018103f2b2d0f589a15de397cdf0172..9a9d65e042ed7b2823a2a7bc17f1ee3f8ca36483 100644 --- a/gso/services/netbox_client.py +++ b/gso/services/netbox_client.py @@ -3,6 +3,7 @@ from uuid import UUID import pydantic import pynetbox +from pydantic_forms.types import UUIDstr from pynetbox.models.dcim import Devices, DeviceTypes, Interfaces from gso.products.product_types.router import Router @@ -180,7 +181,6 @@ class NetboxClient: def delete_device(self, device_name: str) -> None: """Delete device by name.""" self.netbox.dcim.devices.get(name=device_name).delete() - return def attach_interface_to_lag( self, device_name: str, lag_name: str, iface_name: str, description: str | None = None @@ -288,7 +288,7 @@ class NetboxClient: # Convert to bits per second return numeric_part * 1000000 - def get_available_interfaces(self, router_id: UUID, speed: str) -> Interfaces: + def get_available_interfaces(self, router_id: UUID | UUIDstr, speed: str) -> Interfaces: """Return all available interfaces of a device filtered by speed.""" router = Router.from_subscription(router_id).router.router_fqdn diff --git a/gso/utils/helpers.py b/gso/utils/helpers.py index 5e3b149ac45f61168c89a925a3fb0426c48fdf1b..b0f493f13662a912d5414fe65860072ec711ce03 100644 --- a/gso/utils/helpers.py +++ b/gso/utils/helpers.py @@ -56,7 +56,7 @@ def available_interfaces_choices(router_id: UUID, speed: str) -> Choice | None: def available_interfaces_choices_including_current_members( - router_id: UUID, speed: str, interfaces: list[IptrunkInterfaceBlock] + router_id: UUID | UUIDstr, speed: str, interfaces: list[IptrunkInterfaceBlock] ) -> Choice | None: """Return a list of available interfaces for a given router and speed including the current members. @@ -65,6 +65,7 @@ def available_interfaces_choices_including_current_members( """ if Router.from_subscription(router_id).router.router_vendor != RouterVendor.NOKIA: return None + available_interfaces = list(NetboxClient().get_available_interfaces(router_id, speed)) available_interfaces.extend( [ diff --git a/test/utils/__init__.py b/test/utils/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/test/utils/test_helpers.py b/test/utils/test_helpers.py new file mode 100644 index 0000000000000000000000000000000000000000..f8375a4827b4208d09feff1b82fcc523bab85b3b --- /dev/null +++ b/test/utils/test_helpers.py @@ -0,0 +1,64 @@ +from unittest.mock import patch + +import pytest + +from gso.products.product_blocks.iptrunk import IptrunkInterfaceBlock +from gso.products.product_blocks.router import RouterVendor +from gso.utils.helpers import available_interfaces_choices_including_current_members + + +@pytest.fixture +def mock_router(): + """Fixture to mock the Router class.""" + with patch("gso.utils.helpers.Router") as mock: + yield mock + + +@pytest.fixture +def mock_netbox_client(): + """Fixture to mock the NetboxClient class.""" + with patch("gso.utils.helpers.NetboxClient") as mock: + yield mock + + +def test_non_nokia_router_returns_none(mock_router, faker): + mock_router.from_subscription.return_value.router.router_vendor = RouterVendor.JUNIPER + result = available_interfaces_choices_including_current_members(faker.uuid4(), "10G", []) + assert result is None + + +def test_nokia_router_with_no_interfaces_returns_empty_choice(mock_router, mock_netbox_client, faker): + mock_router.from_subscription.return_value.router.router_vendor = RouterVendor.NOKIA + mock_netbox_client().get_available_interfaces.return_value = iter([]) + result = available_interfaces_choices_including_current_members(faker.uuid4(), "10G", []) + assert len(result) == 0 + + +def test_nokia_router_with_interfaces_returns_choice(mock_router, mock_netbox_client, faker): + mock_router.from_subscription.return_value.router.router_vendor = RouterVendor.NOKIA + mock_netbox_client().get_available_interfaces.return_value = iter( + [ + {"name": "interface1", "module": {"display": "module1"}, "description": "desc1"}, + {"name": "interface2", "module": {"display": "module2"}, "description": "desc2"}, + ] + ) + mock_netbox_client().get_interface_by_name_and_device.return_value = { + "name": "interface3", + "module": {"display": "module3"}, + "description": "desc3", + } + interfaces = [ + IptrunkInterfaceBlock( + interface_name="interface3", + interface_description="desc3", + owner_subscription_id=faker.uuid4(), + subscription_instance_id=faker.uuid4(), + ) + ] + + result = available_interfaces_choices_including_current_members(faker.uuid4(), "10G", interfaces) + + assert len(result) == 3 + assert hasattr(result, "interface1") + assert hasattr(result, "interface2") + assert hasattr(result, "interface3")