diff --git a/netbox/dcim/tests/test_views.py b/netbox/dcim/tests/test_views.py index 2485dedee..803fee30b 100644 --- a/netbox/dcim/tests/test_views.py +++ b/netbox/dcim/tests/test_views.py @@ -704,20 +704,8 @@ class ConsolePortTestCase(StandardTestCases.Views): 'type': ConsolePortTypeChoices.TYPE_RJ45, 'description': 'A console port', 'tags': 'Alpha,Bravo,Charlie', - - # Extraneous model fields - 'cable': None, - 'connected_endpoint': None, - 'connection_status': None, } - cls.csv_data = ( - "device,name", - "Device 1,Console Port 4", - "Device 1,Console Port 5", - "Device 1,Console Port 6", - ) - cls.bulk_create_data = { 'device': device.pk, 'name_pattern': 'Console Port [4-6]', @@ -726,14 +714,19 @@ class ConsolePortTestCase(StandardTestCases.Views): 'tags': 'Alpha,Bravo,Charlie', } + cls.csv_data = ( + "device,name", + "Device 1,Console Port 4", + "Device 1,Console Port 5", + "Device 1,Console Port 6", + ) + class ConsoleServerPortTestCase(StandardTestCases.Views): model = ConsoleServerPort # Disable inapplicable views test_get_object = None - - # TODO test_create_object = None def test_bulk_create_objects(self): @@ -755,19 +748,8 @@ class ConsoleServerPortTestCase(StandardTestCases.Views): 'type': ConsolePortTypeChoices.TYPE_RJ45, 'description': 'A console server port', 'tags': 'Alpha,Bravo,Charlie', - - # Extraneous model fields - 'cable': None, - 'connection_status': None, } - cls.csv_data = ( - "device,name", - "Device 1,Console Server Port 4", - "Device 1,Console Server Port 5", - "Device 1,Console Server Port 6", - ) - cls.bulk_create_data = { 'device': device.pk, 'name_pattern': 'Console Server Port [4-6]', @@ -782,6 +764,13 @@ class ConsoleServerPortTestCase(StandardTestCases.Views): 'description': 'New description', } + cls.csv_data = ( + "device,name", + "Device 1,Console Server Port 4", + "Device 1,Console Server Port 5", + "Device 1,Console Server Port 6", + ) + class PowerPortTestCase(StandardTestCases.Views): model = PowerPort @@ -789,8 +778,6 @@ class PowerPortTestCase(StandardTestCases.Views): # Disable inapplicable views test_get_object = None test_bulk_edit_objects = None - - # TODO test_create_object = None def test_bulk_create_objects(self): @@ -814,19 +801,8 @@ class PowerPortTestCase(StandardTestCases.Views): 'allocated_draw': 50, 'description': 'A power port', 'tags': 'Alpha,Bravo,Charlie', - - # Extraneous model fields - 'cable': None, - 'connection_status': None, } - cls.csv_data = ( - "device,name", - "Device 1,Power Port 4", - "Device 1,Power Port 5", - "Device 1,Power Port 6", - ) - cls.bulk_create_data = { 'device': device.pk, 'name_pattern': 'Power Port [4-6]]', @@ -837,14 +813,19 @@ class PowerPortTestCase(StandardTestCases.Views): 'tags': 'Alpha,Bravo,Charlie', } + cls.csv_data = ( + "device,name", + "Device 1,Power Port 4", + "Device 1,Power Port 5", + "Device 1,Power Port 6", + ) + class PowerOutletTestCase(StandardTestCases.Views): model = PowerOutlet # Disable inapplicable views test_get_object = None - - # TODO test_create_object = None def test_bulk_create_objects(self): @@ -874,19 +855,8 @@ class PowerOutletTestCase(StandardTestCases.Views): 'feed_leg': PowerOutletFeedLegChoices.FEED_LEG_B, 'description': 'A power outlet', 'tags': 'Alpha,Bravo,Charlie', - - # Extraneous model fields - 'cable': None, - 'connection_status': None, } - cls.csv_data = ( - "device,name", - "Device 1,Power Outlet 4", - "Device 1,Power Outlet 5", - "Device 1,Power Outlet 6", - ) - cls.bulk_create_data = { 'device': device.pk, 'name_pattern': 'Power Outlet [4-6]', @@ -905,11 +875,18 @@ class PowerOutletTestCase(StandardTestCases.Views): 'description': 'New description', } + cls.csv_data = ( + "device,name", + "Device 1,Power Outlet 4", + "Device 1,Power Outlet 5", + "Device 1,Power Outlet 6", + ) + class InterfaceTestCase(StandardTestCases.Views): model = Interface - # TODO + # Disable inapplicable views test_create_object = None def test_bulk_create_objects(self): @@ -950,19 +927,8 @@ class InterfaceTestCase(StandardTestCases.Views): 'untagged_vlan': vlans[0].pk, 'tagged_vlans': [v.pk for v in vlans[1:4]], 'tags': 'Alpha,Bravo,Charlie', - - # Extraneous model fields - 'cable': None, - 'connection_status': None, } - cls.csv_data = ( - "device,name,type", - "Device 1,Interface 4,1000BASE-T (1GE)", - "Device 1,Interface 5,1000BASE-T (1GE)", - "Device 1,Interface 6,1000BASE-T (1GE)", - ) - cls.bulk_create_data = { 'device': device.pk, 'name_pattern': 'Interface [4-6]', @@ -993,14 +959,19 @@ class InterfaceTestCase(StandardTestCases.Views): 'tagged_vlans': [v.pk for v in vlans[1:4]], } + cls.csv_data = ( + "device,name,type", + "Device 1,Interface 4,1000BASE-T (1GE)", + "Device 1,Interface 5,1000BASE-T (1GE)", + "Device 1,Interface 6,1000BASE-T (1GE)", + ) + class FrontPortTestCase(StandardTestCases.Views): model = FrontPort # Disable inapplicable views test_get_object = None - - # TODO test_create_object = None def test_bulk_create_objects(self): @@ -1034,18 +1005,8 @@ class FrontPortTestCase(StandardTestCases.Views): 'rear_port_position': 1, 'description': 'New description', 'tags': 'Alpha,Bravo,Charlie', - - # Extraneous model fields - 'cable': None, } - cls.csv_data = ( - "device,name,type,rear_port,rear_port_position", - "Device 1,Front Port 4,8P8C,Rear Port 4,1", - "Device 1,Front Port 5,8P8C,Rear Port 5,1", - "Device 1,Front Port 6,8P8C,Rear Port 6,1", - ) - cls.bulk_create_data = { 'device': device.pk, 'name_pattern': 'Front Port [4-6]', @@ -1062,14 +1023,19 @@ class FrontPortTestCase(StandardTestCases.Views): 'description': 'New description', } + cls.csv_data = ( + "device,name,type,rear_port,rear_port_position", + "Device 1,Front Port 4,8P8C,Rear Port 4,1", + "Device 1,Front Port 5,8P8C,Rear Port 5,1", + "Device 1,Front Port 6,8P8C,Rear Port 6,1", + ) + class RearPortTestCase(StandardTestCases.Views): model = RearPort # Disable inapplicable views test_get_object = None - - # TODO test_create_object = None def test_bulk_create_objects(self): @@ -1092,18 +1058,8 @@ class RearPortTestCase(StandardTestCases.Views): 'positions': 3, 'description': 'A rear port', 'tags': 'Alpha,Bravo,Charlie', - - # Extraneous model fields - 'cable': None, } - cls.csv_data = ( - "device,name,type,positions", - "Device 1,Rear Port 4,8P8C,1", - "Device 1,Rear Port 5,8P8C,1", - "Device 1,Rear Port 6,8P8C,1", - ) - cls.bulk_create_data = { 'device': device.pk, 'name_pattern': 'Rear Port [4-6]', @@ -1118,6 +1074,13 @@ class RearPortTestCase(StandardTestCases.Views): 'description': 'New description', } + cls.csv_data = ( + "device,name,type,positions", + "Device 1,Rear Port 4,8P8C,1", + "Device 1,Rear Port 5,8P8C,1", + "Device 1,Rear Port 6,8P8C,1", + ) + class DeviceBayTestCase(StandardTestCases.Views): model = DeviceBay @@ -1151,9 +1114,13 @@ class DeviceBayTestCase(StandardTestCases.Views): 'name': 'Device Bay X', 'description': 'A device bay', 'tags': 'Alpha,Bravo,Charlie', + } - # Extraneous model fields - 'installed_device': None, + cls.bulk_create_data = { + 'device': device2.pk, + 'name_pattern': 'Device Bay [4-6]', + 'description': 'A device bay', + 'tags': 'Alpha,Bravo,Charlie', } cls.csv_data = ( @@ -1163,13 +1130,6 @@ class DeviceBayTestCase(StandardTestCases.Views): "Device 1,Device Bay 6", ) - cls.bulk_create_data = { - 'device': device2.pk, - 'name_pattern': 'Device Bay [4-6]', - 'description': 'A device bay', - 'tags': 'Alpha,Bravo,Charlie', - } - class InventoryItemTestCase(StandardTestCases.Views): model = InventoryItem @@ -1204,13 +1164,6 @@ class InventoryItemTestCase(StandardTestCases.Views): 'tags': 'Alpha,Bravo,Charlie', } - cls.csv_data = ( - "device,name", - "Device 1,Inventory Item 4", - "Device 1,Inventory Item 5", - "Device 1,Inventory Item 6", - ) - cls.bulk_edit_data = { 'device': device.pk, 'manufacturer': manufacturer.pk, @@ -1218,6 +1171,13 @@ class InventoryItemTestCase(StandardTestCases.Views): 'description': 'New description', } + cls.csv_data = ( + "device,name", + "Device 1,Inventory Item 4", + "Device 1,Inventory Item 5", + "Device 1,Inventory Item 6", + ) + class CableTestCase(StandardTestCases.Views): model = Cable diff --git a/netbox/utilities/testing/testcases.py b/netbox/utilities/testing/testcases.py index 44386a0be..b5e2e1bab 100644 --- a/netbox/utilities/testing/testcases.py +++ b/netbox/utilities/testing/testcases.py @@ -1,12 +1,12 @@ from django.contrib.auth.models import Permission, User from django.core.exceptions import ObjectDoesNotExist -from django.forms.models import model_to_dict as model_to_dict_ +from django.forms.models import model_to_dict from django.test import Client, TestCase as _TestCase, override_settings from django.urls import reverse, NoReverseMatch from rest_framework.test import APIClient from users.models import Token -from .utils import disable_warnings, model_to_dict, post_data +from .utils import disable_warnings, post_data class TestCase(_TestCase): @@ -57,12 +57,12 @@ class TestCase(_TestCase): expected_status, response.status_code, getattr(response, 'data', 'No data') )) - def assertInstanceEquals(self, instance, data): + def assertInstanceEqual(self, instance, data): """ Compare a model instance to a dictionary, checking that its attribute values match those specified in the dictionary. """ - model_dict = model_to_dict_(instance, fields=data.keys()) + model_dict = model_to_dict(instance, fields=data.keys()) for key in list(model_dict.keys()): @@ -233,7 +233,7 @@ class StandardTestCases: self.assertEqual(initial_count + 1, self.model.objects.count()) instance = self.model.objects.order_by('-pk').first() - self.assertDictEqual(model_to_dict(instance), self.form_data) + self.assertInstanceEqual(instance, self.form_data) @override_settings(EXEMPT_VIEW_PERMISSIONS=[]) def test_edit_object(self): @@ -257,7 +257,7 @@ class StandardTestCases: self.assertHttpStatus(response, 302) instance = self.model.objects.get(pk=instance.pk) - self.assertDictEqual(model_to_dict(instance), self.form_data) + self.assertInstanceEqual(instance, self.form_data) @override_settings(EXEMPT_VIEW_PERMISSIONS=[]) def test_delete_object(self): @@ -335,13 +335,8 @@ class StandardTestCases: response = self.client.post(**request) self.assertHttpStatus(response, 302) - bulk_edit_fields = self.bulk_edit_data.keys() for i, instance in enumerate(self.model.objects.filter(pk__in=pk_list)): - self.assertDictEqual( - model_to_dict(instance, fields=bulk_edit_fields), - self.bulk_edit_data, - msg="Instance {} failed to validate after bulk edit: {}".format(i, instance) - ) + self.assertInstanceEqual(instance, self.bulk_edit_data) @override_settings(EXEMPT_VIEW_PERMISSIONS=[]) def test_bulk_delete_objects(self): @@ -398,4 +393,4 @@ class StandardTestCases: self.assertEqual(initial_count + expected_count, self.model.objects.count()) for instance in self.model.objects.order_by('-pk')[:expected_count]: - self.assertInstanceEquals(instance, self.bulk_create_data) + self.assertInstanceEqual(instance, self.bulk_create_data) diff --git a/netbox/utilities/testing/utils.py b/netbox/utilities/testing/utils.py index 6d20d4fff..469b21111 100644 --- a/netbox/utilities/testing/utils.py +++ b/netbox/utilities/testing/utils.py @@ -2,35 +2,6 @@ import logging from contextlib import contextmanager from django.contrib.auth.models import Permission, User -from django.forms.models import model_to_dict as _model_to_dict - - -def model_to_dict(instance, fields=None, exclude=None): - """ - Customized wrapper for Django's built-in model_to_dict(). Does the following: - - Excludes the instance ID field - - Exclude any fields prepended with an underscore - - Convert any assigned tags to a comma-separated string - """ - _exclude = ['id'] - if exclude is not None: - _exclude += exclude - - model_dict = _model_to_dict(instance, fields=fields, exclude=_exclude) - - for key in list(model_dict.keys()): - if key.startswith('_'): - del model_dict[key] - - # TODO: Differentiate between tags assigned to the instance and a M2M field for tags (ex: ConfigContext) - elif key == 'tags': - model_dict[key] = ','.join(sorted([tag.name for tag in model_dict['tags']])) - - # Convert ManyToManyField to list of instance PKs - elif model_dict[key] and type(model_dict[key]) in (list, tuple) and hasattr(model_dict[key][0], 'pk'): - model_dict[key] = [obj.pk for obj in model_dict[key]] - - return model_dict def post_data(data): diff --git a/netbox/virtualization/tests/test_views.py b/netbox/virtualization/tests/test_views.py index 7b570c3c7..6cedf9803 100644 --- a/netbox/virtualization/tests/test_views.py +++ b/netbox/virtualization/tests/test_views.py @@ -248,21 +248,8 @@ class InterfaceTestCase(StandardTestCases.Views): 'untagged_vlan': vlans[0].pk, 'tagged_vlans': [v.pk for v in vlans[1:4]], 'tags': 'Alpha,Bravo,Charlie', - - # Extraneous model fields - 'device': None, - 'lag': None, - 'cable': None, - 'connection_status': None, } - cls.csv_data = ( - "device,name,type", - "Device 1,Interface 4,1000BASE-T (1GE)", - "Device 1,Interface 5,1000BASE-T (1GE)", - "Device 1,Interface 6,1000BASE-T (1GE)", - ) - cls.bulk_create_data = { 'virtual_machine': virtualmachines[1].pk, 'name_pattern': 'Interface [4-6]', @@ -287,3 +274,10 @@ class InterfaceTestCase(StandardTestCases.Views): # 'untagged_vlan': vlans[0].pk, # 'tagged_vlans': [v.pk for v in vlans[1:4]], } + + cls.csv_data = ( + "device,name,type", + "Device 1,Interface 4,1000BASE-T (1GE)", + "Device 1,Interface 5,1000BASE-T (1GE)", + "Device 1,Interface 6,1000BASE-T (1GE)", + )