diff --git a/Makefile b/Makefile index cd5867cced..f34d4508d0 100644 --- a/Makefile +++ b/Makefile @@ -257,7 +257,7 @@ superuser: ## Create an admin user with password "admin" test-back: ## run back-end tests, or specific test like `make test-back tests/apps/core/test_web_analytics.py` @args="$(filter-out $@,$(MAKECMDGOALS))" && \ - DB_PORT=$(DB_PORT) bin/pytest --reuse-db $${args:-${1}} + DB_PORT=$(DB_PORT) bin/pytest $${args:-${1}} .PHONY: test-back # -- Internationalization diff --git a/sandbox/settings.py b/sandbox/settings.py index b939819f16..787e3edd07 100644 --- a/sandbox/settings.py +++ b/sandbox/settings.py @@ -600,10 +600,10 @@ class Base(StyleguideMixin, DRFMixin, RichieCoursesConfigurationMixin, Configura # Wheither you can create PageIndex extension on page through toolbar if true or # just editing existing extension if false - RICHIE_PAGEINDEX_ALLOW_CREATION = False + RICHIE_MAINMENUENTRY_ALLOW_CREATION = False # Define which node level can be processed to search for pageindex extension - RICHIE_PAGEINDEX_MENU_ALLOWED_LEVEL = 0 + RICHIE_MAINMENUENTRY_MENU_ALLOWED_LEVEL = 0 @classmethod def _get_environment(cls): diff --git a/src/richie/apps/courses/admin.py b/src/richie/apps/courses/admin.py index 41b80d8f24..4b7c3029ba 100644 --- a/src/richie/apps/courses/admin.py +++ b/src/richie/apps/courses/admin.py @@ -280,9 +280,9 @@ def snapshot(self, request, course_id, *args, **kwargs): return JsonResponse({"id": new_page.course.id}) -class IndexPageAdmin(PageExtensionAdmin): +class MainMenuEntryAdmin(PageExtensionAdmin): """ - Admin class for the IndexPage model + Admin class for the MainMenuEntry model """ list_display = ["title", "allow_submenu"] @@ -364,7 +364,7 @@ class LicenceAdmin(TranslatableAdmin): admin.site.register(models.Course, CourseAdmin) admin.site.register(models.CourseRun, CourseRunAdmin) admin.site.register(models.Licence, LicenceAdmin) -admin.site.register(models.IndexPage, IndexPageAdmin) +admin.site.register(models.MainMenuEntry, MainMenuEntryAdmin) admin.site.register(models.Organization, OrganizationAdmin) admin.site.register(models.PageRole, PageRoleAdmin) admin.site.register(models.Person, PersonAdmin) diff --git a/src/richie/apps/courses/cms_menus.py b/src/richie/apps/courses/cms_menus.py index 9a8d19f311..8a12cfeb57 100644 --- a/src/richie/apps/courses/cms_menus.py +++ b/src/richie/apps/courses/cms_menus.py @@ -7,24 +7,24 @@ from menus.base import Modifier from menus.menu_pool import menu_pool -from .models import IndexPage +from .models import MainMenuEntry -class MenuWithIndexPage(Modifier): +class MenuWithMainMenuEntry(Modifier): """ - Menu modifier to include IndexPage extension data in menu template context. + Menu modifier to include MainMenuEntry extension data in menu template context. In menu template you will be able to reach possible extension data from node attribute ``menu_extension``. If node page has no extension it will have an empty - dict. Only a specific node level is processedn nodes with a different level won't - have the attribute ``menu_extension`` at all. + dict. Only a specific node level is processed and nodes with a different level + won't have the attribute ``menu_extension`` at all. """ # pylint: disable=too-many-arguments def modify(self, request, nodes, namespace, root_id, post_cut, breadcrumb): """ Patch navigation nodes to include data from possible extension - ``IndexPage``. + ``MainMenuEntry``. For performance: @@ -47,7 +47,7 @@ def modify(self, request, nodes, namespace, root_id, post_cut, breadcrumb): page_ids = [ node.id for node in nodes - if node.level == settings.RICHIE_PAGEINDEX_MENU_ALLOWED_LEVEL + if node.level == settings.RICHIE_MAINMENUENTRY_MENU_ALLOWED_LEVEL ] # No need to continue if we don't have any valid node @@ -56,7 +56,7 @@ def modify(self, request, nodes, namespace, root_id, post_cut, breadcrumb): # We directly get the extensions from their related page id and serialized # as a dict instead of model object - extension_queryset = IndexPage.objects.filter( + extension_queryset = MainMenuEntry.objects.filter( extended_object_id__in=page_ids ).values("extended_object_id", "allow_submenu", "menu_color") @@ -76,4 +76,4 @@ def modify(self, request, nodes, namespace, root_id, post_cut, breadcrumb): return nodes -menu_pool.register_modifier(MenuWithIndexPage) +menu_pool.register_modifier(MenuWithMainMenuEntry) diff --git a/src/richie/apps/courses/cms_toolbars.py b/src/richie/apps/courses/cms_toolbars.py index 1acbbcbc6f..1797282c18 100644 --- a/src/richie/apps/courses/cms_toolbars.py +++ b/src/richie/apps/courses/cms_toolbars.py @@ -13,7 +13,7 @@ from cms.utils.urlutils import admin_reverse from .defaults import PAGE_EXTENSION_TOOLBAR_ITEM_POSITION -from .models import Category, Course, IndexPage, Organization, Person +from .models import Category, Course, MainMenuEntry, Organization, Person class BaseExtensionToolbar(ExtensionToolbar): @@ -135,21 +135,21 @@ class PersonExtensionToolbar(BaseExtensionToolbar): @toolbar_pool.register -class IndexPageExtensionToolbar(BaseExtensionToolbar): +class MainMenuEntryExtensionToolbar(BaseExtensionToolbar): """ - This extension class customizes the toolbar for the IndexPage page extension. + This extension class customizes the toolbar for the MainMenuEntry page extension. """ - model = IndexPage + model = MainMenuEntry def populate(self): """ Specific extension populate method. This extension entry only appears in toolbar if page already have extension or - if setting ``RICHIE_PAGEINDEX_ALLOW_CREATION`` is true. Finally the page level - must also match the allowed level from setting - ``RICHIE_PAGEINDEX_MENU_ALLOWED_LEVEL``. + if setting ``RICHIE_MAINMENUENTRY_ALLOW_CREATION`` is true. Finally the page + level must also match the allowed level from setting + ``RICHIE_MAINMENUENTRY_MENU_ALLOWED_LEVEL``. """ # always use draft if we have a page self.page = get_page_draft(self.request.current_page) @@ -167,16 +167,16 @@ def populate(self): level = self.page.node.get_depth() - 1 allowed = page_extension is not None or ( page_extension is None - and settings.RICHIE_PAGEINDEX_ALLOW_CREATION is True + and settings.RICHIE_MAINMENUENTRY_ALLOW_CREATION is True ) if ( allowed - and level == settings.RICHIE_PAGEINDEX_MENU_ALLOWED_LEVEL + and level == settings.RICHIE_MAINMENUENTRY_MENU_ALLOWED_LEVEL and admin_url ): # Adds a toolbar item in position 0 (at the top of the menu) page_menu.add_modal_item( - _("Index Page settings"), + _("Main menu settings"), url=admin_url, disabled=not self.toolbar.edit_mode_active, position=PAGE_EXTENSION_TOOLBAR_ITEM_POSITION, diff --git a/src/richie/apps/courses/defaults.py b/src/richie/apps/courses/defaults.py index 1881849cc7..198a009d85 100644 --- a/src/richie/apps/courses/defaults.py +++ b/src/richie/apps/courses/defaults.py @@ -312,7 +312,7 @@ "reverse_id": "organizations", "template": "courses/cms/organization_detail.html", } -INDEXES_PAGE = { +MENUENTRIES_PAGE = { "reverse_id": None, "template": "richie/single_column.html", } @@ -344,11 +344,6 @@ "in_navigation": True, "template": "search/search.html", }, - INDEXES_PAGE["reverse_id"]: { - "title": "Indexes", - "in_navigation": True, - "template": "richie/single_column.html", - }, ORGANIZATIONS_PAGE["reverse_id"]: { "title": "Organizations", "in_navigation": True, @@ -392,7 +387,7 @@ # The additional runs can be viewed by clicking on `View more` link. RICHIE_MAX_ARCHIVED_COURSE_RUNS = 10 -# Define possible hover color that can be choosen for an IndexPage and to apply on +# Define possible hover color that can be choosen for an MainMenuEntry and to apply on # its menu item INDEX_MENU_COLOR_CLASSES = getattr( settings, diff --git a/src/richie/apps/courses/factories.py b/src/richie/apps/courses/factories.py index a1fc0ef204..d428151442 100644 --- a/src/richie/apps/courses/factories.py +++ b/src/richie/apps/courses/factories.py @@ -912,14 +912,14 @@ def fill_excerpt(self, create, extracted, **kwargs): ) -class IndexPageFactory(BLDPageExtensionDjangoModelFactory): +class MainMenuEntryFactory(BLDPageExtensionDjangoModelFactory): """ - A factory to automatically generate random yet meaningful index page extensions + A factory to automatically generate random yet meaningful menu entry page extensions and their related page in our tests. """ class Meta: - model = models.IndexPage + model = models.MainMenuEntry exclude = [ "page_in_navigation", "page_languages", @@ -930,6 +930,6 @@ class Meta: ] # fields concerning the related page - page_template = models.IndexPage.PAGE["template"] + page_template = models.MainMenuEntry.PAGE["template"] allow_submenu = False menu_color = "" diff --git a/src/richie/apps/courses/migrations/0035_add_indexpage.py b/src/richie/apps/courses/migrations/0035_add_menuentry.py similarity index 79% rename from src/richie/apps/courses/migrations/0035_add_indexpage.py rename to src/richie/apps/courses/migrations/0035_add_menuentry.py index 9c68ac1b65..05b97c3763 100644 --- a/src/richie/apps/courses/migrations/0035_add_indexpage.py +++ b/src/richie/apps/courses/migrations/0035_add_menuentry.py @@ -1,10 +1,8 @@ -# Generated by Django 4.2.14 on 2024-09-09 15:06 +# Generated by Django 4.2.16 on 2024-09-19 00:24 import django.db.models.deletion from django.db import migrations, models -from ..defaults import INDEX_MENU_COLOR_CLASSES - class Migration(migrations.Migration): @@ -15,7 +13,7 @@ class Migration(migrations.Migration): operations = [ migrations.CreateModel( - name="IndexPage", + name="MainMenuEntry", fields=[ ( "id", @@ -38,9 +36,13 @@ class Migration(migrations.Migration): "menu_color", models.CharField( blank=True, - choices=INDEX_MENU_COLOR_CLASSES, + choices=[ + ("", "None"), + ("primary", "Primary"), + ("warning", "Warning"), + ], default="", - help_text="A color used to display page in menu", + help_text="A color used to display page entry in menu.", max_length=10, verbose_name="Color in menu", ), @@ -60,14 +62,14 @@ class Migration(migrations.Migration): null=True, on_delete=django.db.models.deletion.CASCADE, related_name="draft_extension", - to="courses.indexpage", + to="courses.mainmenuentry", ), ), ], options={ - "verbose_name": "index", - "verbose_name_plural": "indexes", - "db_table": "richie_index", + "verbose_name": "main menu entry", + "verbose_name_plural": "main menu entries", + "db_table": "richie_menuentry", "ordering": ["-pk"], }, ), diff --git a/src/richie/apps/courses/models/__init__.py b/src/richie/apps/courses/models/__init__.py index dc237ef91a..9edc58aa4f 100644 --- a/src/richie/apps/courses/models/__init__.py +++ b/src/richie/apps/courses/models/__init__.py @@ -6,7 +6,7 @@ from .blog import * from .category import * from .course import * -from .index import * +from .menuentry import * from .organization import * from .person import * from .program import * diff --git a/src/richie/apps/courses/models/index.py b/src/richie/apps/courses/models/menuentry.py similarity index 62% rename from src/richie/apps/courses/models/index.py rename to src/richie/apps/courses/models/menuentry.py index b6c1714bd6..a3ab5aade1 100644 --- a/src/richie/apps/courses/models/index.py +++ b/src/richie/apps/courses/models/menuentry.py @@ -1,5 +1,5 @@ """ -Declare and configure the models for the index part +Declare and configure the models for the menu entry part """ from django.db import models @@ -11,21 +11,21 @@ from .. import defaults -class IndexPage(BasePageExtension): +class MainMenuEntry(BasePageExtension): """ - The IndexPage extension defines some options for a page entry in the main menu. + The MainMenuEntry extension defines some options for a page entry in the main menu. """ - PAGE = defaults.INDEXES_PAGE + PAGE = defaults.MENUENTRIES_PAGE class Meta: - db_table = "richie_index" + db_table = "richie_menuentry" ordering = ["-pk"] - verbose_name = _("index") - verbose_name_plural = _("indexes") + verbose_name = _("main menu entry") + verbose_name_plural = _("main menu entries") def __str__(self): - """Human representation of an index page""" + """Human representation of an main menu entry page""" model = self._meta.verbose_name.title() name = self.extended_object.get_title() return f"{model:s}: {name:s}" @@ -44,8 +44,8 @@ def __str__(self): default="", blank=True, choices=defaults.INDEX_MENU_COLOR_CLASSES, - help_text=_("A color used to display page in menu"), + help_text=_("A color used to display page entry in menu."), ) -extension_pool.register(IndexPage) +extension_pool.register(MainMenuEntry) diff --git a/src/richie/apps/courses/settings/__init__.py b/src/richie/apps/courses/settings/__init__.py index b758840c28..1cd5828858 100644 --- a/src/richie/apps/courses/settings/__init__.py +++ b/src/richie/apps/courses/settings/__init__.py @@ -580,11 +580,11 @@ def richie_placeholder_conf(name): # If true the toolbar item will already be showed. If false only a page which already # have the extension will have the toolbar item and users won't be able to add -# pageindex extension on existing page, only create new page with index extension +# MainMenuEntry extension on existing page, only create new page with index extension # through the wizard. -RICHIE_PAGEINDEX_ALLOW_CREATION = False +RICHIE_MAINMENUENTRY_ALLOW_CREATION = False -# Define which node level can be processed to search for pageindex extension. You can -# set it to 'None' for never processing any node. +# Define which node level can be processed to search for MainMenuEntry extension. You +# can set it to 'None' for never processing any node. # This is a limit against performance issues to avoid making querysets for nothing. -RICHIE_PAGEINDEX_MENU_ALLOWED_LEVEL = 0 +RICHIE_MAINMENUENTRY_MENU_ALLOWED_LEVEL = 0 diff --git a/tests/apps/courses/test_cms_toolbars.py b/tests/apps/courses/test_cms_toolbars.py index 7d046e6988..b08fc411a7 100644 --- a/tests/apps/courses/test_cms_toolbars.py +++ b/tests/apps/courses/test_cms_toolbars.py @@ -14,7 +14,7 @@ from richie.apps.core.factories import UserFactory from richie.apps.courses.factories import ( CourseFactory, - IndexPageFactory, + MainMenuEntryFactory, OrganizationFactory, PersonFactory, ) @@ -213,13 +213,13 @@ def test_cms_toolbars_no_page_extension(self): self.assertEqual(results, []) # Check that the index page item is absent with default settings - results = page_menu.find_items(ModalItem, name="Index Page settings...") + results = page_menu.find_items(ModalItem, name="Main menu settings...") self.assertEqual(results, []) @override_settings(CMS_PERMISSION=False) - def test_cms_toolbars_indexpage_extension_availability(self): + def test_cms_toolbars_menuentry_extension_availability(self): """ - IndexPage extension has advanced toolbar behaviors depending from settings. + MainMenuEntry extension has advanced toolbar behaviors depending from settings. """ # Testing with a superuser proves our point superuser = UserFactory(is_staff=True, is_superuser=True) @@ -229,7 +229,7 @@ def test_cms_toolbars_indexpage_extension_availability(self): "A page", template="richie/single_column.html", language="en" ) # Create a page on level 0 and with existing extension - indexpage = IndexPageFactory(page_parent=page) + menuentry = MainMenuEntryFactory(page_parent=page) cases = [[False, False], [False, True], [True, False]] @@ -237,87 +237,87 @@ def test_cms_toolbars_indexpage_extension_availability(self): # Extension should not be created from toolbar for any level but could be # edited from tree level 0 with self.settings( - RICHIE_PAGEINDEX_ALLOW_CREATION=False, - RICHIE_PAGEINDEX_MENU_ALLOWED_LEVEL=0, + RICHIE_MAINMENUENTRY_ALLOW_CREATION=False, + RICHIE_MAINMENUENTRY_MENU_ALLOWED_LEVEL=0, ): toolbar = self.get_toolbar_for_page(page, superuser, *args) page_menu = toolbar.find_items(Menu, name="Page")[0].item - # indexpage page entry is present - results = page_menu.find_items(ModalItem, name="Index Page settings...") + # menuentry page entry is present + results = page_menu.find_items(ModalItem, name="Main menu settings...") self.assertEqual(results, []) toolbar = self.get_toolbar_for_page( - indexpage.extended_object, superuser, *args + menuentry.extended_object, superuser, *args ) page_menu = toolbar.find_items(Menu, name="Page")[0].item - # indexpage page entry is present - results = page_menu.find_items(ModalItem, name="Index Page settings...") + # menuentry page entry is present + results = page_menu.find_items(ModalItem, name="Main menu settings...") self.assertEqual(results, []) # Extension should not be created from toolbar for any level but could be # edited from tree level 1 with self.settings( - RICHIE_PAGEINDEX_ALLOW_CREATION=False, - RICHIE_PAGEINDEX_MENU_ALLOWED_LEVEL=1, + RICHIE_MAINMENUENTRY_ALLOW_CREATION=False, + RICHIE_MAINMENUENTRY_MENU_ALLOWED_LEVEL=1, ): toolbar = self.get_toolbar_for_page(page, superuser, *args) page_menu = toolbar.find_items(Menu, name="Page")[0].item - # indexpage page entry is present - results = page_menu.find_items(ModalItem, name="Index Page settings...") + # menuentry page entry is present + results = page_menu.find_items(ModalItem, name="Main menu settings...") self.assertEqual(results, []) toolbar = self.get_toolbar_for_page( - indexpage.extended_object, superuser, *args + menuentry.extended_object, superuser, *args ) page_menu = toolbar.find_items(Menu, name="Page")[0].item - # indexpage page entry is present - results = page_menu.find_items(ModalItem, name="Index Page settings...") + # menuentry page entry is present + results = page_menu.find_items(ModalItem, name="Main menu settings...") self.assertEqual(len(results), 1) # Extension should be created or edited from toolbar for tree level 0 with self.settings( - RICHIE_PAGEINDEX_ALLOW_CREATION=True, - RICHIE_PAGEINDEX_MENU_ALLOWED_LEVEL=0, + RICHIE_MAINMENUENTRY_ALLOW_CREATION=True, + RICHIE_MAINMENUENTRY_MENU_ALLOWED_LEVEL=0, ): toolbar = self.get_toolbar_for_page(page, superuser, *args) page_menu = toolbar.find_items(Menu, name="Page")[0].item - # indexpage page entry is present - results = page_menu.find_items(ModalItem, name="Index Page settings...") + # menuentry page entry is present + results = page_menu.find_items(ModalItem, name="Main menu settings...") self.assertEqual(len(results), 1) toolbar = self.get_toolbar_for_page( - indexpage.extended_object, superuser, *args + menuentry.extended_object, superuser, *args ) page_menu = toolbar.find_items(Menu, name="Page")[0].item - # indexpage page entry is present - results = page_menu.find_items(ModalItem, name="Index Page settings...") + # menuentry page entry is present + results = page_menu.find_items(ModalItem, name="Main menu settings...") self.assertEqual(results, []) # Extension should be created or edited from toolbar for tree level 1 with self.settings( - RICHIE_PAGEINDEX_ALLOW_CREATION=True, - RICHIE_PAGEINDEX_MENU_ALLOWED_LEVEL=1, + RICHIE_MAINMENUENTRY_ALLOW_CREATION=True, + RICHIE_MAINMENUENTRY_MENU_ALLOWED_LEVEL=1, ): toolbar = self.get_toolbar_for_page(page, superuser, *args) page_menu = toolbar.find_items(Menu, name="Page")[0].item - # indexpage page entry is present - results = page_menu.find_items(ModalItem, name="Index Page settings...") + # menuentry page entry is present + results = page_menu.find_items(ModalItem, name="Main menu settings...") self.assertEqual(results, []) toolbar = self.get_toolbar_for_page( - indexpage.extended_object, superuser, *args + menuentry.extended_object, superuser, *args ) page_menu = toolbar.find_items(Menu, name="Page")[0].item - # indexpage page entry is present - results = page_menu.find_items(ModalItem, name="Index Page settings...") + # menuentry page entry is present + results = page_menu.find_items(ModalItem, name="Main menu settings...") self.assertEqual(len(results), 1) @override_settings(CMS_PERMISSION=False) @@ -373,16 +373,16 @@ def test_cms_toolbars_person_has_page_extension_settings_item(self): self.assertEqual(item.url, url) @override_settings(CMS_PERMISSION=False) - def test_cms_toolbars_indexpage_has_page_extension_settings_item(self): + def test_cms_toolbars_menuentry_has_page_extension_settings_item(self): """ - Validate that a new item to edit the organization is available only when visiting the page - in edit mode and for users with permission to edit the page. + Validate that a new item to edit the menu entry is available only when + visiting the page in edit mode and for users with permission to edit the page. """ - indexpage = IndexPageFactory() - url = f"/en/admin/courses/indexpage/{indexpage.id:d}/change/" + menuentry = MainMenuEntryFactory() + url = f"/en/admin/courses/mainmenuentry/{menuentry.id:d}/change/" for args, method in self.get_cases_for_page_change(): - toolbar = self.get_toolbar_for_page(indexpage.extended_object, *args) - item = method(toolbar, "Index Page settings...") + toolbar = self.get_toolbar_for_page(menuentry.extended_object, *args) + item = method(toolbar, "Main menu settings...") if item: self.assertEqual(item.url, url)