Skip to content

[fix] Guard admin reverse and template url behind FIRMWARE_UPGRADER_API #444#447

Open
BHARATH0153 wants to merge 2 commits into
openwisp:masterfrom
BHARATH0153:fix/api-url-guard
Open

[fix] Guard admin reverse and template url behind FIRMWARE_UPGRADER_API #444#447
BHARATH0153 wants to merge 2 commits into
openwisp:masterfrom
BHARATH0153:fix/api-url-guard

Conversation

@BHARATH0153

@BHARATH0153 BHARATH0153 commented Jun 13, 2026

Copy link
Copy Markdown

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.

Reference to Existing Issue

Closes #444

Changes

Guard the reverse("upgrader:api_upgradeoperation_cancel") call in the admin and the {% url %} tag in the template behind FIRMWARE_UPGRADER_API. When the API is disabled, the URL doesn't exist and these cause NoReverseMatch — now they gracefully return empty string instead of crashing.

@coderabbitai

coderabbitai Bot commented Jun 13, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 336130a8-5714-469f-a776-b4ee8521731d

📥 Commits

Reviewing files that changed from the base of the PR and between f9438f2 and ec58533.

📒 Files selected for processing (3)
  • openwisp_firmware_upgrader/admin.py
  • openwisp_firmware_upgrader/templates/admin/firmware_upgrader/device_firmware_inline.html
  • openwisp_firmware_upgrader/tests/test_admin.py
📜 Recent review details
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{py,html}

📄 CodeRabbit inference engine (Custom checks)

For Django pull requests, ensure all user-facing strings are marked as translatable using the Django i18n framework.

Files:

  • openwisp_firmware_upgrader/templates/admin/firmware_upgrader/device_firmware_inline.html
  • openwisp_firmware_upgrader/admin.py
  • openwisp_firmware_upgrader/tests/test_admin.py
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Place imports at the top of the file. Only defer imports when necessary (e.g., Django model imports inside functions or methods where the app registry is not yet ready)
Avoid unnecessary blank lines inside function and method bodies
Mark user-facing strings for translation with Django i18n helpers in Django code
Write comments and docstrings only when they explain why code is shaped a certain way. Put comments before the relevant code block instead of scattering them inside it

Files:

  • openwisp_firmware_upgrader/admin.py
  • openwisp_firmware_upgrader/tests/test_admin.py
🧠 Learnings (4)
📚 Learning: 2026-03-07T01:16:15.471Z
Learnt from: atif09
Repo: openwisp/openwisp-firmware-upgrader PR: 387
File: openwisp_firmware_upgrader/admin.py:420-423
Timestamp: 2026-03-07T01:16:15.471Z
Learning: In openwisp-firmware-upgrader, UpgradeOperation and BatchUpgradeOperation always share the same organization (BatchUpgradeOperation.build.category.organization). A user who can view an UpgradeOperation can always view its related BatchUpgradeOperation. For the UpgradeOperationAdmin.change_view, model-level has_view_permission(request) suffices to show breadcrumbs for batch, and object-level permission checks are not required.

Applied to files:

  • openwisp_firmware_upgrader/admin.py
