openwisp / openwisp/openwisp-users

[change] Make menu item registration idempotent

Open
#445 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
Python
Stars
179
Forks
96
Avg merge
13h 40m
Merged PRs (30d)
16

Description

Describe the bug
Initializing the app multiple times gives error.
Although this is not a main usecase, it can happen when running tests that override settings.

I noticed it when I tried to override installed apps to test migrations between two databases (created with slightly different settings).

Steps To Reproduce
Add a test which is overriding the INSTALLED_APPS setting.

For instance:

from django.test import TestCase
from django.test.utils import modify_settings

class TestDB(TestCase):

    @modify_settings(INSTALLED_APPS={'remove': 'django_filters'})
    def fake_test(self):
        pass

Expected behavior

The app should be able to be initialize multiple times, so that test example should simply pass.

Screenshots

$ ./manage.py test testapp.tests.test_db.TestDB.fake_test
Found 1 test(s).
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
E
======================================================================
ERROR: fake_test (testapp.tests.test_db.TestDB.fake_test)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/alexv/Projects/openwisp-users/.direnv/python-3.12/lib/python3.12/site-packages/django/test/utils.py", line 458, in inner
    with self as context:
         ^^^^
  File "/home/alexv/Projects/openwisp-users/.direnv/python-3.12/lib/python3.12/site-packages/django/test/utils.py", line 423, in __enter__
    return self.enable()
           ^^^^^^^^^^^^^
  File "/home/alexv/Projects/openwisp-users/.direnv/python-3.12/lib/python3.12/site-packages/django/test/utils.py", line 605, in enable
    super().enable()
  File "/home/alexv/Projects/openwisp-users/.direnv/python-3.12/lib/python3.12/site-packages/django/test/utils.py", line 492, in enable
    apps.set_installed_apps(self.options["INSTALLED_APPS"])
  File "/home/alexv/Projects/openwisp-users/.direnv/python-3.12/lib/python3.12/site-packages/django/apps/registry.py", line 362, in set_installed_apps
    self.populate(installed)
  File "/home/alexv/Projects/openwisp-users/.direnv/python-3.12/lib/python3.12/site-packages/django/apps/registry.py", line 124, in populate
    app_config.ready()
  File "/home/alexv/Projects/openwisp-users/openwisp_users/apps.py", line 27, in ready
    self.register_menu_group()
  File "/home/alexv/Projects/openwisp-users/openwisp_users/apps.py", line 66, in register_menu_group
    register_menu_group(
  File "/home/alexv/Projects/openwisp-users/.direnv/python-3.12/lib/python3.12/site-packages/openwisp_utils/admin_theme/menu.py", line 192, in register_menu_group
    raise ImproperlyConfigured(
django.core.exceptions.ImproperlyConfigured: A group/link with config {'label': 'Users & Organizations', 'items': {1: {'label': 'Users', 'model': 'openwisp_users.User', 'name': 'changelist', 'icon': 'user'}, 2: {'label': 'Organizations', 'model': 'openwisp_users.Organization', 'name': 'changelist', 'icon': 'ow-org'}, 3: {'label': 'Groups & Permissions', 'model': 'openwisp_users.Group', 'name': 'changelist', 'icon': 'ow-permission'}, 4: {'label': 'Organization Owners', 'model': 'openwisp_users.OrganizationOwner', 'name': 'changelist', 'icon': 'ow-org-owner'}, 5: {'label': 'Organization Users', 'model': 'openwisp_users.OrganizationUser', 'name': 'changelist', 'icon': 'ow-org-user'}}, 'icon': 'ow-user-and-org'} is being registered at position "40",                but another group named "Users & Organizations" is already registered at the same position.

----------------------------------------------------------------------
Ran 1 test in 0.003s

System Informatioon:

  • OS:
$ cat /etc/issue
Pop!_OS 22.04 LTS
  • Python Version: Python 3.12.7
$ pip list | grep 'openwisp\|django'
django-admin-autocomplete-filter 0.7.1
django-allauth                   65.7.0
django-compress-staticfiles      1.0.1b0
django-extensions                4.1
django-filter                    23.5
django-model-utils               5.0.0
django-organizations             2.5.0
django-phonenumber-field         8.1.0
django-redis                     5.4.0
django-reversion                 5.1.0
django-sesame                    3.2.3
djangorestframework              3.15.2
openwisp-users                   1.2.0a0     /home/alexv/Projects/openwisp-users
openwisp-utils                   1.2a0

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in openwisp_users/apps.py, especially ready() and register_menu_group(), then run the INSTALLED_APPS override reproducer from the issue. Confirm that initializing the app multiple times no longer raises the duplicate menu-group error and that the test completes successfully.

Written by the indexing model from the issue text.

Assessment

Tech stack
django, python
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.