Files
Netbox-Utilities/netbox_utilities/tests/test_connection_vlans.py
T

116 lines
4.6 KiB
Python

from types import SimpleNamespace
from unittest.mock import MagicMock, patch
from django import forms
from django.forms.utils import ErrorDict
from django.test import SimpleTestCase
from netbox_utilities.connection_vlans import (
FORM_FIELD,
_build_connection_vlan_form,
include_connection_vlans_in_fieldsets,
)
from netbox_utilities.models import CableVLANAssignment, WirelessLinkVLANAssignment
class ConnectionVLANTest(SimpleTestCase):
def test_assignment_models_are_tied_to_their_connection_and_vlans(self):
self.assertEqual(
CableVLANAssignment._meta.get_field("cable").remote_field.model._meta.label_lower, "dcim.cable"
)
self.assertEqual(
WirelessLinkVLANAssignment._meta.get_field("wireless_link").remote_field.model._meta.label_lower,
"wireless.wirelesslink",
)
self.assertEqual(CableVLANAssignment._meta.get_field("vlans").remote_field.model._meta.label_lower, "ipam.vlan")
self.assertEqual(
WirelessLinkVLANAssignment._meta.get_field("vlans").remote_field.model._meta.label_lower,
"ipam.vlan",
)
def test_connection_vlan_field_is_inserted_into_link_fieldset(self):
from utilities.forms.rendering import FieldSet
original = (FieldSet("status", "description", "tags", name="Link"),)
extended = include_connection_vlans_in_fieldsets(original)
self.assertEqual(extended[0].items, ("status", "description", FORM_FIELD, "tags"))
self.assertEqual(original[0].items, ("status", "description", "tags"))
def test_resolved_edit_views_expose_connection_vlan_field(self):
import dcim.forms
from dcim.models import Interface
from dcim.views import CableEditView
from wireless.views import WirelessLinkEditView
cable_form = dcim.forms.get_cable_form(Interface, Interface)
self.assertIn(FORM_FIELD, cable_form.base_fields)
self.assertEqual(CableEditView.template_name, "netbox_utilities/cable_edit.html")
self.assertEqual(CableEditView.htmx_template_name, "netbox_utilities/cable_edit_form.html")
self.assertIn(FORM_FIELD, WirelessLinkEditView.form.base_fields)
@patch("netbox_utilities.connection_vlans.CableVLANAssignment.objects")
def test_form_loads_and_saves_multiple_vlans(self, assignment_objects):
from dcim.models import Cable
from utilities.forms.rendering import FieldSet
class BareCableForm(forms.ModelForm):
fieldsets = (FieldSet("description", name="Cable"),)
class Meta:
model = Cable
fields = ()
vlan_a = SimpleNamespace(pk=10)
vlan_b = SimpleNamespace(pk=20)
assignment = MagicMock()
assignment.vlans.all.return_value = [vlan_a, vlan_b]
assignment_objects.filter.return_value.prefetch_related.return_value.first.return_value = assignment
assignment_objects.get_or_create.return_value = (assignment, False)
cable = Cable(pk=7)
form_class = _build_connection_vlan_form(BareCableForm, CableVLANAssignment, "cable")
with patch(
"netbox_utilities.runtime._get_database_settings",
return_value={"tenant_required": True},
):
form = form_class(instance=cable)
self.assertEqual(form.initial[FORM_FIELD], [vlan_a, vlan_b])
form._errors = ErrorDict()
form.cleaned_data = {FORM_FIELD: [vlan_a, vlan_b]}
with patch.object(Cable, "save"):
self.assertIs(form.save(), cable)
assignment_objects.get_or_create.assert_called_once_with(cable=cable)
assignment.vlans.set.assert_called_once_with([vlan_a, vlan_b])
@patch("netbox_utilities.connection_vlans.CableVLANAssignment.objects")
def test_empty_form_selection_removes_assignment(self, assignment_objects):
from dcim.models import Cable
class BareCableForm(forms.ModelForm):
fieldsets = ()
class Meta:
model = Cable
fields = ()
cable = Cable(pk=8)
form_class = _build_connection_vlan_form(BareCableForm, CableVLANAssignment, "cable")
with patch(
"netbox_utilities.runtime._get_database_settings",
return_value={"tenant_required": True},
):
form = form_class(instance=cable)
form._errors = ErrorDict()
form.cleaned_data = {FORM_FIELD: []}
with patch.object(Cable, "save"):
form.save()
assignment_objects.filter.assert_called_with(cable=cable)
assignment_objects.filter.return_value.delete.assert_called_once_with()
assignment_objects.get_or_create.assert_not_called()