From 966f82b922d9b77904e072774b63eecc3a2b9b6c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Thu, 6 Jan 2022 16:22:45 +0100
Subject: [PATCH 3/3] wcs: adapt card display with new schema (#58800)

---
 combo/apps/wcs/models.py                     |   3 +
 combo/apps/wcs/templates/combo/wcs/card.html |  31 ++--
 tests/test_wcs.py                            | 152 +++++++++++++++++--
 3 files changed, 158 insertions(+), 28 deletions(-)

diff --git a/combo/apps/wcs/models.py b/combo/apps/wcs/models.py
index d4de946e..ba9a5252 100644
--- a/combo/apps/wcs/models.py
+++ b/combo/apps/wcs/models.py
@@ -1013,6 +1013,9 @@ class WcsCardInfosCell(CardMixin, CellBase):
     def get_cell_extra_context(self, context):
         extra_context = super().get_cell_extra_context(context)
         extra_context['schema'] = self.cached_json
+        extra_context['fields_by_varnames'] = {
+            i['varname']: i for i in (self.cached_json.get('fields') or []) if i.get('varname')
+        }
         # default value used if card is not found
         if self.title_type in ['auto', 'manual']:
             extra_context['title'] = self.cached_title
diff --git a/combo/apps/wcs/templates/combo/wcs/card.html b/combo/apps/wcs/templates/combo/wcs/card.html
index e3743115..f44429b1 100644
--- a/combo/apps/wcs/templates/combo/wcs/card.html
+++ b/combo/apps/wcs/templates/combo/wcs/card.html
@@ -12,8 +12,9 @@
 <div class="cell--body">
 {% spaceless %}
 {% if cell.custom_schema %}
-  <div class="{{ cell.custom_schema.grid_class }}">
-    {% for item in cell.custom_schema.cells %}
+  {% with cell.get_custom_schema as custom_schema %}
+  <div class="{{ custom_schema.grid_class }}">
+    {% for item in custom_schema.cells %}
       <div class="{{ item.cell_size|default:"" }}">
         {% if item.varname == "@custom@" and item.template %}
           {% with card.custom_fields|get:item.template|force_escape as value %}
@@ -21,30 +22,34 @@
           <h3>{{ value }}</h3>
           {% elif item.display_mode == "label" %}
             <p class="label">{{ value }}</p>
-          {% elif item.display_mode == "value" %}
+          {% elif item.display_mode == "text" %}
             <div class="value">{{ value }}</div>
           {% endif %}
           {% endwith %}
         {% else %}
-        {% for field in schema.fields %}
-          {% if field.varname == item.varname %}
+          {% with fields_by_varnames|get:item.varname as field %}
           {% with card.fields|get:item.varname as value %}
             {% if item.display_mode == "title" %}
+              {% if item.field_content == "label" %}
+              <h3>{{ field.label }}</h3>
+              {% elif item.field_content == "value" %}
               <h3>{% include "combo/wcs/card-field-value.html" with mode="inline" %}</h3>
-            {% endif %}
-            {% if item.display_mode == "label" or item.display_mode == "label-and-value" %}
-              <p class="label">{{ field.label }}</p>
-            {% endif %}
-            {% if item.display_mode == "value" or item.display_mode == "label-and-value" %}
-              {% include "combo/wcs/card-field-value.html" %}
+              {% endif %}
+            {% elif item.display_mode == "text" %}
+              {% if item.field_content == "label" or item.field_content == "label-and-value" %}
+                <p class="label">{{ field.label }}</p>
+              {% endif %}
+              {% if item.field_content == "value" or item.field_content == "label-and-value" %}
+                {% include "combo/wcs/card-field-value.html" %}
+              {% endif %}
             {% endif %}
           {% endwith %}
-          {% endif %}
-        {% endfor%}
+          {% endwith %}
         {% endif %}
       </div>
     {% endfor%}
   </div>
+  {% endwith %}
 
 {% else %}
 {% for field in schema.fields %}
diff --git a/tests/test_wcs.py b/tests/test_wcs.py
index 7f058c15..199e4ba7 100644
--- a/tests/test_wcs.py
+++ b/tests/test_wcs.py
@@ -2071,16 +2071,15 @@ def test_card_cell_render_string_with_url_field(mock_send, context):
 
 
 @mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
-def test_card_cell_render_custom_schema(mock_send, context, app):
+def test_card_cell_render_custom_schema_card_field(mock_send, context):
     page = Page.objects.create(title='xxx', template_name='standard')
-    cell = WcsCardInfosCell(page=page, placeholder='content', order=0)
-    cell.carddef_reference = 'default:card_model_1'
-    cell.custom_schema = {
-        'cells': [
-            {'varname': 'fielda', 'display_mode': 'title'},
-        ]
-    }
-    cell.save()
+    cell = WcsCardInfosCell.objects.create(
+        page=page,
+        placeholder='content',
+        order=0,
+        carddef_reference='default:card_model_1',
+        custom_schema={'cells': [{'varname': 'fielda', 'field_content': 'value', 'display_mode': 'title'}]},
+    )
 
     context['card_model_1_id'] = 11
     request = RequestFactory().get('/')
@@ -2091,13 +2090,136 @@ def test_card_cell_render_custom_schema(mock_send, context, app):
     result = cell.render(context)
     assert PyQuery(result).find('h3').text() == 'a'
 
-    # custom field
-    cell.custom_schema = {
-        'cells': [
-            {'varname': '@custom@', 'template': '<b>Foo</b> bar baz', 'display_mode': 'title'},
-        ]
+    cell.custom_schema['cells'][0] = {'varname': 'fielda', 'field_content': 'label', 'display_mode': 'title'}
+    cell.save()
+    result = cell.render(context)
+    assert PyQuery(result).find('h3').text() == 'Field A'
+
+    cell.custom_schema['cells'][0] = {'varname': 'fielda', 'field_content': 'label', 'display_mode': 'text'}
+    cell.save()
+    result = cell.render(context)
+    assert PyQuery(result).find('p.label').text() == 'Field A'
+
+    cell.custom_schema['cells'][0] = {'varname': 'fielda', 'field_content': 'value', 'display_mode': 'text'}
+    cell.save()
+    result = cell.render(context)
+    assert PyQuery(result).find('span.value').text() == 'a'
+
+    cell.custom_schema['cells'][0] = {
+        'varname': 'fielda',
+        'field_content': 'label-and-value',
+        'display_mode': 'text',
+    }
+    cell.save()
+    result = cell.render(context)
+    assert PyQuery(result).find('p.label').text() == 'Field A'
+    assert PyQuery(result).find('span.value').text() == 'a'
+
+    cell.custom_schema['cells'][0] = {
+        'varname': 'fieldb',
+        'field_content': 'label-and-value',
+        'display_mode': 'text',
+    }
+    cell.save()
+    result = cell.render(context)
+    assert PyQuery(result).find('p.label').text() == 'Field B'
+    assert PyQuery(result).find('span.value').text() == 'yes'
+
+    cell.custom_schema['cells'][0] = {
+        'varname': 'fieldc',
+        'field_content': 'label-and-value',
+        'display_mode': 'text',
+    }
+    cell.save()
+    result = cell.render(context)
+    assert PyQuery(result).find('p.label').text() == 'Field C'
+    assert PyQuery(result).find('span.value').text() == 'Sept. 28, 2020'
+
+    cell.custom_schema['cells'][0] = {
+        'varname': 'related',
+        'field_content': 'label-and-value',
+        'display_mode': 'text',
     }
     cell.save()
+    result = cell.render(context)
+    assert PyQuery(result).find('p.label').text() == 'Related'
+    assert PyQuery(result).find('span.value').text() == 'Foo Bar'
+
+    cell.custom_schema['cells'][0] = {
+        'varname': 'fieldd',
+        'field_content': 'label-and-value',
+        'display_mode': 'text',
+    }
+    cell.save()
+    result = cell.render(context)
+    assert PyQuery(result).find('p.label').text() == 'Field D'
+    assert PyQuery(result).find('span.value').text() == 'file.pdf'
+
+    cell.custom_schema['cells'][0] = {
+        'varname': 'fielde',
+        'field_content': 'label-and-value',
+        'display_mode': 'text',
+    }
+    cell.save()
+    result = cell.render(context)
+    assert PyQuery(result).find('p.label').text() == 'Field E'
+    assert PyQuery(result).find('div.value p:first-child').text().strip() == 'lorem<strong>ipsum'
+    assert PyQuery(result).find('div.value p:last-child').text().strip() == 'hello world'
+
+    cell.custom_schema['cells'][0] = {
+        'varname': 'fieldf',
+        'field_content': 'label-and-value',
+        'display_mode': 'text',
+    }
+    cell.save()
+    result = cell.render(context)
+    assert PyQuery(result).find('p.label').text() == 'Field F'
+    assert PyQuery(result).find('div.value pre').text() == 'lorem<strong>ipsum hello world'
+
+    cell.custom_schema['cells'][0] = {
+        'varname': 'fieldg',
+        'field_content': 'label-and-value',
+        'display_mode': 'text',
+    }
+    cell.save()
+    result = cell.render(context)
+    assert PyQuery(result).find('p.label').text() == 'Field G'
+    assert PyQuery(result).find('span.value a').text() == 'test@localhost'
+    assert PyQuery(result).find('span.value a').attr['href'] == 'mailto:test@localhost'
+
+    cell.custom_schema['cells'][0] = {
+        'varname': 'fieldh',
+        'field_content': 'label-and-value',
+        'display_mode': 'text',
+    }
+    cell.save()
+    result = cell.render(context)
+    assert PyQuery(result).find('p.label').text() == 'Field H'
+    assert PyQuery(result).find('span.value a').text() == 'https://www.example.net/'
+    assert PyQuery(result).find('span.value a').attr['href'] == 'https://www.example.net/'
+
+
+@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
+def test_card_cell_render_custom_schema_custom_entry(mock_send, context, app):
+    page = Page.objects.create(title='xxx', template_name='standard')
+    cell = WcsCardInfosCell.objects.create(
+        page=page,
+        placeholder='content',
+        order=0,
+        carddef_reference='default:card_model_1',
+        custom_schema={
+            'cells': [
+                {'varname': '@custom@', 'template': '<b>Foo</b> bar baz', 'display_mode': 'title'},
+            ]
+        },
+    )
+
+    context['card_model_1_id'] = 11
+    request = RequestFactory().get('/')
+    cell.modify_global_context(context, request)
+    cell.repeat_index = 0
+    context['synchronous'] = True  # to get fresh content
+
     result = cell.render(context)
     assert '&lt;b&gt;Foo&lt;/b&gt;' in result
     assert PyQuery(result).find('h3').text() == '<b>Foo</b> bar baz'
@@ -2117,7 +2239,7 @@ def test_card_cell_render_custom_schema(mock_send, context, app):
             {
                 'varname': '@custom@',
                 'template': '{{ card.fields.related|split:" "|join:"," }}',
-                'display_mode': 'value',
+                'display_mode': 'text',
             },
         ]
     }
-- 
2.34.1

