test_plugins.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. from unittest import skipIf
  2. from django.conf import settings
  3. from django.core.exceptions import ImproperlyConfigured
  4. from django.test import Client, TestCase, override_settings
  5. from django.urls import reverse
  6. from extras.plugins import PluginMenu, get_plugin_config
  7. from extras.tests.dummy_plugin import config as dummy_config
  8. from netbox.graphql.schema import Query
  9. from netbox.registry import registry
  10. @skipIf('extras.tests.dummy_plugin' not in settings.PLUGINS, "dummy_plugin not in settings.PLUGINS")
  11. class PluginTest(TestCase):
  12. def test_config(self):
  13. self.assertIn('extras.tests.dummy_plugin.DummyPluginConfig', settings.INSTALLED_APPS)
  14. def test_models(self):
  15. from extras.tests.dummy_plugin.models import DummyModel
  16. # Test saving an instance
  17. instance = DummyModel(name='Instance 1', number=100)
  18. instance.save()
  19. self.assertIsNotNone(instance.pk)
  20. # Test deleting an instance
  21. instance.delete()
  22. self.assertIsNone(instance.pk)
  23. def test_admin(self):
  24. # Test admin view URL resolution
  25. url = reverse('admin:dummy_plugin_dummymodel_add')
  26. self.assertEqual(url, '/admin/dummy_plugin/dummymodel/add/')
  27. def test_views(self):
  28. # Test URL resolution
  29. url = reverse('plugins:dummy_plugin:dummy_models')
  30. self.assertEqual(url, '/plugins/dummy-plugin/models/')
  31. # Test GET request
  32. client = Client()
  33. response = client.get(url)
  34. self.assertEqual(response.status_code, 200)
  35. @override_settings(EXEMPT_VIEW_PERMISSIONS=['*'])
  36. def test_api_views(self):
  37. # Test URL resolution
  38. url = reverse('plugins-api:dummy_plugin-api:dummymodel-list')
  39. self.assertEqual(url, '/api/plugins/dummy-plugin/dummy-models/')
  40. # Test GET request
  41. client = Client()
  42. response = client.get(url)
  43. self.assertEqual(response.status_code, 200)
  44. def test_registered_views(self):
  45. # Test URL resolution
  46. url = reverse('dcim:site_extra', kwargs={'pk': 1})
  47. self.assertEqual(url, '/dcim/sites/1/other-stuff/')
  48. # Test GET request
  49. client = Client()
  50. response = client.get(url)
  51. self.assertEqual(response.status_code, 200)
  52. def test_menu(self):
  53. """
  54. Check menu registration.
  55. """
  56. menu = registry['plugins']['menus'][0]
  57. self.assertIsInstance(menu, PluginMenu)
  58. self.assertEqual(menu.label, 'Dummy')
  59. def test_menu_items(self):
  60. """
  61. Check menu_items registration.
  62. """
  63. self.assertIn('Dummy plugin', registry['plugins']['menu_items'])
  64. menu_items = registry['plugins']['menu_items']['Dummy plugin']
  65. self.assertEqual(len(menu_items), 2)
  66. self.assertEqual(len(menu_items[0].buttons), 2)
  67. def test_template_extensions(self):
  68. """
  69. Check that plugin TemplateExtensions are registered.
  70. """
  71. from extras.tests.dummy_plugin.template_content import SiteContent
  72. self.assertIn(SiteContent, registry['plugins']['template_extensions']['dcim.site'])
  73. def test_user_preferences(self):
  74. """
  75. Check that plugin UserPreferences are registered.
  76. """
  77. self.assertIn('dummy_plugin', registry['plugins']['preferences'])
  78. user_preferences = registry['plugins']['preferences']['dummy_plugin']
  79. self.assertEqual(type(user_preferences), dict)
  80. self.assertEqual(list(user_preferences.keys()), ['pref1', 'pref2'])
  81. def test_middleware(self):
  82. """
  83. Check that plugin middleware is registered.
  84. """
  85. self.assertIn('extras.tests.dummy_plugin.middleware.DummyMiddleware', settings.MIDDLEWARE)
  86. def test_queues(self):
  87. """
  88. Check that plugin queues are registered with the accurate name.
  89. """
  90. self.assertIn('extras.tests.dummy_plugin.testing-low', settings.RQ_QUEUES)
  91. self.assertIn('extras.tests.dummy_plugin.testing-medium', settings.RQ_QUEUES)
  92. self.assertIn('extras.tests.dummy_plugin.testing-high', settings.RQ_QUEUES)
  93. def test_min_version(self):
  94. """
  95. Check enforcement of minimum NetBox version.
  96. """
  97. with self.assertRaises(ImproperlyConfigured):
  98. dummy_config.validate({}, '0.9')
  99. def test_max_version(self):
  100. """
  101. Check enforcement of maximum NetBox version.
  102. """
  103. with self.assertRaises(ImproperlyConfigured):
  104. dummy_config.validate({}, '10.0')
  105. def test_required_settings(self):
  106. """
  107. Validate enforcement of required settings.
  108. """
  109. class DummyConfigWithRequiredSettings(dummy_config):
  110. required_settings = ['foo']
  111. # Validation should pass when all required settings are present
  112. DummyConfigWithRequiredSettings.validate({'foo': True}, settings.VERSION)
  113. # Validation should fail when a required setting is missing
  114. with self.assertRaises(ImproperlyConfigured):
  115. DummyConfigWithRequiredSettings.validate({}, settings.VERSION)
  116. def test_default_settings(self):
  117. """
  118. Validate population of default config settings.
  119. """
  120. class DummyConfigWithDefaultSettings(dummy_config):
  121. default_settings = {
  122. 'bar': 123,
  123. }
  124. # Populate the default value if setting has not been specified
  125. user_config = {}
  126. DummyConfigWithDefaultSettings.validate(user_config, settings.VERSION)
  127. self.assertEqual(user_config['bar'], 123)
  128. # Don't overwrite specified values
  129. user_config = {'bar': 456}
  130. DummyConfigWithDefaultSettings.validate(user_config, settings.VERSION)
  131. self.assertEqual(user_config['bar'], 456)
  132. def test_graphql(self):
  133. """
  134. Validate the registration and operation of plugin-provided GraphQL schemas.
  135. """
  136. from extras.tests.dummy_plugin.graphql import DummyQuery
  137. self.assertIn(DummyQuery, registry['plugins']['graphql_schemas'])
  138. self.assertTrue(issubclass(Query, DummyQuery))
  139. @override_settings(PLUGINS_CONFIG={'extras.tests.dummy_plugin': {'foo': 123}})
  140. def test_get_plugin_config(self):
  141. """
  142. Validate that get_plugin_config() returns config parameters correctly.
  143. """
  144. plugin = 'extras.tests.dummy_plugin'
  145. self.assertEqual(get_plugin_config(plugin, 'foo'), 123)
  146. self.assertEqual(get_plugin_config(plugin, 'bar'), None)
  147. self.assertEqual(get_plugin_config(plugin, 'bar', default=456), 456)