From ee598bc45ef46d5354725275d2475aebbd75c57d Mon Sep 17 00:00:00 2001 From: Mikhail Podgurskiy Date: Tue, 9 May 2023 13:21:07 +0600 Subject: [PATCH] Changes sync --- CHANGELOG.rst | 4 +- tests/__init__.py | 19 ++++- tests/contrib/__init__.py | 59 +++++++++++++++ tests/test_middleware.py | 48 ++++++++----- tests/test_urls__base.py | 50 +++++++------ .../contrib/import_export/export_action.html | 2 +- .../templates/viewflow/includes/app_menu.html | 4 +- .../viewflow/includes/list_bulk_actions.html | 2 +- .../viewflow/includes/object_detail_card.html | 2 +- .../viewflow/includes/site_menu.html | 1 + .../viewflow/views/confirm_delete.html | 6 +- .../viewflow/views/delete_action.html | 2 +- viewflow/templates/viewflow/views/form.html | 4 +- .../templates/viewflow/views/transition.html | 4 +- viewflow/templatetags/viewflow.py | 45 +++++++++--- viewflow/urls/__init__.py | 62 +++++++++++++--- viewflow/urls/base.py | 14 ++-- viewflow/utils.py | 72 ++++++++++++++----- viewflow/views/detail.py | 35 +++++---- viewflow/workflow/nodes/job.py | 67 +++-------------- 20 files changed, 336 insertions(+), 166 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b24d0cb..5d0e1a9 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,8 +5,8 @@ Changelog GIT VERSION ----------- -Introduce SplitFirst Node - +- Introduce SplitFirst Node +- celery.Timer Node 2.0.0.b3 2023-04-25 ------------------- diff --git a/tests/__init__.py b/tests/__init__.py index fb989c4..cb7aaff 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,3 +1,20 @@ from .celery import app as celery_app -__all__ = ('celery_app',) +__all__ = ("celery_app",) + + +def print_urls(): + """For debug purpose""" + + def list_urls(urls, parent_pattern=""): + for entry in urls: + full_pattern = parent_pattern + entry.pattern.regex.pattern + if hasattr(entry, "url_patterns"): + list_urls(entry.url_patterns, full_pattern) + else: + print(f"{entry.name or ''}: {full_pattern}") + + from django.conf import settings + + urlconf = __import__(settings.ROOT_URLCONF, {}, {}, [""]) + list_urls(urlconf.urlpatterns) diff --git a/tests/contrib/__init__.py b/tests/contrib/__init__.py index e69de29..49643fe 100644 --- a/tests/contrib/__init__.py +++ b/tests/contrib/__init__.py @@ -0,0 +1,59 @@ +import os +import signal +import subprocess +import sys +import time +import unittest + +from django.db import connection +from django.test import TransactionTestCase + +from viewflow.workflow.models import Task + + +@unittest.skipUnless( + "DATABASE_URL" in os.environ, "Celery test requires specific database config" +) +class CeleryTestCase(TransactionTestCase): + def setUp(self): + """Start celery worker connection the the test database""" + env = os.environ.copy() + database_url = env["DATABASE_URL"] + env["DATABASE_URL"] = "{}/{}".format( + database_url[: database_url.rfind("/")], connection.settings_dict["NAME"] + ) + + cmd = [ + "celery", + "--app", + "cookbook.workflow101.config", + "worker", + "--loglevel", + "DEBUG", + "-E", + "-c", + "1", + ] + + self.process = subprocess.Popen( + cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env + ) + self.assertIsNone(self.process.poll()) + + def tearDown(self): + self.process.send_signal(signal.SIGTERM) + if "-v3" in sys.argv: + stdout, stderr = self.process.communicate() + print(" CELERY STDOUT ".center(80, "=")) + print(stdout.decode()) + + print(" CELERY STDERR ".center(80, "="), file=sys.stderr) + print(stderr.decode(), file=sys.stderr) + + def wait_for_task(self, process, flow_task, status=None): + for _ in range(100): + try: + return process.task_set.filter(flow_task=flow_task, status=status).get() + except Task.DoesNotExist: + time.sleep(0.05) + assert False, "Task {} not found".format(flow_task) diff --git a/tests/test_middleware.py b/tests/test_middleware.py index 5461918..8065ac7 100644 --- a/tests/test_middleware.py +++ b/tests/test_middleware.py @@ -5,46 +5,56 @@ from viewflow.urls import AppMenuMixin, Application, Site, Viewset, route class NestedViewset(Viewset): - app_name = 'nested' - page_path = path('page/', TemplateView.as_view(template_name='viewflow/base.html'), name="page") + app_name = "nested" + page_path = path( + "page/", TemplateView.as_view(template_name="viewflow/base.html"), name="page" + ) class CityViewset(AppMenuMixin, Viewset): - index_path = path('', TemplateView.as_view(template_name='viewflow/base.html'), name="index") - nested_path = route('nested', NestedViewset()) + index_path = path( + "", TemplateView.as_view(template_name="viewflow/base.html"), name="index" + ) + nested_path = route("nested/", NestedViewset()) -site = Site(title="Test site", viewsets=[ - Application(app_name="test", viewsets=[ - CityViewset(), - ]) -]) +site = Site( + title="Test site", + viewsets=[ + Application( + app_name="test", + viewsets=[ + CityViewset(), + ], + ) + ], +) -urlpatterns = [ - path('', site.urls) -] +urlpatterns = [path("", site.urls)] @override_settings(ROOT_URLCONF=__name__) class Test(TestCase): def test_context_injected(self): - response = self.client.get('/test/city/') + response = self.client.get("/test/city/") match = response.wsgi_request.resolver_match - self.assertTrue(hasattr(match, 'site')) + self.assertTrue(hasattr(match, "site")) self.assertEqual(match.site, site) - self.assertTrue(hasattr(match, 'app')) + self.assertTrue(hasattr(match, "app")) self.assertEqual(match.app, site._children[0]) # App -> Site -> CityViewset - self.assertTrue(hasattr(match, 'viewset')) + self.assertTrue(hasattr(match, "viewset")) self.assertEqual(match.viewset, site._children[0]._children[0]) def test_nested_viewset_injected(self): - response = self.client.get('/test/city/nested/page/') + response = self.client.get("/test/city/nested/page/") match = response.wsgi_request.resolver_match # App -> Site -> CityViewset -> Nested - self.assertTrue(hasattr(match, 'viewset')) - self.assertEqual(match.viewset, site._children[0]._children[0].nested_path.viewset) + self.assertTrue(hasattr(match, "viewset")) + self.assertEqual( + match.viewset, site._children[0]._children[0].nested_path.viewset + ) diff --git a/tests/test_urls__base.py b/tests/test_urls__base.py index b9b0296..22bc1c1 100644 --- a/tests/test_urls__base.py +++ b/tests/test_urls__base.py @@ -5,52 +5,56 @@ from viewflow.urls import route, IndexViewMixin, Viewset class NestedViewset(IndexViewMixin, Viewset): - app_name = 'nested' + app_name = "nested" - page_path = path('page/', TemplateView.as_view(template_name='viewflow/base.html'), name="page") - route_path = route('test', Viewset()) + page_path = path( + "page/", TemplateView.as_view(template_name="viewflow/base.html"), name="page" + ) + route_path = route("test/", Viewset()) class InheritedViewset(NestedViewset): - app_name = 'nested' + app_name = "nested" - page_path = path('page2/', TemplateView.as_view(template_name='viewflow/base.html'), name="page") + page_path = path( + "page2/", TemplateView.as_view(template_name="viewflow/base.html"), name="page" + ) class RootViewset(Viewset): - app_name = 'root' + app_name = "root" - index_path = path('', TemplateView.as_view(template_name='viewflow/base.html'), name="index") - nested_path = route('test', NestedViewset()) - nested2_path = route('nested2', NestedViewset(app_name='nested2')) + index_path = path( + "", TemplateView.as_view(template_name="viewflow/base.html"), name="index" + ) + nested_path = route("test/", NestedViewset()) + nested2_path = route("nested2/", NestedViewset(app_name="nested2")) # check here that route_url mounted second time successfully - nested3_path = route('inherited', InheritedViewset(app_name='nested2')) + nested3_path = route("inherited/", InheritedViewset(app_name="nested2")) urlconfig = RootViewset() -urlpatterns = [ - path('', urlconfig.urls) -] +urlpatterns = [path("", urlconfig.urls)] @override_settings(ROOT_URLCONF=__name__) class Test(TestCase): # noqa: D101 def test_created_urls(self): - self.assertEqual('/', reverse('root:index')) + self.assertEqual("/", reverse("root:index")) - self.assertEqual('/test/', reverse('root:nested:index')) - self.assertEqual('/test/page/', reverse('root:nested:page')) + self.assertEqual("/test/", reverse("root:nested:index")) + self.assertEqual("/test/page/", reverse("root:nested:page")) - self.assertEqual('/nested2/', reverse('root:nested2:index')) - self.assertEqual('/nested2/page/', reverse('root:nested2:page')) + self.assertEqual("/nested2/", reverse("root:nested2:index")) + self.assertEqual("/nested2/page/", reverse("root:nested2:page")) def test_urlconf_resolve(self): - self.assertEqual('/', urlconfig.reverse('index')) - self.assertEqual('/test/', urlconfig.nested_path.viewset.reverse('index')) - self.assertEqual('/test/page/', urlconfig.nested_path.viewset.reverse('page')) + self.assertEqual("/", urlconfig.reverse("index")) + self.assertEqual("/test/", urlconfig.nested_path.viewset.reverse("index")) + self.assertEqual("/test/page/", urlconfig.nested_path.viewset.reverse("page")) def test_auto_redirect(self): - response = self.client.get(reverse('root:nested:index')) - self.assertRedirects(response, '/test/page/') + response = self.client.get(reverse("root:nested:index")) + self.assertRedirects(response, "/test/page/") diff --git a/viewflow/templates/viewflow/contrib/import_export/export_action.html b/viewflow/templates/viewflow/contrib/import_export/export_action.html index b710a3b..58bd292 100644 --- a/viewflow/templates/viewflow/contrib/import_export/export_action.html +++ b/viewflow/templates/viewflow/contrib/import_export/export_action.html @@ -10,7 +10,7 @@

