From ad8730151fb810e645dcc155dfd2a3a268059041 Mon Sep 17 00:00:00 2001 From: Jason Novinger Date: Fri, 11 Sep 2026 02:27:10 -0500 Subject: [PATCH] Populate bulk_update_invalid_data for dcim API tests test_bulk_update_objects_validation_error skips unless a test class sets bulk_update_invalid_data, and only SiteTestCase did, so the test has been skipping for nearly every model since it was added. Give each dcim test class an invalid payload, preferring a real choice field where the model has one, then a validated ColorField, then a nonexistent FK pk. Note that component template serializers have no owner field, so those classes use an FK instead. All 53 dcim API test classes now run the test. --- netbox/dcim/tests/test_api.py | 153 ++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) diff --git a/netbox/dcim/tests/test_api.py b/netbox/dcim/tests/test_api.py index 5ba406ee5..5e3319afc 100644 --- a/netbox/dcim/tests/test_api.py +++ b/netbox/dcim/tests/test_api.py @@ -106,6 +106,9 @@ class RegionTestCase(APIViewTestCases.APIViewTestCase): 'description': 'New description', 'comments': 'New comments', } + bulk_update_invalid_data = { + 'owner': 99999, + } @classmethod def setUpTestData(cls): @@ -139,6 +142,9 @@ class SiteGroupTestCase(APIViewTestCases.APIViewTestCase): 'description': 'New description', 'comments': 'I do exist!', } + bulk_update_invalid_data = { + 'owner': 99999, + } @classmethod def setUpTestData(cls): @@ -973,6 +979,9 @@ class LocationTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'status': 'not-a-valid-status', + } user_permissions = ('dcim.view_site',) graphql_filter_tests = ( GraphQLFilterTest( @@ -1095,6 +1104,9 @@ class RackGroupTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'owner': 99999, + } @classmethod def setUpTestData(cls): @@ -1130,6 +1142,9 @@ class RackRoleTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'color': 'not-a-color', + } @classmethod def setUpTestData(cls): @@ -1150,6 +1165,9 @@ class RackTypeTestCase(APIViewTestCases.APIViewTestCase): 'cooling_capability': RackCoolingCapabilityChoices.CAPABILITY_HYBRID, 'cooling_capacity': 50, } + bulk_update_invalid_data = { + 'form_factor': 'not-a-valid-form-factor', + } user_permissions = ('dcim.view_manufacturer',) @classmethod @@ -1213,6 +1231,9 @@ class RackTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'status': 'planned', } + bulk_update_invalid_data = { + 'status': 'not-a-valid-status', + } user_permissions = ('dcim.view_site', ) @classmethod @@ -1339,6 +1360,9 @@ class RackReservationTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'status': 'not-a-valid-status', + } user_permissions = ('dcim.view_rack', 'users.view_user') @classmethod @@ -1428,6 +1452,9 @@ class ManufacturerTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'owner': 99999, + } @classmethod def setUpTestData(cls): @@ -1447,6 +1474,9 @@ class DeviceTypeTestCase(APIViewTestCases.APIViewTestCase): 'part_number': 'ABC123', 'end_of_life': '2030-01-01', } + bulk_update_invalid_data = { + 'airflow': 'not-a-valid-airflow', + } user_permissions = ('dcim.view_manufacturer', ) @classmethod @@ -1495,6 +1525,9 @@ class ModuleTypeTestCase(APIViewTestCases.APIViewTestCase): 'part_number': 'ABC123', 'end_of_life': '2030-01-01', } + bulk_update_invalid_data = { + 'airflow': 'not-a-valid-airflow', + } user_permissions = ('dcim.view_manufacturer', ) @classmethod @@ -1584,6 +1617,9 @@ class ModuleTypeProfileTestCase(APIViewTestCases.APIViewTestCase): 'description': 'New description', 'comments': 'New comments', } + bulk_update_invalid_data = { + 'owner': 99999, + } @classmethod def setUpTestData(cls): @@ -1610,6 +1646,9 @@ class ModuleBayTypeTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'color': 'not-a-color', + } @classmethod def setUpTestData(cls): @@ -1651,6 +1690,9 @@ class ConsolePortTemplateTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'type': 'not-a-valid-type', + } @classmethod def setUpTestData(cls): @@ -1695,6 +1737,9 @@ class ConsoleServerPortTemplateTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'type': 'not-a-valid-type', + } @classmethod def setUpTestData(cls): @@ -1739,6 +1784,9 @@ class PowerPortTemplateTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'type': 'not-a-valid-type', + } @classmethod def setUpTestData(cls): @@ -1783,6 +1831,9 @@ class PowerOutletTemplateTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'type': 'not-a-valid-type', + } user_permissions = ('dcim.view_devicetype', ) @classmethod @@ -1841,6 +1892,9 @@ class InterfaceTemplateTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'poe_mode': 'not-a-valid-poe-mode', + } @classmethod def setUpTestData(cls): @@ -1906,6 +1960,9 @@ class FrontPortTemplateTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'color': 'not-a-color', + } user_permissions = ('dcim.view_rearporttemplate', ) @classmethod @@ -2023,6 +2080,9 @@ class RearPortTemplateTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'color': 'not-a-color', + } @classmethod def setUpTestData(cls): @@ -2139,6 +2199,9 @@ class ModuleBayTemplateTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'device_type': 99999, + } user_permissions = ('dcim.view_devicetype', ) @classmethod @@ -2191,6 +2254,9 @@ class DeviceBayTemplateTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'device_type': 99999, + } user_permissions = ('dcim.view_devicetype', ) @classmethod @@ -2233,6 +2299,9 @@ class InventoryItemTemplateTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'role': 99999, + } user_permissions = ('dcim.view_devicetype', 'dcim.view_manufacturer',) @classmethod @@ -2312,6 +2381,9 @@ class DeviceRoleTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'color': 'not-a-color', + } @classmethod def setUpTestData(cls): @@ -2343,6 +2415,9 @@ class PlatformTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'owner': 99999, + } @classmethod def setUpTestData(cls): @@ -2362,6 +2437,9 @@ class DeviceTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'status': 'failed', } + bulk_update_invalid_data = { + 'status': 'not-a-valid-status', + } user_permissions = ( 'dcim.view_site', 'dcim.view_rack', 'dcim.view_location', 'dcim.view_devicerole', 'dcim.view_devicetype', ) @@ -2821,6 +2899,9 @@ class ModuleTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'serial': '1234ABCD', } + bulk_update_invalid_data = { + 'status': 'not-a-valid-status', + } user_permissions = ( 'dcim.view_modulebay', 'dcim.view_moduletype', 'dcim.view_moduletypeprofile', 'dcim.view_device' ) @@ -3317,6 +3398,9 @@ class ConsolePortTestCase(Mixins.ComponentTraceMixin, APIViewTestCases.APIViewTe bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'type': 'not-a-valid-type', + } peer_termination_type = ConsoleServerPort user_permissions = ('dcim.view_device', ) @@ -3360,6 +3444,9 @@ class ConsoleServerPortTestCase(Mixins.ComponentTraceMixin, APIViewTestCases.API bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'type': 'not-a-valid-type', + } peer_termination_type = ConsolePort user_permissions = ('dcim.view_device', ) @@ -3403,6 +3490,9 @@ class PowerPortTestCase(Mixins.ComponentTraceMixin, APIViewTestCases.APIViewTest bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'type': 'not-a-valid-type', + } peer_termination_type = PowerOutlet user_permissions = ('dcim.view_device', ) @@ -3443,6 +3533,9 @@ class PowerOutletTestCase(Mixins.ComponentTraceMixin, APIViewTestCases.APIViewTe bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'status': 'not-a-valid-status', + } peer_termination_type = PowerPort user_permissions = ('dcim.view_device', ) @@ -3492,6 +3585,9 @@ class InterfaceTestCase(Mixins.ComponentTraceMixin, APIViewTestCases.APIViewTest bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'poe_mode': 'not-a-valid-poe-mode', + } peer_termination_type = Interface user_permissions = ('dcim.view_device', ) @@ -4051,6 +4147,9 @@ class FrontPortTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'color': 'not-a-color', + } peer_termination_type = Interface user_permissions = ('dcim.view_device', 'dcim.view_rearport') @@ -4170,6 +4269,9 @@ class RearPortTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'color': 'not-a-color', + } peer_termination_type = Interface user_permissions = ('dcim.view_device', ) @@ -4286,6 +4388,9 @@ class ModuleBayTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'owner': 99999, + } user_permissions = ('dcim.view_device', ) @classmethod @@ -4417,6 +4522,9 @@ class DeviceBayTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'owner': 99999, + } user_permissions = ('dcim.view_device', ) @classmethod @@ -4481,6 +4589,9 @@ class InventoryItemTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'status': 'not-a-valid-status', + } user_permissions = ('dcim.view_device', 'dcim.view_manufacturer') @classmethod @@ -4565,6 +4676,9 @@ class InventoryItemRoleTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'color': 'not-a-color', + } @classmethod def setUpTestData(cls): @@ -4588,6 +4702,9 @@ class CableBundleTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'owner': 99999, + } @classmethod def setUpTestData(cls): @@ -4638,6 +4755,9 @@ class CableTestCase(APIViewTestCases.APIViewTestCase): 'length': 100, 'length_unit': 'm', } + bulk_update_invalid_data = { + 'status': 'not-a-valid-status', + } # TODO: Allow updating cable terminations test_update_object = None @@ -5094,6 +5214,9 @@ class VirtualChassisTestCase(APIViewTestCases.APIViewTestCase): 'domain': 'newdomain', 'master': None } + cls.bulk_update_invalid_data = { + 'owner': 99999, + } class PowerPanelTestCase(APIViewTestCases.APIViewTestCase): @@ -5144,6 +5267,9 @@ class PowerPanelTestCase(APIViewTestCases.APIViewTestCase): 'site': sites[1].pk, 'location': locations[3].pk } + cls.bulk_update_invalid_data = { + 'owner': 99999, + } class PowerFeedTestCase(APIViewTestCases.APIViewTestCase): @@ -5152,6 +5278,9 @@ class PowerFeedTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'status': 'planned', } + bulk_update_invalid_data = { + 'status': 'not-a-valid-status', + } user_permissions = ('dcim.view_powerpanel', ) @classmethod @@ -5208,6 +5337,9 @@ class CoolingIntakeTemplateTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'type': 'not-a-valid-type', + } @classmethod def setUpTestData(cls): @@ -5253,6 +5385,9 @@ class CoolingOutflowTemplateTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'type': 'not-a-valid-type', + } user_permissions = ('dcim.view_devicetype', ) @classmethod @@ -5312,6 +5447,9 @@ class CoolingIntakeTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'type': 'not-a-valid-type', + } user_permissions = ('dcim.view_device', ) @classmethod @@ -5356,6 +5494,9 @@ class CoolingOutflowTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'type': 'not-a-valid-type', + } user_permissions = ('dcim.view_device', ) @classmethod @@ -5459,6 +5600,9 @@ class CoolingSourceTestCase(APIViewTestCases.APIViewTestCase): 'site': sites[1].pk, 'location': locations[3].pk } + cls.bulk_update_invalid_data = { + 'status': 'not-a-valid-status', + } class CoolingFeedTestCase(APIViewTestCases.APIViewTestCase): @@ -5467,6 +5611,9 @@ class CoolingFeedTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'status': 'planned', } + bulk_update_invalid_data = { + 'status': 'not-a-valid-status', + } user_permissions = ('dcim.view_coolingsource', ) @classmethod @@ -5528,6 +5675,9 @@ class VirtualDeviceContextTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'status': 'planned', } + bulk_update_invalid_data = { + 'status': 'not-a-valid-status', + } @classmethod def setUpTestData(cls): @@ -5651,6 +5801,9 @@ class MACAddressTestCase(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + bulk_update_invalid_data = { + 'owner': 99999, + } @classmethod def setUpTestData(cls):