Seperate CUI url paths and tests (#6543)

* move CUI JS files to CUI url section

* add flag to seperate CUI code and tests

* re-enable tests

* move urls back to backend patterns

* swap switch logic

* fix merge

* returning PUI paths if CUI not enabled

* revert test changes

* fix plugin settings url

* URL is not dependant on UI generation

* small fixes

Co-authored-by: Oliver <oliver.henry.walters@gmail.com>

---------

Co-authored-by: Oliver <oliver.henry.walters@gmail.com>
This commit is contained in:
Matthias Mair 2024-02-22 22:56:50 +00:00 committed by GitHub
parent f5e02fd292
commit 6f0b2b31a8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 156 additions and 34 deletions

View File

@ -913,3 +913,10 @@ def inheritors(cls: type[Inheritors_T]) -> set[type[Inheritors_T]]:
def is_ajax(request): def is_ajax(request):
"""Check if the current request is an AJAX request.""" """Check if the current request is an AJAX request."""
return request.headers.get('x-requested-with') == 'XMLHttpRequest' return request.headers.get('x-requested-with') == 'XMLHttpRequest'
def pui_url(subpath: str) -> str:
"""Return the URL for a PUI subpath."""
if not subpath.startswith('/'):
subpath = '/' + subpath
return f'/{settings.FRONTEND_URL_BASE}{subpath}'

View File

@ -80,6 +80,9 @@ DEBUG = get_boolean_setting('INVENTREE_DEBUG', 'debug', True)
ENABLE_CLASSIC_FRONTEND = get_boolean_setting( ENABLE_CLASSIC_FRONTEND = get_boolean_setting(
'INVENTREE_CLASSIC_FRONTEND', 'classic_frontend', True 'INVENTREE_CLASSIC_FRONTEND', 'classic_frontend', True
) )
# Disable CUI parts if CUI tests are disabled
if TESTING and '--exclude-tag=cui' in sys.argv:
ENABLE_CLASSIC_FRONTEND = False
ENABLE_PLATFORM_FRONTEND = get_boolean_setting( ENABLE_PLATFORM_FRONTEND = get_boolean_setting(
'INVENTREE_PLATFORM_FRONTEND', 'platform_frontend', True 'INVENTREE_PLATFORM_FRONTEND', 'platform_frontend', True
) )

View File

@ -2,6 +2,7 @@
from django.conf import settings from django.conf import settings
from django.http import Http404 from django.http import Http404
from django.test import tag
from django.urls import reverse from django.urls import reverse
from error_report.models import Error from error_report.models import Error
@ -10,6 +11,8 @@ from InvenTree.exceptions import log_error
from InvenTree.unit_test import InvenTreeTestCase from InvenTree.unit_test import InvenTreeTestCase
# TODO change test to not rely on CUI
@tag('cui')
class MiddlewareTests(InvenTreeTestCase): class MiddlewareTests(InvenTreeTestCase):
"""Test for middleware functions.""" """Test for middleware functions."""

View File

@ -4,10 +4,11 @@ import os
import re import re
from pathlib import Path from pathlib import Path
from django.test import TestCase from django.test import TestCase, tag
from django.urls import reverse from django.urls import reverse
@tag('cui')
class URLTest(TestCase): class URLTest(TestCase):
"""Test all files for broken url tags.""" """Test all files for broken url tags."""

View File

@ -3,6 +3,7 @@
import os import os
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.test import tag
from django.urls import reverse from django.urls import reverse
from InvenTree.unit_test import InvenTreeTestCase from InvenTree.unit_test import InvenTreeTestCase
@ -35,6 +36,7 @@ class ViewTests(InvenTreeTestCase):
return str(response.content.decode()) return str(response.content.decode())
@tag('cui')
def test_panels(self): def test_panels(self):
"""Test that the required 'panels' are present.""" """Test that the required 'panels' are present."""
content = self.get_index_page() content = self.get_index_page()
@ -43,6 +45,7 @@ class ViewTests(InvenTreeTestCase):
# TODO: In future, run the javascript and ensure that the panels get created! # TODO: In future, run the javascript and ensure that the panels get created!
@tag('cui')
def test_settings_page(self): def test_settings_page(self):
"""Test that the 'settings' page loads correctly.""" """Test that the 'settings' page loads correctly."""
# Settings page loads # Settings page loads
@ -101,6 +104,8 @@ class ViewTests(InvenTreeTestCase):
self.assertNotIn(f'select-{panel}', content) self.assertNotIn(f'select-{panel}', content)
self.assertNotIn(f'panel-{panel}', content) self.assertNotIn(f'panel-{panel}', content)
# TODO: Replace this with a PUI test
@tag('cui')
def test_url_login(self): def test_url_login(self):
"""Test logging in via arguments.""" """Test logging in via arguments."""
# Log out # Log out

View File

@ -12,7 +12,7 @@ from django.conf import settings
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.core import mail from django.core import mail
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.test import TestCase, override_settings from django.test import TestCase, override_settings, tag
from django.urls import reverse from django.urls import reverse
import pint.errors import pint.errors
@ -1319,6 +1319,8 @@ class MagicLoginTest(InvenTreeTestCase):
self.assertEqual(resp.wsgi_request.user, self.user) self.assertEqual(resp.wsgi_request.user, self.user)
# TODO - refactor to not use CUI
@tag('cui')
class MaintenanceModeTest(InvenTreeTestCase): class MaintenanceModeTest(InvenTreeTestCase):
"""Unit tests for maintenance mode.""" """Unit tests for maintenance mode."""

View File

@ -362,15 +362,19 @@ translated_javascript_urls = [
] ]
backendpatterns = [ backendpatterns = [
# "Dynamic" javascript files which are rendered using InvenTree templating.
path('js/dynamic/', include(dynamic_javascript_urls)),
path('js/i18n/', include(translated_javascript_urls)),
path('auth/', include('rest_framework.urls', namespace='rest_framework')), path('auth/', include('rest_framework.urls', namespace='rest_framework')),
path('auth/', auth_request), path('auth/', auth_request),
path('api/', include(apipatterns)), path('api/', include(apipatterns)),
path('api-doc/', SpectacularRedocView.as_view(url_name='schema'), name='api-doc'), path('api-doc/', SpectacularRedocView.as_view(url_name='schema'), name='api-doc'),
] ]
if settings.ENABLE_CLASSIC_FRONTEND:
# "Dynamic" javascript files which are rendered using InvenTree templating.
backendpatterns += [
re_path(r'^js/dynamic/', include(dynamic_javascript_urls)),
re_path(r'^js/i18n/', include(translated_javascript_urls)),
]
classic_frontendpatterns = [ classic_frontendpatterns = [
# Apps # Apps
path('build/', include(build_urls)), path('build/', include(build_urls)),
@ -436,6 +440,15 @@ if settings.ENABLE_CLASSIC_FRONTEND:
frontendpatterns += classic_frontendpatterns frontendpatterns += classic_frontendpatterns
if settings.ENABLE_PLATFORM_FRONTEND: if settings.ENABLE_PLATFORM_FRONTEND:
frontendpatterns += platform_urls frontendpatterns += platform_urls
if not settings.ENABLE_CLASSIC_FRONTEND:
# Add a redirect for login views
frontendpatterns += [
path(
'accounts/login/',
RedirectView.as_view(url=settings.FRONTEND_URL_BASE, permanent=False),
name='account_login',
)
]
urlpatterns += frontendpatterns urlpatterns += frontendpatterns
@ -461,5 +474,14 @@ urlpatterns.append(
# Send any unknown URLs to the parts page # Send any unknown URLs to the parts page
urlpatterns += [ urlpatterns += [
re_path(r'^.*$', RedirectView.as_view(url='/index/', permanent=False), name='index') re_path(
r'^.*$',
RedirectView.as_view(
url='/index/'
if settings.ENABLE_CLASSIC_FRONTEND
else settings.FRONTEND_URL_BASE,
permanent=False,
),
name='index',
)
] ]

View File

@ -4,6 +4,7 @@ import decimal
import logging import logging
import os import os
from datetime import datetime from datetime import datetime
from django.conf import settings
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
@ -161,7 +162,9 @@ class Build(InvenTree.models.InvenTreeBarcodeMixin, InvenTree.models.InvenTreeNo
def get_absolute_url(self): def get_absolute_url(self):
"""Return the web URL associated with this BuildOrder""" """Return the web URL associated with this BuildOrder"""
return reverse('build-detail', kwargs={'pk': self.id}) if settings.ENABLE_CLASSIC_FRONTEND:
return reverse('build-detail', kwargs={'pk': self.id})
return InvenTree.helpers.pui_url(f'/build/{self.id}')
reference = models.CharField( reference = models.CharField(
unique=True, unique=True,

View File

@ -1,5 +1,7 @@
"""Basic unit tests for the BuildOrder app""" """Basic unit tests for the BuildOrder app"""
from django.conf import settings
from django.test import tag
from django.urls import reverse from django.urls import reverse
from datetime import datetime, timedelta from datetime import datetime, timedelta
@ -40,7 +42,8 @@ class BuildTestSimple(InvenTreeTestCase):
def test_url(self): def test_url(self):
"""Test URL lookup""" """Test URL lookup"""
b1 = Build.objects.get(pk=1) b1 = Build.objects.get(pk=1)
self.assertEqual(b1.get_absolute_url(), '/build/1/') if settings.ENABLE_CLASSIC_FRONTEND:
self.assertEqual(b1.get_absolute_url(), '/build/1/')
def test_is_complete(self): def test_is_complete(self):
"""Test build completion status""" """Test build completion status"""
@ -116,11 +119,13 @@ class TestBuildViews(InvenTreeTestCase):
is_building=True, is_building=True,
) )
@tag('cui')
def test_build_index(self): def test_build_index(self):
"""Test build index view.""" """Test build index view."""
response = self.client.get(reverse('build-index')) response = self.client.get(reverse('build-index'))
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
@tag('cui')
def test_build_detail(self): def test_build_detail(self):
"""Test the detail view for a Build object.""" """Test the detail view for a Build object."""
pk = 1 pk = 1

View File

@ -5,6 +5,7 @@ from datetime import datetime
from decimal import Decimal from decimal import Decimal
from django.apps import apps from django.apps import apps
from django.conf import settings
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.validators import MinValueValidator from django.core.validators import MinValueValidator
from django.db import models from django.db import models
@ -216,7 +217,9 @@ class Company(
def get_absolute_url(self): def get_absolute_url(self):
"""Get the web URL for the detail view for this Company.""" """Get the web URL for the detail view for this Company."""
return reverse('company-detail', kwargs={'pk': self.id}) if settings.ENABLE_CLASSIC_FRONTEND:
return reverse('company-detail', kwargs={'pk': self.id})
return InvenTree.helpers.pui_url(f'/company/{self.id}')
def get_image_url(self): def get_image_url(self):
"""Return the URL of the image for this company.""" """Return the URL of the image for this company."""
@ -683,7 +686,9 @@ class SupplierPart(
def get_absolute_url(self): def get_absolute_url(self):
"""Return the web URL of the detail view for this SupplierPart.""" """Return the web URL of the detail view for this SupplierPart."""
return reverse('supplier-part-detail', kwargs={'pk': self.id}) if settings.ENABLE_CLASSIC_FRONTEND:
return reverse('supplier-part-detail', kwargs={'pk': self.id})
return InvenTree.helpers.pui_url(f'/purchasing/supplier-part/{self.id}')
def api_instance_filters(self): def api_instance_filters(self):
"""Return custom API filters for this particular instance.""" """Return custom API filters for this particular instance."""

View File

@ -1,10 +1,12 @@
"""Unit tests for Company views (see views.py).""" """Unit tests for Company views (see views.py)."""
from django.test import tag
from django.urls import reverse from django.urls import reverse
from InvenTree.unit_test import InvenTreeTestCase from InvenTree.unit_test import InvenTreeTestCase
@tag('cui')
class CompanyViewTest(InvenTreeTestCase): class CompanyViewTest(InvenTreeTestCase):
"""Tests for various 'Company' views.""" """Tests for various 'Company' views."""

View File

@ -3,6 +3,7 @@
import os import os
from decimal import Decimal from decimal import Decimal
from django.conf import settings
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.test import TestCase from django.test import TestCase
@ -59,7 +60,8 @@ class CompanySimpleTest(TestCase):
def test_company_url(self): def test_company_url(self):
"""Test the detail URL for a company.""" """Test the detail URL for a company."""
c = Company.objects.get(pk=1) c = Company.objects.get(pk=1)
self.assertEqual(c.get_absolute_url(), '/company/1/') if settings.ENABLE_CLASSIC_FRONTEND:
self.assertEqual(c.get_absolute_url(), '/company/1/')
def test_image_renamer(self): def test_image_renamer(self):
"""Test the company image upload functionality.""" """Test the company image upload functionality."""

View File

@ -142,7 +142,8 @@ class LabelTest(InvenTreeAPITestCase):
# Test that each element has been rendered correctly # Test that each element has been rendered correctly
self.assertIn(f'part: {part_pk} - {part_name}', content) self.assertIn(f'part: {part_pk} - {part_name}', content)
self.assertIn(f'data: {{"part": {part_pk}}}', content) self.assertIn(f'data: {{"part": {part_pk}}}', content)
self.assertIn(f'http://testserver/part/{part_pk}/', content) if settings.ENABLE_CLASSIC_FRONTEND:
self.assertIn(f'http://testserver/part/{part_pk}/', content)
# Check that a encoded image has been generated # Check that a encoded image has been generated
self.assertIn('data:image/png;charset=utf-8;base64,', content) self.assertIn('data:image/png;charset=utf-8;base64,', content)

View File

@ -6,6 +6,7 @@ import sys
from datetime import datetime from datetime import datetime
from decimal import Decimal from decimal import Decimal
from django.conf import settings
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.validators import MinValueValidator from django.core.validators import MinValueValidator
@ -41,7 +42,7 @@ from InvenTree.fields import (
InvenTreeURLField, InvenTreeURLField,
RoundingDecimalField, RoundingDecimalField,
) )
from InvenTree.helpers import decimal2string from InvenTree.helpers import decimal2string, pui_url
from InvenTree.helpers_model import getSetting, notify_responsible from InvenTree.helpers_model import getSetting, notify_responsible
from InvenTree.status_codes import ( from InvenTree.status_codes import (
PurchaseOrderStatus, PurchaseOrderStatus,
@ -348,7 +349,9 @@ class PurchaseOrder(TotalPriceMixin, Order):
def get_absolute_url(self): def get_absolute_url(self):
"""Get the 'web' URL for this order.""" """Get the 'web' URL for this order."""
return reverse('po-detail', kwargs={'pk': self.pk}) if settings.ENABLE_CLASSIC_FRONTEND:
return reverse('po-detail', kwargs={'pk': self.pk})
return pui_url(f'/purchasing/purchase-order/{self.pk}')
@staticmethod @staticmethod
def get_api_url(): def get_api_url():
@ -804,7 +807,9 @@ class SalesOrder(TotalPriceMixin, Order):
def get_absolute_url(self): def get_absolute_url(self):
"""Get the 'web' URL for this order.""" """Get the 'web' URL for this order."""
return reverse('so-detail', kwargs={'pk': self.pk}) if settings.ENABLE_CLASSIC_FRONTEND:
return reverse('so-detail', kwargs={'pk': self.pk})
return pui_url(f'/sales/sales-order/{self.pk}')
@staticmethod @staticmethod
def get_api_url(): def get_api_url():
@ -1940,7 +1945,9 @@ class ReturnOrder(TotalPriceMixin, Order):
def get_absolute_url(self): def get_absolute_url(self):
"""Get the 'web' URL for this order.""" """Get the 'web' URL for this order."""
return reverse('return-order-detail', kwargs={'pk': self.pk}) if settings.ENABLE_CLASSIC_FRONTEND:
return reverse('return-order-detail', kwargs={'pk': self.pk})
return pui_url(f'/sales/return-order/{self.pk}')
@staticmethod @staticmethod
def get_api_url(): def get_api_url():

View File

@ -1,5 +1,6 @@
"""Unit tests for Order views (see views.py).""" """Unit tests for Order views (see views.py)."""
from django.test import tag
from django.urls import reverse from django.urls import reverse
from InvenTree.unit_test import InvenTreeTestCase from InvenTree.unit_test import InvenTreeTestCase
@ -34,6 +35,7 @@ class OrderViewTestCase(InvenTreeTestCase):
] ]
@tag('cui')
class PurchaseOrderListTest(OrderViewTestCase): class PurchaseOrderListTest(OrderViewTestCase):
"""Unit tests for the PurchaseOrder index page.""" """Unit tests for the PurchaseOrder index page."""
@ -44,6 +46,7 @@ class PurchaseOrderListTest(OrderViewTestCase):
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
@tag('cui')
class PurchaseOrderTests(OrderViewTestCase): class PurchaseOrderTests(OrderViewTestCase):
"""Tests for PurchaseOrder views.""" """Tests for PurchaseOrder views."""
@ -65,6 +68,7 @@ class PurchaseOrderTests(OrderViewTestCase):
self.assertIn('streaming_content', dir(response)) self.assertIn('streaming_content', dir(response))
@tag('cui')
class SalesOrderViews(OrderViewTestCase): class SalesOrderViews(OrderViewTestCase):
"""Unit tests for the SalesOrder pages.""" """Unit tests for the SalesOrder pages."""
@ -79,6 +83,7 @@ class SalesOrderViews(OrderViewTestCase):
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
@tag('cui')
class ReturnOrderVIews(OrderViewTestCase): class ReturnOrderVIews(OrderViewTestCase):
"""Unit tests for the ReturnOrder pages.""" """Unit tests for the ReturnOrder pages."""

View File

@ -4,6 +4,7 @@ from datetime import datetime, timedelta
from decimal import Decimal from decimal import Decimal
import django.core.exceptions as django_exceptions import django.core.exceptions as django_exceptions
from django.conf import settings
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group from django.contrib.auth.models import Group
from django.test import TestCase from django.test import TestCase
@ -41,7 +42,10 @@ class OrderTest(TestCase):
for pk in range(1, 8): for pk in range(1, 8):
order = PurchaseOrder.objects.get(pk=pk) order = PurchaseOrder.objects.get(pk=pk)
self.assertEqual(order.get_absolute_url(), f'/order/purchase-order/{pk}/') if settings.ENABLE_CLASSIC_FRONTEND:
self.assertEqual(
order.get_absolute_url(), f'/order/purchase-order/{pk}/'
)
self.assertEqual(order.reference, f'PO-{pk:04d}') self.assertEqual(order.reference, f'PO-{pk:04d}')

View File

@ -132,7 +132,9 @@ class PartCategory(InvenTree.models.InvenTreeTree):
def get_absolute_url(self): def get_absolute_url(self):
"""Return the web URL associated with the detail view for this PartCategory instance.""" """Return the web URL associated with the detail view for this PartCategory instance."""
return reverse('category-detail', kwargs={'pk': self.id}) if settings.ENABLE_CLASSIC_FRONTEND:
return reverse('category-detail', kwargs={'pk': self.id})
return helpers.pui_url(f'/part/category/{self.id}')
def clean(self): def clean(self):
"""Custom clean action for the PartCategory model. """Custom clean action for the PartCategory model.
@ -754,7 +756,9 @@ class Part(
def get_absolute_url(self): def get_absolute_url(self):
"""Return the web URL for viewing this part.""" """Return the web URL for viewing this part."""
return reverse('part-detail', kwargs={'pk': self.id}) if settings.ENABLE_CLASSIC_FRONTEND:
return reverse('part-detail', kwargs={'pk': self.id})
return helpers.pui_url(f'/part/{self.id}')
def get_image_url(self): def get_image_url(self):
"""Return the URL of the image for this part.""" """Return the URL of the image for this part."""

View File

@ -1,5 +1,6 @@
"""Unit tests for the PartCategory model.""" """Unit tests for the PartCategory model."""
from django.conf import settings
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.test import TestCase from django.test import TestCase
@ -125,7 +126,8 @@ class CategoryTest(TestCase):
def test_url(self): def test_url(self):
"""Test that the PartCategory URL works.""" """Test that the PartCategory URL works."""
self.assertEqual(self.capacitors.get_absolute_url(), '/part/category/3/') if settings.ENABLE_CLASSIC_FRONTEND:
self.assertEqual(self.capacitors.get_absolute_url(), '/part/category/3/')
def test_part_count(self): def test_part_count(self):
"""Test that the Category part count works.""" """Test that the Category part count works."""

View File

@ -237,7 +237,8 @@ class PartTest(TestCase):
def test_attributes(self): def test_attributes(self):
"""Test Part attributes.""" """Test Part attributes."""
self.assertEqual(self.r1.name, 'R_2K2_0805') self.assertEqual(self.r1.name, 'R_2K2_0805')
self.assertEqual(self.r1.get_absolute_url(), '/part/3/') if settings.ENABLE_CLASSIC_FRONTEND:
self.assertEqual(self.r1.get_absolute_url(), '/part/3/')
def test_category(self): def test_category(self):
"""Test PartCategory path.""" """Test PartCategory path."""

View File

@ -1,5 +1,6 @@
"""Unit tests for Part Views (see views.py).""" """Unit tests for Part Views (see views.py)."""
from django.test import tag
from django.urls import reverse from django.urls import reverse
from InvenTree.unit_test import InvenTreeTestCase from InvenTree.unit_test import InvenTreeTestCase
@ -16,6 +17,7 @@ class PartViewTestCase(InvenTreeTestCase):
superuser = True superuser = True
@tag('cui')
class PartListTest(PartViewTestCase): class PartListTest(PartViewTestCase):
"""Unit tests for the PartList view.""" """Unit tests for the PartList view."""
@ -33,6 +35,7 @@ class PartListTest(PartViewTestCase):
class PartDetailTest(PartViewTestCase): class PartDetailTest(PartViewTestCase):
"""Unit tests for the PartDetail view.""" """Unit tests for the PartDetail view."""
@tag('cui')
def test_part_detail(self): def test_part_detail(self):
"""Test that we can retrieve a part detail page.""" """Test that we can retrieve a part detail page."""
pk = 1 pk = 1
@ -50,6 +53,7 @@ class PartDetailTest(PartViewTestCase):
self.assertEqual(response.context['part'].pk, pk) self.assertEqual(response.context['part'].pk, pk)
self.assertEqual(response.context['category'], part.category) self.assertEqual(response.context['category'], part.category)
@tag('cui')
def test_part_detail_from_ipn(self): def test_part_detail_from_ipn(self):
"""Test that we can retrieve a part detail page from part IPN. """Test that we can retrieve a part detail page from part IPN.

View File

@ -3,7 +3,7 @@
import os import os
from django.conf import settings from django.conf import settings
from django.test import TestCase from django.test import TestCase, tag
from django.urls import include, path, re_path, reverse from django.urls import include, path, re_path, reverse
from error_report.models import Error from error_report.models import Error
@ -363,6 +363,7 @@ class PanelMixinTests(InvenTreeTestCase):
plugins = registry.with_mixin('panel', active=False) plugins = registry.with_mixin('panel', active=False)
self.assertEqual(len(plugins), 0) self.assertEqual(len(plugins), 0)
@tag('cui')
def test_disabled(self): def test_disabled(self):
"""Test that the panels *do not load* if the plugin is not enabled.""" """Test that the panels *do not load* if the plugin is not enabled."""
plugin = registry.get_plugin('samplepanel') plugin = registry.get_plugin('samplepanel')
@ -390,6 +391,7 @@ class PanelMixinTests(InvenTreeTestCase):
self.assertNotIn('Hello world', str(response.content)) self.assertNotIn('Hello world', str(response.content))
self.assertNotIn('Custom Part Panel', str(response.content)) self.assertNotIn('Custom Part Panel', str(response.content))
@tag('cui')
def test_enabled(self): def test_enabled(self):
"""Test that the panels *do* load if the plugin is enabled.""" """Test that the panels *do* load if the plugin is enabled."""
plugin = registry.get_plugin('samplepanel') plugin = registry.get_plugin('samplepanel')

View File

@ -1,5 +1,6 @@
"""Unit tests for InvenTreeBarcodePlugin.""" """Unit tests for InvenTreeBarcodePlugin."""
from django.conf import settings
from django.urls import reverse from django.urls import reverse
import part.models import part.models
@ -270,9 +271,10 @@ class TestInvenTreeBarcode(InvenTreeAPITestCase):
self.assertEqual( self.assertEqual(
response.data['stocklocation']['api_url'], '/api/stock/location/5/' response.data['stocklocation']['api_url'], '/api/stock/location/5/'
) )
self.assertEqual( if settings.ENABLE_CLASSIC_FRONTEND:
response.data['stocklocation']['web_url'], '/stock/location/5/' self.assertEqual(
) response.data['stocklocation']['web_url'], '/stock/location/5/'
)
self.assertEqual(response.data['plugin'], 'InvenTreeBarcode') self.assertEqual(response.data['plugin'], 'InvenTreeBarcode')
# Scan a Part object # Scan a Part object

View File

@ -13,6 +13,7 @@ from django.urls.base import reverse
from django.utils.text import slugify from django.utils.text import slugify
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from InvenTree.helpers import pui_url
from plugin.helpers import get_git_log from plugin.helpers import get_git_log
logger = logging.getLogger('inventree') logger = logging.getLogger('inventree')
@ -364,7 +365,13 @@ class InvenTreePlugin(VersionMixin, MixinBase, MetaBase):
@property @property
def settings_url(self): def settings_url(self):
"""URL to the settings panel for this plugin.""" """URL to the settings panel for this plugin."""
return f'{reverse("settings")}#select-plugin-{self.slug}' if settings.ENABLE_CLASSIC_FRONTEND:
return f'{reverse("settings")}#select-plugin-{self.slug}'
config = self.plugin_config()
if config:
return pui_url(f'/settings/admin/plugin/{config.pk}/')
else:
return pui_url('/settings/admin/plugin/')
# region package info # region package info
def _get_package_commit(self): def _get_package_commit(self):

View File

@ -7,6 +7,7 @@ import os
from datetime import datetime, timedelta from datetime import datetime, timedelta
from decimal import Decimal, InvalidOperation from decimal import Decimal, InvalidOperation
from django.conf import settings
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.exceptions import FieldError, ValidationError from django.core.exceptions import FieldError, ValidationError
from django.core.validators import MinValueValidator from django.core.validators import MinValueValidator
@ -258,7 +259,9 @@ class StockLocation(
def get_absolute_url(self): def get_absolute_url(self):
"""Return url for instance.""" """Return url for instance."""
return reverse('stock-location-detail', kwargs={'pk': self.id}) if settings.ENABLE_CLASSIC_FRONTEND:
return reverse('stock-location-detail', kwargs={'pk': self.id})
return InvenTree.helpers.pui_url(f'/stock/location/{self.id}')
def get_stock_items(self, cascade=True): def get_stock_items(self, cascade=True):
"""Return a queryset for all stock items under this category. """Return a queryset for all stock items under this category.
@ -727,7 +730,9 @@ class StockItem(
def get_absolute_url(self): def get_absolute_url(self):
"""Return url for instance.""" """Return url for instance."""
return reverse('stock-item-detail', kwargs={'pk': self.id}) if settings.ENABLE_CLASSIC_FRONTEND:
return reverse('stock-item-detail', kwargs={'pk': self.id})
return InvenTree.helpers.pui_url(f'/stock/item/{self.id}')
def get_part_name(self): def get_part_name(self):
"""Returns part name.""" """Returns part name."""
@ -2304,7 +2309,9 @@ class StockItemTracking(InvenTree.models.InvenTreeModel):
def get_absolute_url(self): def get_absolute_url(self):
"""Return url for instance.""" """Return url for instance."""
return f'/stock/track/{self.id}' if settings.ENABLE_CLASSIC_FRONTEND:
return f'/stock/track/{self.id}'
return InvenTree.helpers.pui_url(f'/stock/item/{self.item.id}')
def label(self): def label(self):
"""Return label.""" """Return label."""

View File

@ -1,6 +1,7 @@
"""Unit tests for Stock views (see views.py).""" """Unit tests for Stock views (see views.py)."""
from django.contrib.auth.models import Group from django.contrib.auth.models import Group
from django.test import tag
from django.urls import reverse from django.urls import reverse
from common.models import InvenTreeSetting from common.models import InvenTreeSetting
@ -18,6 +19,7 @@ class StockViewTestCase(InvenTreeTestCase):
roles = 'all' roles = 'all'
@tag('cui')
class StockListTest(StockViewTestCase): class StockListTest(StockViewTestCase):
"""Tests for Stock list views.""" """Tests for Stock list views."""
@ -30,6 +32,7 @@ class StockListTest(StockViewTestCase):
class StockDetailTest(StockViewTestCase): class StockDetailTest(StockViewTestCase):
"""Unit test for the 'stock detail' page.""" """Unit test for the 'stock detail' page."""
@tag('cui')
def test_basic_info(self): def test_basic_info(self):
"""Test that basic stock item info is rendered.""" """Test that basic stock item info is rendered."""
url = reverse('stock-item-detail', kwargs={'pk': 1}) url = reverse('stock-item-detail', kwargs={'pk': 1})

View File

@ -2,6 +2,7 @@
import datetime import datetime
from django.conf import settings
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.db.models import Sum from django.db.models import Sum
from django.test import override_settings from django.test import override_settings
@ -256,9 +257,9 @@ class StockTest(StockTestBase):
def test_url(self): def test_url(self):
"""Test get_absolute_url function.""" """Test get_absolute_url function."""
it = StockItem.objects.get(pk=2) it = StockItem.objects.get(pk=2)
self.assertEqual(it.get_absolute_url(), '/stock/item/2/') if settings.ENABLE_CLASSIC_FRONTEND:
self.assertEqual(it.get_absolute_url(), '/stock/item/2/')
self.assertEqual(self.home.get_absolute_url(), '/stock/location/1/') self.assertEqual(self.home.get_absolute_url(), '/stock/location/1/')
def test_strings(self): def test_strings(self):
"""Test str function.""" """Test str function."""

View File

@ -2,7 +2,7 @@
from django.apps import apps from django.apps import apps
from django.contrib.auth.models import Group from django.contrib.auth.models import Group
from django.test import TestCase from django.test import TestCase, tag
from django.urls import reverse from django.urls import reverse
from InvenTree.unit_test import InvenTreeTestCase from InvenTree.unit_test import InvenTreeTestCase
@ -165,6 +165,8 @@ class OwnerModelTest(InvenTreeTestCase):
self.assertEqual(response.status_code, status_code) self.assertEqual(response.status_code, status_code)
return response.data return response.data
# TODO: Find out why this depends on CUI
@tag('cui')
def test_owner(self): def test_owner(self):
"""Tests for the 'owner' model.""" """Tests for the 'owner' model."""
# Check that owner was created for user # Check that owner was created for user

View File

@ -804,10 +804,17 @@ def test_translations(c):
'migrations': 'Run migration unit tests', 'migrations': 'Run migration unit tests',
'report': 'Display a report of slow tests', 'report': 'Display a report of slow tests',
'coverage': 'Run code coverage analysis (requires coverage package)', 'coverage': 'Run code coverage analysis (requires coverage package)',
'cui': 'Do not run CUI tests',
} }
) )
def test( def test(
c, disable_pty=False, runtest='', migrations=False, report=False, coverage=False c,
disable_pty=False,
runtest='',
migrations=False,
report=False,
coverage=False,
cui=False,
): ):
"""Run unit-tests for InvenTree codebase. """Run unit-tests for InvenTree codebase.
@ -843,6 +850,9 @@ def test(
else: else:
cmd += ' --exclude-tag migration_test' cmd += ' --exclude-tag migration_test'
if cui:
cmd += ' --exclude-tag=cui'
if coverage: if coverage:
# Run tests within coverage environment, and generate report # Run tests within coverage environment, and generate report
c.run(f'coverage run {managePyPath()} {cmd}') c.run(f'coverage run {managePyPath()} {cmd}')