Skip to content

[change] Add config_app_label and app_label into device test_admin#748

Open
asmodehn wants to merge 2 commits intoopenwisp:masterfrom
asmodehn:config_app_label_in_monitoring_device_tests
Open

[change] Add config_app_label and app_label into device test_admin#748
asmodehn wants to merge 2 commits intoopenwisp:masterfrom
asmodehn:config_app_label_in_monitoring_device_tests

Conversation

@asmodehn
Copy link
Copy Markdown
Contributor

Checklist

  • I have read the OpenWISP Contributing Guidelines.
  • I have manually tested the changes proposed in this pull request.
  • I have written new test cases for new code and/or updated existing tests for changes to existing code.
  • I have updated the documentation.

Description of Changes

This adds config_app_label attrs in device test_admin tests to make them derivable in other django apps.

I currently also need to set app_label, since the derived TestImportExportMixin requires it... we could probably devise a slightly nicer way of dealing with it, like f.i. renaming the variable config_app_label (in controller) in TestImportExportMixin to make it more explicit which app it is referring to...

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 26, 2026

📝 Walkthrough

Walkthrough

This change updates tests in openwisp_monitoring/device/tests/test_admin.py to remove hard-coded admin URL reversals and use per-class attributes for app labels. TestAdmin now defines public attributes app_label = Device._meta.app_label and config_app_label = Device._meta.app_label, and TestWifiSessionAdmin sets config_app_label = Device._meta.app_label. All admin URL lookups and corresponding expected HTML/link strings in these tests were updated to construct paths using those attributes. No runtime view or production code logic was modified.

Sequence Diagram(s)

