Merge branch 'master' of https://github.com/inventree/InvenTree into style-fixes

This commit is contained in:
Matthias Mair 2022-05-21 23:57:41 +02:00
commit 5805685c48
28 changed files with 296 additions and 483 deletions

View File

@ -13,10 +13,7 @@ from django.http.response import StreamingHttpResponse
from rest_framework.test import APITestCase
class InvenTreeAPITestCase(APITestCase):
"""
Base class for running InvenTree API tests
"""
class UserMixin:
# User information
username = 'testuser'
@ -53,37 +50,49 @@ class InvenTreeAPITestCase(APITestCase):
self.user.save()
for role in self.roles:
self.assignRole(role)
# Assign all roles if set
if self.roles == 'all':
self.assignRole(assign_all=True)
# else filter the roles
else:
for role in self.roles:
self.assignRole(role)
if self.auto_login:
self.client.login(username=self.username, password=self.password)
def assignRole(self, role):
def assignRole(self, role=None, assign_all: bool = False):
"""
Set the user roles for the registered user
"""
# role is of the format 'rule.permission' e.g. 'part.add'
rule, perm = role.split('.')
if not assign_all and role:
rule, perm = role.split('.')
for ruleset in self.group.rule_sets.all():
if ruleset.name == rule:
if assign_all or ruleset.name == rule:
if perm == 'view':
if assign_all or perm == 'view':
ruleset.can_view = True
elif perm == 'change':
elif assign_all or perm == 'change':
ruleset.can_change = True
elif perm == 'delete':
elif assign_all or perm == 'delete':
ruleset.can_delete = True
elif perm == 'add':
elif assign_all or perm == 'add':
ruleset.can_add = True
ruleset.save()
break
class InvenTreeAPITestCase(UserMixin, APITestCase):
"""
Base class for running InvenTree API tests
"""
def getActions(self, url):
"""
Return a dict of the 'actions' available at a given endpoint.

View File

@ -4,13 +4,12 @@ only used for testing the js files! - This file is omited from coverage
"""
import os # pragma: no cover
import pathlib # pragma: no cover
import pathlib
from django.contrib.auth import get_user_model # pragma: no cover
from django.test import TestCase # pragma: no cover
from InvenTree.helpers import InvenTreeTestCase # pragma: no cover
class RenderJavascriptFiles(TestCase): # pragma: no cover
class RenderJavascriptFiles(InvenTreeTestCase): # pragma: no cover
"""
A unit test to "render" javascript files.
@ -18,18 +17,6 @@ class RenderJavascriptFiles(TestCase): # pragma: no cover
we need the fully-rendered files for linting and static tests.
"""
def setUp(self):
user = get_user_model()
self.user = user.objects.create_user(
username='testuser',
password='testpassword',
email='user@gmail.com',
)
self.client.login(username='testuser', password='testpassword')
def download_file(self, filename, prefix):
url = os.path.join(prefix, filename)

View File

@ -12,6 +12,7 @@ from wsgiref.util import FileWrapper
from django.contrib.auth.models import Permission
from django.core.exceptions import FieldError, ValidationError
from django.http import StreamingHttpResponse
from django.test import TestCase
from django.utils.translation import gettext_lazy as _
from djmoney.money import Money
@ -21,6 +22,7 @@ import InvenTree.version
from common.models import InvenTreeSetting
from common.settings import currency_code_default
from .api_tester import UserMixin
from .settings import MEDIA_URL, STATIC_URL
@ -779,3 +781,7 @@ def inheritors(cls):
subcls.add(child)
work.append(child)
return subcls
class InvenTreeTestCase(UserMixin, TestCase):
pass

View File

@ -2,18 +2,16 @@
from base64 import b64encode
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.test import TestCase
from django.urls import reverse
from rest_framework import status
from InvenTree.api_tester import InvenTreeAPITestCase
from InvenTree.helpers import InvenTreeTestCase
from users.models import RuleSet
class HTMLAPITests(TestCase):
class HTMLAPITests(InvenTreeTestCase):
"""
Test that we can access the REST API endpoints via the HTML interface.
@ -21,33 +19,7 @@ class HTMLAPITests(TestCase):
which raised an AssertionError when using the HTML API interface,
while the regular JSON interface continued to work as expected.
"""
def setUp(self):
super().setUp()
# Create a user
user = get_user_model()
self.user = user.objects.create_user(
username='username',
email='user@email.com',
password='password'
)
# Put the user into a group with the correct permissions
group = Group.objects.create(name='mygroup')
self.user.groups.add(group)
# Give the group *all* the permissions!
for rule in group.rule_sets.all():
rule.can_view = True
rule.can_change = True
rule.can_add = True
rule.can_delete = True
rule.save()
self.client.login(username='username', password='password')
roles = 'all'
def test_part_api(self):
url = reverse('api-part-list')

