mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-29 20:16:44 +00:00
Fixes for unit tests
This commit is contained in:
parent
928b90a833
commit
ac849c1566
@ -8,30 +8,38 @@ import plugin.registry as registry
|
|||||||
|
|
||||||
|
|
||||||
def plugin_update(queryset, new_status: bool):
|
def plugin_update(queryset, new_status: bool):
|
||||||
"""general function for bulk changing plugins"""
|
"""
|
||||||
|
General function for bulk changing plugins
|
||||||
|
"""
|
||||||
|
|
||||||
apps_changed = False
|
apps_changed = False
|
||||||
|
|
||||||
# run through all plugins in the queryset as the save method needs to be overridden
|
# Run through all plugins in the queryset as the save method needs to be overridden
|
||||||
for plugin in queryset:
|
for plugin in queryset:
|
||||||
if plugin.active is not new_status:
|
if plugin.active is not new_status:
|
||||||
plugin.active = new_status
|
plugin.active = new_status
|
||||||
plugin.save(no_reload=True)
|
plugin.save(no_reload=True)
|
||||||
apps_changed = True
|
apps_changed = True
|
||||||
|
|
||||||
# reload plugins if they changed
|
# Reload plugins if they changed
|
||||||
if apps_changed:
|
if apps_changed:
|
||||||
registry.plugin_registry.reload_plugins()
|
registry.plugin_registry.reload_plugins()
|
||||||
|
|
||||||
|
|
||||||
@admin.action(description='Activate plugin(s)')
|
@admin.action(description='Activate plugin(s)')
|
||||||
def plugin_activate(modeladmin, request, queryset):
|
def plugin_activate(modeladmin, request, queryset):
|
||||||
"""activate a set of plugins"""
|
"""
|
||||||
|
Activate a set of plugins
|
||||||
|
"""
|
||||||
plugin_update(queryset, True)
|
plugin_update(queryset, True)
|
||||||
|
|
||||||
|
|
||||||
@admin.action(description='Deactivate plugin(s)')
|
@admin.action(description='Deactivate plugin(s)')
|
||||||
def plugin_deactivate(modeladmin, request, queryset):
|
def plugin_deactivate(modeladmin, request, queryset):
|
||||||
"""deactivate a set of plugins"""
|
"""
|
||||||
|
Deactivate a set of plugins
|
||||||
|
"""
|
||||||
|
|
||||||
plugin_update(queryset, False)
|
plugin_update(queryset, False)
|
||||||
|
|
||||||
|
|
||||||
@ -51,7 +59,10 @@ class PluginSettingInline(admin.TabularInline):
|
|||||||
|
|
||||||
|
|
||||||
class PluginConfigAdmin(admin.ModelAdmin):
|
class PluginConfigAdmin(admin.ModelAdmin):
|
||||||
"""Custom admin with restricted id fields"""
|
"""
|
||||||
|
Custom admin with restricted id fields
|
||||||
|
"""
|
||||||
|
|
||||||
readonly_fields = ["key", "name", ]
|
readonly_fields = ["key", "name", ]
|
||||||
list_display = ['name', 'key', '__str__', 'active', ]
|
list_display = ['name', 'key', '__str__', 'active', ]
|
||||||
list_filter = ['active']
|
list_filter = ['active']
|
||||||
|
@ -34,17 +34,9 @@ class SettingsMixin:
|
|||||||
Return the 'value' of the setting associated with this plugin
|
Return the 'value' of the setting associated with this plugin
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Find the plugin configuration associated with this plugin
|
return PluginSetting.get_setting(key, plugin=self)
|
||||||
|
|
||||||
plugin = self.plugin_config()
|
def set_setting(self, key, value, user=None):
|
||||||
|
|
||||||
if plugin:
|
|
||||||
return PluginSetting.get_setting(key, plugin=plugin, settings=self.settings)
|
|
||||||
else:
|
|
||||||
# Plugin cannot be found, return default value
|
|
||||||
return PluginSetting.get_setting_default(key, settings=self.settings)
|
|
||||||
|
|
||||||
def set_setting(self, key, value, user):
|
|
||||||
"""
|
"""
|
||||||
Set plugin setting value by key
|
Set plugin setting value by key
|
||||||
"""
|
"""
|
||||||
@ -58,7 +50,7 @@ class SettingsMixin:
|
|||||||
# Cannot find associated plugin model, return
|
# Cannot find associated plugin model, return
|
||||||
return
|
return
|
||||||
|
|
||||||
PluginSetting.set_setting(key, value, user, plugin=plugin, settings=self.settings)
|
PluginSetting.set_setting(key, value, user, plugin=plugin)
|
||||||
|
|
||||||
|
|
||||||
class UrlsMixin:
|
class UrlsMixin:
|
||||||
|
@ -19,19 +19,27 @@ logger = logging.getLogger("inventree")
|
|||||||
|
|
||||||
|
|
||||||
class MixinBase:
|
class MixinBase:
|
||||||
"""general base for mixins"""
|
"""
|
||||||
|
General base for mixins
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self._mixinreg = {}
|
self._mixinreg = {}
|
||||||
self._mixins = {}
|
self._mixins = {}
|
||||||
|
|
||||||
def add_mixin(self, key: str, fnc_enabled=True, cls=None):
|
def add_mixin(self, key: str, fnc_enabled=True, cls=None):
|
||||||
"""add a mixin to the plugins registry"""
|
"""
|
||||||
|
Add a mixin to the plugins registry
|
||||||
|
"""
|
||||||
|
|
||||||
self._mixins[key] = fnc_enabled
|
self._mixins[key] = fnc_enabled
|
||||||
self.setup_mixin(key, cls=cls)
|
self.setup_mixin(key, cls=cls)
|
||||||
|
|
||||||
def setup_mixin(self, key, cls=None):
|
def setup_mixin(self, key, cls=None):
|
||||||
"""define mixin details for the current mixin -> provides meta details for all active mixins"""
|
"""
|
||||||
|
Define mixin details for the current mixin -> provides meta details for all active mixins
|
||||||
|
"""
|
||||||
|
|
||||||
# get human name
|
# get human name
|
||||||
human_name = getattr(cls.MixinMeta, 'MIXIN_NAME', key) if cls and hasattr(cls, 'MixinMeta') else key
|
human_name = getattr(cls.MixinMeta, 'MIXIN_NAME', key) if cls and hasattr(cls, 'MixinMeta') else key
|
||||||
|
|
||||||
@ -43,7 +51,10 @@ class MixinBase:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def registered_mixins(self, with_base: bool = False):
|
def registered_mixins(self, with_base: bool = False):
|
||||||
"""get all registered mixins for the plugin"""
|
"""
|
||||||
|
Get all registered mixins for the plugin
|
||||||
|
"""
|
||||||
|
|
||||||
mixins = getattr(self, '_mixinreg', None)
|
mixins = getattr(self, '_mixinreg', None)
|
||||||
if mixins:
|
if mixins:
|
||||||
# filter out base
|
# filter out base
|
||||||
|
@ -18,9 +18,9 @@ class InvenTreePlugin():
|
|||||||
# Override the plugin name for each concrete plugin instance
|
# Override the plugin name for each concrete plugin instance
|
||||||
PLUGIN_NAME = ''
|
PLUGIN_NAME = ''
|
||||||
|
|
||||||
PLUGIN_SLUG = ''
|
PLUGIN_SLUG = None
|
||||||
|
|
||||||
PLUGIN_TITLE = ''
|
PLUGIN_TITLE = None
|
||||||
|
|
||||||
def plugin_name(self):
|
def plugin_name(self):
|
||||||
"""
|
"""
|
||||||
@ -35,11 +35,14 @@ class InvenTreePlugin():
|
|||||||
if slug is None:
|
if slug is None:
|
||||||
slug = self.plugin_name()
|
slug = self.plugin_name()
|
||||||
|
|
||||||
return slugify(slug)
|
return slugify(slug.lower())
|
||||||
|
|
||||||
def plugin_title(self):
|
def plugin_title(self):
|
||||||
|
|
||||||
return self.PLUGIN_TITLE
|
if self.PLUGIN_TITLE:
|
||||||
|
return self.PLUGIN_TITLE
|
||||||
|
else:
|
||||||
|
return self.plugin_name()
|
||||||
|
|
||||||
def plugin_config(self, raise_error=False):
|
def plugin_config(self, raise_error=False):
|
||||||
"""
|
"""
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
"""
|
"""
|
||||||
registry for plugins
|
Registry for loading and managing multiple plugins at run-time
|
||||||
holds the class and the object that contains all code to maintain plugin states
|
|
||||||
|
- Holds the class and the object that contains all code to maintain plugin states
|
||||||
|
- Manages setup and teardown of plugin class instances
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import importlib
|
import importlib
|
||||||
import pathlib
|
import pathlib
|
||||||
import logging
|
import logging
|
||||||
@ -34,6 +37,10 @@ logger = logging.getLogger('inventree')
|
|||||||
|
|
||||||
|
|
||||||
class PluginsRegistry:
|
class PluginsRegistry:
|
||||||
|
"""
|
||||||
|
The PluginsRegistry class
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
# plugin registry
|
# plugin registry
|
||||||
self.plugins = {}
|
self.plugins = {}
|
||||||
@ -54,11 +61,15 @@ class PluginsRegistry:
|
|||||||
|
|
||||||
# region public plugin functions
|
# region public plugin functions
|
||||||
def load_plugins(self):
|
def load_plugins(self):
|
||||||
"""load and activate all IntegrationPlugins"""
|
"""
|
||||||
|
Load and activate all IntegrationPlugins
|
||||||
|
"""
|
||||||
|
|
||||||
from plugin.helpers import log_plugin_error
|
from plugin.helpers import log_plugin_error
|
||||||
|
|
||||||
logger.info('Start loading plugins')
|
logger.info('Start loading plugins')
|
||||||
# set maintanace mode
|
|
||||||
|
# Set maintanace mode
|
||||||
_maintenance = bool(get_maintenance_mode())
|
_maintenance = bool(get_maintenance_mode())
|
||||||
if not _maintenance:
|
if not _maintenance:
|
||||||
set_maintenance_mode(True)
|
set_maintenance_mode(True)
|
||||||
@ -68,7 +79,7 @@ class PluginsRegistry:
|
|||||||
retry_counter = settings.PLUGIN_RETRY
|
retry_counter = settings.PLUGIN_RETRY
|
||||||
while not registered_sucessfull:
|
while not registered_sucessfull:
|
||||||
try:
|
try:
|
||||||
# we are using the db so for migrations etc we need to try this block
|
# We are using the db so for migrations etc we need to try this block
|
||||||
self._init_plugins(blocked_plugin)
|
self._init_plugins(blocked_plugin)
|
||||||
self._activate_plugins()
|
self._activate_plugins()
|
||||||
registered_sucessfull = True
|
registered_sucessfull = True
|
||||||
@ -81,13 +92,14 @@ class PluginsRegistry:
|
|||||||
log_plugin_error({error.path: error.message}, 'load')
|
log_plugin_error({error.path: error.message}, 'load')
|
||||||
blocked_plugin = error.path # we will not try to load this app again
|
blocked_plugin = error.path # we will not try to load this app again
|
||||||
|
|
||||||
# init apps without any integration plugins
|
# Initialize apps without any integration plugins
|
||||||
self._clean_registry()
|
self._clean_registry()
|
||||||
self._clean_installed_apps()
|
self._clean_installed_apps()
|
||||||
self._activate_plugins(force_reload=True)
|
self._activate_plugins(force_reload=True)
|
||||||
|
|
||||||
# we do not want to end in an endless loop
|
# We do not want to end in an endless loop
|
||||||
retry_counter -= 1
|
retry_counter -= 1
|
||||||
|
|
||||||
if retry_counter <= 0:
|
if retry_counter <= 0:
|
||||||
if settings.PLUGIN_TESTING:
|
if settings.PLUGIN_TESTING:
|
||||||
print('[PLUGIN] Max retries, breaking loading')
|
print('[PLUGIN] Max retries, breaking loading')
|
||||||
@ -98,15 +110,20 @@ class PluginsRegistry:
|
|||||||
|
|
||||||
# now the loading will re-start up with init
|
# now the loading will re-start up with init
|
||||||
|
|
||||||
# remove maintenance
|
# Remove maintenance mode
|
||||||
if not _maintenance:
|
if not _maintenance:
|
||||||
set_maintenance_mode(False)
|
set_maintenance_mode(False)
|
||||||
|
|
||||||
logger.info('Finished loading plugins')
|
logger.info('Finished loading plugins')
|
||||||
|
|
||||||
def unload_plugins(self):
|
def unload_plugins(self):
|
||||||
"""unload and deactivate all IntegrationPlugins"""
|
"""
|
||||||
|
Unload and deactivate all IntegrationPlugins
|
||||||
|
"""
|
||||||
|
|
||||||
logger.info('Start unloading plugins')
|
logger.info('Start unloading plugins')
|
||||||
# set maintanace mode
|
|
||||||
|
# Set maintanace mode
|
||||||
_maintenance = bool(get_maintenance_mode())
|
_maintenance = bool(get_maintenance_mode())
|
||||||
if not _maintenance:
|
if not _maintenance:
|
||||||
set_maintenance_mode(True)
|
set_maintenance_mode(True)
|
||||||
@ -123,21 +140,27 @@ class PluginsRegistry:
|
|||||||
logger.info('Finished unloading plugins')
|
logger.info('Finished unloading plugins')
|
||||||
|
|
||||||
def reload_plugins(self):
|
def reload_plugins(self):
|
||||||
"""safely reload IntegrationPlugins"""
|
"""
|
||||||
# do not reload whe currently loading
|
Safely reload IntegrationPlugins
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Do not reload whe currently loading
|
||||||
if self.is_loading:
|
if self.is_loading:
|
||||||
return
|
return
|
||||||
|
|
||||||
logger.info('Start reloading plugins')
|
logger.info('Start reloading plugins')
|
||||||
|
|
||||||
with maintenance_mode_on():
|
with maintenance_mode_on():
|
||||||
self.unload_plugins()
|
self.unload_plugins()
|
||||||
self.load_plugins()
|
self.load_plugins()
|
||||||
logger.info('Finished reloading plugins')
|
|
||||||
# endregion
|
|
||||||
|
|
||||||
# region general plugin managment mechanisms
|
logger.info('Finished reloading plugins')
|
||||||
|
|
||||||
def collect_plugins(self):
|
def collect_plugins(self):
|
||||||
"""collect integration plugins from all possible ways of loading"""
|
"""
|
||||||
|
Collect integration plugins from all possible ways of loading
|
||||||
|
"""
|
||||||
|
|
||||||
self.plugin_modules = [] # clear
|
self.plugin_modules = [] # clear
|
||||||
|
|
||||||
# Collect plugins from paths
|
# Collect plugins from paths
|
||||||
@ -146,7 +169,7 @@ class PluginsRegistry:
|
|||||||
if modules:
|
if modules:
|
||||||
[self.plugin_modules.append(item) for item in modules]
|
[self.plugin_modules.append(item) for item in modules]
|
||||||
|
|
||||||
# check if not running in testing mode and apps should be loaded from hooks
|
# Check if not running in testing mode and apps should be loaded from hooks
|
||||||
if (not settings.PLUGIN_TESTING) or (settings.PLUGIN_TESTING and settings.PLUGIN_TESTING_SETUP):
|
if (not settings.PLUGIN_TESTING) or (settings.PLUGIN_TESTING and settings.PLUGIN_TESTING_SETUP):
|
||||||
# Collect plugins from setup entry points
|
# Collect plugins from setup entry points
|
||||||
for entry in metadata.entry_points().get('inventree_plugins', []):
|
for entry in metadata.entry_points().get('inventree_plugins', []):
|
||||||
@ -159,22 +182,25 @@ class PluginsRegistry:
|
|||||||
logger.info(", ".join([a.__module__ for a in self.plugin_modules]))
|
logger.info(", ".join([a.__module__ for a in self.plugin_modules]))
|
||||||
|
|
||||||
def _init_plugins(self, disabled=None):
|
def _init_plugins(self, disabled=None):
|
||||||
"""initialise all found plugins
|
"""
|
||||||
|
Initialise all found plugins
|
||||||
|
|
||||||
:param disabled: loading path of disabled app, defaults to None
|
:param disabled: loading path of disabled app, defaults to None
|
||||||
:type disabled: str, optional
|
:type disabled: str, optional
|
||||||
:raises error: IntegrationPluginError
|
:raises error: IntegrationPluginError
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from plugin.models import PluginConfig
|
from plugin.models import PluginConfig
|
||||||
|
|
||||||
logger.info('Starting plugin initialisation')
|
logger.info('Starting plugin initialisation')
|
||||||
|
|
||||||
# Initialize integration plugins
|
# Initialize integration plugins
|
||||||
for plugin in self.plugin_modules:
|
for plugin in self.plugin_modules:
|
||||||
# check if package
|
# Check if package
|
||||||
was_packaged = getattr(plugin, 'is_package', False)
|
was_packaged = getattr(plugin, 'is_package', False)
|
||||||
|
|
||||||
# check if activated
|
# Check if activated
|
||||||
# these checks only use attributes - never use plugin supplied functions -> that would lead to arbitrary code execution!!
|
# These checks only use attributes - never use plugin supplied functions -> that would lead to arbitrary code execution!!
|
||||||
plug_name = plugin.PLUGIN_NAME
|
plug_name = plugin.PLUGIN_NAME
|
||||||
plug_key = plugin.PLUGIN_SLUG if getattr(plugin, 'PLUGIN_SLUG', None) else plug_name
|
plug_key = plugin.PLUGIN_SLUG if getattr(plugin, 'PLUGIN_SLUG', None) else plug_name
|
||||||
plug_key = slugify(plug_key) # keys are slugs!
|
plug_key = slugify(plug_key) # keys are slugs!
|
||||||
@ -186,23 +212,23 @@ class PluginsRegistry:
|
|||||||
raise error
|
raise error
|
||||||
plugin_db_setting = None
|
plugin_db_setting = None
|
||||||
|
|
||||||
# always activate if testing
|
# Always activate if testing
|
||||||
if settings.PLUGIN_TESTING or (plugin_db_setting and plugin_db_setting.active):
|
if settings.PLUGIN_TESTING or (plugin_db_setting and plugin_db_setting.active):
|
||||||
# check if the plugin was blocked -> threw an error
|
# Check if the plugin was blocked -> threw an error
|
||||||
if disabled:
|
if disabled:
|
||||||
# option1: package, option2: file-based
|
# option1: package, option2: file-based
|
||||||
if (plugin.__name__ == disabled) or (plugin.__module__ == disabled):
|
if (plugin.__name__ == disabled) or (plugin.__module__ == disabled):
|
||||||
# errors are bad so disable the plugin in the database
|
# Errors are bad so disable the plugin in the database
|
||||||
if not settings.PLUGIN_TESTING:
|
if not settings.PLUGIN_TESTING:
|
||||||
plugin_db_setting.active = False
|
plugin_db_setting.active = False
|
||||||
# TODO save the error to the plugin
|
# TODO save the error to the plugin
|
||||||
plugin_db_setting.save(no_reload=True)
|
plugin_db_setting.save(no_reload=True)
|
||||||
|
|
||||||
# add to inactive plugins so it shows up in the ui
|
# Add to inactive plugins so it shows up in the ui
|
||||||
self.plugins_inactive[plug_key] = plugin_db_setting
|
self.plugins_inactive[plug_key] = plugin_db_setting
|
||||||
continue # continue -> the plugin is not loaded
|
continue # continue -> the plugin is not loaded
|
||||||
|
|
||||||
# init package
|
# Initialize package
|
||||||
# now we can be sure that an admin has activated the plugin
|
# now we can be sure that an admin has activated the plugin
|
||||||
# TODO check more stuff -> as of Nov 2021 there are not many checks in place
|
# TODO check more stuff -> as of Nov 2021 there are not many checks in place
|
||||||
# but we could enhance those to check signatures, run the plugin against a whitelist etc.
|
# but we could enhance those to check signatures, run the plugin against a whitelist etc.
|
||||||
@ -235,7 +261,7 @@ class PluginsRegistry:
|
|||||||
plugins = self.plugins.items()
|
plugins = self.plugins.items()
|
||||||
logger.info(f'Found {len(plugins)} active plugins')
|
logger.info(f'Found {len(plugins)} active plugins')
|
||||||
|
|
||||||
self.activate_integration_globalsettings(plugins)
|
self.activate_integration_settings(plugins)
|
||||||
self.activate_integration_app(plugins, force_reload=force_reload)
|
self.activate_integration_app(plugins, force_reload=force_reload)
|
||||||
|
|
||||||
def _deactivate_plugins(self):
|
def _deactivate_plugins(self):
|
||||||
@ -243,10 +269,9 @@ class PluginsRegistry:
|
|||||||
Run integration deactivation functions for all plugins
|
Run integration deactivation functions for all plugins
|
||||||
"""
|
"""
|
||||||
self.deactivate_integration_app()
|
self.deactivate_integration_app()
|
||||||
self.deactivate_integration_globalsettings()
|
self.deactivate_integration_settings()
|
||||||
# endregion
|
|
||||||
|
|
||||||
def activate_integration_globalsettings(self, plugins):
|
def activate_integration_settings(self, plugins):
|
||||||
from common.models import InvenTreeSetting
|
from common.models import InvenTreeSetting
|
||||||
|
|
||||||
if settings.PLUGIN_TESTING or InvenTreeSetting.get_setting('ENABLE_PLUGINS_GLOBALSETTING'):
|
if settings.PLUGIN_TESTING or InvenTreeSetting.get_setting('ENABLE_PLUGINS_GLOBALSETTING'):
|
||||||
@ -256,7 +281,7 @@ class PluginsRegistry:
|
|||||||
plugin_setting = plugin.settings
|
plugin_setting = plugin.settings
|
||||||
self.mixins_settings[slug] = plugin_setting
|
self.mixins_settings[slug] = plugin_setting
|
||||||
|
|
||||||
def deactivate_integration_globalsettings(self):
|
def deactivate_integration_settings(self):
|
||||||
|
|
||||||
# collect all settings
|
# collect all settings
|
||||||
plugin_settings = {}
|
plugin_settings = {}
|
||||||
@ -267,7 +292,6 @@ class PluginsRegistry:
|
|||||||
# clear cache
|
# clear cache
|
||||||
self.mixins_Fsettings = {}
|
self.mixins_Fsettings = {}
|
||||||
|
|
||||||
# region integration_app
|
|
||||||
def activate_integration_app(self, plugins, force_reload=False):
|
def activate_integration_app(self, plugins, force_reload=False):
|
||||||
"""activate AppMixin plugins - add custom apps and reload
|
"""activate AppMixin plugins - add custom apps and reload
|
||||||
|
|
||||||
@ -441,8 +465,6 @@ class PluginsRegistry:
|
|||||||
return True, []
|
return True, []
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
get_plugin_error(error, do_raise=True)
|
get_plugin_error(error, do_raise=True)
|
||||||
# endregion
|
|
||||||
# endregion
|
|
||||||
|
|
||||||
|
|
||||||
plugin_registry = PluginsRegistry()
|
plugin_registry = PluginsRegistry()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
"""
|
"""
|
||||||
JSON serializers for Stock app
|
JSON serializers for plugin app
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
@ -20,7 +20,8 @@ from plugin.models import PluginConfig, PluginSetting
|
|||||||
|
|
||||||
|
|
||||||
class PluginConfigSerializer(serializers.ModelSerializer):
|
class PluginConfigSerializer(serializers.ModelSerializer):
|
||||||
""" Serializer for a PluginConfig:
|
"""
|
||||||
|
Serializer for a PluginConfig:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
meta = serializers.DictField(read_only=True)
|
meta = serializers.DictField(read_only=True)
|
||||||
@ -73,7 +74,7 @@ class PluginConfigInstallSerializer(serializers.Serializer):
|
|||||||
if not data.get('confirm'):
|
if not data.get('confirm'):
|
||||||
raise ValidationError({'confirm': _('Installation not confirmed')})
|
raise ValidationError({'confirm': _('Installation not confirmed')})
|
||||||
if (not data.get('url')) and (not data.get('packagename')):
|
if (not data.get('url')) and (not data.get('packagename')):
|
||||||
msg = _('Either packagenmae of url must be provided')
|
msg = _('Either packagename of URL must be provided')
|
||||||
raise ValidationError({'url': msg, 'packagename': msg})
|
raise ValidationError({'url': msg, 'packagename': msg})
|
||||||
|
|
||||||
return data
|
return data
|
||||||
@ -115,7 +116,7 @@ class PluginConfigInstallSerializer(serializers.Serializer):
|
|||||||
ret['result'] = str(error.output, 'utf-8')
|
ret['result'] = str(error.output, 'utf-8')
|
||||||
ret['error'] = True
|
ret['error'] = True
|
||||||
|
|
||||||
# register plugins
|
# Register plugins
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
@ -8,7 +8,7 @@ from InvenTree.api_tester import InvenTreeAPITestCase
|
|||||||
|
|
||||||
class PluginDetailAPITest(InvenTreeAPITestCase):
|
class PluginDetailAPITest(InvenTreeAPITestCase):
|
||||||
"""
|
"""
|
||||||
Tests the plugin AP I endpoints
|
Tests the plugin API endpoints
|
||||||
"""
|
"""
|
||||||
|
|
||||||
roles = [
|
roles = [
|
||||||
@ -19,7 +19,7 @@ class PluginDetailAPITest(InvenTreeAPITestCase):
|
|||||||
]
|
]
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.MSG_NO_PKG = 'Either packagenmae of url must be provided'
|
self.MSG_NO_PKG = 'Either packagename of URL must be provided'
|
||||||
|
|
||||||
self.PKG_NAME = 'minimal'
|
self.PKG_NAME = 'minimal'
|
||||||
super().setUp()
|
super().setUp()
|
||||||
|
@ -42,7 +42,7 @@ class SettingsMixinTest(BaseMixinDefinition, TestCase):
|
|||||||
|
|
||||||
def test_function(self):
|
def test_function(self):
|
||||||
# settings variable
|
# settings variable
|
||||||
self.assertEqual(self.mixin.globalsettings, self.TEST_SETTINGS)
|
self.assertEqual(self.mixin.settings, self.TEST_SETTINGS)
|
||||||
|
|
||||||
# calling settings
|
# calling settings
|
||||||
# not existing
|
# not existing
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
""" Unit tests for plugins """
|
"""
|
||||||
|
Unit tests for plugins
|
||||||
|
"""
|
||||||
|
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
@ -6,7 +8,6 @@ import plugin.plugin
|
|||||||
import plugin.integration
|
import plugin.integration
|
||||||
from plugin.samples.integration.sample import SampleIntegrationPlugin
|
from plugin.samples.integration.sample import SampleIntegrationPlugin
|
||||||
from plugin.samples.integration.another_sample import WrongIntegrationPlugin, NoIntegrationPlugin
|
from plugin.samples.integration.another_sample import WrongIntegrationPlugin, NoIntegrationPlugin
|
||||||
# from plugin.plugins import load_action_plugins, load_barcode_plugins
|
|
||||||
import plugin.templatetags.plugin_extras as plugin_tags
|
import plugin.templatetags.plugin_extras as plugin_tags
|
||||||
from plugin import plugin_registry
|
from plugin import plugin_registry
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
"""
|
"""
|
||||||
URL lookup for plugin app
|
URL lookup for plugin app
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.conf.urls import url, include
|
from django.conf.urls import url, include
|
||||||
|
|
||||||
from plugin import plugin_registry
|
from plugin import plugin_registry
|
||||||
@ -10,9 +11,14 @@ PLUGIN_BASE = 'plugin' # Constant for links
|
|||||||
|
|
||||||
|
|
||||||
def get_plugin_urls():
|
def get_plugin_urls():
|
||||||
"""returns a urlpattern that can be integrated into the global urls"""
|
"""
|
||||||
|
Returns a urlpattern that can be integrated into the global urls
|
||||||
|
"""
|
||||||
|
|
||||||
urls = []
|
urls = []
|
||||||
|
|
||||||
for plugin in plugin_registry.plugins.values():
|
for plugin in plugin_registry.plugins.values():
|
||||||
if plugin.mixin_enabled('urls'):
|
if plugin.mixin_enabled('urls'):
|
||||||
urls.append(plugin.urlpatterns)
|
urls.append(plugin.urlpatterns)
|
||||||
|
|
||||||
return url(f'^{PLUGIN_BASE}/', include((urls, 'plugin')))
|
return url(f'^{PLUGIN_BASE}/', include((urls, 'plugin')))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user