Repository: openwisp/openwisp-utils (language: python)

Issue:
[bug] help_text_stacked not calling static()
Same as https://github.com/openwisp/openwisp-monitoring/commit/cf67548393162a00e3773ecca8e99605cba185fd here:

https://github.com/openwisp/openwisp-utils/blob/7a86dffbcc72c72392a283a3db3fca9a0e021ce7/openwisp_utils/admin_theme/templates/admin/edit_inline/help_text_stacked.html#L30


Discussion / hints:

Fix patch:
diff --git a/openwisp_utils/admin_theme/templates/admin/edit_inline/help_text_stacked.html b/openwisp_utils/admin_theme/templates/admin/edit_inline/help_text_stacked.html
index e681b70e..dcc25736 100644
--- a/openwisp_utils/admin_theme/templates/admin/edit_inline/help_text_stacked.html
+++ b/openwisp_utils/admin_theme/templates/admin/edit_inline/help_text_stacked.html
@@ -1,3 +1,4 @@
+{% load static %}
 {% comment %}
 Copied from https://github.com/django/django/blob/HEAD/django/contrib/admin/templates/admin/edit_inline/stacked.html
 to add customization.
@@ -8,43 +9,45 @@
      data-inline-type="stacked"
      data-inline-formset="{{ inline_admin_formset.inline_formset_data }}">
 
-<fieldset class="module {{ inline_admin_formset.classes }}">
-  {% if inline_admin_formset.formset.max_num == 1 %}
-    <h2>{{ inline_admin_formset.opts.verbose_name|capfirst }}</h2>
-  {% else %}
-    <h2>{{ inline_admin_formset.opts.verbose_name_plural|capfirst }}</h2>
-  {% endif %}
-{{ inline_admin_formset.formset.management_form }}
-{{ inline_admin_formset.formset.non_form_errors }}
+  <fieldset class="module {{ inline_admin_formset.classes }}">
+    {% if inline_admin_formset.formset.max_num == 1 %}
+      <h2>{{ inline_admin_formset.opts.verbose_name|capfirst }}</h2>
+    {% else %}
+      <h2>{{ inline_admin_formset.opts.verbose_name_plural|capfirst }}</h2>
+    {% endif %}
+    {{ inline_admin_formset.formset.management_form }}
+    {{ inline_admin_formset.formset.non_form_errors }}
 
