fix: restore rack and reorder width views
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
from unittest.mock import patch
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.context_processors import PermWrapper
|
||||
from django.contrib.auth.models import AnonymousUser
|
||||
from django.test import RequestFactory, SimpleTestCase
|
||||
|
||||
from netbox_utilities.template_content import UtilitiesGlobalContent
|
||||
|
||||
|
||||
class OptionalRackIntegrationHeadTest(SimpleTestCase):
|
||||
@staticmethod
|
||||
def _context(path):
|
||||
request = RequestFactory().get(path)
|
||||
request.user = AnonymousUser()
|
||||
return {
|
||||
"request": request,
|
||||
"settings": settings,
|
||||
"csrf_token": "",
|
||||
"perms": PermWrapper(request.user),
|
||||
}
|
||||
|
||||
def test_reorder_adapter_is_emitted_for_an_empty_enabled_payload(self):
|
||||
data = {
|
||||
"columns": 12,
|
||||
"unit_width": 220,
|
||||
"images": True,
|
||||
"labels": True,
|
||||
"devices": [],
|
||||
"status": "ready",
|
||||
}
|
||||
with (
|
||||
patch("netbox_utilities.template_content.get_reorder_rack_width_data", return_value=data),
|
||||
patch("netbox_utilities.template_content.get_topology_rack_width_data", return_value=None),
|
||||
):
|
||||
html = UtilitiesGlobalContent(self._context("/dcim/racks/3/reorder/")).head()
|
||||
|
||||
self.assertIn('id="netbox-utilities-reorder-rack-width-data"', html)
|
||||
self.assertIn("netbox_utilities/reorder-rack-width.js", html)
|
||||
self.assertIn('"status": "ready"', html)
|
||||
|
||||
def test_topology_adapter_is_emitted_for_an_empty_enabled_payload(self):
|
||||
data = {"devices": [], "status": "ready"}
|
||||
with (
|
||||
patch("netbox_utilities.template_content.get_reorder_rack_width_data", return_value=None),
|
||||
patch("netbox_utilities.template_content.get_topology_rack_width_data", return_value=data),
|
||||
):
|
||||
html = UtilitiesGlobalContent(
|
||||
self._context("/plugins/netbox_topology_views/rack-elevation/?rack_id=3")
|
||||
).head()
|
||||
|
||||
self.assertIn('id="netbox-utilities-topology-rack-width-data"', html)
|
||||
self.assertIn("netbox_utilities/topology-rack-width.js", html)
|
||||
self.assertIn('"status": "ready"', html)
|
||||
@@ -1,7 +1,7 @@
|
||||
from importlib import import_module
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import MagicMock, patch
|
||||
from unittest.mock import MagicMock, call, patch
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.context_processors import PermWrapper
|
||||
@@ -43,6 +43,67 @@ class RackWidthTest(SimpleTestCase):
|
||||
self.assertIn("device_type", devices.query.select_related)
|
||||
self.assertIn("manufacturer", devices.query.select_related["device_type"])
|
||||
|
||||
def test_core_rack_units_remain_available_to_other_plugins(self):
|
||||
from dcim.models import Rack
|
||||
|
||||
self.assertEqual(Rack.get_rack_units.__module__, "dcim.models.racks")
|
||||
self.assertFalse(hasattr(Rack.get_rack_units, "__wrapped__"))
|
||||
|
||||
def test_svg_draws_all_partial_devices_sharing_one_unit_exactly_once(self):
|
||||
from dcim.svg.racks import RackElevationSVG
|
||||
|
||||
regular = SimpleNamespace(pk=1, face="front")
|
||||
partial_right = SimpleNamespace(
|
||||
pk=2,
|
||||
face="front",
|
||||
position=11,
|
||||
device_type=SimpleNamespace(u_height=1),
|
||||
netbox_utilities_rack_placement=SimpleNamespace(width=2, horizontal_position=2),
|
||||
)
|
||||
partial_left = SimpleNamespace(
|
||||
pk=3,
|
||||
face="front",
|
||||
position=11,
|
||||
device_type=SimpleNamespace(u_height=1),
|
||||
netbox_utilities_rack_placement=SimpleNamespace(width=2, horizontal_position=1),
|
||||
)
|
||||
rack = SimpleNamespace(
|
||||
get_rack_units=MagicMock(
|
||||
return_value=[
|
||||
{"id": 12, "device": regular, "height": 1},
|
||||
# NetBox's native unit list can expose only one of multiple
|
||||
# partial devices occupying the same rack unit.
|
||||
{"id": 11, "device": partial_right, "height": 1},
|
||||
]
|
||||
)
|
||||
)
|
||||
elevation = SimpleNamespace(
|
||||
rack=rack,
|
||||
unit_width=200,
|
||||
unit_height=20,
|
||||
permitted_device_ids={1, 2, 3},
|
||||
drawing=SimpleNamespace(add=MagicMock()),
|
||||
_get_device_coords=MagicMock(return_value=(10, 20)),
|
||||
draw_device_front=MagicMock(),
|
||||
draw_device_rear=MagicMock(),
|
||||
)
|
||||
|
||||
with patch(
|
||||
"netbox_utilities.rack_width._partial_width_elevation_devices",
|
||||
return_value=[partial_left, partial_right],
|
||||
):
|
||||
RackElevationSVG.draw_face(elevation, "front")
|
||||
|
||||
rack.get_rack_units.assert_called_once_with(face="front", expand_devices=False)
|
||||
self.assertEqual(
|
||||
elevation.draw_device_front.call_args_list,
|
||||
[
|
||||
call(regular, (10, 20), (200, 20)),
|
||||
call(partial_left, (10.0, 20), (100.0, 20)),
|
||||
call(partial_right, (110.0, 20), (100.0, 20)),
|
||||
],
|
||||
)
|
||||
|
||||
def test_adds_rack_width_fields_to_existing_location_fieldset(self):
|
||||
from utilities.forms.rendering import FieldSet
|
||||
|
||||
|
||||
@@ -223,7 +223,10 @@ class ReorderRackFrontendTest(SimpleTestCase):
|
||||
rack_model.objects.restrict.return_value.filter.return_value.first.return_value = SimpleNamespace(pk=5)
|
||||
|
||||
with patch("netbox_utilities.reorder_rack.Device.objects.restrict", side_effect=AttributeError("stale")):
|
||||
self.assertIsNone(get_reorder_rack_width_data(request))
|
||||
result = get_reorder_rack_width_data(request)
|
||||
|
||||
self.assertEqual(result["status"], "native-fallback")
|
||||
self.assertEqual(result["devices"], [])
|
||||
|
||||
@patch("netbox_utilities.reorder_rack.reorder_rack_width_enabled", return_value=True)
|
||||
@patch("netbox_utilities.reorder_rack.get_permission_for_model", return_value="dcim.change_device")
|
||||
@@ -246,6 +249,7 @@ class ReorderRackFrontendTest(SimpleTestCase):
|
||||
device = SimpleNamespace(
|
||||
pk=10,
|
||||
name="Fritzbox",
|
||||
label="Fritzbox",
|
||||
virtual_chassis=None,
|
||||
device_type=SimpleNamespace(
|
||||
u_height=1,
|
||||
@@ -263,7 +267,6 @@ class ReorderRackFrontendTest(SimpleTestCase):
|
||||
device_model.objects.restrict.return_value = device_queryset
|
||||
|
||||
with (
|
||||
patch("dcim.svg.racks.get_device_name", return_value="Fritzbox"),
|
||||
patch(
|
||||
"netbox.config.get_config",
|
||||
return_value=SimpleNamespace(RACK_ELEVATION_DEFAULT_UNIT_WIDTH=220),
|
||||
@@ -273,6 +276,8 @@ class ReorderRackFrontendTest(SimpleTestCase):
|
||||
result = get_reorder_rack_width_data(request)
|
||||
|
||||
self.assertEqual(result["columns"], 12)
|
||||
self.assertEqual(result["status"], "ready")
|
||||
self.assertEqual(result["devices"][0]["label"], "Fritzbox")
|
||||
self.assertFalse(result["images"])
|
||||
self.assertTrue(result["labels"])
|
||||
self.assertEqual(
|
||||
|
||||
@@ -94,8 +94,9 @@ class TopologyViewsRackWidthTest(SimpleTestCase):
|
||||
position__isnull=False,
|
||||
)
|
||||
placement_objects.filter.assert_called_once_with(device__in="permitted-device-query")
|
||||
self.assertEqual(result[0]["width"], 2)
|
||||
self.assertEqual(result[0]["horizontal_position"], 2)
|
||||
self.assertEqual(result["status"], "ready")
|
||||
self.assertEqual(result["devices"][0]["width"], 2)
|
||||
self.assertEqual(result["devices"][0]["horizontal_position"], 2)
|
||||
|
||||
def test_frontend_supports_live_view_and_all_rack_export_formats(self):
|
||||
script = (Path(__file__).parents[1] / "static" / "netbox_utilities" / "topology-rack-width.js").read_text(
|
||||
@@ -112,6 +113,8 @@ class TopologyViewsRackWidthTest(SimpleTestCase):
|
||||
self.assertIn("event.stopImmediatePropagation()", script)
|
||||
self.assertIn("rackExportCompatible", script)
|
||||
self.assertIn("liveViewCompatible", script)
|
||||
self.assertIn("payload?.devices", script)
|
||||
self.assertIn("payload.status !== 'ready'", script)
|
||||
self.assertLess(script.index("liveViewCompatible"), script.index("netbox-utilities-partial-width"))
|
||||
self.assertLess(script.index("exportGraphic(graphic"), script.index("event.preventDefault()"))
|
||||
|
||||
@@ -119,7 +122,10 @@ class TopologyViewsRackWidthTest(SimpleTestCase):
|
||||
def test_malformed_partial_placement_fails_open(self, _enabled):
|
||||
self.request.resolver_match = SimpleNamespace(view_name="plugins:netbox_topology_views:rack_elevation")
|
||||
with patch("dcim.models.Rack.objects.restrict", side_effect=AttributeError("stale")):
|
||||
self.assertIsNone(get_topology_rack_width_data(self.request))
|
||||
result = get_topology_rack_width_data(self.request)
|
||||
|
||||
self.assertEqual(result["status"], "native-fallback")
|
||||
self.assertEqual(result["devices"], [])
|
||||
|
||||
def test_partial_width_css_uses_topology_device_slot_geometry(self):
|
||||
stylesheet = (Path(__file__).parents[1] / "static" / "netbox_utilities" / "netbox_utilities.css").read_text(
|
||||
|
||||
Reference in New Issue
Block a user