Repository: wagtail/wagtail

Issue:
Tests fail if sendfile is not installed
Now that `django-sendfile` has been removed from the dependencies (#1363), bringing up a fresh Wagtail environment (using https://github.com/gasman/vagrant-wagtail-develop) and running `./runtests.py` immediately fails. This is because wagtail/tests/settings.py still includes `sendfile` in `INSTALLED_APPS`. With this commented out, the tests run, but the `test_sendfile_*_backend` tests fail with an ImportError.

Either `django-sendfile` needs to be added to requirements-dev.txt, or (preferably) the tests set up to be skipped if it's not installed.



Discussion:
That is odd. I ran all the test locally before merging #1363. Will spin up a new environment with latest master.

Can confirm the above. Cleared the wrong venv and had django-sendfile still installed, which is why the tests worked fine.

PR: #1377


Resolving patch:
diff --git a/wagtail/wagtailadmin/edit_handlers.py b/wagtail/wagtailadmin/edit_handlers.py
--- a/wagtail/wagtailadmin/edit_handlers.py
+++ b/wagtail/wagtailadmin/edit_handlers.py
@@ -235,6 +235,14 @@ def field_type(self):
         """
         return ""
 
+    def id_for_label(self):
+        """
+        The ID to be used as the 'for' attribute of any <label> elements that refer
+        to this object but are rendered outside of it. Leave blank if this object does not render
+        as a single input field.
+        """
+        return ""
+
     def render_as_object(self):
         """
         Render this object as it should appear within an ObjectList. Should not
@@ -438,19 +446,21 @@ def classes(self):
             classes.append("error")
 
         classes.append(self.field_type())
-        classes.append("single-field")
 
         return classes
 
     def field_type(self):
         return camelcase_to_underscore(self.bound_field.field.__class__.__name__)
 
+    def id_for_label(self):
+        return self.bound_field.id_for_label
+
     object_template = "wagtailadmin/edit_handlers/single_field_panel.html"
 
     def render_as_object(self):
         return mark_safe(render_to_string(self.object_template, {
             'self': self,
-            'field_content': self.render_as_field(),
+            'field': self.bound_field,
         }))
 
     field_template = "wagtailadmin/edit_handlers/field_panel_field.html"
@@ -728,13 +738,6 @@ def classes(self):
         classes = super(BaseStreamFieldPanel, self).classes()
         classes.append("stream-field")
 
-        # BaseFieldPanel is essentially for single fields, which are rendered on the front end
-        # with the assumption that the label (singular) will always be promoted to the full-width
-        # divider bar thing.
-        # This results in all the other labels being promoted similarly, so it's better not to
-        # treat this as a single field, and remove the "single-field" class.
-        classes.remove("single-field")
-
         # In case of a validation error, BlockWidget will take care of outputting the error on the
         # relevant sub-block, so we don't want the stream block as a whole to be wrapped in an 'error' class.
         if 'error' in classes:
@@ -746,6 +749,12 @@ def classes(self):
     def html_declarations(cls):
         return cls.block_def.all_html_declarations()
 
+    def id_for_label(self):
+        # a StreamField may consist of many input fields, so it's not meaningful to
+        # attach the label to any specific one
+        return ""
+
+
 class StreamFieldPanel(object):
     def __init__(self, field_name):
         self.field_name = field_name


Test patch:
diff --git a/wagtail/wagtailadmin/tests/test_edit_handlers.py b/wagtail/wagtailadmin/tests/test_edit_handlers.py
--- a/wagtail/wagtailadmin/tests/test_edit_handlers.py
+++ b/wagtail/wagtailadmin/tests/test_edit_handlers.py
@@ -247,8 +247,11 @@ def test_render(self):
         # result should contain ObjectList furniture
         self.assertIn('<ul class="objects">', result)
 
-        # result should contain h2 headings for children
-        self.assertIn('<h2>Start date</h2>', result)
+        # result should contain h2 headings (including labels) for children
+        self.assertInHTML('<h2><label for="id_date_from">Start date</label></h2>', result)
+
+        # result should include help text for children
+        self.assertIn('<div class="object-help help">Not required if event is on a single day</div>', result)
 
         # result should contain rendered content from descendants
         self.assertIn('Abergavenny sheepdog trials</textarea>', result)
@@ -278,12 +281,13 @@ def test_render_as_object(self):
         )
         result = field_panel.render_as_object()
 
-        # check that label appears in the 'object' wrapper as well as the field
+        # check that label appears as a legend in the 'object' wrapper,
+        # but not as a field label (that would be provided by ObjectList instead)
         self.assertIn('<legend>End date</legend>', result)
-        self.assertIn('<label for="id_date_to">End date:</label>', result)
+        self.assertNotIn('<label for="id_date_to">End date:</label>', result)
 
-        # check that help text is included
-        self.assertIn('Not required if event is on a single day', result)
+        # check that help text is not included (it's provided by ObjectList instead)
+        self.assertNotIn('Not required if event is on a single day', result)
 
         # check that the populated form field is included
         self.assertIn('value="2014-07-22"', result)