(Skipped — changes are test-only URL construction updates and do not introduce a new multi-component control flow.)

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding config_app_label and app_label attributes to the device test_admin tests.
Description check ✅ Passed The description covers the main purpose and includes context about derived classes, but the checklist shows tests and documentation updates were not completed.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@openwisp_monitoring/device/tests/test_admin.py`:
- Around line 46-52: Remove the duplicate assignment to the module-level
variable app_label (it’s assigned twice to "config"); keep a single app_label =
"config" (the existing one is sufficient), and leave config_app_label = "config"
and the modification to resources_fields
(TestImportExportMixin.resource_fields.append("monitoring_status")) unchanged;
update the block that currently contains two app_label = "config" lines to only
include one.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fe1da65 and 8986308.

📒 Files selected for processing (1)
  • openwisp_monitoring/device/tests/test_admin.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: Python==3.11 | django~=5.1.0
  • GitHub Check: Python==3.10 | django~=5.1.0
  • GitHub Check: Python==3.12 | django~=5.2.0
  • GitHub Check: Python==3.11 | django~=5.2.0
  • GitHub Check: Python==3.12 | django~=5.1.0
  • GitHub Check: Python==3.13 | django~=5.2.0
  • GitHub Check: Python==3.10 | django~=4.2.0
  • GitHub Check: Python==3.10 | django~=5.2.0
  • GitHub Check: Python==3.13 | django~=5.1.0
  • GitHub Check: Python==3.12 | django~=4.2.0
  • GitHub Check: Python==3.11 | django~=4.2.0
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2026-02-21T01:03:37.822Z
Learnt from: nemesifier
Repo: openwisp/openwisp-monitoring PR: 738
File: openwisp_monitoring/tests/test_selenium.py:827-859
Timestamp: 2026-02-21T01:03:37.822Z
Learning: In Selenium tests (e.g., in openwisp_monitoring/tests/test_selenium.py and similar test files), when testing JS animations on dashboards or elements driven by JavaScript (such as real-time location updates), insert a short sleep (e.g., sleep(0.3)) before WebDriverWait assertions to allow animations to complete and reduce flakiness. Note: use this as a targeted workaround and prefer explicit waits or animation-end checks where possible to avoid relying on fixed delays.

Applied to files:

  • openwisp_monitoring/device/tests/test_admin.py
📚 Learning: 2026-02-21T18:44:28.852Z
Learnt from: dee077
Repo: openwisp/openwisp-monitoring PR: 738
File: openwisp_monitoring/device/api/views.py:263-281
Timestamp: 2026-02-21T18:44:28.852Z
Learning: In openwisp-monitoring, MonitoringIndoorCoordinatesList inherits organization scoping from the parent IndoorCoordinatesList (from openwisp-controller), which uses FilterByParentManaged mixin and filters by location_id in get_queryset(). The child class only overrides the queryset attribute to add monitoring-specific select_related fields; this pattern is safe as long as get_queryset() from the parent is not bypassed. During reviews, verify that MonitoringIndoorCoordinatesList continues to rely on the parent's get_queryset() and that any added select_related fields in the child do not alter the parent's filtering logic.

Applied to files:

  • openwisp_monitoring/device/tests/test_admin.py
📚 Learning: 2026-02-25T18:42:08.825Z
Learnt from: dee077
Repo: openwisp/openwisp-monitoring PR: 738
File: openwisp_monitoring/tests/test_selenium.py:309-317
Timestamp: 2026-02-25T18:42:08.825Z
Learning: In Selenium tests that use ChannelsLiveServerTestCase (e.g., openwisp_monitoring/tests/test_selenium.py), override settings to configure CHANNEL_LAYERS with channels_redis.core.RedisChannelLayer instead of InMemoryChannelLayer. This is required because the live server runs in a separate process from the test process, and InMemoryChannelLayer is per-process only and cannot handle cross-process WebSocket broadcasting needed for real-time location update tests.

Applied to files:

  • openwisp_monitoring/device/tests/test_admin.py
🔇 Additional comments (2)
openwisp_monitoring/device/tests/test_admin.py (2)

125-125: LGTM!

The dynamic URL construction using self.config_app_label enables test extensibility for derived apps while maintaining the same default behavior.


915-916: LGTM!

Adding config_app_label to TestWifiSessionAdmin correctly enables dynamic URL construction for this test class. Since it doesn't inherit from TestImportExportMixin, omitting app_label here is appropriate.

Comment thread openwisp_monitoring/device/tests/test_admin.py Outdated
@asmodehn asmodehn force-pushed the config_app_label_in_monitoring_device_tests branch from 8986308 to d923e30 Compare March 2, 2026 09:43
@asmodehn asmodehn marked this pull request as ready for review March 2, 2026 09:44
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
openwisp_monitoring/device/tests/test_admin.py (1)

46-52: ⚠️ Potential issue | 🟠 Major

Remove the hardcoded app_label override.

Line 52 (app_label = "config") overrides the dynamic assignment at Line 47, which defeats the goal of making this test class derivable across apps.

🔧 Proposed fix
 class TestAdmin(
     TestWifiClientSessionMixin, TestImportExportMixin, DeviceMonitoringTestCase
 ):
@@
     # Since TestImportExportMixin expects app_label for config app
     app_label = Device._meta.app_label
     config_app_label = Device._meta.app_label
@@
     resources_fields = TestImportExportMixin.resource_fields
     resources_fields.append("monitoring_status")
-    app_label = "config"
     _device_params = {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openwisp_monitoring/device/tests/test_admin.py` around lines 46 - 52, The