-{% for inline_admin_form in inline_admin_formset %}<div class="inline-related{% if inline_admin_form.original or inline_admin_form.show_url %} has_original{% endif %}{% if forloop.last and inline_admin_formset.has_add_permission %} empty-form last-related{% endif %}" id="{{ inline_admin_formset.formset.prefix }}-{% if not forloop.last %}{{ forloop.counter0 }}{% else %}empty{% endif %}">
-  <h3><b>{{ inline_admin_formset.opts.verbose_name|capfirst }}:</b> <span class="inline_label">{% if inline_admin_form.original %}{{ inline_admin_form.original }}{% if inline_admin_form.model_admin.show_change_link and inline_admin_form.model_admin.has_registered_model %} <a href="{% url inline_admin_form.model_admin.opts|admin_urlname:'change' inline_admin_form.original.pk|admin_urlquote %}" class="{% if inline_admin_formset.has_change_permission %}inlinechangelink{% else %}inlineviewlink{% endif %}">{% if inline_admin_formset.has_change_permission %}{% trans "Change" %}{% else %}{% trans "View" %}{% endif %}</a>{% endif %}
-{% else %}#{{ forloop.counter }}{% endif %}</span>
-      {% if inline_admin_form.show_url %}<a href="{{ inline_admin_form.absolute_url }}">{% trans "View on site" %}</a>{% endif %}
-    {% if inline_admin_formset.formset.can_delete and inline_admin_formset.has_delete_permission and inline_admin_form.original %}<span class="delete">{{ inline_admin_form.deletion_field.field }} {{ inline_admin_form.deletion_field.label_tag }}</span>{% endif %}
-  </h3>
-  {% comment %} OpenWISP customization begin {% endcomment %}
-  {% if inline_admin_formset.formset.help_text %}
-    {% with inline_admin_formset.formset.help_text as help_text %}
-        <div class="ow-help-text">
-            <img src="{{ help_text.image_url|default:'/static/admin/img/icon-alert.svg' }}">
-            <p>{{ help_text.text}}
-            {% if help_text.documentation_url %}
-              {% blocktrans with anchor_open='<a href="'|add:help_text.documentation_url|add:'">'|safe anchor_close='</a>'|safe %}
-                Please refer to the {{ anchor_open }}documentation{{ anchor_close }} for more information.
-              {% endblocktrans %}
-            {% endif %}
-            </p>
-        </div>
-    {% endwith %}
-  {% endif %}
-  {% comment %} OpenWISP customization ends {% endcomment %}
-  {% if inline_admin_form.form.non_field_errors %}{{ inline_admin_form.form.non_field_errors }}{% endif %}
-  {% for fieldset in inline_admin_form %}
-    {% include "admin/includes/fieldset.html" %}
-  {% endfor %}
-  {% if inline_admin_form.needs_explicit_pk_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
-  {% if inline_admin_form.fk_field %}{{ inline_admin_form.fk_field.field }}{% endif %}
-</div>{% endfor %}
-</fieldset>
+    {% for inline_admin_form in inline_admin_formset %}<div class="inline-related{% if inline_admin_form.original or inline_admin_form.show_url %} has_original{% endif %}{% if forloop.last and inline_admin_formset.has_add_permission %} empty-form last-related{% endif %}" id="{{ inline_admin_formset.formset.prefix }}-{% if not forloop.last %}{{ forloop.counter0 }}{% else %}empty{% endif %}">
+      <h3><b>{{ inline_admin_formset.opts.verbose_name|capfirst }}:</b> <span class="inline_label">{% if inline_admin_form.original %}{{ inline_admin_form.original }}{% if inline_admin_form.model_admin.show_change_link and inline_admin_form.model_admin.has_registered_model %} <a href="{% url inline_admin_form.model_admin.opts|admin_urlname:'change' inline_admin_form.original.pk|admin_urlquote %}" class="{% if inline_admin_formset.has_change_permission %}inlinechangelink{% else %}inlineviewlink{% endif %}">{% if inline_admin_formset.has_change_permission %}{% trans "Change" %}{% else %}{% trans "View" %}{% endif %}</a>{% endif %}
+      {% else %}#{{ forloop.counter }}{% endif %}</span>
+        {% if inline_admin_form.show_url %}<a href="{{ inline_admin_form.absolute_url }}">{% trans "View on site" %}</a>{% endif %}
+        {% if inline_admin_formset.formset.can_delete and inline_admin_formset.has_delete_permission and inline_admin_form.original %}<span class="delete">{{ inline_admin_form.deletion_field.field }} {{ inline_admin_form.deletion_field.label_tag }}</span>{% endif %}
+      </h3>
+      {% comment %} OpenWISP customization begin {% endcomment %}
+      {% if inline_admin_formset.formset.help_text %}
+        {% with inline_admin_formset.formset.help_text as help_text %}
+          {% with help_text.image_url|default:'/admin/img/icon-alert.svg' as icon_url %}
+            <div class="ow-help-text">
+              <img src="{% static icon_url %}">
+              <p>{{ help_text.text }}
+                {% if help_text.documentation_url %}
+                  {% blocktrans with anchor_open='<a href="'|add:help_text.documentation_url|add:'">'|safe anchor_close='</a>'|safe %}
+                    Please refer to the {{ anchor_open }}documentation{{ anchor_close }} for more information.
+                  {% endblocktrans %}
+                {% endif %}
+              </p>
+            </div>
+          {% endwith %}
+        {% endwith %}
+      {% endif %}
+      {% comment %} OpenWISP customization ends {% endcomment %}
+      {% if inline_admin_form.form.non_field_errors %}{{ inline_admin_form.form.non_field_errors }}{% endif %}
+      {% for fieldset in inline_admin_form %}
+        {% include "admin/includes/fieldset.html" %}
+      {% endfor %}
+      {% if inline_admin_form.needs_explicit_pk_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
+      {% if inline_admin_form.fk_field %}{{ inline_admin_form.fk_field.field }}{% endif %}
+    </div>{% endfor %}
+  </fieldset>
 </div>


Test patch:
diff --git a/tests/test_project/tests/test_admin.py b/tests/test_project/tests/test_admin.py
index 71622446..cee56bbb 100644
--- a/tests/test_project/tests/test_admin.py
+++ b/tests/test_project/tests/test_admin.py
@@ -237,6 +237,10 @@ def test_stacked_inline_help_text(self):
             response, 'Only added operators will have permission to access the project.'
         )
         self.assertContains(response, 'https://github.com/openwisp/openwisp-utils/')
+        # Response should contain static in 'icon_url'
+        self.assertContains(
+            response, '<img src="/static/admin/img/icon-alert.svg">', html=True
+        )
 
     def test_admin_theme_css_setting(self):
         # test for improper configuration : not a list