📚 Learning: 2026-06-02T08:16:00.439Z
Learnt from: asmodehn
Repo: openwisp/openwisp-firmware-upgrader PR: 362
File: tests/openwisp2/urls.py:10-38
Timestamp: 2026-06-02T08:16:00.439Z
Learning: In this repository, treat `SAMPLE_APP` as a conventionally truthy environment variable: code should use the established pattern `os.environ.get("SAMPLE_APP", False)` and rely on the resulting value’s truthiness (truthy string → enabled). During code reviews, avoid recommending changes to explicit boolean parsing (e.g., checking for `

Applied to files:

  • openwisp_firmware_upgrader/admin.py
  • openwisp_firmware_upgrader/tests/test_admin.py
📚 Learning: 2026-02-27T19:08:56.218Z
Learnt from: nemesifier
Repo: openwisp/openwisp-firmware-upgrader PR: 383
File: openwisp_firmware_upgrader/tests/test_admin.py:50-50
Timestamp: 2026-02-27T19:08:56.218Z
Learning: In tests for openwisp-firmware-upgrader, derive app_label values from model meta instead of hard-coding. Specifically, let BaseTestAdmin compute app_label from Build._meta.app_label and config_app_label from Device._meta.app_label to ensure tests remain correct if models are swapped. This pattern should apply to all test files under openwisp_firmware_upgrader/tests.

Applied to files:

  • openwisp_firmware_upgrader/tests/test_admin.py
📚 Learning: 2026-06-15T20:19:28.326Z
Learnt from: atif09
Repo: openwisp/openwisp-firmware-upgrader PR: 437
File: openwisp_firmware_upgrader/tests/test_admin.py:1072-1147
Timestamp: 2026-06-15T20:19:28.326Z
Learning: In this codebase (OpenWISP projects, including openwisp-firmware-upgrader), prefer test methods that are fully self-contained: each test should do its own setup and make its own explicit assertions within the test body. Avoid introducing shared assertion helpers or parameterized helper methods that abstract away assertions across tests, even if it leads to some duplication.

Applied to files:

  • openwisp_firmware_upgrader/tests/test_admin.py
🔇 Additional comments (6)
openwisp_firmware_upgrader/admin.py (3)

31-31: LGTM!


438-444: LGTM!


816-822: LGTM!

openwisp_firmware_upgrader/tests/test_admin.py (2)

30-30: LGTM!


1070-1093: LGTM!

openwisp_firmware_upgrader/templates/admin/firmware_upgrader/device_firmware_inline.html (1)

8-8: 🎯 Functional Correctness

No frontend handling needed here. The cancel URL isn’t referenced by any JavaScript in this codebase, so an empty value won’t trigger a POST to the current page.

			> Likely an incorrect or invalid review comment.

📝 Walkthrough

Walkthrough

This PR updates admin URL handling to respect FIRMWARE_UPGRADER_API. The upgrade-operation view and device firmware inline formset now provide the cancel URL only when the API is enabled, while the template reads that supplied value. Tests verify that both admin pages render successfully with an empty cancel URL when the API is disabled.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: nemesifier


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (2 errors, 1 warning)

Check name Status Explanation Resolution
Bug Fixes ❌ Error Root cause is fixed and unit regressions cover API-disabled admin pages, but the UI bug lacks the requested Selenium/browser regression test. Add a Selenium test for the device and upgrade-operation admin pages with FIRMWARE_UPGRADER_API=False, asserting they render without NoReverseMatch.
General Rules ❌ Error API-off pages still render a cancel button whose JS posts to an empty URL and only errors; the unsupported control isn't guarded, so the fix is incomplete. citeturn7view0turn7view1turn4view3tu... Hide/disable the cancel button (or short-circuit the JS) when FIRMWARE_UPGRADER_API is false, and add a regression test for that no-cancel path.
Changes ⚠️ Warning UI/admin behavior changed but the PR description has no screenshots or screen recording; tests for the disabled-API path are present. Add a screenshot or short recording to the PR description for the admin UI change, or explicitly note why the UI checklist item doesn’t apply.
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the bug fix and references the guarded admin/template URL behavior.
Description check ✅ Passed The description follows the template with checklist, issue reference, and a clear changes summary.
Linked Issues check ✅ Passed The PR guards both unconditional reverse calls behind FIRMWARE_UPGRADER_API and adds tests for the disabled path, matching #444.
Out of Scope Changes check ✅ Passed The changes stay within the issue scope: admin logic, template handling, and tests for the API-disabled case.
Features ✅ Passed This is a bug fix, not a feature request, so the feature-specific issue/docs/screenshots requirements don’t apply; the PR adds tests for the disabled-API path.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot added bug Something isn't working python Pull requests that update Python code labels Jun 13, 2026
@BHARATH0153

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 13, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@BHARATH0153

Copy link
Copy Markdown
Author

@coderabbitai any outstanding issues?

@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Get PR details, review comments, and checks
gh pr view 447 --repo openwisp/openwisp-firmware-upgrader --json title,state,reviews,reviewDecision,statusCheckRollup

echo "=== PR REVIEW COMMENTS ==="
gh api repos/openwisp/openwisp-firmware-upgrader/pulls/447/comments --jq '.[] | {user: .user.login, body: .body, path: .path, line: .line, resolved: .pull_request_review_id}'

echo "=== PR ISSUE COMMENTS ==="
gh api repos/openwisp/openwisp-firmware-upgrader/issues/447/comments --jq '.[] | {user: .user.login, body: .body[0:300]}'

echo "=== PR FILES ==="
gh api repos/openwisp/openwisp-firmware-upgrader/pulls/447/files --jq '.[] | {filename: .filename, additions: .additions, deletions: .deletions}'

Length of output: 7009


🏁 Script executed:

#!/bin/bash
# Look at the actual diff to check for issues
gh api repos/openwisp/openwisp-firmware-upgrader/pulls/447 --jq '.body'

Length of output: 892


🏁 Script executed:

#!/bin/bash
# Get the changed files content
echo "=== admin.py patch ==="
gh api repos/openwisp/openwisp-firmware-upgrader/pulls/447/files --jq '.[] | select(.filename | contains("admin")) | .patch'

echo "=== template patch ==="
gh api repos/openwisp/openwisp-firmware-upgrader/pulls/447/files --jq '.[] | select(.filename | contains("template") or contains("html")) | .patch'

Length of output: 2364



@BHARATH0153 Here's a summary of outstanding issues I see with this PR:


✅ Good news

All CI checks pass across all Python/Django matrix combinations, and there are no unresolved review comments.


⚠️ Outstanding issues

  1. No automated tests (checklist item unchecked — most important)
    There are no new test cases verifying the fix. A test that sets OPENWISP_FIRMWARE_UPGRADER_API = False and asserts that:

    • The UpgradeOperationAdmin change view renders without NoReverseMatch
    • The DeviceFirmwareInline page renders without error
      …would be essential before this can be merged.
  2. Frontend JS is not guarded
    When the API is disabled, owUpgradeOperationCancelUrl is set to "". If the JavaScript that drives the cancel-upgrade UI unconditionally wires event handlers to that URL, clicking cancel could trigger a request to an empty URL (""). Ideally the cancel button/functionality should be hidden or disabled when the URL is an empty string.

  3. Inconsistent suppression strategies (minor)
    admin.py uses an explicit Python-level if/else, while device_firmware_inline.html uses Django's {% url ... as var %}{{ var|default:'' }} silent suppression. The template approach would also silently swallow a genuine typo in the URL name — this is low-risk but worth being aware of.

  4. Docs/manual testing (checklist items unchecked)
    These may or may not need updates depending on the project's conventions, but they're flagged as incomplete.

The most blocking item before merge is adding tests for the OPENWISP_FIRMWARE_UPGRADER_API = False path.

@nemesifier nemesifier left a comment

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.

A failing test would have been nice, it should be possible to achieve this by mocking app_settings.

Please clarify why the entire checklist is empty in the PR description, you should flag at least the first two checkboxes. Have you manually tested this?

@openwisp-companion

Copy link
Copy Markdown

Hi @BHARATH0153 👋,

This is a friendly reminder that this pull request has had no activity for 7 days since changes were requested.

We'd love to see this contribution merged! Please take a moment to:

  • Address the review feedback
  • Push your changes
  • Let us know if you have any questions or need clarification

If you're busy or need more time, no worries! Just leave a comment to let us know you're still working on it.

Note: within 7 more days, the linked issue will be unassigned to allow other contributors to work on it.

Thank you for your contribution! 🙏

@BHARATH0153
BHARATH0153 force-pushed the fix/api-url-guard branch 3 times, most recently from 2bc735b to c51dd3a Compare July 9, 2026 11:19

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@openwisp_firmware_upgrader/templates/admin/firmware_upgrader/device_firmware_inline.html`:
- Line 8: The inline template’s cancel URL handling is relying on Django’s
implicit empty-string fallback and still appends a redundant default filter.
Remove the unnecessary fallback filter in device_firmware_inline.html, and align
this with the admin.py approach by resolving/passing the API availability or
cancel URL from Python context (using the relevant firmware upgrader
admin/template symbols). Also ensure the JavaScript that consumes
owUpgradeOperationCancelUrl checks for an empty string and disables/hides the
cancel action when the URL is unavailable.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 08f53779-238e-444f-b7de-da0fbcb08409

📥 Commits

Reviewing files that changed from the base of the PR and between 047be8b and 521ac81.

📒 Files selected for processing (3)
  • openwisp_firmware_upgrader/admin.py
  • openwisp_firmware_upgrader/templates/admin/firmware_upgrader/device_firmware_inline.html
  • openwisp_firmware_upgrader/tests/test_admin.py
📜 Review details
⏰ Context from checks skipped due to timeout. (12)
  • GitHub Check: Python==3.13 | django~=5.2.0
  • GitHub Check: Python==3.12 | django~=5.1.0
  • GitHub Check: Python==3.10 | django~=4.2.0
  • GitHub Check: Python==3.13 | django~=4.2.0
  • GitHub Check: Python==3.12 | django~=4.2.0
  • GitHub Check: Python==3.11 | django~=5.1.0
  • GitHub Check: Python==3.13 | django~=5.1.0
  • GitHub Check: Python==3.10 | django~=5.1.0
  • GitHub Check: Python==3.11 | django~=4.2.0
  • GitHub Check: Python==3.12 | django~=5.2.0
  • GitHub Check: Python==3.11 | django~=5.2.0
  • GitHub Check: Python==3.10 | django~=5.2.0
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{py,html}

📄 CodeRabbit inference engine (Custom checks)

For Django pull requests, ensure all user-facing strings are marked as translatable using the Django i18n framework.

Files:

  • openwisp_firmware_upgrader/templates/admin/firmware_upgrader/device_firmware_inline.html
  • openwisp_firmware_upgrader/tests/test_admin.py
  • openwisp_firmware_upgrader/admin.py
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Place imports at the top of the file. Only defer imports when necessary (e.g., Django model imports inside functions or methods where the app registry is not yet ready)
Avoid unnecessary blank lines inside function and method bodies
Mark user-facing strings for translation with Django i18n helpers in Django code
Write comments and docstrings only when they explain why code is shaped a certain way. Put comments before the relevant code block instead of scattering them inside it

Files:

  • openwisp_firmware_upgrader/tests/test_admin.py
  • openwisp_firmware_upgrader/admin.py
🧠 Learnings (4)
📚 Learning: 2026-02-27T19:08:56.218Z
Learnt from: nemesifier
Repo: openwisp/openwisp-firmware-upgrader PR: 383
File: openwisp_firmware_upgrader/tests/test_admin.py:50-50
Timestamp: 2026-02-27T19:08:56.218Z
Learning: In tests for openwisp-firmware-upgrader, derive app_label values from model meta instead of hard-coding. Specifically, let BaseTestAdmin compute app_label from Build._meta.app_label and config_app_label from Device._meta.app_label to ensure tests remain correct if models are swapped. This pattern should apply to all test files under openwisp_firmware_upgrader/tests.

Applied to files:

  • openwisp_firmware_upgrader/tests/test_admin.py
📚 Learning: 2026-06-02T08:16:00.439Z
Learnt from: asmodehn
Repo: openwisp/openwisp-firmware-upgrader PR: 362
File: tests/openwisp2/urls.py:10-38
Timestamp: 2026-06-02T08:16:00.439Z
Learning: In this repository, treat `SAMPLE_APP` as a conventionally truthy environment variable: code should use the established pattern `os.environ.get("SAMPLE_APP", False)` and rely on the resulting value’s truthiness (truthy string → enabled). During code reviews, avoid recommending changes to explicit boolean parsing (e.g., checking for `

Applied to files:

  • openwisp_firmware_upgrader/tests/test_admin.py
  • openwisp_firmware_upgrader/admin.py
📚 Learning: 2026-06-15T20:19:28.326Z
Learnt from: atif09
Repo: openwisp/openwisp-firmware-upgrader PR: 437
File: openwisp_firmware_upgrader/tests/test_admin.py:1072-1147
Timestamp: 2026-06-15T20:19:28.326Z
Learning: In this codebase (OpenWISP projects, including openwisp-firmware-upgrader), prefer test methods that are fully self-contained: each test should do its own setup and make its own explicit assertions within the test body. Avoid introducing shared assertion helpers or parameterized helper methods that abstract away assertions across tests, even if it leads to some duplication.

Applied to files:

  • openwisp_firmware_upgrader/tests/test_admin.py
📚 Learning: 2026-03-07T01:16:15.471Z
Learnt from: atif09
Repo: openwisp/openwisp-firmware-upgrader PR: 387
File: openwisp_firmware_upgrader/admin.py:420-423
Timestamp: 2026-03-07T01:16:15.471Z
Learning: In openwisp-firmware-upgrader, UpgradeOperation and BatchUpgradeOperation always share the same organization (BatchUpgradeOperation.build.category.organization). A user who can view an UpgradeOperation can always view its related BatchUpgradeOperation. For the UpgradeOperationAdmin.change_view, model-level has_view_permission(request) suffices to show breadcrumbs for batch, and object-level permission checks are not required.

Applied to files:

  • openwisp_firmware_upgrader/admin.py
🔇 Additional comments (3)
openwisp_firmware_upgrader/admin.py (1)

31-31: LGTM!

Also applies to: 438-444

openwisp_firmware_upgrader/tests/test_admin.py (2)

30-30: LGTM!

Also applies to: 1070-1098


1070-1098: 🩺 Stability & Availability

No follow-up needed on this URL lookup. The remaining template reversal already falls back to an empty string when the URL name is unavailable, and the API routes are only included when FIRMWARE_UPGRADER_API is enabled.

			> Likely an incorrect or invalid review comment.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
openwisp_firmware_upgrader/templates/admin/firmware_upgrader/device_firmware_inline.html (1)

8-8: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Past review concerns still apply.

The previous review flagged three issues on this line that remain unresolved:

  1. |default:'' is redundant{% url ... as cancel_url %} already stores "" when reversal fails, so the default filter never changes the output.
  2. Inconsistent strategyadmin.py explicitly checks app_settings.FIRMWARE_UPGRADER_API, while this template relies on Django's implicit NoReverseMatch suppression. Consider passing the setting or a pre-resolved URL from Python context for consistency.
  3. JS empty-URL risk — when the API is disabled, owUpgradeOperationCancelUrl becomes "". The downstream cancelUpgradeOperation in upgrade-progress.js calls owUpgradeOperationCancelUrl.replace(...) and POSTs the result, which would send the request to the current page URL. The cancel UI should be hidden or disabled when the URL is empty.
♻️ Remove redundant default filter
-var owUpgradeOperationCancelUrl = "{% url 'upgrader:api_upgradeoperation_cancel' '00000000-0000-0000-0000-000000000000' as cancel_url %}{{ cancel_url|default:'' }}";
+var owUpgradeOperationCancelUrl = "{% url 'upgrader:api_upgradeoperation_cancel' '00000000-0000-0000-0000-000000000000' as cancel_url %}{{ cancel_url }}";
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@openwisp_firmware_upgrader/templates/admin/firmware_upgrader/device_firmware_inline.html`
at line 8, The cancel URL setup in device_firmware_inline.html still has three
issues: the {% url ... as cancel_url %} tag already yields an empty string so
the default filter should be removed, the template should be made consistent
with admin.py by passing or computing the API-enabled state and resolved cancel
URL from Python context rather than relying on implicit NoReverseMatch handling,
and the cancel action in upgrade-progress.js must not run when
owUpgradeOperationCancelUrl is empty. Update the template and the related
cancelUpgradeOperation flow so the cancel UI is hidden or disabled when the URL
is unavailable, and reference owUpgradeOperationCancelUrl,
cancelUpgradeOperation, and app_settings.FIRMWARE_UPGRADER_API while making the
change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@openwisp_firmware_upgrader/tests/test_admin.py`:
- Around line 1082-1092: The `test_device_change_page_api_disabled` case is only
a smoke test because toggling `app_settings.FIRMWARE_UPGRADER_API` does not
prevent `upgrader:api_upgradeoperation_cancel` from resolving, so the template
can still render `cancel_url` and a 200 response won’t catch regressions. Update
the test around `self.client.get(change_url)` to mock the URL resolver for that
named route to raise `NoReverseMatch`, or assert the rendered `cancel_url` value
directly from the `device_change` response, so the behavior of the `{% url ...
as cancel_url %}` path is actually verified.

---

Duplicate comments:
In
`@openwisp_firmware_upgrader/templates/admin/firmware_upgrader/device_firmware_inline.html`:
- Line 8: The cancel URL setup in device_firmware_inline.html still has three
issues: the {% url ... as cancel_url %} tag already yields an empty string so
the default filter should be removed, the template should be made consistent
with admin.py by passing or computing the API-enabled state and resolved cancel
URL from Python context rather than relying on implicit NoReverseMatch handling,
and the cancel action in upgrade-progress.js must not run when
owUpgradeOperationCancelUrl is empty. Update the template and the related
cancelUpgradeOperation flow so the cancel UI is hidden or disabled when the URL
is unavailable, and reference owUpgradeOperationCancelUrl,
cancelUpgradeOperation, and app_settings.FIRMWARE_UPGRADER_API while making the
change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6bb1eef2-6b23-4308-83ab-9d112c97875f

📥 Commits

Reviewing files that changed from the base of the PR and between 521ac81 and f9438f2.

📒 Files selected for processing (3)
  • openwisp_firmware_upgrader/admin.py
  • openwisp_firmware_upgrader/templates/admin/firmware_upgrader/device_firmware_inline.html
  • openwisp_firmware_upgrader/tests/test_admin.py
📜 Review details
⏰ Context from checks skipped due to timeout. (12)
  • GitHub Check: Python==3.12 | django~=5.1.0
  • GitHub Check: Python==3.11 | django~=5.2.0
  • GitHub Check: Python==3.10 | django~=5.1.0
  • GitHub Check: Python==3.13 | django~=4.2.0
  • GitHub Check: Python==3.13 | 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.13 | django~=5.2.0
  • GitHub Check: Python==3.11 | django~=4.2.0
  • GitHub Check: Python==3.10 | django~=5.2.0
  • GitHub Check: Python==3.12 | django~=4.2.0
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{py,html}

📄 CodeRabbit inference engine (Custom checks)

For Django pull requests, ensure all user-facing strings are marked as translatable using the Django i18n framework.

Files:

  • openwisp_firmware_upgrader/templates/admin/firmware_upgrader/device_firmware_inline.html
  • openwisp_firmware_upgrader/admin.py
  • openwisp_firmware_upgrader/tests/test_admin.py
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Place imports at the top of the file. Only defer imports when necessary (e.g., Django model imports inside functions or methods where the app registry is not yet ready)
Avoid unnecessary blank lines inside function and method bodies
Mark user-facing strings for translation with Django i18n helpers in Django code
Write comments and docstrings only when they explain why code is shaped a certain way. Put comments before the relevant code block instead of scattering them inside it

Files:

  • openwisp_firmware_upgrader/admin.py
  • openwisp_firmware_upgrader/tests/test_admin.py
🧠 Learnings (4)
📚 Learning: 2026-03-07T01:16:15.471Z
Learnt from: atif09
Repo: openwisp/openwisp-firmware-upgrader PR: 387
File: openwisp_firmware_upgrader/admin.py:420-423
Timestamp: 2026-03-07T01:16:15.471Z
Learning: In openwisp-firmware-upgrader, UpgradeOperation and BatchUpgradeOperation always share the same organization (BatchUpgradeOperation.build.category.organization). A user who can view an UpgradeOperation can always view its related BatchUpgradeOperation. For the UpgradeOperationAdmin.change_view, model-level has_view_permission(request) suffices to show breadcrumbs for batch, and object-level permission checks are not required.

Applied to files:

  • openwisp_firmware_upgrader/admin.py
📚 Learning: 2026-06-02T08:16:00.439Z
Learnt from: asmodehn
Repo: openwisp/openwisp-firmware-upgrader PR: 362
File: tests/openwisp2/urls.py:10-38
Timestamp: 2026-06-02T08:16:00.439Z
Learning: In this repository, treat `SAMPLE_APP` as a conventionally truthy environment variable: code should use the established pattern `os.environ.get("SAMPLE_APP", False)` and rely on the resulting value’s truthiness (truthy string → enabled). During code reviews, avoid recommending changes to explicit boolean parsing (e.g., checking for `

Applied to files:

  • openwisp_firmware_upgrader/admin.py
  • openwisp_firmware_upgrader/tests/test_admin.py
📚 Learning: 2026-02-27T19:08:56.218Z
Learnt from: nemesifier
Repo: openwisp/openwisp-firmware-upgrader PR: 383
File: openwisp_firmware_upgrader/tests/test_admin.py:50-50
Timestamp: 2026-02-27T19:08:56.218Z
Learning: In tests for openwisp-firmware-upgrader, derive app_label values from model meta instead of hard-coding. Specifically, let BaseTestAdmin compute app_label from Build._meta.app_label and config_app_label from Device._meta.app_label to ensure tests remain correct if models are swapped. This pattern should apply to all test files under openwisp_firmware_upgrader/tests.

Applied to files:

  • openwisp_firmware_upgrader/tests/test_admin.py
📚 Learning: 2026-06-15T20:19:28.326Z
Learnt from: atif09
Repo: openwisp/openwisp-firmware-upgrader PR: 437
File: openwisp_firmware_upgrader/tests/test_admin.py:1072-1147
Timestamp: 2026-06-15T20:19:28.326Z
Learning: In this codebase (OpenWISP projects, including openwisp-firmware-upgrader), prefer test methods that are fully self-contained: each test should do its own setup and make its own explicit assertions within the test body. Avoid introducing shared assertion helpers or parameterized helper methods that abstract away assertions across tests, even if it leads to some duplication.

Applied to files:

  • openwisp_firmware_upgrader/tests/test_admin.py
🔇 Additional comments (4)
openwisp_firmware_upgrader/admin.py (2)

31-31: LGTM!


438-444: LGTM!

openwisp_firmware_upgrader/tests/test_admin.py (2)

30-30: LGTM!


1070-1081: LGTM!

Comment thread openwisp_firmware_upgrader/tests/test_admin.py
@BHARATH0153
BHARATH0153 force-pushed the fix/api-url-guard branch 8 times, most recently from 0acd394 to c930598 Compare July 9, 2026 14:50
@BHARATH0153
BHARATH0153 requested a review from nemesifier July 9, 2026 14:51
@BHARATH0153
BHARATH0153 marked this pull request as draft July 9, 2026 15:06
@BHARATH0153
BHARATH0153 force-pushed the fix/api-url-guard branch 2 times, most recently from 23d8753 to 99499be Compare July 9, 2026 15:15
openwisp#444

Guard the reverse("upgrader:api_upgradeoperation_cancel") call in the admin and the {% url %} tag in the template behind FIRMWARE_UPGRADER_API. When the API is disabled, these gracefully return empty string instead of raising NoReverseMatch.

test_upgrade_operation_change_view_api_disabled verifies the cancel URL context variable is an empty string. test_device_change_page_api_disabled verifies the admin page renders without crashing when the API is disabled.

Closes openwisp#444
openwisp#444

Guard the reverse("upgrader:api_upgradeoperation_cancel") call in the admin and the {% url %} tag in the template behind FIRMWARE_UPGRADER_API. When the API is disabled, these gracefully return empty string instead of raising NoReverseMatch.

test_upgrade_operation_change_view_api_disabled verifies the cancel URL context variable is an empty string. test_device_change_page_api_disabled verifies the admin page renders without crashing when the API is disabled and the cancel URL is empty.

Closes openwisp#444
@github-project-automation github-project-automation Bot moved this from To do (general) to In progress in OpenWISP Contributor's Board Jul 9, 2026
@BHARATH0153
BHARATH0153 marked this pull request as ready for review July 9, 2026 15:54
@BHARATH0153

Copy link
Copy Markdown
Author

@nemesifier please review when you are free thanks!

@CodingWithSaksham

Copy link
Copy Markdown

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

Labels

bug Something isn't working python Pull requests that update Python code

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

[bug] Admin reverses upgrader: URLs unconditionally, ignoring FIRMWARE_UPGRADER_API

3 participants