test currently overrides the dynamically set app_label by hardcoding app_label =
"config"; remove that hardcoded assignment so app_label remains derived from
Device._meta.app_label; ensure TestImportExportMixin.resource_fields is still
appended with "monitoring_status" (reference: Device,
TestImportExportMixin.resource_fields, monitoring_status, app_label) so the test
stays derivable across apps.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@openwisp_monitoring/device/tests/test_admin.py`:
- Around line 46-52: The test currently overrides the dynamically set app_label
by hardcoding app_label = "config"; remove that hardcoded assignment so
app_label remains derived from Device._meta.app_label; ensure
TestImportExportMixin.resource_fields is still appended with "monitoring_status"
(reference: Device, TestImportExportMixin.resource_fields, monitoring_status,
app_label) so the test stays derivable across apps.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8986308 and d923e30.

📒 Files selected for processing (1)
  • openwisp_monitoring/device/tests/test_admin.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: Python==3.13 | django~=5.2.0
  • GitHub Check: Python==3.13 | django~=5.1.0
  • GitHub Check: Python==3.12 | django~=5.1.0
  • GitHub Check: Python==3.12 | django~=5.2.0
  • GitHub Check: Python==3.10 | django~=4.2.0
  • GitHub Check: Python==3.11 | django~=5.1.0
  • GitHub Check: Python==3.12 | django~=4.2.0
  • GitHub Check: Python==3.10 | django~=5.1.0
  • GitHub Check: Python==3.11 | django~=4.2.0
  • GitHub Check: Python==3.10 | django~=5.2.0
  • GitHub Check: Python==3.11 | django~=5.2.0
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2026-02-21T01:03:37.822Z
Learnt from: nemesifier
Repo: openwisp/openwisp-monitoring PR: 738
File: openwisp_monitoring/tests/test_selenium.py:827-859
Timestamp: 2026-02-21T01:03:37.822Z
Learning: In Selenium tests (e.g., in openwisp_monitoring/tests/test_selenium.py and similar test files), when testing JS animations on dashboards or elements driven by JavaScript (such as real-time location updates), insert a short sleep (e.g., sleep(0.3)) before WebDriverWait assertions to allow animations to complete and reduce flakiness. Note: use this as a targeted workaround and prefer explicit waits or animation-end checks where possible to avoid relying on fixed delays.

Applied to files:

  • openwisp_monitoring/device/tests/test_admin.py
📚 Learning: 2026-02-21T18:44:28.852Z
Learnt from: dee077
Repo: openwisp/openwisp-monitoring PR: 738
File: openwisp_monitoring/device/api/views.py:263-281
Timestamp: 2026-02-21T18:44:28.852Z
Learning: In openwisp-monitoring, MonitoringIndoorCoordinatesList inherits organization scoping from the parent IndoorCoordinatesList (from openwisp-controller), which uses FilterByParentManaged mixin and filters by location_id in get_queryset(). The child class only overrides the queryset attribute to add monitoring-specific select_related fields; this pattern is safe as long as get_queryset() from the parent is not bypassed. During reviews, verify that MonitoringIndoorCoordinatesList continues to rely on the parent's get_queryset() and that any added select_related fields in the child do not alter the parent's filtering logic.

Applied to files:

  • openwisp_monitoring/device/tests/test_admin.py
📚 Learning: 2026-02-25T18:42:08.825Z
Learnt from: dee077
Repo: openwisp/openwisp-monitoring PR: 738
File: openwisp_monitoring/tests/test_selenium.py:309-317
Timestamp: 2026-02-25T18:42:08.825Z
Learning: In Selenium tests that use ChannelsLiveServerTestCase (e.g., openwisp_monitoring/tests/test_selenium.py), override settings to configure CHANNEL_LAYERS with channels_redis.core.RedisChannelLayer instead of InMemoryChannelLayer. This is required because the live server runs in a separate process from the test process, and InMemoryChannelLayer is per-process only and cannot handle cross-process WebSocket broadcasting needed for real-time location update tests.

Applied to files:

  • openwisp_monitoring/device/tests/test_admin.py
🔇 Additional comments (2)
openwisp_monitoring/device/tests/test_admin.py (2)

125-125: Good migration to dynamic admin URL construction.

Using self.config_app_label in these reversals removes hard-coded app namespace coupling and makes test reuse across derived apps much cleaner.

Also applies to: 196-196, 236-236, 261-261, 336-336, 342-342, 363-363, 382-382, 387-387, 394-394, 423-423, 491-491, 502-502, 538-538, 567-567, 612-612, 755-755, 870-877, 1060-1062, 1087-1089


915-915: config_app_label on TestWifiSessionAdmin is a good extensibility hook.

Adding this class attribute makes downstream overrides straightforward where device admin namespace differs.

TestWifiClientSessionMixin,
TestCase,
):
config_app_label = "config"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is missing right?

Suggested change
config_app_label = "config"
config_app_label = Device._meta.app_label

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correct. I ll fix it asap.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@openwisp_monitoring/device/tests/test_admin.py`:
- Around line 46-48: Tests currently hardcode "device" in admin URL names and
paths; add a dynamic config_model_name = Device._meta.model_name and replace all
hardcoded "device" usages (e.g., admin:{self.config_app_label}_device_change,
device_changelist, and /admin/{self.config_app_label}/device/recover/) with the
model-name variable (use
admin:{self.config_app_label}_{self.config_model_name}_change,
{self.config_app_label}_{self.config_model_name}_changelist, and
/admin/{self.config_app_label}/{self.config_model_name}/recover/). Update every
occurrence noted in the review (including the blocks around lines 124-125, 341,
869-876, 914-915, 1059-1061, 1086-1088) to use config_model_name so the tests
work when a concrete Device model has a different name, following the pattern
used for WifiSession._meta.model_name.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: d37804cc-09eb-468b-9c3b-a84db7d91a12

