mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-18 13:05:42 +00:00
move tests to their functions
This commit is contained in:
61
InvenTree/plugin/base/action/test_action.py
Normal file
61
InvenTree/plugin/base/action/test_action.py
Normal file
@ -0,0 +1,61 @@
|
||||
""" Unit tests for action plugins """
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
from plugin.base.action.action import ActionPlugin
|
||||
|
||||
|
||||
class ActionPluginTests(TestCase):
|
||||
""" Tests for ActionPlugin """
|
||||
ACTION_RETURN = 'a action was performed'
|
||||
|
||||
def setUp(self):
|
||||
self.plugin = ActionPlugin('user')
|
||||
|
||||
class TestActionPlugin(ActionPlugin):
|
||||
"""a action plugin"""
|
||||
ACTION_NAME = 'abc123'
|
||||
|
||||
def perform_action(self):
|
||||
return ActionPluginTests.ACTION_RETURN + 'action'
|
||||
|
||||
def get_result(self):
|
||||
return ActionPluginTests.ACTION_RETURN + 'result'
|
||||
|
||||
def get_info(self):
|
||||
return ActionPluginTests.ACTION_RETURN + 'info'
|
||||
|
||||
self.action_plugin = TestActionPlugin('user')
|
||||
|
||||
class NameActionPlugin(ActionPlugin):
|
||||
PLUGIN_NAME = 'Aplugin'
|
||||
|
||||
self.action_name = NameActionPlugin('user')
|
||||
|
||||
def test_action_name(self):
|
||||
"""check the name definition possibilities"""
|
||||
self.assertEqual(self.plugin.action_name(), '')
|
||||
self.assertEqual(self.action_plugin.action_name(), 'abc123')
|
||||
self.assertEqual(self.action_name.action_name(), 'Aplugin')
|
||||
|
||||
def test_function(self):
|
||||
"""check functions"""
|
||||
# the class itself
|
||||
self.assertIsNone(self.plugin.perform_action())
|
||||
self.assertEqual(self.plugin.get_result(), False)
|
||||
self.assertIsNone(self.plugin.get_info())
|
||||
self.assertEqual(self.plugin.get_response(), {
|
||||
"action": '',
|
||||
"result": False,
|
||||
"info": None,
|
||||
})
|
||||
|
||||
# overriden functions
|
||||
self.assertEqual(self.action_plugin.perform_action(), self.ACTION_RETURN + 'action')
|
||||
self.assertEqual(self.action_plugin.get_result(), self.ACTION_RETURN + 'result')
|
||||
self.assertEqual(self.action_plugin.get_info(), self.ACTION_RETURN + 'info')
|
||||
self.assertEqual(self.action_plugin.get_response(), {
|
||||
"action": 'abc123',
|
||||
"result": self.ACTION_RETURN + 'result',
|
||||
"info": self.ACTION_RETURN + 'info',
|
||||
})
|
266
InvenTree/plugin/base/barcodes/test_barcode.py
Normal file
266
InvenTree/plugin/base/barcodes/test_barcode.py
Normal file
@ -0,0 +1,266 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Unit tests for Barcode endpoints
|
||||
"""
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.urls import reverse
|
||||
|
||||
from rest_framework.test import APITestCase
|
||||
from rest_framework import status
|
||||
|
||||
from stock.models import StockItem
|
||||
|
||||
|
||||
class BarcodeAPITest(APITestCase):
|
||||
|
||||
fixtures = [
|
||||
'category',
|
||||
'part',
|
||||
'location',
|
||||
'stock'
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
# Create a user for auth
|
||||
user = get_user_model()
|
||||
user.objects.create_user('testuser', 'test@testing.com', 'password')
|
||||
|
||||
self.client.login(username='testuser', password='password')
|
||||
|
||||
self.scan_url = reverse('api-barcode-scan')
|
||||
self.assign_url = reverse('api-barcode-link')
|
||||
|
||||
def postBarcode(self, url, barcode):
|
||||
|
||||
return self.client.post(url, format='json', data={'barcode': str(barcode)})
|
||||
|
||||
def test_invalid(self):
|
||||
|
||||
# test scan url
|
||||
response = self.client.post(self.scan_url, format='json', data={})
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# test wrong assign urls
|
||||
response = self.client.post(self.assign_url, format='json', data={})
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
response = self.client.post(self.assign_url, format='json', data={'barcode': '123'})
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
response = self.client.post(self.assign_url, format='json', data={'barcode': '123', 'stockitem': '123'})
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
def test_empty(self):
|
||||
|
||||
response = self.postBarcode(self.scan_url, '')
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
|
||||
data = response.data
|
||||
self.assertIn('error', data)
|
||||
|
||||
self.assertIn('barcode_data', data)
|
||||
self.assertIn('hash', data)
|
||||
self.assertIn('plugin', data)
|
||||
self.assertIsNone(data['plugin'])
|
||||
|
||||
def test_find_part(self):
|
||||
"""
|
||||
Test that we can lookup a part based on ID
|
||||
"""
|
||||
|
||||
response = self.client.post(
|
||||
self.scan_url,
|
||||
{
|
||||
'barcode': {
|
||||
'part': 1,
|
||||
},
|
||||
},
|
||||
format='json',
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertIn('part', response.data)
|
||||
self.assertIn('barcode_data', response.data)
|
||||
self.assertEqual(response.data['part']['pk'], 1)
|
||||
|
||||
def test_invalid_part(self):
|
||||
"""Test response for invalid part"""
|
||||
response = self.client.post(
|
||||
self.scan_url,
|
||||
{
|
||||
'barcode': {
|
||||
'part': 999999999,
|
||||
}
|
||||
},
|
||||
format='json'
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
self.assertEqual(response.data['part'], 'Part does not exist')
|
||||
|
||||
def test_find_stock_item(self):
|
||||
"""
|
||||
Test that we can lookup a stock item based on ID
|
||||
"""
|
||||
|
||||
response = self.client.post(
|
||||
self.scan_url,
|
||||
{
|
||||
'barcode': {
|
||||
'stockitem': 1,
|
||||
}
|
||||
},
|
||||
format='json',
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertIn('stockitem', response.data)
|
||||
self.assertIn('barcode_data', response.data)
|
||||
self.assertEqual(response.data['stockitem']['pk'], 1)
|
||||
|
||||
def test_invalid_item(self):
|
||||
"""Test response for invalid stock item"""
|
||||
|
||||
response = self.client.post(
|
||||
self.scan_url,
|
||||
{
|
||||
'barcode': {
|
||||
'stockitem': 999999999,
|
||||
}
|
||||
},
|
||||
format='json'
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
self.assertEqual(response.data['stockitem'], 'Stock item does not exist')
|
||||
|
||||
def test_find_location(self):
|
||||
"""
|
||||
Test that we can lookup a stock location based on ID
|
||||
"""
|
||||
|
||||
response = self.client.post(
|
||||
self.scan_url,
|
||||
{
|
||||
'barcode': {
|
||||
'stocklocation': 1,
|
||||
},
|
||||
},
|
||||
format='json'
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertIn('stocklocation', response.data)
|
||||
self.assertIn('barcode_data', response.data)
|
||||
self.assertEqual(response.data['stocklocation']['pk'], 1)
|
||||
|
||||
def test_invalid_location(self):
|
||||
"""Test response for an invalid location"""
|
||||
|
||||
response = self.client.post(
|
||||
self.scan_url,
|
||||
{
|
||||
'barcode': {
|
||||
'stocklocation': 999999999,
|
||||
}
|
||||
},
|
||||
format='json'
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
self.assertEqual(response.data['stocklocation'], 'Stock location does not exist')
|
||||
|
||||
def test_integer_barcode(self):
|
||||
|
||||
response = self.postBarcode(self.scan_url, '123456789')
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
|
||||
data = response.data
|
||||
self.assertIn('error', data)
|
||||
|
||||
self.assertIn('barcode_data', data)
|
||||
self.assertIn('hash', data)
|
||||
self.assertIn('plugin', data)
|
||||
self.assertIsNone(data['plugin'])
|
||||
|
||||
def test_array_barcode(self):
|
||||
|
||||
response = self.postBarcode(self.scan_url, "['foo', 'bar']")
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
|
||||
data = response.data
|
||||
self.assertIn('error', data)
|
||||
|
||||
self.assertIn('barcode_data', data)
|
||||
self.assertIn('hash', data)
|
||||
self.assertIn('plugin', data)
|
||||
self.assertIsNone(data['plugin'])
|
||||
|
||||
def test_barcode_generation(self):
|
||||
|
||||
item = StockItem.objects.get(pk=522)
|
||||
|
||||
response = self.postBarcode(self.scan_url, item.format_barcode())
|
||||
data = response.data
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
|
||||
self.assertIn('stockitem', data)
|
||||
|
||||
pk = data['stockitem']['pk']
|
||||
|
||||
self.assertEqual(pk, item.pk)
|
||||
|
||||
def test_association(self):
|
||||
"""
|
||||
Test that a barcode can be associated with a StockItem
|
||||
"""
|
||||
|
||||
item = StockItem.objects.get(pk=522)
|
||||
|
||||
self.assertEqual(len(item.uid), 0)
|
||||
|
||||
barcode_data = 'A-TEST-BARCODE-STRING'
|
||||
|
||||
response = self.client.post(
|
||||
self.assign_url, format='json',
|
||||
data={
|
||||
'barcode': barcode_data,
|
||||
'stockitem': item.pk
|
||||
}
|
||||
)
|
||||
|
||||
data = response.data
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
|
||||
self.assertIn('success', data)
|
||||
|
||||
result_hash = data['hash']
|
||||
|
||||
# Read the item out from the database again
|
||||
item = StockItem.objects.get(pk=522)
|
||||
|
||||
self.assertEqual(result_hash, item.uid)
|
||||
|
||||
# Ensure that the same UID cannot be assigned to a different stock item!
|
||||
response = self.client.post(
|
||||
self.assign_url, format='json',
|
||||
data={
|
||||
'barcode': barcode_data,
|
||||
'stockitem': 521
|
||||
}
|
||||
)
|
||||
|
||||
data = response.data
|
||||
|
||||
self.assertIn('error', data)
|
||||
self.assertNotIn('success', data)
|
214
InvenTree/plugin/base/integration/test_mixins.py
Normal file
214
InvenTree/plugin/base/integration/test_mixins.py
Normal file
@ -0,0 +1,214 @@
|
||||
""" Unit tests for base mixins for plugins """
|
||||
|
||||
from django.test import TestCase
|
||||
from django.conf import settings
|
||||
from django.urls import include, re_path
|
||||
from django.contrib.auth import get_user_model
|
||||
|
||||
from plugin import IntegrationPluginBase
|
||||
from plugin.mixins import AppMixin, SettingsMixin, UrlsMixin, NavigationMixin, APICallMixin
|
||||
from plugin.urls import PLUGIN_BASE
|
||||
|
||||
|
||||
class BaseMixinDefinition:
|
||||
def test_mixin_name(self):
|
||||
# mixin name
|
||||
self.assertIn(self.MIXIN_NAME, [item['key'] for item in self.mixin.registered_mixins])
|
||||
# human name
|
||||
self.assertIn(self.MIXIN_HUMAN_NAME, [item['human_name'] for item in self.mixin.registered_mixins])
|
||||
|
||||
|
||||
class SettingsMixinTest(BaseMixinDefinition, TestCase):
|
||||
MIXIN_HUMAN_NAME = 'Settings'
|
||||
MIXIN_NAME = 'settings'
|
||||
MIXIN_ENABLE_CHECK = 'has_settings'
|
||||
|
||||
TEST_SETTINGS = {'SETTING1': {'default': '123', }}
|
||||
|
||||
def setUp(self):
|
||||
class SettingsCls(SettingsMixin, IntegrationPluginBase):
|
||||
SETTINGS = self.TEST_SETTINGS
|
||||
self.mixin = SettingsCls()
|
||||
|
||||
class NoSettingsCls(SettingsMixin, IntegrationPluginBase):
|
||||
pass
|
||||
self.mixin_nothing = NoSettingsCls()
|
||||
|
||||
user = get_user_model()
|
||||
self.test_user = user.objects.create_user('testuser', 'test@testing.com', 'password')
|
||||
self.test_user.is_staff = True
|
||||
|
||||
def test_function(self):
|
||||
# settings variable
|
||||
self.assertEqual(self.mixin.settings, self.TEST_SETTINGS)
|
||||
|
||||
# calling settings
|
||||
# not existing
|
||||
self.assertEqual(self.mixin.get_setting('ABCD'), '')
|
||||
self.assertEqual(self.mixin_nothing.get_setting('ABCD'), '')
|
||||
|
||||
# right setting
|
||||
self.mixin.set_setting('SETTING1', '12345', self.test_user)
|
||||
self.assertEqual(self.mixin.get_setting('SETTING1'), '12345')
|
||||
|
||||
# no setting
|
||||
self.assertEqual(self.mixin_nothing.get_setting(''), '')
|
||||
|
||||
|
||||
class UrlsMixinTest(BaseMixinDefinition, TestCase):
|
||||
MIXIN_HUMAN_NAME = 'URLs'
|
||||
MIXIN_NAME = 'urls'
|
||||
MIXIN_ENABLE_CHECK = 'has_urls'
|
||||
|
||||
def setUp(self):
|
||||
class UrlsCls(UrlsMixin, IntegrationPluginBase):
|
||||
def test():
|
||||
return 'ccc'
|
||||
URLS = [re_path('testpath', test, name='test'), ]
|
||||
self.mixin = UrlsCls()
|
||||
|
||||
class NoUrlsCls(UrlsMixin, IntegrationPluginBase):
|
||||
pass
|
||||
self.mixin_nothing = NoUrlsCls()
|
||||
|
||||
def test_function(self):
|
||||
plg_name = self.mixin.plugin_name()
|
||||
|
||||
# base_url
|
||||
target_url = f'{PLUGIN_BASE}/{plg_name}/'
|
||||
self.assertEqual(self.mixin.base_url, target_url)
|
||||
|
||||
# urlpattern
|
||||
target_pattern = re_path(f'^{plg_name}/', include((self.mixin.urls, plg_name)), name=plg_name)
|
||||
self.assertEqual(self.mixin.urlpatterns.reverse_dict, target_pattern.reverse_dict)
|
||||
|
||||
# resolve the view
|
||||
self.assertEqual(self.mixin.urlpatterns.resolve('/testpath').func(), 'ccc')
|
||||
self.assertEqual(self.mixin.urlpatterns.reverse('test'), 'testpath')
|
||||
|
||||
# no url
|
||||
self.assertIsNone(self.mixin_nothing.urls)
|
||||
self.assertIsNone(self.mixin_nothing.urlpatterns)
|
||||
|
||||
# internal name
|
||||
self.assertEqual(self.mixin.internal_name, f'plugin:{self.mixin.slug}:')
|
||||
|
||||
|
||||
class AppMixinTest(BaseMixinDefinition, TestCase):
|
||||
MIXIN_HUMAN_NAME = 'App registration'
|
||||
MIXIN_NAME = 'app'
|
||||
MIXIN_ENABLE_CHECK = 'has_app'
|
||||
|
||||
def setUp(self):
|
||||
class TestCls(AppMixin, IntegrationPluginBase):
|
||||
pass
|
||||
self.mixin = TestCls()
|
||||
|
||||
def test_function(self):
|
||||
# test that this plugin is in settings
|
||||
self.assertIn('plugin.samples.integration', settings.INSTALLED_APPS)
|
||||
|
||||
|
||||
class NavigationMixinTest(BaseMixinDefinition, TestCase):
|
||||
MIXIN_HUMAN_NAME = 'Navigation Links'
|
||||
MIXIN_NAME = 'navigation'
|
||||
MIXIN_ENABLE_CHECK = 'has_naviation'
|
||||
|
||||
def setUp(self):
|
||||
class NavigationCls(NavigationMixin, IntegrationPluginBase):
|
||||
NAVIGATION = [
|
||||
{'name': 'aa', 'link': 'plugin:test:test_view'},
|
||||
]
|
||||
NAVIGATION_TAB_NAME = 'abcd1'
|
||||
self.mixin = NavigationCls()
|
||||
|
||||
class NothingNavigationCls(NavigationMixin, IntegrationPluginBase):
|
||||
pass
|
||||
self.nothing_mixin = NothingNavigationCls()
|
||||
|
||||
def test_function(self):
|
||||
# check right configuration
|
||||
self.assertEqual(self.mixin.navigation, [{'name': 'aa', 'link': 'plugin:test:test_view'}, ])
|
||||
# check wrong links fails
|
||||
with self.assertRaises(NotImplementedError):
|
||||
class NavigationCls(NavigationMixin, IntegrationPluginBase):
|
||||
NAVIGATION = ['aa', 'aa']
|
||||
NavigationCls()
|
||||
|
||||
# navigation name
|
||||
self.assertEqual(self.mixin.navigation_name, 'abcd1')
|
||||
self.assertEqual(self.nothing_mixin.navigation_name, '')
|
||||
|
||||
|
||||
class APICallMixinTest(BaseMixinDefinition, TestCase):
|
||||
MIXIN_HUMAN_NAME = 'API calls'
|
||||
MIXIN_NAME = 'api_call'
|
||||
MIXIN_ENABLE_CHECK = 'has_api_call'
|
||||
|
||||
def setUp(self):
|
||||
class MixinCls(APICallMixin, SettingsMixin, IntegrationPluginBase):
|
||||
PLUGIN_NAME = "Sample API Caller"
|
||||
|
||||
SETTINGS = {
|
||||
'API_TOKEN': {
|
||||
'name': 'API Token',
|
||||
'protected': True,
|
||||
},
|
||||
'API_URL': {
|
||||
'name': 'External URL',
|
||||
'description': 'Where is your API located?',
|
||||
'default': 'reqres.in',
|
||||
},
|
||||
}
|
||||
API_URL_SETTING = 'API_URL'
|
||||
API_TOKEN_SETTING = 'API_TOKEN'
|
||||
|
||||
def get_external_url(self):
|
||||
'''
|
||||
returns data from the sample endpoint
|
||||
'''
|
||||
return self.api_call('api/users/2')
|
||||
self.mixin = MixinCls()
|
||||
|
||||
class WrongCLS(APICallMixin, IntegrationPluginBase):
|
||||
pass
|
||||
self.mixin_wrong = WrongCLS()
|
||||
|
||||
class WrongCLS2(APICallMixin, IntegrationPluginBase):
|
||||
API_URL_SETTING = 'test'
|
||||
self.mixin_wrong2 = WrongCLS2()
|
||||
|
||||
def test_function(self):
|
||||
# check init
|
||||
self.assertTrue(self.mixin.has_api_call)
|
||||
# api_url
|
||||
self.assertEqual('https://reqres.in', self.mixin.api_url)
|
||||
|
||||
# api_headers
|
||||
headers = self.mixin.api_headers
|
||||
self.assertEqual(headers, {'Bearer': '', 'Content-Type': 'application/json'})
|
||||
|
||||
# api_build_url_args
|
||||
# 1 arg
|
||||
result = self.mixin.api_build_url_args({'a': 'b'})
|
||||
self.assertEqual(result, '?a=b')
|
||||
# more args
|
||||
result = self.mixin.api_build_url_args({'a': 'b', 'c': 'd'})
|
||||
self.assertEqual(result, '?a=b&c=d')
|
||||
# list args
|
||||
result = self.mixin.api_build_url_args({'a': 'b', 'c': ['d', 'e', 'f', ]})
|
||||
self.assertEqual(result, '?a=b&c=d,e,f')
|
||||
|
||||
# api_call
|
||||
result = self.mixin.get_external_url()
|
||||
self.assertTrue(result)
|
||||
self.assertIn('data', result,)
|
||||
|
||||
# wrongly defined plugins should not load
|
||||
with self.assertRaises(ValueError):
|
||||
self.mixin_wrong.has_api_call()
|
||||
|
||||
# cover wrong token setting
|
||||
with self.assertRaises(ValueError):
|
||||
self.mixin_wrong.has_api_call()
|
||||
|
Reference in New Issue
Block a user