diff --git a/netbox/utilities/testing/api.py b/netbox/utilities/testing/api.py index 7ca8f332d..c8bea8447 100644 --- a/netbox/utilities/testing/api.py +++ b/netbox/utilities/testing/api.py @@ -254,6 +254,7 @@ class APIViewTestCases: action=ObjectChangeActionChoices.ACTION_CREATE, ) self.assertEqual(objectchange.message, data['changelog_message']) + self.assertObjectChangeData(objectchange, prechange_data=None, postchange_data=True) def test_bulk_create_objects(self): """ @@ -307,6 +308,8 @@ class APIViewTestCases: self.assertEqual(len(objectchanges), len(self.create_data)) for oc in objectchanges: self.assertEqual(oc.message, changelog_message) + self.assertIsNone(oc.prechange_data) + self.assertIsNotNone(oc.postchange_data) class UpdateObjectViewTestCase(APITestCase): update_data = {} @@ -366,6 +369,8 @@ class APIViewTestCases: ) self.assertEqual(objectchange.action, ObjectChangeActionChoices.ACTION_UPDATE) self.assertEqual(objectchange.message, data['changelog_message']) + self.assertObjectChangeData(objectchange, prechange_data=True, postchange_data=True) + self.assertNotEqual(objectchange.prechange_data, objectchange.postchange_data) def test_bulk_update_objects(self): """ @@ -416,6 +421,9 @@ class APIViewTestCases: for oc in objectchanges: self.assertEqual(oc.action, ObjectChangeActionChoices.ACTION_UPDATE) self.assertEqual(oc.message, changelog_message) + self.assertIsNotNone(oc.prechange_data) + self.assertIsNotNone(oc.postchange_data) + self.assertNotEqual(oc.prechange_data, oc.postchange_data) class DeleteObjectViewTestCase(APITestCase): @@ -464,6 +472,7 @@ class APIViewTestCases: ) self.assertEqual(objectchange.action, ObjectChangeActionChoices.ACTION_DELETE) self.assertEqual(objectchange.message, data['changelog_message']) + self.assertObjectChangeData(objectchange, prechange_data=True, postchange_data=None) def test_bulk_delete_objects(self): """ @@ -505,6 +514,8 @@ class APIViewTestCases: for oc in objectchanges: self.assertEqual(oc.action, ObjectChangeActionChoices.ACTION_DELETE) self.assertEqual(oc.message, changelog_message) + self.assertIsNotNone(oc.prechange_data) + self.assertIsNone(oc.postchange_data) class GraphQLTestCase(APITestCase): diff --git a/netbox/utilities/testing/base.py b/netbox/utilities/testing/base.py index b39dd69b7..52cdb9d83 100644 --- a/netbox/utilities/testing/base.py +++ b/netbox/utilities/testing/base.py @@ -83,6 +83,20 @@ class TestCase(_TestCase): # Custom assertions # + def assertObjectChangeData(self, objectchange, prechange_data, postchange_data): + """ + Assert that an ObjectChange record has the expected prechange_data and postchange_data. + Pass None to assert the field is null; pass any non-None value to assert it is populated. + """ + if prechange_data is None: + self.assertIsNone(objectchange.prechange_data, "Expected prechange_data to be None") + else: + self.assertIsNotNone(objectchange.prechange_data, "Expected prechange_data to be populated") + if postchange_data is None: + self.assertIsNone(objectchange.postchange_data, "Expected postchange_data to be None") + else: + self.assertIsNotNone(objectchange.postchange_data, "Expected postchange_data to be populated") + def assertHttpStatus(self, response, expected_status): """ TestCase method. Provide more detail in the event of an unexpected HTTP response. diff --git a/netbox/utilities/testing/views.py b/netbox/utilities/testing/views.py index 353f69222..c1415c726 100644 --- a/netbox/utilities/testing/views.py +++ b/netbox/utilities/testing/views.py @@ -194,6 +194,7 @@ class ViewTestCases: self.assertEqual(len(objectchanges), 1) self.assertEqual(objectchanges[0].action, ObjectChangeActionChoices.ACTION_CREATE) self.assertEqual(objectchanges[0].message, self.form_data['changelog_message']) + self.assertObjectChangeData(objectchanges[0], prechange_data=None, postchange_data=True) @override_settings(EXEMPT_VIEW_PERMISSIONS=['*'], EXEMPT_EXCLUDE_MODELS=[]) def test_create_object_with_constrained_permission(self): @@ -301,6 +302,8 @@ class ViewTestCases: self.assertEqual(len(objectchanges), 1) self.assertEqual(objectchanges[0].action, ObjectChangeActionChoices.ACTION_UPDATE) self.assertEqual(objectchanges[0].message, self.form_data['changelog_message']) + self.assertObjectChangeData(objectchanges[0], prechange_data=True, postchange_data=True) + self.assertNotEqual(objectchanges[0].prechange_data, objectchanges[0].postchange_data) @override_settings(EXEMPT_VIEW_PERMISSIONS=['*'], EXEMPT_EXCLUDE_MODELS=[]) def test_edit_object_with_constrained_permission(self): @@ -396,6 +399,7 @@ class ViewTestCases: self.assertEqual(len(objectchanges), 1) self.assertEqual(objectchanges[0].action, ObjectChangeActionChoices.ACTION_DELETE) self.assertEqual(objectchanges[0].message, form_data['changelog_message']) + self.assertObjectChangeData(objectchanges[0], prechange_data=True, postchange_data=None) @override_settings(EXEMPT_VIEW_PERMISSIONS=['*']) def test_delete_object_with_constrained_permission(self): @@ -717,6 +721,8 @@ class ViewTestCases: for oc in objectchanges: self.assertEqual(oc.message, data['changelog_message']) + self.assertIsNone(oc.prechange_data) + self.assertIsNotNone(oc.postchange_data) @override_settings(EXEMPT_VIEW_PERMISSIONS=['*']) def test_bulk_update_objects_with_permission(self): @@ -870,6 +876,9 @@ class ViewTestCases: for oc in objectchanges: self.assertEqual(oc.action, ObjectChangeActionChoices.ACTION_UPDATE) self.assertEqual(oc.message, data['changelog_message']) + self.assertIsNotNone(oc.prechange_data) + self.assertIsNotNone(oc.postchange_data) + self.assertNotEqual(oc.prechange_data, oc.postchange_data) @override_settings(EXEMPT_VIEW_PERMISSIONS=['*'], EXEMPT_EXCLUDE_MODELS=[]) def test_bulk_edit_objects_with_constrained_permission(self): @@ -966,6 +975,8 @@ class ViewTestCases: for oc in objectchanges: self.assertEqual(oc.action, ObjectChangeActionChoices.ACTION_DELETE) self.assertEqual(oc.message, data['changelog_message']) + self.assertIsNotNone(oc.prechange_data) + self.assertIsNone(oc.postchange_data) def test_bulk_delete_objects_with_constrained_permission(self): pk_list = self._get_queryset().values_list('pk', flat=True)