mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
More plugin testing (#3052)
* Add a check of a child panel too * do not cover error catching * test for implementation error * Add warning to test for * Add test for event_sample * ignore safety switches * Add a settings flag to enable event testing * test if not implemented is raises * raise plugin specific errors * use plugin specific error * fix assertation * add test for mixin * this point can't be reached * add tests for locate plugin * fix assertations * fix function call * refert switch * this is already caught by the internal API * also cover mixin redirect
This commit is contained in:
parent
a7ef560ee3
commit
1c6e5f0f20
@ -910,6 +910,7 @@ if DEBUG or TESTING:
|
||||
# Plugin test settings
|
||||
PLUGIN_TESTING = get_setting('PLUGIN_TESTING', TESTING) # are plugins beeing tested?
|
||||
PLUGIN_TESTING_SETUP = get_setting('PLUGIN_TESTING_SETUP', False) # load plugins from setup hooks in testing?
|
||||
PLUGIN_TESTING_EVENTS = False # Flag if events are tested right now
|
||||
PLUGIN_RETRY = get_setting('PLUGIN_RETRY', 5) # how often should plugin loading be tried?
|
||||
PLUGIN_FILE_CHECKED = False # Was the plugin file checked?
|
||||
|
||||
|
@ -76,7 +76,7 @@ class BulkNotificationMethodTests(BaseNotificationIntegrationTest):
|
||||
def test_BulkNotificationMethod(self):
|
||||
"""
|
||||
Ensure the implementation requirements are tested.
|
||||
NotImplementedError needs to raise if the send_bulk() method is not set.
|
||||
MixinNotImplementedError needs to raise if the send_bulk() method is not set.
|
||||
"""
|
||||
|
||||
class WrongImplementation(BulkNotificationMethod):
|
||||
@ -94,7 +94,7 @@ class SingleNotificationMethodTests(BaseNotificationIntegrationTest):
|
||||
def test_SingleNotificationMethod(self):
|
||||
"""
|
||||
Ensure the implementation requirements are tested.
|
||||
NotImplementedError needs to raise if the send() method is not set.
|
||||
MixinNotImplementedError needs to raise if the send() method is not set.
|
||||
"""
|
||||
|
||||
class WrongImplementation(SingleNotificationMethod):
|
||||
|
@ -26,9 +26,10 @@ def trigger_event(event, *args, **kwargs):
|
||||
|
||||
if not settings.PLUGINS_ENABLED:
|
||||
# Do nothing if plugins are not enabled
|
||||
return
|
||||
return # pragma: no cover
|
||||
|
||||
if not canAppAccessDatabase():
|
||||
# Make sure the database can be accessed and is not beeing tested rn
|
||||
if not canAppAccessDatabase() and not settings.PLUGIN_TESTING_EVENTS:
|
||||
logger.debug(f"Ignoring triggered event '{event}' - database not ready")
|
||||
return
|
||||
|
||||
@ -91,7 +92,7 @@ def process_event(plugin_slug, event, *args, **kwargs):
|
||||
|
||||
plugin = registry.plugins.get(plugin_slug, None)
|
||||
|
||||
if plugin is None:
|
||||
if plugin is None: # pragma: no cover
|
||||
logger.error(f"Could not find matching plugin for '{plugin_slug}'")
|
||||
return
|
||||
|
||||
@ -106,7 +107,7 @@ def allow_table_event(table_name):
|
||||
|
||||
if isImportingData():
|
||||
# Prevent table events during the data import process
|
||||
return False
|
||||
return False # pragma: no cover
|
||||
|
||||
table_name = table_name.lower().strip()
|
||||
|
||||
|
@ -541,7 +541,7 @@ class PanelMixin:
|
||||
|
||||
def get_custom_panels(self, view, request):
|
||||
""" This method *must* be implemented by the plugin class """
|
||||
raise NotImplementedError(f"{__class__} is missing the 'get_custom_panels' method")
|
||||
raise MixinNotImplementedError(f"{__class__} is missing the 'get_custom_panels' method")
|
||||
|
||||
def get_panel_context(self, view, request, context):
|
||||
"""
|
||||
@ -559,7 +559,7 @@ class PanelMixin:
|
||||
|
||||
try:
|
||||
context['object'] = view.get_object()
|
||||
except AttributeError:
|
||||
except AttributeError: # pragma: no cover
|
||||
pass
|
||||
|
||||
return context
|
||||
|
@ -8,6 +8,7 @@ from error_report.models import Error
|
||||
|
||||
from InvenTree.helpers import InvenTreeTestCase
|
||||
from plugin import InvenTreePlugin
|
||||
from plugin.base.integration.mixins import PanelMixin
|
||||
from plugin.helpers import MixinNotImplementedError
|
||||
from plugin.mixins import (APICallMixin, AppMixin, NavigationMixin,
|
||||
SettingsMixin, UrlsMixin)
|
||||
@ -324,7 +325,7 @@ class PanelMixinTests(InvenTreeTestCase):
|
||||
urls = [
|
||||
reverse('part-detail', kwargs={'pk': 1}),
|
||||
reverse('stock-item-detail', kwargs={'pk': 2}),
|
||||
reverse('stock-location-detail', kwargs={'pk': 1}),
|
||||
reverse('stock-location-detail', kwargs={'pk': 2}),
|
||||
]
|
||||
|
||||
plugin.set_setting('ENABLE_HELLO_WORLD', False)
|
||||
@ -379,3 +380,13 @@ class PanelMixinTests(InvenTreeTestCase):
|
||||
|
||||
# Assert that each request threw an error
|
||||
self.assertEqual(Error.objects.count(), n_errors + len(urls))
|
||||
|
||||
def test_mixin(self):
|
||||
"""Test that ImplementationError is raised"""
|
||||
|
||||
with self.assertRaises(MixinNotImplementedError):
|
||||
class Wrong(PanelMixin, InvenTreePlugin):
|
||||
pass
|
||||
|
||||
plugin = Wrong()
|
||||
plugin.get_custom_panels('abc', 'abc')
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
import logging
|
||||
|
||||
from plugin.helpers import MixinImplementationError
|
||||
from plugin.helpers import MixinNotImplementedError
|
||||
|
||||
logger = logging.getLogger('inventree')
|
||||
|
||||
@ -58,7 +58,7 @@ class LocateMixin:
|
||||
if item.in_stock and item.location is not None:
|
||||
self.locate_stock_location(item.location.pk)
|
||||
|
||||
except StockItem.DoesNotExist:
|
||||
except StockItem.DoesNotExist: # pragma: no cover
|
||||
logger.warning("LocateMixin: StockItem pk={item_pk} not found")
|
||||
pass
|
||||
|
||||
@ -71,4 +71,4 @@ class LocateMixin:
|
||||
|
||||
Note: The default implementation here does nothing!
|
||||
"""
|
||||
raise MixinImplementationError
|
||||
raise MixinNotImplementedError
|
||||
|
@ -5,7 +5,8 @@ Unit tests for the 'locate' plugin mixin class
|
||||
from django.urls import reverse
|
||||
|
||||
from InvenTree.api_tester import InvenTreeAPITestCase
|
||||
from plugin.registry import registry
|
||||
from plugin import InvenTreePlugin, MixinNotImplementedError, registry
|
||||
from plugin.base.locate.mixins import LocateMixin
|
||||
from stock.models import StockItem, StockLocation
|
||||
|
||||
|
||||
@ -145,3 +146,17 @@ class LocatePluginTests(InvenTreeAPITestCase):
|
||||
|
||||
# Item metadata should have been altered!
|
||||
self.assertTrue(location.metadata['located'])
|
||||
|
||||
def test_mixin_locate(self):
|
||||
"""Test the sample mixin redirection"""
|
||||
class SamplePlugin(LocateMixin, InvenTreePlugin):
|
||||
pass
|
||||
|
||||
plugin = SamplePlugin()
|
||||
|
||||
# Test that the request is patched through to location
|
||||
with self.assertRaises(MixinNotImplementedError):
|
||||
plugin.locate_stock_item(1)
|
||||
|
||||
# Test that it runs through
|
||||
plugin.locate_stock_item(999)
|
||||
|
@ -2,6 +2,10 @@
|
||||
Sample plugin which responds to events
|
||||
"""
|
||||
|
||||
import warnings
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
from plugin import InvenTreePlugin
|
||||
from plugin.mixins import EventMixin
|
||||
|
||||
@ -21,3 +25,7 @@ class EventPluginSample(EventMixin, InvenTreePlugin):
|
||||
print(f"Processing triggered event: '{event}'")
|
||||
print("args:", str(args))
|
||||
print("kwargs:", str(kwargs))
|
||||
|
||||
# Issue warning that we can test for
|
||||
if settings.PLUGIN_TESTING:
|
||||
warnings.warn(f'Event `{event}` triggered')
|
||||
|
40
InvenTree/plugin/samples/event/test_event_sample.py
Normal file
40
InvenTree/plugin/samples/event/test_event_sample.py
Normal file
@ -0,0 +1,40 @@
|
||||
"""Unit tests for event_sample sample plugins"""
|
||||
|
||||
from django.conf import settings
|
||||
from django.test import TestCase
|
||||
|
||||
from plugin import InvenTreePlugin, registry
|
||||
from plugin.base.event.events import trigger_event
|
||||
from plugin.helpers import MixinNotImplementedError
|
||||
from plugin.mixins import EventMixin
|
||||
|
||||
|
||||
class EventPluginSampleTests(TestCase):
|
||||
"""Tests for EventPluginSample"""
|
||||
|
||||
def test_run_event(self):
|
||||
"""Check if the event is issued"""
|
||||
# Activate plugin
|
||||
config = registry.get_plugin('sampleevent').plugin_config()
|
||||
config.active = True
|
||||
config.save()
|
||||
|
||||
# Enable event testing
|
||||
settings.PLUGIN_TESTING_EVENTS = True
|
||||
# Check that an event is issued
|
||||
with self.assertWarns(Warning) as cm:
|
||||
trigger_event('test.event')
|
||||
self.assertEqual(cm.warning.args[0], 'Event `test.event` triggered')
|
||||
|
||||
# Disable again
|
||||
settings.PLUGIN_TESTING_EVENTS = False
|
||||
|
||||
def test_mixin(self):
|
||||
"""Test that MixinNotImplementedError is raised"""
|
||||
|
||||
with self.assertRaises(MixinNotImplementedError):
|
||||
class Wrong(EventMixin, InvenTreePlugin):
|
||||
pass
|
||||
|
||||
plugin = Wrong()
|
||||
plugin.process_event('abc')
|
@ -37,7 +37,7 @@ class SampleLocatePlugin(LocateMixin, InvenTreePlugin):
|
||||
# Tag metadata
|
||||
item.set_metadata('located', True)
|
||||
|
||||
except (ValueError, StockItem.DoesNotExist):
|
||||
except (ValueError, StockItem.DoesNotExist): # pragma: no cover
|
||||
logger.error(f"StockItem ID {item_pk} does not exist!")
|
||||
|
||||
def locate_stock_location(self, location_pk):
|
||||
@ -53,5 +53,5 @@ class SampleLocatePlugin(LocateMixin, InvenTreePlugin):
|
||||
# Tag metadata
|
||||
location.set_metadata('located', True)
|
||||
|
||||
except (ValueError, StockLocation.DoesNotExist):
|
||||
except (ValueError, StockLocation.DoesNotExist): # pragma: no cover
|
||||
logger.error(f"Location ID {location_pk} does not exist!")
|
||||
|
60
InvenTree/plugin/samples/locate/test_locate_sample.py
Normal file
60
InvenTree/plugin/samples/locate/test_locate_sample.py
Normal file
@ -0,0 +1,60 @@
|
||||
"""Unit tests for locate_sample sample plugins"""
|
||||
|
||||
from django.urls import reverse
|
||||
|
||||
from InvenTree.api_tester import InvenTreeAPITestCase
|
||||
from plugin import InvenTreePlugin, registry
|
||||
from plugin.helpers import MixinNotImplementedError
|
||||
from plugin.mixins import LocateMixin
|
||||
|
||||
|
||||
class SampleLocatePlugintests(InvenTreeAPITestCase):
|
||||
"""Tests for SampleLocatePlugin"""
|
||||
|
||||
fixtures = [
|
||||
'location',
|
||||
'category',
|
||||
'part',
|
||||
'stock'
|
||||
]
|
||||
|
||||
def test_run_locator(self):
|
||||
"""Check if the event is issued"""
|
||||
# Activate plugin
|
||||
config = registry.get_plugin('samplelocate').plugin_config()
|
||||
config.active = True
|
||||
config.save()
|
||||
|
||||
# Test APIs
|
||||
url = reverse('api-locate-plugin')
|
||||
|
||||
# No plugin
|
||||
self.post(url, {}, expected_code=400)
|
||||
|
||||
# Wrong plugin
|
||||
self.post(url, {'plugin': 'sampleevent'}, expected_code=400)
|
||||
|
||||
# Right plugin - no search item
|
||||
self.post(url, {'plugin': 'samplelocate'}, expected_code=400)
|
||||
|
||||
# Right plugin - wrong reference
|
||||
self.post(url, {'plugin': 'samplelocate', 'item': 999}, expected_code=404)
|
||||
|
||||
# Right plugin - right reference
|
||||
self.post(url, {'plugin': 'samplelocate', 'item': 1}, expected_code=200)
|
||||
|
||||
# Right plugin - wrong reference
|
||||
self.post(url, {'plugin': 'samplelocate', 'location': 999}, expected_code=404)
|
||||
|
||||
# Right plugin - right reference
|
||||
self.post(url, {'plugin': 'samplelocate', 'location': 1}, expected_code=200)
|
||||
|
||||
def test_mixin(self):
|
||||
"""Test that MixinNotImplementedError is raised"""
|
||||
|
||||
with self.assertRaises(MixinNotImplementedError):
|
||||
class Wrong(LocateMixin, InvenTreePlugin):
|
||||
pass
|
||||
|
||||
plugin = Wrong()
|
||||
plugin.locate_stock_location(1)
|
Loading…
Reference in New Issue
Block a user