View File

@ -1,11 +1,11 @@
"""Tests for middleware functions"""
from django.contrib.auth import get_user_model
from django.test import TestCase
from django.urls import reverse
from InvenTree.helpers import InvenTreeTestCase
class MiddlewareTests(TestCase):
class MiddlewareTests(InvenTreeTestCase):
"""Test for middleware functions"""
def check_path(self, url, code=200, **kwargs):
@ -13,15 +13,6 @@ class MiddlewareTests(TestCase):
self.assertEqual(response.status_code, code)
return response
def setUp(self):
super().setUp()
# Create a user
user = get_user_model()
self.user = user.objects.create_user(username='username', email='user@email.com', password='password')
self.client.login(username='username', password='password')
def test_AuthRequiredMiddleware(self):
"""Test the auth middleware"""

View File

@ -5,28 +5,17 @@ Unit tests for the main web views
import os
import re
from django.contrib.auth import get_user_model
from django.test import TestCase
from django.urls import reverse
from InvenTree.helpers import InvenTreeTestCase
class ViewTests(TestCase):
class ViewTests(InvenTreeTestCase):
""" Tests for various top-level views """
username = 'test_user'
password = 'test_pass'
def setUp(self):
# Create a user
self.user = get_user_model().objects.create_user(self.username, 'user@email.com', self.password)
self.user.set_password(self.password)
self.user.save()
result = self.client.login(username=self.username, password=self.password)
self.assertEqual(result, True)
def test_api_doc(self):
""" Test that the api-doc view works """

View File

@ -450,18 +450,12 @@ class TestStatus(TestCase):
self.assertEqual(ready.isImportingData(), False)
class TestSettings(TestCase):
class TestSettings(helpers.InvenTreeTestCase):
"""
Unit tests for settings
"""
def setUp(self) -> None:
self.user_mdl = get_user_model()
# Create a user for auth
user = get_user_model()
self.user = user.objects.create_superuser('testuser1', 'test1@testing.com', 'password1')
self.client.login(username='testuser1', password='password1')
superuser = True
def in_env_context(self, envs={}):
"""Patch the env to include the given dict"""
@ -476,8 +470,9 @@ class TestSettings(TestCase):
@override_settings(TESTING_ENV=True)
def test_set_user_to_few(self):
user_model = get_user_model()
# add shortcut
user_count = self.user_mdl.objects.count
user_count = user_model.objects.count
# enable testing mode
settings.TESTING_ENV = True
@ -499,14 +494,18 @@ class TestSettings(TestCase):
})
self.assertEqual(user_count(), 2)
username2 = 'testuser1'
email2 = 'test1@testing.com'
password2 = 'password1'
# create user manually
self.user_mdl.objects.create_user('testuser', 'test@testing.com', 'password')
user_model.objects.create_user(username2, email2, password2)
self.assertEqual(user_count(), 3)
# check it will not be created again
self.run_reload({
'INVENTREE_ADMIN_USER': 'testuser',
'INVENTREE_ADMIN_EMAIL': 'test@testing.com',
'INVENTREE_ADMIN_PASSWORD': 'password',
'INVENTREE_ADMIN_USER': username2,
'INVENTREE_ADMIN_EMAIL': email2,
'INVENTREE_ADMIN_PASSWORD': password2,
})
self.assertEqual(user_count(), 3)
@ -541,7 +540,7 @@ class TestSettings(TestCase):
# with env set
with self.in_env_context({'INVENTREE_CONFIG_FILE': 'my_special_conf.yaml'}):
self.assertIn('inventree/inventree/my_special_conf.yaml', config.get_config_file().lower())
self.assertIn('inventree/my_special_conf.yaml', config.get_config_file().lower())
def test_helpers_plugin_file(self):
# normal run - not configured
@ -567,18 +566,11 @@ class TestSettings(TestCase):
self.assertEqual(config.get_setting(TEST_ENV_NAME, None), '321')
class TestInstanceName(TestCase):
class TestInstanceName(helpers.InvenTreeTestCase):
"""
Unit tests for instance name
"""
def setUp(self):
# Create a user for auth
user = get_user_model()
self.user = user.objects.create_superuser('testuser', 'test@testing.com', 'password')
self.client.login(username='testuser', password='password')
def test_instance_name(self):
# default setting

View File

