From ecdd30778a9ef6f6fbcf31dd356dceec21203756 Mon Sep 17 00:00:00 2001 From: Peter Eckel Date: Thu, 30 May 2024 15:49:43 +0000 Subject: [PATCH] Added essential tests for the double event rule invocation problem --- netbox/extras/tests/test_event_rules.py | 47 ++++++++++++++++++- .../dummy_plugin/migrations/0001_initial.py | 2 +- netbox/netbox/tests/dummy_plugin/models.py | 4 ++ 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/netbox/extras/tests/test_event_rules.py b/netbox/extras/tests/test_event_rules.py index 8cea2078a..80375ba82 100644 --- a/netbox/extras/tests/test_event_rules.py +++ b/netbox/extras/tests/test_event_rules.py @@ -16,6 +16,8 @@ from extras.events import enqueue_object, flush_events, serialize_for_event from extras.models import EventRule, Tag, Webhook from extras.webhooks import generate_signature, send_webhook from utilities.testing import APITestCase +from netbox.tests.dummy_plugin.models import DummyModel +from netbox.context import events_queue class EventRuleTest(APITestCase): @@ -31,6 +33,7 @@ class EventRuleTest(APITestCase): def setUpTestData(cls): site_type = ObjectType.objects.get_for_model(Site) + dummy_type = ObjectType.objects.get_for_model(DummyModel) DUMMY_URL = 'http://localhost:9000/' DUMMY_SECRET = 'LOOKATMEIMASECRETSTRING' @@ -65,7 +68,7 @@ class EventRuleTest(APITestCase): ), )) for event_rule in event_rules: - event_rule.object_types.set([site_type]) + event_rule.object_types.set([site_type, dummy_type]) Tag.objects.bulk_create(( Tag(name='Foo', slug='foo'), @@ -377,3 +380,45 @@ class EventRuleTest(APITestCase): # Patch the Session object with our dummy_send() method, then process the webhook for sending with patch.object(Session, 'send', dummy_send) as mock_send: send_webhook(**job.kwargs) + + def test_webhook_double_save_create(self): + data = { + 'name': 'Dummy', + } + url = reverse('plugins-api:dummy_plugin-api:dummymodel-list') + self.add_permissions('dummy_plugin.add_dummymodel') + response = self.client.post(url, data, format='json', **self.header) + self.assertHttpStatus(response, status.HTTP_201_CREATED) + self.assertEqual(DummyModel.objects.count(), 1) + + dummy = DummyModel.objects.first() + + self.assertEqual(self.queue.count, 1) + job = self.queue.jobs[0] + self.assertEqual(job.kwargs['event_rule'], EventRule.objects.get(type_create=True)) + self.assertEqual(job.kwargs['event'], ObjectChangeActionChoices.ACTION_CREATE) + self.assertEqual(job.kwargs['model_name'], 'dummymodel') + self.assertEqual(job.kwargs['data']['id'], dummy.pk) + self.assertEqual(job.kwargs['snapshots']['postchange']['name'], 'Dummy') + + def test_webhook_double_save_update(self): + dummy = DummyModel.objects.create(name='Dummy') + + data = { + 'name': 'New Dummy', + 'number': 42, + } + url = reverse('plugins-api:dummy_plugin-api:dummymodel-detail', kwargs={'pk': dummy.pk}) + self.add_permissions('dummy_plugin.change_dummymodel') + response = self.client.patch(url, data, format='json', **self.header) + self.assertHttpStatus(response, status.HTTP_200_OK) + self.assertEqual(DummyModel.objects.count(), 1) + + self.assertEqual(self.queue.count, 1) + job = self.queue.jobs[0] + self.assertEqual(job.kwargs['event_rule'], EventRule.objects.get(type_update=True)) + self.assertEqual(job.kwargs['event'], ObjectChangeActionChoices.ACTION_UPDATE) + self.assertEqual(job.kwargs['model_name'], 'dummymodel') + self.assertEqual(job.kwargs['data']['id'], dummy.pk) + self.assertEqual(job.kwargs['snapshots']['postchange']['name'], 'New Dummy') + self.assertEqual(job.kwargs['snapshots']['postchange']['number'], 42) diff --git a/netbox/netbox/tests/dummy_plugin/migrations/0001_initial.py b/netbox/netbox/tests/dummy_plugin/migrations/0001_initial.py index 9cd597ff4..9ba1547d3 100644 --- a/netbox/netbox/tests/dummy_plugin/migrations/0001_initial.py +++ b/netbox/netbox/tests/dummy_plugin/migrations/0001_initial.py @@ -15,7 +15,7 @@ class Migration(migrations.Migration): ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), ('name', models.CharField(max_length=20)), ('number', models.IntegerField(default=100)), - ('created', models.DateField(auto_now_add=True, null=True)), + ('created', models.DateTimeField(auto_now_add=True, null=True)), ('last_updated', models.DateTimeField(auto_now=True, null=True)), ], options={ diff --git a/netbox/netbox/tests/dummy_plugin/models.py b/netbox/netbox/tests/dummy_plugin/models.py index 19500e619..0c9d8e6dc 100644 --- a/netbox/netbox/tests/dummy_plugin/models.py +++ b/netbox/netbox/tests/dummy_plugin/models.py @@ -13,3 +13,7 @@ class DummyModel(EventRulesMixin, ChangeLoggingMixin, models.Model): class Meta: ordering = ['name'] + + def save(self, *args, **kwargs): + super().save() + super().save()