From ac587432f9b4844b911ea25cb9cf516401ab958a Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 31 Oct 2022 14:46:27 -0400 Subject: [PATCH] Add tests --- netbox/extras/api/urls.py | 2 +- netbox/extras/filtersets.py | 12 +++- netbox/extras/tests/test_api.py | 69 +++++++++++++++++++++- netbox/extras/tests/test_filtersets.py | 79 ++++++++++++++++++++++++++ netbox/extras/tests/test_views.py | 52 +++++++++++++++++ netbox/utilities/testing/base.py | 8 ++- 6 files changed, 217 insertions(+), 5 deletions(-) diff --git a/netbox/extras/api/urls.py b/netbox/extras/api/urls.py index 1d8418508..91067d40d 100644 --- a/netbox/extras/api/urls.py +++ b/netbox/extras/api/urls.py @@ -9,7 +9,7 @@ router.register('webhooks', views.WebhookViewSet) router.register('custom-fields', views.CustomFieldViewSet) router.register('custom-links', views.CustomLinkViewSet) router.register('export-templates', views.ExportTemplateViewSet) -router.register('saved-filter', views.SavedFilterViewSet) +router.register('saved-filters', views.SavedFilterViewSet) router.register('tags', views.TagViewSet) router.register('image-attachments', views.ImageAttachmentViewSet) router.register('journal-entries', views.JournalEntryViewSet) diff --git a/netbox/extras/filtersets.py b/netbox/extras/filtersets.py index 000c4a839..263692557 100644 --- a/netbox/extras/filtersets.py +++ b/netbox/extras/filtersets.py @@ -148,10 +148,20 @@ class SavedFilterFilterSet(BaseFilterSet): field_name='content_types__id' ) content_types = ContentTypeFilter() + user_id = django_filters.ModelMultipleChoiceFilter( + queryset=User.objects.all(), + label='User (ID)', + ) + user = django_filters.ModelMultipleChoiceFilter( + field_name='user__username', + queryset=User.objects.all(), + to_field_name='username', + label='User (name)', + ) class Meta: model = SavedFilter - fields = ['id', 'content_types', 'name', 'description', 'user', 'enabled', 'shared', 'weight'] + fields = ['id', 'content_types', 'name', 'description', 'enabled', 'shared', 'weight'] def search(self, queryset, name, value): if not value.strip(): diff --git a/netbox/extras/tests/test_api.py b/netbox/extras/tests/test_api.py index 42246b651..045391ea8 100644 --- a/netbox/extras/tests/test_api.py +++ b/netbox/extras/tests/test_api.py @@ -3,7 +3,6 @@ from unittest import skipIf from django.contrib.auth.models import User from django.contrib.contenttypes.models import ContentType -from django.test import override_settings from django.urls import reverse from django.utils.timezone import make_aware from django_rq.queues import get_connection @@ -17,7 +16,6 @@ from extras.reports import Report from extras.scripts import BooleanVar, IntegerVar, Script, StringVar from utilities.testing import APITestCase, APIViewTestCases - rq_worker_running = Worker.count(get_connection('default')) @@ -192,6 +190,73 @@ class CustomLinkTest(APIViewTestCases.APIViewTestCase): custom_link.content_types.set([site_ct]) +class SavedFilterTest(APIViewTestCases.APIViewTestCase): + model = SavedFilter + brief_fields = ['display', 'id', 'name', 'url'] + create_data = [ + { + 'content_types': ['dcim.site'], + 'name': 'Saved Filter 4', + 'weight': 100, + 'enabled': True, + 'shared': True, + 'parameters': {'status': ['active']}, + }, + { + 'content_types': ['dcim.site'], + 'name': 'Saved Filter 5', + 'weight': 200, + 'enabled': True, + 'shared': True, + 'parameters': {'status': ['planned']}, + }, + { + 'content_types': ['dcim.site'], + 'name': 'Saved Filter 6', + 'weight': 300, + 'enabled': True, + 'shared': True, + 'parameters': {'status': ['retired']}, + }, + ] + bulk_update_data = { + 'weight': 1000, + 'enabled': False, + 'shared': False, + } + + @classmethod + def setUpTestData(cls): + site_ct = ContentType.objects.get_for_model(Site) + + saved_filters = ( + SavedFilter( + name='Saved Filter 1', + weight=100, + enabled=True, + shared=True, + parameters={'status': ['active']} + ), + SavedFilter( + name='Saved Filter 2', + weight=200, + enabled=True, + shared=True, + parameters={'status': ['planned']} + ), + SavedFilter( + name='Saved Filter 3', + weight=300, + enabled=True, + shared=True, + parameters={'status': ['retired']} + ), + ) + SavedFilter.objects.bulk_create(saved_filters) + for i, savedfilter in enumerate(saved_filters): + savedfilter.content_types.set([site_ct]) + + class ExportTemplateTest(APIViewTestCases.APIViewTestCase): model = ExportTemplate brief_fields = ['display', 'id', 'name', 'url'] diff --git a/netbox/extras/tests/test_filtersets.py b/netbox/extras/tests/test_filtersets.py index dd1fdb6b3..9209cb3a1 100644 --- a/netbox/extras/tests/test_filtersets.py +++ b/netbox/extras/tests/test_filtersets.py @@ -222,6 +222,85 @@ class CustomLinkTestCase(TestCase, BaseFilterSetTests): self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) +class SavedFilterTestCase(TestCase, BaseFilterSetTests): + queryset = SavedFilter.objects.all() + filterset = SavedFilterFilterSet + + @classmethod + def setUpTestData(cls): + content_types = ContentType.objects.filter(model__in=['site', 'rack', 'device']) + + users = ( + User(username='User 1'), + User(username='User 2'), + User(username='User 3'), + ) + User.objects.bulk_create(users) + + saved_filters = ( + SavedFilter( + name='Saved Filter 1', + user=users[0], + weight=100, + enabled=True, + shared=True, + parameters={'status': ['active']} + ), + SavedFilter( + name='Saved Filter 2', + user=users[1], + weight=200, + enabled=True, + shared=True, + parameters={'status': ['planned']} + ), + SavedFilter( + name='Saved Filter 3', + user=users[2], + weight=300, + enabled=False, + shared=False, + parameters={'status': ['retired']} + ), + ) + SavedFilter.objects.bulk_create(saved_filters) + for i, savedfilter in enumerate(saved_filters): + savedfilter.content_types.set([content_types[i]]) + + def test_name(self): + params = {'name': ['Saved Filter 1', 'Saved Filter 2']} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + + def test_content_types(self): + params = {'content_types': 'dcim.site'} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + params = {'content_type_id': [ContentType.objects.get_for_model(Site).pk]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + + def test_user(self): + users = User.objects.filter(username__startswith='User') + params = {'user': [users[0].username, users[1].username]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + params = {'user_id': [users[0].pk, users[1].pk]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + + def test_weight(self): + params = {'weight': [100, 200]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + + def test_enabled(self): + params = {'enabled': True} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + params = {'enabled': False} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + + def test_shared(self): + params = {'enabled': True} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + params = {'enabled': False} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + + class ExportTemplateTestCase(TestCase, BaseFilterSetTests): queryset = ExportTemplate.objects.all() filterset = ExportTemplateFilterSet diff --git a/netbox/extras/tests/test_views.py b/netbox/extras/tests/test_views.py index 85e5aea5e..175ffb9ca 100644 --- a/netbox/extras/tests/test_views.py +++ b/netbox/extras/tests/test_views.py @@ -107,6 +107,58 @@ class CustomLinkTestCase(ViewTestCases.PrimaryObjectViewTestCase): } +class SavedFilterTestCase(ViewTestCases.PrimaryObjectViewTestCase): + model = SavedFilter + + @classmethod + def setUpTestData(cls): + site_ct = ContentType.objects.get_for_model(Site) + + users = ( + User(username='User 1'), + User(username='User 2'), + User(username='User 3'), + ) + User.objects.bulk_create(users) + + saved_filters = ( + SavedFilter(name='Saved Filter 1', user=users[0], weight=100, parameters={'status': ['active']}), + SavedFilter(name='Saved Filter 2', user=users[1], weight=200, parameters={'status': ['planned']}), + SavedFilter(name='Saved Filter 3', user=users[2], weight=300, parameters={'status': ['retired']}), + ) + SavedFilter.objects.bulk_create(saved_filters) + for i, savedfilter in enumerate(saved_filters): + savedfilter.content_types.set([site_ct]) + + cls.form_data = { + 'name': 'Saved Filter X', + 'content_types': [site_ct.pk], + 'description': 'Foo', + 'weight': 1000, + 'enabled': True, + 'shared': True, + 'parameters': '{"foo": 123}', + } + + cls.csv_data = ( + 'name,content_types,weight,enabled,shared,parameters', + 'Saved Filter 4,dcim.device,400,True,True,{"foo": "a"}', + 'Saved Filter 5,dcim.device,500,True,True,{"foo": "b"}', + 'Saved Filter 6,dcim.device,600,True,True,{"foo": "c"}', + ) + + cls.csv_update_data = ( + "id,name", + f"{saved_filters[0].pk},Saved Filter 7", + f"{saved_filters[1].pk},Saved Filter 8", + f"{saved_filters[2].pk},Saved Filter 9", + ) + + cls.bulk_edit_data = { + 'weight': 999, + } + + class ExportTemplateTestCase(ViewTestCases.PrimaryObjectViewTestCase): model = ExportTemplate diff --git a/netbox/utilities/testing/base.py b/netbox/utilities/testing/base.py index 499a5e2e7..04ceca1e2 100644 --- a/netbox/utilities/testing/base.py +++ b/netbox/utilities/testing/base.py @@ -1,8 +1,10 @@ +import json + from django.contrib.auth.models import User from django.contrib.contenttypes.models import ContentType from django.contrib.postgres.fields import ArrayField from django.core.exceptions import FieldDoesNotExist -from django.db.models import ManyToManyField +from django.db.models import ManyToManyField, JSONField from django.forms.models import model_to_dict from django.test import Client, TestCase as _TestCase from netaddr import IPNetwork @@ -132,6 +134,10 @@ class ModelTestCase(TestCase): if type(instance._meta.get_field(key)) is ArrayField: model_dict[key] = ','.join([str(v) for v in value]) + # JSON + if type(instance._meta.get_field(key)) is JSONField and value is not None: + model_dict[key] = json.dumps(value) + return model_dict #