@ -2,10 +2,6 @@ from datetime import datetime, timedelta
from django.urls import reverse
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from rest_framework.test import APITestCase
from rest_framework import status
from part.models import Part
@ -16,7 +12,7 @@ from InvenTree.status_codes import BuildStatus
from InvenTree.api_tester import InvenTreeAPITestCase
class TestBuildAPI(APITestCase):
class TestBuildAPI(InvenTreeAPITestCase):
"""
Series of tests for the Build DRF API
- Tests for Build API
@ -30,25 +26,11 @@ class TestBuildAPI(APITestCase):
'build',
]
def setUp(self):
# Create a user for auth
user = get_user_model()
self.user = user.objects.create_user('testuser', 'test@testing.com', 'password')
g = Group.objects.create(name='builders')
self.user.groups.add(g)
for rule in g.rule_sets.all():
if rule.name == 'build':
rule.can_change = True
rule.can_add = True
rule.can_delete = True
rule.save()
g.save()
self.client.login(username='testuser', password='password')
roles = [
'build.change',
'build.add',
'build.delete',
]
def test_get_build_list(self):
"""

View File

@ -1,18 +1,16 @@
from django.test import TestCase
from django.urls import reverse
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from datetime import datetime, timedelta
from InvenTree.helpers import InvenTreeTestCase
from .models import Build
from stock.models import StockItem
from InvenTree.status_codes import BuildStatus
class BuildTestSimple(TestCase):
class BuildTestSimple(InvenTreeTestCase):
fixtures = [
'category',
@ -21,27 +19,11 @@ class BuildTestSimple(TestCase):
'build',
]
def setUp(self):
# Create a user for auth
user = get_user_model()
user.objects.create_user('testuser', 'test@testing.com', 'password')
self.user = user.objects.get(username='testuser')
g = Group.objects.create(name='builders')
self.user.groups.add(g)
for rule in g.rule_sets.all():
if rule.name == 'build':
rule.can_change = True
rule.can_add = True
rule.can_delete = True
rule.save()
g.save()
self.client.login(username='testuser', password='password')
roles = [
'build.change',
'build.add',
'build.delete',
]
def test_build_objects(self):
# Ensure the Build objects were correctly created
@ -106,7 +88,7 @@ class BuildTestSimple(TestCase):
self.assertEqual(build.status, BuildStatus.CANCELLED)
class TestBuildViews(TestCase):
class TestBuildViews(InvenTreeTestCase):
""" Tests for Build app views """
fixtures = [
@ -116,28 +98,15 @@ class TestBuildViews(TestCase):
'build',
]
roles = [
'build.change',
'build.add',
'build.delete',
]
def setUp(self):
super().setUp()
# Create a user
user = get_user_model()
self.user = user.objects.create_user('username', 'user@email.com', 'password')
g = Group.objects.create(name='builders')
self.user.groups.add(g)
for rule in g.rule_sets.all():
if rule.name == 'build':
rule.can_change = True
rule.can_add = True
rule.can_delete = True
rule.save()
g.save()
self.client.login(username='username', password='password')
# Create a build output for build # 1
self.build = Build.objects.get(pk=1)

View File

@ -3,12 +3,11 @@ import json
from datetime import timedelta
from http import HTTPStatus
from django.contrib.auth import get_user_model
from django.test import Client, TestCase
from django.urls import reverse
from InvenTree.api_tester import InvenTreeAPITestCase
from InvenTree.helpers import str2bool
from InvenTree.helpers import InvenTreeTestCase, str2bool
from plugin import registry
from plugin.models import NotificationUserSetting, PluginConfig
@ -19,7 +18,7 @@ from .models import (ColorTheme, InvenTreeSetting, InvenTreeUserSetting,
CONTENT_TYPE_JSON = 'application/json'
class SettingsTest(TestCase):
class SettingsTest(InvenTreeTestCase):
"""
Tests for the 'settings' model
"""
@ -28,16 +27,6 @@ class SettingsTest(TestCase):
'settings',
]
def setUp(self):
user = get_user_model()
self.user = user.objects.create_user('username', 'user@email.com', 'password')
self.user.is_staff = True
self.user.save()
self.client.login(username='username', password='password')
def test_settings_objects(self):
# There should be two settings objects in the database

View File

@ -1,12 +1,11 @@
""" Unit tests for Company views (see views.py) """
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.test import TestCase
from django.urls import reverse
from InvenTree.helpers import InvenTreeTestCase
class CompanyViewTestBase(TestCase):
class CompanyViewTestBase(InvenTreeTestCase):
fixtures = [
'category',
@ -17,32 +16,7 @@ class CompanyViewTestBase(TestCase):
'supplier_part',
]
def setUp(self):
super().setUp()
# Create a user
user = get_user_model()
self.user = user.objects.create_user(
username='username',
email='user@email.com',
password='password'
)
# Put the user into a group with the correct permissions
group = Group.objects.create(name='mygroup')
self.user.groups.add(group)
# Give the group *all* the permissions!
for rule in group.rule_sets.all():
rule.can_view = True
rule.can_change = True
rule.can_add = True
rule.can_delete = True
rule.save()
self.client.login(username='username', password='password')
roles = 'all'
class CompanyViewTest(CompanyViewTestBase):