📥 Commits

Reviewing files that changed from the base of the PR and between d923e30 and fb6da62.

📒 Files selected for processing (1)
  • openwisp_monitoring/device/tests/test_admin.py
📜 Review details
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2026-02-21T01:03:37.822Z
Learnt from: nemesifier
Repo: openwisp/openwisp-monitoring PR: 738
File: openwisp_monitoring/tests/test_selenium.py:827-859
Timestamp: 2026-02-21T01:03:37.822Z
Learning: In Selenium tests (e.g., in openwisp_monitoring/tests/test_selenium.py and similar test files), when testing JS animations on dashboards or elements driven by JavaScript (such as real-time location updates), insert a short sleep (e.g., sleep(0.3)) before WebDriverWait assertions to allow animations to complete and reduce flakiness. Note: use this as a targeted workaround and prefer explicit waits or animation-end checks where possible to avoid relying on fixed delays.

Applied to files:

  • openwisp_monitoring/device/tests/test_admin.py
📚 Learning: 2026-02-21T18:44:28.852Z
Learnt from: dee077
Repo: openwisp/openwisp-monitoring PR: 738
File: openwisp_monitoring/device/api/views.py:263-281
Timestamp: 2026-02-21T18:44:28.852Z
Learning: In openwisp-monitoring, MonitoringIndoorCoordinatesList inherits organization scoping from the parent IndoorCoordinatesList (from openwisp-controller), which uses FilterByParentManaged mixin and filters by location_id in get_queryset(). The child class only overrides the queryset attribute to add monitoring-specific select_related fields; this pattern is safe as long as get_queryset() from the parent is not bypassed. During reviews, verify that MonitoringIndoorCoordinatesList continues to rely on the parent's get_queryset() and that any added select_related fields in the child do not alter the parent's filtering logic.

Applied to files:

  • openwisp_monitoring/device/tests/test_admin.py
📚 Learning: 2026-02-25T18:42:08.825Z
Learnt from: dee077
Repo: openwisp/openwisp-monitoring PR: 738
File: openwisp_monitoring/tests/test_selenium.py:309-317
Timestamp: 2026-02-25T18:42:08.825Z
Learning: In Selenium tests that use ChannelsLiveServerTestCase (e.g., openwisp_monitoring/tests/test_selenium.py), override settings to configure CHANNEL_LAYERS with channels_redis.core.RedisChannelLayer instead of InMemoryChannelLayer. This is required because the live server runs in a separate process from the test process, and InMemoryChannelLayer is per-process only and cannot handle cross-process WebSocket broadcasting needed for real-time location update tests.

Applied to files:

  • openwisp_monitoring/device/tests/test_admin.py

Comment on lines +46 to +48
# Since TestImportExportMixin expects app_label for config app
app_label = Device._meta.app_label
config_app_label = Device._meta.app_label
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's read the test file to understand the current implementation
cat -n openwisp_monitoring/device/tests/test_admin.py | head -150