{{ view.model|verbose_name_plural|title }}

- {{ view.model|verbose_name_plural|title }} + {{ view.model|verbose_name_plural|title }} {% trans 'Export' %}

diff --git a/viewflow/templates/viewflow/includes/app_menu.html b/viewflow/templates/viewflow/includes/app_menu.html index 55137a2..aa3d420 100644 --- a/viewflow/templates/viewflow/includes/app_menu.html +++ b/viewflow/templates/viewflow/includes/app_menu.html @@ -4,7 +4,7 @@ {% if app.title %}

{{ app.title }}

{% endif %} {% block viewset_links %} {% if app.parent and app.parent != site %} - {% reverse app.parent 'index' as parent_index %}{% if parent_index %} + {% current_viewset_reverse app.parent 'index' as parent_index %}{% if parent_index %} arrow_back {% trans 'Back' %} @@ -12,7 +12,7 @@ {% endif %} {% endif %} {% for viewset in app.menu_items %}{% if viewset|has_perm:request.user %} - {% reverse viewset 'index' as index_url %}{% if index_url %} + {% current_viewset_reverse viewset 'index' as index_url %}{% if index_url %} {% if viewset.icon %}{{ viewset.icon }}{% else %}view_carousel{% endif %} {% trans viewset.title %} diff --git a/viewflow/templates/viewflow/includes/list_bulk_actions.html b/viewflow/templates/viewflow/includes/list_bulk_actions.html index 2d07052..0291f4c 100644 --- a/viewflow/templates/viewflow/includes/list_bulk_actions.html +++ b/viewflow/templates/viewflow/includes/list_bulk_actions.html @@ -40,7 +40,7 @@