View File

@ -57,6 +57,7 @@ src="{% static 'img/blank_image.png' %}"
<ul class='dropdown-menu' role='menu'>
<li><a class='dropdown-item' href='#' id='edit-order'><span class='fas fa-edit icon-green'></span> {% trans "Edit order" %}</a></li>
{% if order.status == SalesOrderStatus.PENDING %}
<li><a class='dropdown-item' href='#' id='complete-order-shipments'><span class='fas fa-truck'></span> {% trans "Complete Shipments" %}</a></li>
<li><a class='dropdown-item' href='#' id='cancel-order'><span class='fas fa-times-circle icon-red'></span> {% trans "Cancel order" %}</a></li>
{% endif %}
</ul>
@ -223,6 +224,16 @@ $("#edit-order").click(function() {
});
});
$("#complete-order-shipments").click(function() {
completePendingShipments(
{{ order.pk }},
{
reload: true,
}
);
});
$("#cancel-order").click(function() {
cancelSalesOrder(

View File

@ -1,12 +1,11 @@
""" Unit tests for Order views (see views.py) """
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.test import TestCase
from django.urls import reverse
from InvenTree.helpers import InvenTreeTestCase
class OrderViewTestCase(TestCase):
class OrderViewTestCase(InvenTreeTestCase):
fixtures = [
'category',
@ -19,27 +18,14 @@ class OrderViewTestCase(TestCase):
'order',
]
def setUp(self):
super().setUp()
# Create a user
user = get_user_model().objects.create_user('username', 'user@email.com', 'password')
# Ensure that the user has the correct permissions!
g = Group.objects.create(name='orders')
user.groups.add(g)
for rule in g.rule_sets.all():
if rule.name in ['purchase_order', 'sales_order']:
rule.can_change = True
rule.can_add = True
rule.can_delete = True
rule.save()
g.save()
self.client.login(username='username', password='password')
roles = [
'purchase_order.change',
'purchase_order.add',
'purchase_order.delete',
'sales_order.change',
'sales_order.add',
'sales_order.delete',
]
class OrderListTest(OrderViewTestCase):

View File

@ -4,13 +4,12 @@ Unit testing for BOM export functionality
import csv
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.test import TestCase
from django.urls import reverse
from InvenTree.helpers import InvenTreeTestCase
class BomExportTest(TestCase):
class BomExportTest(InvenTreeTestCase):
fixtures = [
'category',
@ -19,33 +18,11 @@ class BomExportTest(TestCase):
'bom',
]
roles = 'all'
def setUp(self):
super().setUp()
# Create a user
user = get_user_model()
self.user = user.objects.create_user(
username='username',
email='user@email.com',
password='password'
)
# Put the user into a group with the correct permissions
group = Group.objects.create(name='mygroup')
self.user.groups.add(group)
# Give the group *all* the permissions!
for rule in group.rule_sets.all():
rule.can_view = True
rule.can_change = True
rule.can_add = True
rule.can_delete = True
rule.save()
self.client.login(username='username', password='password')
self.url = reverse('bom-download', kwargs={'pk': 100})
def test_bom_template(self):

View File

@ -3,7 +3,6 @@
import os
from django.conf import settings
from django.contrib.auth import get_user_model
from django.core.exceptions import ValidationError
from django.test import TestCase
@ -14,21 +13,16 @@ from common.models import (InvenTreeSetting, InvenTreeUserSetting,
NotificationEntry, NotificationMessage)
from common.notifications import UIMessageNotification, storage
from InvenTree import version
from InvenTree.helpers import InvenTreeTestCase
from .models import (Part, PartCategory, PartCategoryStar, PartStar,
PartTestTemplate, rename_part_image)
from .templatetags import inventree_extras
class TemplateTagTest(TestCase):
class TemplateTagTest(InvenTreeTestCase):
""" Tests for the custom template tag code """
def setUp(self):
# Create a user for auth
user = get_user_model()
self.user = user.objects.create_user('testuser', 'test@testing.com', 'password')
self.client.login(username='testuser', password='password')
def test_define(self):
self.assertEqual(int(inventree_extras.define(3)), 3)
@ -329,24 +323,13 @@ class TestTemplateTest(TestCase):
self.assertEqual(variant.getTestTemplates().count(), n + 1)
class PartSettingsTest(TestCase):
class PartSettingsTest(InvenTreeTestCase):
"""
Tests to ensure that the user-configurable default values work as expected.
Some fields for the Part model can have default values specified by the user.
"""
def setUp(self):
# Create a user for auth
user = get_user_model()
self.user = user.objects.create_user(
username='testuser',
email='test@testing.com',
password='password',
is_staff=True
)
def make_part(self):
"""
Helper function to create a simple part
@ -460,7 +443,7 @@ class PartSettingsTest(TestCase):
Part.objects.create(name='abc', revision='6', description='A part', IPN=' ')
class PartSubscriptionTests(TestCase):
class PartSubscriptionTests(InvenTreeTestCase):
fixtures = [
'location',
@ -469,15 +452,7 @@ class PartSubscriptionTests(TestCase):
]
def setUp(self):
# Create a user for auth
user = get_user_model()
self.user = user.objects.create_user(
username='testuser',
email='test@testing.com',
password='password',
is_staff=True
)
super().setUp()
# electronics / IC / MCU
self.category = PartCategory.objects.get(pk=4)
@ -577,7 +552,7 @@ class PartSubscriptionTests(TestCase):
self.assertTrue(self.part.is_starred_by(self.user))
class BaseNotificationIntegrationTest(TestCase):
class BaseNotificationIntegrationTest(InvenTreeTestCase):
""" Integration test for notifications """
fixtures = [
@ -588,15 +563,7 @@ class BaseNotificationIntegrationTest(TestCase):
]
def setUp(self):
# Create a user for auth
user = get_user_model()
self.user = user.objects.create_user(
username='testuser',
email='test@testing.com',
password='password',
is_staff=True
)
super().setUp()
# Add Mailadress
EmailAddress.objects.create(user=self.user, email='test@testing.com')

View File

@ -1,14 +1,13 @@
""" Unit tests for Part Views (see views.py) """
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.test import TestCase
from django.urls import reverse
from InvenTree.helpers import InvenTreeTestCase
from .models import Part
class PartViewTestCase(TestCase):
class PartViewTestCase(InvenTreeTestCase):
fixtures = [
'category',
@ -19,33 +18,12 @@ class PartViewTestCase(TestCase):
'supplier_part',
]
roles = 'all'
superuser = True
def setUp(self):
super().setUp()
# Create a user
user = get_user_model()
self.user = user.objects.create_user(
username='username',
email='user@email.com',
password='password'
)
# Put the user into a group with the correct permissions
group = Group.objects.create(name='mygroup')
self.user.groups.add(group)
# Give the group *all* the permissions!
for rule in group.rule_sets.all():
rule.can_view = True
rule.can_change = True
rule.can_add = True
rule.can_delete = True
rule.save()
self.client.login(username='username', password='password')
class PartListTest(PartViewTestCase):

View File

@ -1,8 +1,8 @@
""" Unit tests for action plugins """
from django.contrib.auth import get_user_model
from django.test import TestCase
from InvenTree.helpers import InvenTreeTestCase
from plugin import InvenTreePlugin
from plugin.mixins import ActionMixin
@ -65,15 +65,9 @@ class ActionMixinTests(TestCase):
})
class APITests(TestCase):
class APITests(InvenTreeTestCase):
""" Tests for action api """
def setUp(self):
# Create a user for auth
user = get_user_model()
self.test_user = user.objects.create_user('testuser', 'test@testing.com', 'password')
self.client.login(username='testuser', password='password')
def test_post_errors(self):
"""Check the possible errors with post"""

View File

@ -4,16 +4,15 @@
Unit tests for Barcode endpoints
"""
from django.contrib.auth import get_user_model
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APITestCase
from InvenTree.api_tester import InvenTreeAPITestCase
from stock.models import StockItem
class BarcodeAPITest(APITestCase):
class BarcodeAPITest(InvenTreeAPITestCase):
fixtures = [
'category',
@ -23,11 +22,7 @@ class BarcodeAPITest(APITestCase):
]
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')
super().setUp()
self.scan_url = reverse('api-barcode-scan')
self.assign_url = reverse('api-barcode-link')

View File

@ -1,13 +1,12 @@
""" Unit tests for base mixins for plugins """
from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.test import TestCase
from django.urls import include, re_path, reverse
from error_report.models import Error
from InvenTree.helpers import InvenTreeTestCase
from plugin import InvenTreePlugin
from plugin.helpers import MixinNotImplementedError
from plugin.mixins import (APICallMixin, AppMixin, NavigationMixin,
@ -24,7 +23,7 @@ class BaseMixinDefinition:
self.assertIn(self.MIXIN_HUMAN_NAME, [item['human_name'] for item in self.mixin.registered_mixins])
class SettingsMixinTest(BaseMixinDefinition, TestCase):
class SettingsMixinTest(BaseMixinDefinition, InvenTreeTestCase):
MIXIN_HUMAN_NAME = 'Settings'
MIXIN_NAME = 'settings'
MIXIN_ENABLE_CHECK = 'has_settings'
@ -40,9 +39,7 @@ class SettingsMixinTest(BaseMixinDefinition, TestCase):
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
super().setUp()
def test_function(self):
# settings variable
@ -54,7 +51,7 @@ class SettingsMixinTest(BaseMixinDefinition, TestCase):
self.assertEqual(self.mixin_nothing.get_setting('ABCD'), '')
# right setting
self.mixin.set_setting('SETTING1', '12345', self.test_user)
self.mixin.set_setting('SETTING1', '12345', self.user)
self.assertEqual(self.mixin.get_setting('SETTING1'), '12345')
# no setting
@ -251,7 +248,7 @@ class APICallMixinTest(BaseMixinDefinition, TestCase):
self.mixin_wrong2.has_api_call()
class PanelMixinTests(TestCase):
class PanelMixinTests(InvenTreeTestCase):
"""Test that the PanelMixin plugin operates correctly"""
fixtures = [
@ -261,32 +258,7 @@ class PanelMixinTests(TestCase):
'stock',
]
def setUp(self):
super().setUp()
# Create a user which has all the privelages
user = get_user_model()
self.user = user.objects.create_user(
username='username',
email='user@email.com',
password='password'
)
# Put the user into a group with the correct permissions
group = Group.objects.create(name='mygroup')
self.user.groups.add(group)
# Give the group *all* the permissions!
for rule in group.rule_sets.all():
rule.can_view = True
rule.can_change = True
rule.can_add = True
rule.can_delete = True
rule.save()
self.client.login(username='username', password='password')
roles = 'all'
def test_installed(self):
"""Test that the sample panel plugin is installed"""

View File

@ -1,20 +1,15 @@
""" Unit tests for action plugins """
from django.contrib.auth import get_user_model
from django.test import TestCase
from InvenTree.helpers import InvenTreeTestCase
from plugin.builtin.action.simpleactionplugin import SimpleActionPlugin
class SimpleActionPluginTests(TestCase):
class SimpleActionPluginTests(InvenTreeTestCase):
""" Tests for SampleIntegrationPlugin """
def setUp(self):
# Create a user for auth
user = get_user_model()
self.test_user = user.objects.create_user('testuser', 'test@testing.com', 'password')
super().setUp()
self.client.login(username='testuser', password='password')
self.plugin = SimpleActionPlugin()
def test_name(self):
@ -33,7 +28,7 @@ class SimpleActionPluginTests(TestCase):
"action": 'simple',
"result": True,
"info": {
"user": "testuser",
"user": self.username,
"hello": "world",
},
}

View File

@ -1,14 +1,14 @@
# -*- coding: utf-8 -*-
"""Unit tests for InvenTreeBarcodePlugin"""
from django.contrib.auth import get_user_model
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APITestCase
from InvenTree.api_tester import InvenTreeAPITestCase
class TestInvenTreeBarcode(APITestCase):
class TestInvenTreeBarcode(InvenTreeAPITestCase):
fixtures = [
'category',
@ -17,13 +17,6 @@ class TestInvenTreeBarcode(APITestCase):
'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')
def test_errors(self):
"""
Test all possible error cases for assigment action

View File

@ -1,19 +1,11 @@
""" Unit tests for action plugins """
from django.contrib.auth import get_user_model
from django.test import TestCase
from InvenTree.helpers import InvenTreeTestCase
class SampleIntegrationPluginTests(TestCase):
class SampleIntegrationPluginTests(InvenTreeTestCase):
""" Tests for SampleIntegrationPlugin """
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')
def test_view(self):
"""check the function of the custom sample plugin """
response = self.client.get('/plugin/sample/ho/he/')

View File

@ -1,14 +1,13 @@
""" Unit tests for Stock views (see views.py) """
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.test import TestCase
from django.urls import reverse
from InvenTree.helpers import InvenTreeTestCase
# from common.models import InvenTreeSetting
class StockViewTestCase(TestCase):
class StockViewTestCase(InvenTreeTestCase):
fixtures = [
'category',
@ -19,35 +18,7 @@ class StockViewTestCase(TestCase):
'stock',
]
def setUp(self):
super().setUp()
# Create a user
user = get_user_model()
self.user = user.objects.create_user(
username='username',
email='user@email.com',
password='password'
)
self.user.is_staff = True
self.user.save()
# Put the user into a group with the correct permissions
group = Group.objects.create(name='mygroup')
self.user.groups.add(group)
# Give the group *all* the permissions!
for rule in group.rule_sets.all():
rule.can_view = True
rule.can_change = True
rule.can_add = True
rule.can_delete = True
rule.save()
self.client.login(username='username', password='password')
roles = 'all'
class StockListTest(StockViewTestCase):

View File

@ -1,11 +1,10 @@
import datetime
from django.contrib.auth import get_user_model
from django.core.exceptions import ValidationError
from django.db.models import Sum
from django.test import TestCase
from build.models import Build
from InvenTree.helpers import InvenTreeTestCase
from InvenTree.status_codes import StockHistoryCode
from part.models import Part
@ -13,7 +12,7 @@ from .models import (StockItem, StockItemTestResult, StockItemTracking,
StockLocation)
class StockTest(TestCase):
class StockTest(InvenTreeTestCase):
"""
Tests to ensure that the stock location tree functions correcly
"""
@ -28,6 +27,8 @@ class StockTest(TestCase):
]
def setUp(self):
super().setUp()
# Extract some shortcuts from the fixtures
self.home = StockLocation.objects.get(name='Home')
self.bathroom = StockLocation.objects.get(name='Bathroom')
@ -38,14 +39,6 @@ class StockTest(TestCase):
self.drawer2 = StockLocation.objects.get(name='Drawer_2')
self.drawer3 = StockLocation.objects.get(name='Drawer_3')
# Create a user
user = get_user_model()
user.objects.create_user('username', 'user@email.com', 'password')
self.client.login(username='username', password='password')
self.user = user.objects.get(username='username')
# Ensure the MPTT objects are correctly rebuild
Part.objects.rebuild()
StockItem.objects.rebuild()

View File

@ -561,6 +561,11 @@ function constructFormBody(fields, options) {
insertPersistButton(options);
}
// Insert secondary buttons (if required)
if (options.buttons) {
insertSecondaryButtons(options);
}
// Display the modal
$(modal).modal('show');
@ -650,6 +655,31 @@ function insertPersistButton(options) {
$(options.modal).find('#modal-footer-buttons').append(html);
}
/*
* Add secondary buttons to the left of the close and submit buttons
* with callback functions
*/
function insertSecondaryButtons(options) {
for (var idx = 0; idx < options.buttons.length; idx++) {
var html = `
<button type="button" class="btn btn-outline-secondary" id="modal-form-${options.buttons[idx].name}">
${options.buttons[idx].title}
</button>
`;
$(options.modal).find('#modal-footer-secondary-buttons').append(html);
if (options.buttons[idx].onClick instanceof Function) {
// Copy callback reference to prevent errors if `idx` changes value before execution
var onclick_callback = options.buttons[idx].onClick;
$(options.modal).find(`#modal-form-${options.buttons[idx].name}`).click(function() {
onclick_callback(options);
});
}
}
}
/*
* Extract all specified form values as a single object

View File

@ -75,6 +75,9 @@ function createNewModal(options={}) {
</div>
<span class='flex-item' style='flex-grow: 1;'></span>
<h4><span id='modal-progress-spinner' class='fas fa-circle-notch fa-spin' style='display: none;'></span></h4>
<div id='modal-footer-secondary-buttons'>
<!-- Extra secondary buttons can be inserted here -->
</div>
<button type='button' class='btn btn-secondary' id='modal-form-close' data-bs-dismiss='modal'>{% trans "Cancel" %}</button>
<button type='button' class='btn btn-${submitClass}' id='modal-form-submit'>{% trans "Submit" %}</button>
</div>
@ -99,7 +102,7 @@ function createNewModal(options={}) {
$(modal_name).focus();
if (options.hideCloseButton) {
$(modal_name).find('#modal-form-cancel').hide();
$(modal_name).find('#modal-form-close').hide();
}
if (options.preventSubmit || options.hideSubmitButton) {

View File

@ -24,6 +24,7 @@
cancelSalesOrder,
completePurchaseOrder,
completeShipment,
completePendingShipments,
createSalesOrder,
createSalesOrderShipment,
editPurchaseOrderLineItem,
@ -69,7 +70,7 @@ function salesOrderShipmentFields(options={}) {
/*
* Complete a shipment
*/
function completeShipment(shipment_id) {
function completeShipment(shipment_id, options={}) {
// Request the list of stock items which will be shipped
inventreeGet(`/api/order/so/shipment/${shipment_id}/`, {}, {
@ -126,28 +127,128 @@ function completeShipment(shipment_id) {
constructForm(`/api/order/so/shipment/${shipment_id}/ship/`, {
method: 'POST',
title: '{% trans "Complete Shipment" %}',
title: `{% trans "Complete Shipment" %} ${shipment.reference}`,
fields: {
tracking_number: {},
},
preFormContent: html,
confirm: true,
confirmMessage: '{% trans "Confirm Shipment" %}',
buttons: options.buttons,
onSuccess: function(data) {
// Reload tables
$('#so-lines-table').bootstrapTable('refresh');
$('#pending-shipments-table').bootstrapTable('refresh');
$('#completed-shipments-table').bootstrapTable('refresh');
if (options.onSuccess instanceof Function) {
options.onSuccess(data);
}
},
reload: true
reload: options.reload
});
}
});
}
/*
* Launches a modal to mark all allocated pending shipments as complete
*/
function completePendingShipments(order_id, options={}) {
var pending_shipments = null;
// Request the list of stock items which will be shipped
inventreeGet(`/api/order/so/shipment/.*`,
{
order: order_id,
shipped: false
},
{
async: false,
success: function(shipments) {
pending_shipments = shipments;
}
}
);
var allocated_shipments = [];
for (var idx = 0; idx < pending_shipments.length; idx++) {
if (pending_shipments[idx].allocations.length > 0) {
allocated_shipments.push(pending_shipments[idx]);
}
}
if (allocated_shipments.length > 0) {
completePendingShipmentsHelper(allocated_shipments, 0, options);
} else {
html = `
<div class='alert alert-block alert-danger'>
`;
if (!pending_shipments.length) {
html += `
{% trans "No pending shipments found" %}
`;
} else {
html += `
{% trans "No stock items have been allocated to pending shipments" %}
`;
}
html += `
</div>
`;
constructForm(`/api/order/so/shipment/0/ship/`, {
method: 'POST',
title: '{% trans "Complete Shipments" %}',
preFormContent: html,
onSubmit: function(fields, options) {
handleFormSuccess(fields, options);
},
closeText: 'Close',
hideSubmitButton: true,
});
}
}
/*
* Recursive helper for opening shipment completion modals
*/
function completePendingShipmentsHelper(shipments, shipment_idx, options={}) {
if (shipment_idx < shipments.length) {
completeShipment(shipments[shipment_idx].pk,
{
buttons: [
{
name: 'skip',
title: `{% trans "Skip" %}`,
onClick: function(form_options) {
if (form_options.modal) {
$(form_options.modal).modal('hide');
}
completePendingShipmentsHelper(shipments, shipment_idx + 1, options);
}
}
],
onSuccess: function(data) {
completePendingShipmentsHelper(shipments, shipment_idx + 1, options);
},
}
);
} else if (options.reload) {
location.reload();
}
}
/*
* Launches a modal form to mark a PurchaseOrder as "complete"
*/
*/
function completePurchaseOrder(order_id, options={}) {
constructForm(

View File

@ -1,11 +1,11 @@
from django.apps import apps
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.test import TestCase
from django.urls import reverse
from rest_framework.authtoken.models import Token
from InvenTree.helpers import InvenTreeTestCase
from users.models import Owner, RuleSet
@ -160,20 +160,11 @@ class RuleSetModelTest(TestCase):
self.assertEqual(group.permissions.count(), 0)
class OwnerModelTest(TestCase):
class OwnerModelTest(InvenTreeTestCase):
"""
Some simplistic tests to ensure the Owner model is setup correctly.
"""
def setUp(self):
""" Add users and groups """
# Create a new user
self.user = get_user_model().objects.create_user('username', 'user@email.com', 'password')
# Put the user into a new group
self.group = Group.objects.create(name='new_group')
self.user.groups.add(self.group)
def do_request(self, endpoint, filters, status_code=200):
response = self.client.get(endpoint, filters, format='json')
self.assertEqual(response.status_code, status_code)
@ -212,11 +203,13 @@ class OwnerModelTest(TestCase):
"""
Test user APIs
"""
self.client.logout()
# not authed
self.do_request(reverse('api-owner-list'), {}, 401)
self.do_request(reverse('api-owner-detail', kwargs={'pk': self.user.id}), {}, 401)
self.client.login(username='username', password='password')
self.client.login(username=self.username, password=self.password)
# user list
self.do_request(reverse('api-owner-list'), {})
# user list with search
@ -229,12 +222,14 @@ class OwnerModelTest(TestCase):
"""
Test token mechanisms
"""
self.client.logout()
token = Token.objects.filter(user=self.user)
# not authed
self.do_request(reverse('api-token'), {}, 401)
self.client.login(username='username', password='password')
self.client.login(username=self.username, password=self.password)
# token get
response = self.do_request(reverse('api-token'), {})
self.assertEqual(response['token'], token.first().key)