Reduce duplication in plugin testing (#3800)

* move plugin loading into mixin

* move to mixin

* remove unneeded test step?

* fix merge
This commit is contained in:
Matthias Mair 2022-10-17 11:29:54 +02:00 committed by GitHub
parent 9c4faad68e
commit 0b0594c7ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 51 deletions

View File

@ -10,6 +10,9 @@ from django.http.response import StreamingHttpResponse
from rest_framework.test import APITestCase from rest_framework.test import APITestCase
from plugin import registry
from plugin.models import PluginConfig
class UserMixin: class UserMixin:
"""Mixin to setup a user and login for tests. """Mixin to setup a user and login for tests.
@ -87,6 +90,21 @@ class UserMixin:
break break
class PluginMixin:
"""Mixin to ensure that all plugins are loaded for tests."""
def setUp(self):
"""Setup for plugin tests."""
super().setUp()
# Load plugin configs
self.plugin_confs = PluginConfig.objects.all()
# Reload if not present
if not self.plugin_confs:
registry.reload_plugins()
self.plugin_confs = PluginConfig.objects.all()
class InvenTreeAPITestCase(UserMixin, APITestCase): class InvenTreeAPITestCase(UserMixin, APITestCase):
"""Base class for running InvenTree API tests.""" """Base class for running InvenTree API tests."""

View File

@ -9,10 +9,9 @@ from django.core.cache import cache
from django.test import Client, TestCase from django.test import Client, TestCase
from django.urls import reverse from django.urls import reverse
from InvenTree.api_tester import InvenTreeAPITestCase from InvenTree.api_tester import InvenTreeAPITestCase, PluginMixin
from InvenTree.helpers import InvenTreeTestCase, str2bool from InvenTree.helpers import InvenTreeTestCase, str2bool
from plugin import registry from plugin.models import NotificationUserSetting
from plugin.models import NotificationUserSetting, PluginConfig
from .api import WebhookView from .api import WebhookView
from .models import (ColorTheme, InvenTreeSetting, InvenTreeUserSetting, from .models import (ColorTheme, InvenTreeSetting, InvenTreeUserSetting,
@ -540,7 +539,7 @@ class NotificationUserSettingsApiTest(InvenTreeAPITestCase):
self.assertEqual(str(test_setting), 'NOTIFICATION_METHOD_MAIL (for testuser): True') self.assertEqual(str(test_setting), 'NOTIFICATION_METHOD_MAIL (for testuser): True')
class PluginSettingsApiTest(InvenTreeAPITestCase): class PluginSettingsApiTest(PluginMixin, InvenTreeAPITestCase):
"""Tests for the plugin settings API.""" """Tests for the plugin settings API."""
def test_plugin_list(self): def test_plugin_list(self):
@ -561,12 +560,6 @@ class PluginSettingsApiTest(InvenTreeAPITestCase):
def test_valid_plugin_slug(self): def test_valid_plugin_slug(self):
"""Test that an valid plugin slug runs through.""" """Test that an valid plugin slug runs through."""
# load plugin configs
fixtures = PluginConfig.objects.all()
if not fixtures:
registry.reload_plugins()
fixtures = PluginConfig.objects.all()
# get data # get data
url = reverse('api-plugin-setting-detail', kwargs={'plugin': 'sample', 'key': 'API_KEY'}) url = reverse('api-plugin-setting-detail', kwargs={'plugin': 'sample', 'key': 'API_KEY'})
response = self.get(url, expected_code=200) response = self.get(url, expected_code=200)

View File

@ -2,10 +2,10 @@
from django.urls import reverse from django.urls import reverse
from InvenTree.api_tester import InvenTreeAPITestCase from InvenTree.api_tester import InvenTreeAPITestCase, PluginMixin
class PluginDetailAPITest(InvenTreeAPITestCase): class PluginDetailAPITest(PluginMixin, InvenTreeAPITestCase):
"""Tests the plugin API endpoints.""" """Tests the plugin API endpoints."""
roles = [ roles = [
@ -72,26 +72,14 @@ class PluginDetailAPITest(InvenTreeAPITestCase):
def test_admin_action(self): def test_admin_action(self):
"""Test the PluginConfig action commands.""" """Test the PluginConfig action commands."""
from plugin import registry
from plugin.models import PluginConfig
url = reverse('admin:plugin_pluginconfig_changelist') url = reverse('admin:plugin_pluginconfig_changelist')
fixtures = PluginConfig.objects.all()
# check if plugins were registered -> in some test setups the startup has no db access test_plg = self.plugin_confs.first()
print(f'[PLUGIN-TEST] currently {len(fixtures)} plugin entries found')
if not fixtures:
registry.reload_plugins()
fixtures = PluginConfig.objects.all()
print(f'Reloaded plugins - now {len(fixtures)} entries found')
print([str(a) for a in fixtures])
fixtures = fixtures[0:1]
# deactivate plugin # deactivate plugin
response = self.client.post(url, { response = self.client.post(url, {
'action': 'plugin_deactivate', 'action': 'plugin_deactivate',
'index': 0, 'index': 0,
'_selected_action': [f.pk for f in fixtures], '_selected_action': [test_plg.pk],
}, follow=True) }, follow=True)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
@ -99,7 +87,7 @@ class PluginDetailAPITest(InvenTreeAPITestCase):
response = self.client.post(url, { response = self.client.post(url, {
'action': 'plugin_deactivate', 'action': 'plugin_deactivate',
'index': 0, 'index': 0,
'_selected_action': [f.pk for f in fixtures], '_selected_action': [test_plg.pk],
}, follow=True) }, follow=True)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
@ -107,47 +95,27 @@ class PluginDetailAPITest(InvenTreeAPITestCase):
response = self.client.post(url, { response = self.client.post(url, {
'action': 'plugin_activate', 'action': 'plugin_activate',
'index': 0, 'index': 0,
'_selected_action': [f.pk for f in fixtures], '_selected_action': [test_plg.pk],
}, follow=True) }, follow=True)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
# activate everything
fixtures = PluginConfig.objects.all()
response = self.client.post(url, {
'action': 'plugin_activate',
'index': 0,
'_selected_action': [f.pk for f in fixtures],
}, follow=True)
self.assertEqual(response.status_code, 200)
fixtures = PluginConfig.objects.filter(active=True)
# save to deactivate a plugin # save to deactivate a plugin
response = self.client.post(reverse('admin:plugin_pluginconfig_change', args=(fixtures.first().pk, )), { response = self.client.post(reverse('admin:plugin_pluginconfig_change', args=(test_plg.pk, )), {
'_save': 'Save', '_save': 'Save',
}, follow=True) }, follow=True)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
def test_model(self): def test_model(self):
"""Test the PluginConfig model.""" """Test the PluginConfig model."""
from plugin import registry
from plugin.models import PluginConfig
fixtures = PluginConfig.objects.all()
# check if plugins were registered
if not fixtures:
registry.reload_plugins()
fixtures = PluginConfig.objects.all()
# check mixin registry # check mixin registry
plg = fixtures.first() plg = self.plugin_confs.first()
mixin_dict = plg.mixins() mixin_dict = plg.mixins()
self.assertIn('base', mixin_dict) self.assertIn('base', mixin_dict)
self.assertDictContainsSubset({'base': {'key': 'base', 'human_name': 'base'}}, mixin_dict) self.assertDictContainsSubset({'base': {'key': 'base', 'human_name': 'base'}}, mixin_dict)
# check reload on save # check reload on save
with self.assertWarns(Warning) as cm: with self.assertWarns(Warning) as cm:
plg_inactive = fixtures.filter(active=False).first() plg_inactive = self.plugin_confs.filter(active=False).first()
plg_inactive.active = True plg_inactive.active = True
plg_inactive.save() plg_inactive.save()
self.assertEqual(cm.warning.args[0], 'A reload was triggered') self.assertEqual(cm.warning.args[0], 'A reload was triggered')