Просмотр исходного кода

Add _get_url() for View test case

Jeremy Stretch 6 лет назад
Родитель
Сommit
7daf1df22d
1 измененных файлов с 37 добавлено и 20 удалено
  1. 37 20
      netbox/utilities/testing/testcases.py

+ 37 - 20
netbox/utilities/testing/testcases.py

@@ -1,7 +1,7 @@
 from django.contrib.auth.models import Permission, User
 from django.core.exceptions import ObjectDoesNotExist
 from django.test import Client, TestCase as _TestCase
-from django.urls import reverse
+from django.urls import reverse, NoReverseMatch
 from rest_framework.test import APIClient
 
 from users.models import Token
@@ -88,15 +88,44 @@ class StandardTestCases:
         form_data = {}
         csv_data = {}
 
+        maxDiff = None
+
         def __init__(self, *args, **kwargs):
 
             super().__init__(*args, **kwargs)
 
-            if self.model is not None:
-                self.base_url_name = '{}:{}_{{}}'.format(self.model._meta.app_label, self.model._meta.model_name)
+            if self.model is None:
+                raise Exception("Test case requires model to be defined")
+
+        def _get_url(self, action, instance=None):
+            """
+            Return the URL name for a specific action. An instance must be specified for
+            get/edit/delete views.
+            """
+            url_format = '{}:{}_{{}}'.format(
+                self.model._meta.app_label,
+                self.model._meta.model_name
+            )
+
+            if action in ('list', 'add', 'import'):
+                return reverse(url_format.format(action))
+
+            elif action in ('get', 'edit', 'delete'):
+                if instance is None:
+                    raise Exception("Resolving {} URL requires specifying an instance".format(action))
+                # Attempt to resolve using slug first
+                if hasattr(self.model, 'slug'):
+                    try:
+                        return reverse(url_format.format(action), kwargs={'slug': instance.slug})
+                    except NoReverseMatch:
+                        pass
+                return reverse(url_format.format(action), kwargs={'pk': instance.pk})
+
+            else:
+                raise Exception("Invalid action for URL resolution: {}".format(action))
 
         def test_list_objects(self):
-            response = self.client.get(reverse(self.base_url_name.format('list')))
+            response = self.client.get(self._get_url('list'))
             self.assertHttpStatus(response, 200)
 
         def test_get_object(self):
@@ -107,7 +136,7 @@ class StandardTestCases:
         def test_create_object(self):
             initial_count = self.model.objects.count()
             request = {
-                'path': reverse(self.base_url_name.format('add')),
+                'path': self._get_url('add'),
                 'data': post_data(self.form_data),
                 'follow': True,
             }
@@ -128,14 +157,8 @@ class StandardTestCases:
         def test_edit_object(self):
             instance = self.model.objects.first()
 
-            # Determine the proper kwargs to pass to the edit URL
-            if hasattr(instance, 'slug'):
-                kwargs = {'slug': instance.slug}
-            else:
-                kwargs = {'pk': instance.pk}
-
             request = {
-                'path': reverse(self.base_url_name.format('edit'), kwargs=kwargs),
+                'path': self._get_url('edit', instance),
                 'data': post_data(self.form_data),
                 'follow': True,
             }
@@ -155,14 +178,8 @@ class StandardTestCases:
         def test_delete_object(self):
             instance = self.model.objects.first()
 
-            # Determine the proper kwargs to pass to the deletion URL
-            if hasattr(instance, 'slug'):
-                kwargs = {'slug': instance.slug}
-            else:
-                kwargs = {'pk': instance.pk}
-
             request = {
-                'path': reverse(self.base_url_name.format('delete'), kwargs=kwargs),
+                'path': self._get_url('delete', instance),
                 'data': {'confirm': True},
                 'follow': True,
             }
@@ -182,7 +199,7 @@ class StandardTestCases:
         def test_import_objects(self):
             initial_count = self.model.objects.count()
             request = {
-                'path': reverse(self.base_url_name.format('import')),
+                'path': self._get_url('import'),
                 'data': {
                     'csv': '\n'.join(self.csv_data)
                 }