From 6f0b2b31a8e484af50db19a5295d338f5263c9ca Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Thu, 22 Feb 2024 22:56:50 +0000 Subject: [PATCH] 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 --------- Co-authored-by: Oliver --- InvenTree/InvenTree/helpers.py | 7 +++++ InvenTree/InvenTree/settings.py | 3 ++ InvenTree/InvenTree/test_middleware.py | 3 ++ InvenTree/InvenTree/test_urls.py | 3 +- InvenTree/InvenTree/test_views.py | 5 ++++ InvenTree/InvenTree/tests.py | 4 ++- InvenTree/InvenTree/urls.py | 30 ++++++++++++++++--- InvenTree/build/models.py | 5 +++- InvenTree/build/tests.py | 7 ++++- InvenTree/company/models.py | 9 ++++-- InvenTree/company/test_views.py | 2 ++ InvenTree/company/tests.py | 4 ++- InvenTree/label/tests.py | 3 +- InvenTree/order/models.py | 15 +++++++--- InvenTree/order/test_views.py | 5 ++++ InvenTree/order/tests.py | 6 +++- InvenTree/part/models.py | 8 +++-- InvenTree/part/test_category.py | 4 ++- InvenTree/part/test_part.py | 3 +- InvenTree/part/test_views.py | 4 +++ .../plugin/base/integration/test_mixins.py | 4 ++- .../barcodes/test_inventree_barcode.py | 8 +++-- InvenTree/plugin/plugin.py | 9 +++++- InvenTree/stock/models.py | 13 ++++++-- InvenTree/stock/test_views.py | 3 ++ InvenTree/stock/tests.py | 7 +++-- InvenTree/users/tests.py | 4 ++- tasks.py | 12 +++++++- 28 files changed, 156 insertions(+), 34 deletions(-) diff --git a/InvenTree/InvenTree/helpers.py b/InvenTree/InvenTree/helpers.py index d36f93704e..d43a462f92 100644 --- a/InvenTree/InvenTree/helpers.py +++ b/InvenTree/InvenTree/helpers.py @@ -913,3 +913,10 @@ def inheritors(cls: type[Inheritors_T]) -> set[type[Inheritors_T]]: def is_ajax(request): """Check if the current request is an AJAX request.""" 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}' diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index d425182a79..0e995843f5 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -80,6 +80,9 @@ DEBUG = get_boolean_setting('INVENTREE_DEBUG', 'debug', True) ENABLE_CLASSIC_FRONTEND = get_boolean_setting( '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( 'INVENTREE_PLATFORM_FRONTEND', 'platform_frontend', True ) diff --git a/InvenTree/InvenTree/test_middleware.py b/InvenTree/InvenTree/test_middleware.py index 8f091f34da..c4fcc52858 100644 --- a/InvenTree/InvenTree/test_middleware.py +++ b/InvenTree/InvenTree/test_middleware.py @@ -2,6 +2,7 @@ from django.conf import settings from django.http import Http404 +from django.test import tag from django.urls import reverse from error_report.models import Error @@ -10,6 +11,8 @@ from InvenTree.exceptions import log_error from InvenTree.unit_test import InvenTreeTestCase +# TODO change test to not rely on CUI +@tag('cui') class MiddlewareTests(InvenTreeTestCase): """Test for middleware functions.""" diff --git a/InvenTree/InvenTree/test_urls.py b/InvenTree/InvenTree/test_urls.py index d15493a750..42744e0a16 100644 --- a/InvenTree/InvenTree/test_urls.py +++ b/InvenTree/InvenTree/test_urls.py @@ -4,10 +4,11 @@ import os import re from pathlib import Path -from django.test import TestCase +from django.test import TestCase, tag from django.urls import reverse +@tag('cui') class URLTest(TestCase): """Test all files for broken url tags.""" diff --git a/InvenTree/InvenTree/test_views.py b/InvenTree/InvenTree/test_views.py index 8bbfa7ffc9..0ad1ae5e45 100644 --- a/InvenTree/InvenTree/test_views.py +++ b/InvenTree/InvenTree/test_views.py @@ -3,6 +3,7 @@ import os from django.contrib.auth import get_user_model +from django.test import tag from django.urls import reverse from InvenTree.unit_test import InvenTreeTestCase @@ -35,6 +36,7 @@ class ViewTests(InvenTreeTestCase): return str(response.content.decode()) + @tag('cui') def test_panels(self): """Test that the required 'panels' are present.""" 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! + @tag('cui') def test_settings_page(self): """Test that the 'settings' page loads correctly.""" # Settings page loads @@ -101,6 +104,8 @@ class ViewTests(InvenTreeTestCase): self.assertNotIn(f'select-{panel}', content) self.assertNotIn(f'panel-{panel}', content) + # TODO: Replace this with a PUI test + @tag('cui') def test_url_login(self): """Test logging in via arguments.""" # Log out diff --git a/InvenTree/InvenTree/tests.py b/InvenTree/InvenTree/tests.py index 0556a46e80..4ffc2c0515 100644 --- a/InvenTree/InvenTree/tests.py +++ b/InvenTree/InvenTree/tests.py @@ -12,7 +12,7 @@ from django.conf import settings from django.contrib.auth import get_user_model from django.core import mail 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 import pint.errors @@ -1319,6 +1319,8 @@ class MagicLoginTest(InvenTreeTestCase): self.assertEqual(resp.wsgi_request.user, self.user) +# TODO - refactor to not use CUI +@tag('cui') class MaintenanceModeTest(InvenTreeTestCase): """Unit tests for maintenance mode.""" diff --git a/InvenTree/InvenTree/urls.py b/InvenTree/InvenTree/urls.py index 4711bc1652..6f007a084a 100644 --- a/InvenTree/InvenTree/urls.py +++ b/InvenTree/InvenTree/urls.py @@ -362,15 +362,19 @@ translated_javascript_urls = [ ] 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/', auth_request), path('api/', include(apipatterns)), 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 = [ # Apps path('build/', include(build_urls)), @@ -436,6 +440,15 @@ if settings.ENABLE_CLASSIC_FRONTEND: frontendpatterns += classic_frontendpatterns if settings.ENABLE_PLATFORM_FRONTEND: 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 @@ -461,5 +474,14 @@ urlpatterns.append( # Send any unknown URLs to the parts page 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', + ) ] diff --git a/InvenTree/build/models.py b/InvenTree/build/models.py index 72f87e87fc..ca3b202317 100644 --- a/InvenTree/build/models.py +++ b/InvenTree/build/models.py @@ -4,6 +4,7 @@ import decimal import logging import os from datetime import datetime +from django.conf import settings from django.contrib.auth.models import User from django.core.exceptions import ValidationError @@ -161,7 +162,9 @@ class Build(InvenTree.models.InvenTreeBarcodeMixin, InvenTree.models.InvenTreeNo def get_absolute_url(self): """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( unique=True, diff --git a/InvenTree/build/tests.py b/InvenTree/build/tests.py index 196701729b..904f2a3a62 100644 --- a/InvenTree/build/tests.py +++ b/InvenTree/build/tests.py @@ -1,5 +1,7 @@ """Basic unit tests for the BuildOrder app""" +from django.conf import settings +from django.test import tag from django.urls import reverse from datetime import datetime, timedelta @@ -40,7 +42,8 @@ class BuildTestSimple(InvenTreeTestCase): def test_url(self): """Test URL lookup""" 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): """Test build completion status""" @@ -116,11 +119,13 @@ class TestBuildViews(InvenTreeTestCase): is_building=True, ) + @tag('cui') def test_build_index(self): """Test build index view.""" response = self.client.get(reverse('build-index')) self.assertEqual(response.status_code, 200) + @tag('cui') def test_build_detail(self): """Test the detail view for a Build object.""" pk = 1 diff --git a/InvenTree/company/models.py b/InvenTree/company/models.py index 62d9af03b7..f8cdedcc8b 100644 --- a/InvenTree/company/models.py +++ b/InvenTree/company/models.py @@ -5,6 +5,7 @@ from datetime import datetime from decimal import Decimal from django.apps import apps +from django.conf import settings from django.core.exceptions import ValidationError from django.core.validators import MinValueValidator from django.db import models @@ -216,7 +217,9 @@ class Company( def get_absolute_url(self): """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): """Return the URL of the image for this company.""" @@ -683,7 +686,9 @@ class SupplierPart( def get_absolute_url(self): """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): """Return custom API filters for this particular instance.""" diff --git a/InvenTree/company/test_views.py b/InvenTree/company/test_views.py index d35e0662b2..7504ebf0f2 100644 --- a/InvenTree/company/test_views.py +++ b/InvenTree/company/test_views.py @@ -1,10 +1,12 @@ """Unit tests for Company views (see views.py).""" +from django.test import tag from django.urls import reverse from InvenTree.unit_test import InvenTreeTestCase +@tag('cui') class CompanyViewTest(InvenTreeTestCase): """Tests for various 'Company' views.""" diff --git a/InvenTree/company/tests.py b/InvenTree/company/tests.py index 9496fc278f..a789b951d4 100644 --- a/InvenTree/company/tests.py +++ b/InvenTree/company/tests.py @@ -3,6 +3,7 @@ import os from decimal import Decimal +from django.conf import settings from django.core.exceptions import ValidationError from django.test import TestCase @@ -59,7 +60,8 @@ class CompanySimpleTest(TestCase): def test_company_url(self): """Test the detail URL for a company.""" 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): """Test the company image upload functionality.""" diff --git a/InvenTree/label/tests.py b/InvenTree/label/tests.py index b4a66b6f4d..08669c338d 100644 --- a/InvenTree/label/tests.py +++ b/InvenTree/label/tests.py @@ -142,7 +142,8 @@ class LabelTest(InvenTreeAPITestCase): # Test that each element has been rendered correctly self.assertIn(f'part: {part_pk} - {part_name}', 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 self.assertIn('data:image/png;charset=utf-8;base64,', content) diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py index 80ac2f616c..ca550b19f9 100644 --- a/InvenTree/order/models.py +++ b/InvenTree/order/models.py @@ -6,6 +6,7 @@ import sys from datetime import datetime from decimal import Decimal +from django.conf import settings from django.contrib.auth.models import User from django.core.exceptions import ValidationError from django.core.validators import MinValueValidator @@ -41,7 +42,7 @@ from InvenTree.fields import ( InvenTreeURLField, RoundingDecimalField, ) -from InvenTree.helpers import decimal2string +from InvenTree.helpers import decimal2string, pui_url from InvenTree.helpers_model import getSetting, notify_responsible from InvenTree.status_codes import ( PurchaseOrderStatus, @@ -348,7 +349,9 @@ class PurchaseOrder(TotalPriceMixin, Order): def get_absolute_url(self): """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 def get_api_url(): @@ -804,7 +807,9 @@ class SalesOrder(TotalPriceMixin, Order): def get_absolute_url(self): """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 def get_api_url(): @@ -1940,7 +1945,9 @@ class ReturnOrder(TotalPriceMixin, Order): def get_absolute_url(self): """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 def get_api_url(): diff --git a/InvenTree/order/test_views.py b/InvenTree/order/test_views.py index 825495daa4..d0a6cfce0f 100644 --- a/InvenTree/order/test_views.py +++ b/InvenTree/order/test_views.py @@ -1,5 +1,6 @@ """Unit tests for Order views (see views.py).""" +from django.test import tag from django.urls import reverse from InvenTree.unit_test import InvenTreeTestCase @@ -34,6 +35,7 @@ class OrderViewTestCase(InvenTreeTestCase): ] +@tag('cui') class PurchaseOrderListTest(OrderViewTestCase): """Unit tests for the PurchaseOrder index page.""" @@ -44,6 +46,7 @@ class PurchaseOrderListTest(OrderViewTestCase): self.assertEqual(response.status_code, 200) +@tag('cui') class PurchaseOrderTests(OrderViewTestCase): """Tests for PurchaseOrder views.""" @@ -65,6 +68,7 @@ class PurchaseOrderTests(OrderViewTestCase): self.assertIn('streaming_content', dir(response)) +@tag('cui') class SalesOrderViews(OrderViewTestCase): """Unit tests for the SalesOrder pages.""" @@ -79,6 +83,7 @@ class SalesOrderViews(OrderViewTestCase): self.assertEqual(response.status_code, 200) +@tag('cui') class ReturnOrderVIews(OrderViewTestCase): """Unit tests for the ReturnOrder pages.""" diff --git a/InvenTree/order/tests.py b/InvenTree/order/tests.py index c3a22f71ef..1b6cdb9081 100644 --- a/InvenTree/order/tests.py +++ b/InvenTree/order/tests.py @@ -4,6 +4,7 @@ from datetime import datetime, timedelta from decimal import Decimal import django.core.exceptions as django_exceptions +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 @@ -41,7 +42,10 @@ class OrderTest(TestCase): for pk in range(1, 8): 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}') diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index b07c320626..c962ba3d81 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -132,7 +132,9 @@ class PartCategory(InvenTree.models.InvenTreeTree): def get_absolute_url(self): """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): """Custom clean action for the PartCategory model. @@ -754,7 +756,9 @@ class Part( def get_absolute_url(self): """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): """Return the URL of the image for this part.""" diff --git a/InvenTree/part/test_category.py b/InvenTree/part/test_category.py index d12b2f9fee..d3e89994ab 100644 --- a/InvenTree/part/test_category.py +++ b/InvenTree/part/test_category.py @@ -1,5 +1,6 @@ """Unit tests for the PartCategory model.""" +from django.conf import settings from django.core.exceptions import ValidationError from django.test import TestCase @@ -125,7 +126,8 @@ class CategoryTest(TestCase): def test_url(self): """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): """Test that the Category part count works.""" diff --git a/InvenTree/part/test_part.py b/InvenTree/part/test_part.py index 3523e8e50b..c267043855 100644 --- a/InvenTree/part/test_part.py +++ b/InvenTree/part/test_part.py @@ -237,7 +237,8 @@ class PartTest(TestCase): def test_attributes(self): """Test Part attributes.""" 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): """Test PartCategory path.""" diff --git a/InvenTree/part/test_views.py b/InvenTree/part/test_views.py index c96e675405..0fe44c09ec 100644 --- a/InvenTree/part/test_views.py +++ b/InvenTree/part/test_views.py @@ -1,5 +1,6 @@ """Unit tests for Part Views (see views.py).""" +from django.test import tag from django.urls import reverse from InvenTree.unit_test import InvenTreeTestCase @@ -16,6 +17,7 @@ class PartViewTestCase(InvenTreeTestCase): superuser = True +@tag('cui') class PartListTest(PartViewTestCase): """Unit tests for the PartList view.""" @@ -33,6 +35,7 @@ class PartListTest(PartViewTestCase): class PartDetailTest(PartViewTestCase): """Unit tests for the PartDetail view.""" + @tag('cui') def test_part_detail(self): """Test that we can retrieve a part detail page.""" pk = 1 @@ -50,6 +53,7 @@ class PartDetailTest(PartViewTestCase): self.assertEqual(response.context['part'].pk, pk) self.assertEqual(response.context['category'], part.category) + @tag('cui') def test_part_detail_from_ipn(self): """Test that we can retrieve a part detail page from part IPN. diff --git a/InvenTree/plugin/base/integration/test_mixins.py b/InvenTree/plugin/base/integration/test_mixins.py index ebee35999d..0cba7f5854 100644 --- a/InvenTree/plugin/base/integration/test_mixins.py +++ b/InvenTree/plugin/base/integration/test_mixins.py @@ -3,7 +3,7 @@ import os 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 error_report.models import Error @@ -363,6 +363,7 @@ class PanelMixinTests(InvenTreeTestCase): plugins = registry.with_mixin('panel', active=False) self.assertEqual(len(plugins), 0) + @tag('cui') def test_disabled(self): """Test that the panels *do not load* if the plugin is not enabled.""" plugin = registry.get_plugin('samplepanel') @@ -390,6 +391,7 @@ class PanelMixinTests(InvenTreeTestCase): self.assertNotIn('Hello world', str(response.content)) self.assertNotIn('Custom Part Panel', str(response.content)) + @tag('cui') def test_enabled(self): """Test that the panels *do* load if the plugin is enabled.""" plugin = registry.get_plugin('samplepanel') diff --git a/InvenTree/plugin/builtin/barcodes/test_inventree_barcode.py b/InvenTree/plugin/builtin/barcodes/test_inventree_barcode.py index 98a6aa30d2..4f5a4b405c 100644 --- a/InvenTree/plugin/builtin/barcodes/test_inventree_barcode.py +++ b/InvenTree/plugin/builtin/barcodes/test_inventree_barcode.py @@ -1,5 +1,6 @@ """Unit tests for InvenTreeBarcodePlugin.""" +from django.conf import settings from django.urls import reverse import part.models @@ -270,9 +271,10 @@ class TestInvenTreeBarcode(InvenTreeAPITestCase): self.assertEqual( response.data['stocklocation']['api_url'], '/api/stock/location/5/' ) - self.assertEqual( - response.data['stocklocation']['web_url'], '/stock/location/5/' - ) + if settings.ENABLE_CLASSIC_FRONTEND: + self.assertEqual( + response.data['stocklocation']['web_url'], '/stock/location/5/' + ) self.assertEqual(response.data['plugin'], 'InvenTreeBarcode') # Scan a Part object diff --git a/InvenTree/plugin/plugin.py b/InvenTree/plugin/plugin.py index 339a2d4f01..5b70ac49e1 100644 --- a/InvenTree/plugin/plugin.py +++ b/InvenTree/plugin/plugin.py @@ -13,6 +13,7 @@ from django.urls.base import reverse from django.utils.text import slugify from django.utils.translation import gettext_lazy as _ +from InvenTree.helpers import pui_url from plugin.helpers import get_git_log logger = logging.getLogger('inventree') @@ -364,7 +365,13 @@ class InvenTreePlugin(VersionMixin, MixinBase, MetaBase): @property def settings_url(self): """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 def _get_package_commit(self): diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py index 517345b243..99d3ae9eee 100644 --- a/InvenTree/stock/models.py +++ b/InvenTree/stock/models.py @@ -7,6 +7,7 @@ import os from datetime import datetime, timedelta from decimal import Decimal, InvalidOperation +from django.conf import settings from django.contrib.auth.models import User from django.core.exceptions import FieldError, ValidationError from django.core.validators import MinValueValidator @@ -258,7 +259,9 @@ class StockLocation( def get_absolute_url(self): """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): """Return a queryset for all stock items under this category. @@ -727,7 +730,9 @@ class StockItem( def get_absolute_url(self): """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): """Returns part name.""" @@ -2304,7 +2309,9 @@ class StockItemTracking(InvenTree.models.InvenTreeModel): def get_absolute_url(self): """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): """Return label.""" diff --git a/InvenTree/stock/test_views.py b/InvenTree/stock/test_views.py index 2d2167f012..e6bb420636 100644 --- a/InvenTree/stock/test_views.py +++ b/InvenTree/stock/test_views.py @@ -1,6 +1,7 @@ """Unit tests for Stock views (see views.py).""" from django.contrib.auth.models import Group +from django.test import tag from django.urls import reverse from common.models import InvenTreeSetting @@ -18,6 +19,7 @@ class StockViewTestCase(InvenTreeTestCase): roles = 'all' +@tag('cui') class StockListTest(StockViewTestCase): """Tests for Stock list views.""" @@ -30,6 +32,7 @@ class StockListTest(StockViewTestCase): class StockDetailTest(StockViewTestCase): """Unit test for the 'stock detail' page.""" + @tag('cui') def test_basic_info(self): """Test that basic stock item info is rendered.""" url = reverse('stock-item-detail', kwargs={'pk': 1}) diff --git a/InvenTree/stock/tests.py b/InvenTree/stock/tests.py index a9a6e1cfda..89d9e8e9d2 100644 --- a/InvenTree/stock/tests.py +++ b/InvenTree/stock/tests.py @@ -2,6 +2,7 @@ import datetime +from django.conf import settings from django.core.exceptions import ValidationError from django.db.models import Sum from django.test import override_settings @@ -256,9 +257,9 @@ class StockTest(StockTestBase): def test_url(self): """Test get_absolute_url function.""" it = StockItem.objects.get(pk=2) - self.assertEqual(it.get_absolute_url(), '/stock/item/2/') - - self.assertEqual(self.home.get_absolute_url(), '/stock/location/1/') + if settings.ENABLE_CLASSIC_FRONTEND: + self.assertEqual(it.get_absolute_url(), '/stock/item/2/') + self.assertEqual(self.home.get_absolute_url(), '/stock/location/1/') def test_strings(self): """Test str function.""" diff --git a/InvenTree/users/tests.py b/InvenTree/users/tests.py index 4e29bf0497..84f0cd1668 100644 --- a/InvenTree/users/tests.py +++ b/InvenTree/users/tests.py @@ -2,7 +2,7 @@ from django.apps import apps from django.contrib.auth.models import Group -from django.test import TestCase +from django.test import TestCase, tag from django.urls import reverse from InvenTree.unit_test import InvenTreeTestCase @@ -165,6 +165,8 @@ class OwnerModelTest(InvenTreeTestCase): self.assertEqual(response.status_code, status_code) return response.data + # TODO: Find out why this depends on CUI + @tag('cui') def test_owner(self): """Tests for the 'owner' model.""" # Check that owner was created for user diff --git a/tasks.py b/tasks.py index 49cb3db158..e7d09d1605 100644 --- a/tasks.py +++ b/tasks.py @@ -804,10 +804,17 @@ def test_translations(c): 'migrations': 'Run migration unit tests', 'report': 'Display a report of slow tests', 'coverage': 'Run code coverage analysis (requires coverage package)', + 'cui': 'Do not run CUI tests', } ) 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. @@ -843,6 +850,9 @@ def test( else: cmd += ' --exclude-tag migration_test' + if cui: + cmd += ' --exclude-tag=cui' + if coverage: # Run tests within coverage environment, and generate report c.run(f'coverage run {managePyPath()} {cmd}')