Arthur 1 week geleden
bovenliggende
commit
f76b3671cc
3 gewijzigde bestanden met toevoegingen van 69 en 2 verwijderingen
  1. 7 0
      netbox/dcim/filtersets.py
  2. 5 1
      netbox/dcim/tests/test_filtersets.py
  3. 57 1
      netbox/dcim/tests/test_models.py

+ 7 - 0
netbox/dcim/filtersets.py

@@ -3207,6 +3207,13 @@ class CoolingSourceFilterSet(PrimaryModelFilterSet, ContactModelFilterSet):
         lookup_expr='in',
         lookup_expr='in',
         label=_('Location (ID)'),
         label=_('Location (ID)'),
     )
     )
+    location = TreeNodeMultipleChoiceFilter(
+        queryset=Location.objects.all(),
+        field_name='location',
+        lookup_expr='in',
+        to_field_name='slug',
+        label=_('Location (slug)'),
+    )
     type = django_filters.MultipleChoiceFilter(
     type = django_filters.MultipleChoiceFilter(
         choices=CoolingSourceTypeChoices,
         choices=CoolingSourceTypeChoices,
         distinct=False,
         distinct=False,

+ 5 - 1
netbox/dcim/tests/test_filtersets.py

@@ -8268,7 +8268,9 @@ class CoolingSourceTestCase(TestCase, ChangeLoggedFilterSetTests):
                 description='foobar3'
                 description='foobar3'
             ),
             ),
         )
         )
-        CoolingSource.objects.bulk_create(cooling_sources)
+        # Use save() rather than bulk_create() so that the normalized _abs_*_temperature fields are populated
+        for cooling_source in cooling_sources:
+            cooling_source.save()
 
 
     def test_q(self):
     def test_q(self):
         params = {'q': 'foobar1'}
         params = {'q': 'foobar1'}
@@ -8331,6 +8333,8 @@ class CoolingSourceTestCase(TestCase, ChangeLoggedFilterSetTests):
         locations = Location.objects.all()[:2]
         locations = Location.objects.all()[:2]
         params = {'location_id': [locations[0].pk, locations[1].pk]}
         params = {'location_id': [locations[0].pk, locations[1].pk]}
         self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
         self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+        params = {'location': [locations[0].slug, locations[1].slug]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
 
 
 
 
 class CoolingFeedTestCase(TestCase, ChangeLoggedFilterSetTests):
 class CoolingFeedTestCase(TestCase, ChangeLoggedFilterSetTests):

+ 57 - 1
netbox/dcim/tests/test_models.py

@@ -11,7 +11,7 @@ from dcim.models import *
 from extras.events import serialize_for_event
 from extras.events import serialize_for_event
 from extras.models import CustomField
 from extras.models import CustomField
 from ipam.models import Prefix
 from ipam.models import Prefix
-from netbox.choices import DiameterUnitChoices, WeightUnitChoices
+from netbox.choices import DiameterUnitChoices, TemperatureUnitChoices, WeightUnitChoices
 from tenancy.models import Tenant
 from tenancy.models import Tenant
 from utilities.data import drange
 from utilities.data import drange
 from virtualization.models import Cluster, ClusterType
 from virtualization.models import Cluster, ClusterType
@@ -2925,3 +2925,59 @@ class CoolingComponentTestCase(TestCase):
 
 
         with self.assertRaises(ValidationError):
         with self.assertRaises(ValidationError):
             cooling_outlet.full_clean()
             cooling_outlet.full_clean()
+
+    def test_cooling_source_location_site_mismatch(self):
+        """
+        CoolingSource.clean() should raise a ValidationError when its location belongs to a different site.
+        """
+        site2 = Site.objects.create(name='Site 2', slug='site-2')
+        location = Location.objects.create(name='Location 1', slug='location-1', site=site2)
+        cooling_source = CoolingSource(
+            site=self.site,
+            location=location,
+            name='Cooling Source 1',
+            status=CoolingSourceStatusChoices.STATUS_ACTIVE,
+        )
+        with self.assertRaises(ValidationError):
+            cooling_source.full_clean()
+
+    def test_cooling_source_temperature_without_unit(self):
+        """
+        CoolingSource.clean() should raise a ValidationError when a temperature is set without a unit.
+        """
+        cooling_source = CoolingSource(
+            site=self.site,
+            name='Cooling Source 2',
+            status=CoolingSourceStatusChoices.STATUS_ACTIVE,
+            supply_temperature=Decimal('18'),
+        )
+        with self.assertRaises(ValidationError):
+            cooling_source.full_clean()
+
+        # Setting a unit should resolve the error and populate the normalized value on save
+        cooling_source.temperature_unit = TemperatureUnitChoices.UNIT_CELSIUS
+        cooling_source.full_clean()
+        cooling_source.save()
+        self.assertEqual(cooling_source._abs_supply_temperature, Decimal('18.0000'))
+
+    def test_cooling_feed_rack_site_mismatch(self):
+        """
+        CoolingFeed.clean() should raise a ValidationError when its rack is in a different site than the
+        cooling source.
+        """
+        site2 = Site.objects.create(name='Site 3', slug='site-3')
+        cooling_source = CoolingSource.objects.create(
+            site=self.site,
+            name='Cooling Source 3',
+            status=CoolingSourceStatusChoices.STATUS_ACTIVE,
+        )
+        rack = Rack.objects.create(name='Rack 1', site=site2, status=RackStatusChoices.STATUS_ACTIVE)
+        cooling_feed = CoolingFeed(
+            cooling_source=cooling_source,
+            rack=rack,
+            name='Cooling Feed 1',
+            status=CoolingFeedStatusChoices.STATUS_ACTIVE,
+            type=CoolingFeedTypeChoices.TYPE_SUPPLY,
+        )
+        with self.assertRaises(ValidationError):
+            cooling_feed.full_clean()