Repository: openwisp/openwisp-monitoring

Length of output: 7299


🏁 Script executed:

# Check lines around the mentioned segments
sed -n '40,130p' openwisp_monitoring/device/tests/test_admin.py | cat -n

Repository: openwisp/openwisp-monitoring

Length of output: 4271


🌐 Web query:

Django admin URL names app_label model_name convention

💡 Result:

Django admin URL names for a model follow this convention (in the admin URL namespace):

  • admin:{app_label}_{model_name}_changelist
  • admin:{app_label}_{model_name}_add
  • admin:{app_label}_{model_name}_change (expects args=(object_id,))
  • admin:{app_label}_{model_name}_delete (expects args=(object_id,))
  • admin:{app_label}_{model_name}_history (expects args=(object_id,))

These are generated from ModelAdmin.get_urls() using info = (self.opts.app_label, self.opts.model_name) (note: model_name is the lowercased _meta.model_name). [1]

Example:

from django.urls import reverse
reverse("admin:auth_user_changelist")
reverse("admin:polls_choice_change", args=(obj.pk,))

If you have a custom AdminSite(name="custom"), pass current_app="custom" to reverse the URL for that specific admin instance. [2]

Related: the per-app index is admin:app_list with kwargs={"app_label": "auth"}. [3]

Sources: Django admin source/docs for ModelAdmin.get_urls() and reversing admin URLs. [1][2][3]


🏁 Script executed:

# Check all the mentioned line ranges
sed -n '120,130p' openwisp_monitoring/device/tests/test_admin.py | cat -n
echo "---"
sed -n '335,345p' openwisp_monitoring/device/tests/test_admin.py | cat -n
echo "---"
sed -n '865,880p' openwisp_monitoring/device/tests/test_admin.py | cat -n
echo "---"
sed -n '910,920p' openwisp_monitoring/device/tests/test_admin.py | cat -n

Repository: openwisp/openwisp-monitoring

Length of output: 2339


🏁 Script executed:

# Check how check_model_name and metric_model_name are used
rg -n "check_model_name|metric_model_name" openwisp_monitoring/device/tests/test_admin.py | head -30

Repository: openwisp/openwisp-monitoring

Length of output: 2836


🏁 Script executed:

# Search for TestWifiSessionAdmin class
sed -n '900,950p' openwisp_monitoring/device/tests/test_admin.py | cat -n

Repository: openwisp/openwisp-monitoring

Length of output: 2539


Add dynamic model name for Device admin URLs.

Django admin URLs require both app_label and model_name. While the code makes app_label dynamic with config_app_label = Device._meta.app_label, it hardcodes "device" in all reversals and path expectations: admin:{self.config_app_label}_device_change, device_changelist, and /admin/{self.config_app_label}/device/recover/. If a derived app swaps config.Device with a differently named concrete model, these will break. Add config_model_name = Device._meta.model_name and use it consistently, following the same pattern already demonstrated in TestWifiSessionAdmin for WifiSession._meta.model_name (lines 917, 924-925).

Also applies to: 124-125, 341-341, 869-876, 914-915, 1059-1061, 1086-1088

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openwisp_monitoring/device/tests/test_admin.py` around lines 46 - 48, Tests
currently hardcode "device" in admin URL names and paths; add a dynamic
config_model_name = Device._meta.model_name and replace all hardcoded "device"
usages (e.g., admin:{self.config_app_label}_device_change, device_changelist,
and /admin/{self.config_app_label}/device/recover/) with the model-name variable
(use admin:{self.config_app_label}_{self.config_model_name}_change,
{self.config_app_label}_{self.config_model_name}_changelist, and
/admin/{self.config_app_label}/{self.config_model_name}/recover/). Update every
occurrence noted in the review (including the blocks around lines 124-125, 341,
869-876, 914-915, 1059-1061, 1086-1088) to use config_model_name so the tests
work when a concrete Device model has a different name, following the pattern
used for WifiSession._meta.model_name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants