Projet

Général

Profil

0001-wcs-card-cell-multiple-card-identifiers-58862.patch

Lauréline Guérin, 23 novembre 2021 16:58

Télécharger (16,8 ko)

Voir les différences:

Subject: [PATCH] wcs: card cell & multiple card identifiers (#58862)

 combo/apps/wcs/forms.py                    |   2 +-
 combo/apps/wcs/migrations/0043_card_ids.py |  21 +++
 combo/apps/wcs/models.py                   |  39 ++++--
 combo/data/models.py                       |   3 +-
 combo/public/templatetags/combo.py         |   4 +-
 tests/test_wcs.py                          | 154 ++++++++++++++++-----
 6 files changed, 175 insertions(+), 48 deletions(-)
 create mode 100644 combo/apps/wcs/migrations/0043_card_ids.py
combo/apps/wcs/forms.py
71 71

  
72 72
    class Meta:
73 73
        model = WcsCardInfosCell
74
        fields = ('carddef_reference', 'title_type', 'custom_title', 'card_id', 'custom_schema')
74
        fields = ('carddef_reference', 'title_type', 'custom_title', 'card_ids', 'custom_schema')
75 75
        widgets = {
76 76
            'custom_schema': forms.HiddenInput(),
77 77
        }
combo/apps/wcs/migrations/0043_card_ids.py
1
from django.db import migrations, models
2

  
3

  
4
class Migration(migrations.Migration):
5

  
6
    dependencies = [
7
        ('wcs', '0042_current_forms_custom_title'),
8
    ]
9

  
10
    operations = [
11
        migrations.RenameField(
12
            model_name='wcscardinfoscell',
13
            old_name='card_id',
14
            new_name='card_ids',
15
        ),
16
        migrations.AlterField(
17
            model_name='wcscardinfoscell',
18
            name='card_ids',
19
            field=models.CharField(blank=True, max_length=1000, verbose_name='Card Identifiers'),
20
        ),
21
    ]
combo/apps/wcs/models.py
24 24
from django.db import models
25 25
from django.forms import Select
26 26
from django.forms import models as model_forms
27
from django.template import Context, Template, TemplateSyntaxError, VariableDoesNotExist
27
from django.template import Context, RequestContext, Template, TemplateSyntaxError, VariableDoesNotExist
28 28
from django.utils.safestring import mark_safe
29 29
from django.utils.text import slugify
30 30
from django.utils.translation import ugettext_lazy as _
......
899 899
@register_cell_class
900 900
class WcsCardInfosCell(CardMixin, CellBase):
901 901
    carddef_reference = models.CharField(_('Card Model'), max_length=150)
902
    card_id = models.CharField(_('Card Identifier'), max_length=1000, blank=True)
902
    card_ids = models.CharField(_('Card Identifiers'), max_length=1000, blank=True)
903 903
    without_user = models.BooleanField(_('Ignore the logged-in user'), default=False)
904 904
    custom_schema = JSONField(blank=True, default=dict)
905 905

  
......
961 961

  
962 962
        populate_cache()
963 963

  
964
    def get_card_id(self, context):
965
        if self.card_id:
964
    @property
965
    def global_context_key(self):
966
        return '%s-card-ids' % self.get_reference()
967

  
968
    def modify_global_context(self, context, request):
969
        if self.global_context_key not in context:
970
            card_ids = self.get_card_ids(context, request)
971
            context[self.global_context_key] = card_ids
972

  
973
    def get_repeat_template(self, context):
974
        return len(context[self.global_context_key])
975

  
976
    def get_card_ids(self, original_context, request):
977
        if self.card_ids:
966 978
            try:
967
                return Template(self.card_id).render(Context(context))
979
                context = RequestContext(request)
980
                context.push(original_context)
981
                ids = Template(self.card_ids).render(context).split(',')
982
                return [i.strip() for i in ids if i.strip()]
968 983
            except (VariableDoesNotExist, TemplateSyntaxError):
969
                return None
984
                return []
970 985

  
971 986
        card_slug = self.carddef_reference.split(':')[1]
972 987
        card_id = '%s_id' % card_slug
973
        return context.get(card_id) or None
988
        if original_context.get(card_id):
989
            return [original_context[card_id]]
990
        return []
991

  
992
    def get_card_id(self, context):
993
        repeat_index = getattr(self, 'repeat_index', context.get('repeat_index'))
994
        if repeat_index is not None:
995
            return context[self.global_context_key][repeat_index]
996
        return None
974 997

  
975 998
    def get_extra_manager_context(self):
976 999
        extra_context = super().get_extra_manager_context()
......
992 1015

  
993 1016
        card_id = self.get_card_id(context)
994 1017
        if not card_id:
995
            if self.card_id:  # template defined, but result is empty or None
1018
            if self.card_ids:  # template defined, but result is empty or None
996 1019
                extra_context['card_not_found'] = True
997 1020
            return extra_context
998 1021
        card_slug = self.carddef_reference.split(':')[1]
combo/data/models.py
2104 2104
    def make_global(self):
2105 2105
        return settings.JSON_CELL_TYPES[self.key].get('make_global', False)
2106 2106

  
2107
    @property
2108
    def repeat(self):
2107
    def get_repeat_template(self, context):
2109 2108
        return settings.JSON_CELL_TYPES[self.key].get('repeat')
2110 2109

  
2111 2110
    @property
combo/public/templatetags/combo.py
108 108
        context['skeleton'] = ''
109 109

  
110 110
    if not context.get('placeholder_search_mode'):
111
        for cell in [x for x in context['cells'] if hasattr(x, 'repeat')]:
112
            repeat_template = cell.repeat
111
        for cell in [x for x in context['cells'] if hasattr(x, 'get_repeat_template')]:
112
            repeat_template = cell.get_repeat_template(context)
113 113
            if not repeat_template:
114 114
                continue
115 115

  
tests/test_wcs.py
21 21
from combo.apps.search.engines import engines
22 22
from combo.apps.search.models import SearchCell
23 23
from combo.apps.search.utils import index_site, search_site
24
from combo.apps.wcs.context_processors import Cards
25 24
from combo.apps.wcs.models import (
26 25
    BackofficeSubmissionCell,
27 26
    CategoriesCell,
......
1616 1615
    cell.carddef_reference = 'default:card_model_1'
1617 1616
    cell.save()
1618 1617

  
1619
    context['card_model_1_id'] = 11
1620 1618
    context['synchronous'] = True  # to get fresh content
1621 1619

  
1622 1620
    assert context['request'].user is None
......
1828 1826
    assert '<p>Unknown Card</p>' in result
1829 1827

  
1830 1828
    context['card_model_1_id'] = 11
1829
    request = RequestFactory().get('/')
1830
    cell.modify_global_context(context, request)
1831
    cell.repeat_index = 0
1831 1832

  
1832 1833
    # query should fail as nothing is cached
1833 1834
    cache.clear()
......
1897 1898
    cell.save()
1898 1899

  
1899 1900
    context['card_model_1_id'] = 11
1901
    request = RequestFactory().get('/')
1902
    cell.modify_global_context(context, request)
1903
    cell.repeat_index = 0
1900 1904
    context['synchronous'] = True  # to get fresh content
1901 1905

  
1902 1906
    result = cell.render(context)
......
1927 1931
    cell.save()
1928 1932

  
1929 1933
    context['card_model_1_id'] = 11
1934
    request = RequestFactory().get('/')
1935
    cell.modify_global_context(context, request)
1936
    cell.repeat_index = 0
1930 1937
    context['synchronous'] = True  # to get fresh content
1931 1938

  
1932 1939
    result = cell.render(context)
......
1952 1959
    cell.save()
1953 1960

  
1954 1961
    context['card_model_1_id'] = 11
1962
    request = RequestFactory().get('/')
1963
    cell.modify_global_context(context, request)
1964
    cell.repeat_index = 0
1955 1965
    context['synchronous'] = True  # to get fresh content
1956 1966

  
1957 1967
    result = cell.render(context)
......
1994 2004

  
1995 2005

  
1996 2006
@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
1997
def test_card_cell_render_identifier(mock_send, context, nocache):
1998
    page = Page.objects.create(title='xxx', template_name='standard')
2007
def test_card_cell_render_identifier(mock_send, nocache, app):
2008
    page = Page.objects.create(
2009
        title='xxx', slug='foo', template_name='standard', sub_slug='(?P<card_model_1_id>[a-z0-9]+)'
2010
    )
1999 2011
    cell = WcsCardInfosCell(page=page, placeholder='content', order=0)
2000 2012
    cell.carddef_reference = 'default:card_model_1'
2001 2013
    cell.save()
2002 2014

  
2003
    context['card_model_1_id'] = 11
2004
    context['synchronous'] = True  # to get fresh content
2015
    cell_url = reverse(
2016
        'combo-public-ajax-page-cell',
2017
        kwargs={'page_pk': page.pk, 'cell_reference': cell.get_reference()},
2018
    )
2005 2019

  
2006 2020
    # check url called
2007 2021
    mock_send.reset_mock()
2008
    result = cell.render(context)
2022
    resp = app.get(page.get_online_url() + '11/')
2023
    assert len(resp.context['cells']) == 1
2024
    assert resp.context['cells'][0].pk == cell.pk
2025
    assert resp.context['cells'][0].repeat_index == 0
2026
    extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
2027
    cell_resp = app.get(cell_url + '?ctx=' + extra_ctx[0])
2028
    assert cell_resp.context['repeat_index'] == 0
2029
    assert 'Card Model 1' in cell_resp
2030
    assert '<p>Unknown Card</p>' not in cell_resp
2031
    assert len(mock_send.call_args_list) == 1
2009 2032
    assert '/api/cards/card_model_1/11/' in mock_send.call_args_list[0][0][0].url
2010
    assert 'Card Model 1' in result
2011
    assert '<p>Unknown Card</p>' not in result
2012 2033

  
2013
    # with identifier
2014
    cell.card_id = '42'
2034
    # with identifiers
2035
    page.sub_slug = ''
2036
    page.save()
2037
    cell.card_ids = '42'
2015 2038
    cell.save()
2016 2039
    mock_send.reset_mock()
2017
    result = cell.render(context)
2040
    resp = app.get(page.get_online_url())
2041
    assert len(resp.context['cells']) == 1
2042
    assert resp.context['cells'][0].pk == cell.pk
2043
    assert resp.context['cells'][0].repeat_index == 0
2044
    extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
2045
    cell_resp = app.get(cell_url + '?ctx=' + extra_ctx[0])
2046
    assert cell_resp.context['repeat_index'] == 0
2047
    assert 'Card Model 1' in cell_resp
2048
    assert '<p>Unknown Card</p>' in cell_resp
2049
    assert len(mock_send.call_args_list) == 1
2018 2050
    assert '/api/cards/card_model_1/42/' in mock_send.call_args_list[0][0][0].url
2019
    assert 'Card Model 1' in result
2020
    assert '<p>Unknown Card</p>' in result
2021 2051

  
2022
    context['cards'] = Cards()
2023
    cell.card_id = '{% cards|objects:"card_model_1"|last|get:"id" %}'  # syntax error
2052
    cell.card_ids = '42, , 35'
2024 2053
    cell.save()
2025 2054
    mock_send.reset_mock()
2026
    result = cell.render(context)
2027
    assert mock_send.call_args_list == []
2028
    assert result.replace('\n', '') == ''  # empty-cell
2055
    resp = app.get(page.get_online_url())
2056
    assert len(resp.context['cells']) == 2
2057
    extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
2058
    for i in range(0, 2):
2059
        assert resp.context['cells'][i].pk == cell.pk
2060
        assert resp.context['cells'][i].repeat_index == i
2061
        cell_resp = app.get(cell_url + '?ctx=' + extra_ctx[i])
2062
        assert cell_resp.context['repeat_index'] == i
2063
        assert 'Card Model 1' in cell_resp
2064
        assert '<p>Unknown Card</p>' in cell_resp
2065
    assert len(mock_send.call_args_list) == 2
2066
    assert '/api/cards/card_model_1/42/' in mock_send.call_args_list[0][0][0].url
2067
    assert '/api/cards/card_model_1/35/' in mock_send.call_args_list[1][0][0].url
2029 2068

  
2030
    del context['card_not_found']
2031
    cell.card_id = '{{ cards|objects:"card_model_1"|last|get:"id" }}'
2069
    cell.card_ids = '{% cards|objects:"card_model_1"|last|get:"id" %}'  # syntax error
2032 2070
    cell.save()
2033 2071
    mock_send.reset_mock()
2034
    result = cell.render(context)
2035
    assert '/api/cards/card_model_1/list' in mock_send.call_args_list[0][0][0].url
2036
    assert '/api/cards/card_model_1/13/' in mock_send.call_args_list[1][0][0].url
2037
    assert 'Card Model 1' in result
2038
    assert '<p>Unknown Card</p>' in result
2072
    resp = app.get(page.get_online_url())
2073
    assert len(resp.context['cells']) == 1
2074
    extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
2075
    cell_resp = app.get(cell_url + '?ctx=' + extra_ctx[0])
2076
    assert cell_resp.text.replace('\n', '') == ''  # empty-cell
2039 2077

  
2040
    # with a card_id template, but result is empty
2041
    del context['card_model_1_id']
2042
    cell.card_id = '{{ foo }}'
2078
    cell.card_ids = '{{ cards|objects:"card_model_1"|last|get:"id" }}'
2043 2079
    cell.save()
2044
    assert cell.get_card_id(context) == ''
2045 2080
    mock_send.reset_mock()
2046
    result = cell.render(context)
2047
    assert mock_send.call_args_list == []
2048
    assert result.replace('\n', '') == ''  # empty-cell
2081
    resp = app.get(page.get_online_url())
2082
    assert len(resp.context['cells']) == 1
2083
    assert resp.context['cells'][0].pk == cell.pk
2084
    assert resp.context['cells'][0].repeat_index == 0
2085
    extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
2086
    cell_resp = app.get(cell_url + '?ctx=' + extra_ctx[0])
2087
    assert cell_resp.context['repeat_index'] == 0
2088
    assert len(mock_send.call_args_list) == 3
2089
    # page rendering
2090
    assert '/api/cards/card_model_1/list' in mock_send.call_args_list[0][0][0].url
2091
    # cell rendering
2092
    assert '/api/cards/card_model_1/list' in mock_send.call_args_list[1][0][0].url
2093
    assert '/api/cards/card_model_1/13/' in mock_send.call_args_list[2][0][0].url
2094

  
2095
    for card_ids in [
2096
        '{% for card in cards|objects:"card_model_1" %}{{ card.id }},{% endfor %}',
2097
        '{{ cards|objects:"card_model_1"|getlist:"id"|join:"," }}',
2098
    ]:
2099
        cell.card_ids = card_ids
2100
        cell.save()
2101
        mock_send.reset_mock()
2102
        resp = app.get(page.get_online_url())
2103
        assert len(resp.context['cells']) == 3
2104
        extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
2105
        for i in range(0, 3):
2106
            assert resp.context['cells'][i].pk == cell.pk
2107
            assert resp.context['cells'][i].repeat_index == i
2108
            cell_resp = app.get(cell_url + '?ctx=' + extra_ctx[i])
2109
            assert cell_resp.context['repeat_index'] == i
2110
        assert len(mock_send.call_args_list) == 7
2111
        # page rendering
2112
        assert '/api/cards/card_model_1/list' in mock_send.call_args_list[0][0][0].url
2113
        # cell rendering
2114
        for i in range(0, 3):
2115
            assert '/api/cards/card_model_1/list' in mock_send.call_args_list[i * 2 + 1][0][0].url
2116
            assert (
2117
                '/api/cards/card_model_1/%s/' % WCS_CARDS_DATA[i]['id']
2118
                in mock_send.call_args_list[i * 2 + 2][0][0].url
2119
            )
2120

  
2121
    # with a card_ids template, but result is empty
2122
    cell.card_ids = '{{ foo }}'
2123
    cell.save()
2124
    resp = app.get(page.get_online_url())
2125
    assert len(resp.context['cells']) == 1
2126
    extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
2127
    cell_resp = app.get(cell_url + '?ctx=' + extra_ctx[0])
2128
    assert cell_resp.text.replace('\n', '') == ''  # empty-cell
2049 2129

  
2050 2130

  
2051 2131
@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
......
2056 2136
    cell.save()
2057 2137

  
2058 2138
    context['card_model_1_id'] = 11
2139
    request = RequestFactory().get('/')
2140
    cell.modify_global_context(context, request)
2141
    cell.repeat_index = 0
2059 2142
    context['synchronous'] = True  # to get fresh content
2060 2143

  
2061 2144
    assert context['request'].user is None
......
2679 2762
    page.save()
2680 2763
    cell = WcsCardInfosCell(page=page, placeholder='content', order=0)
2681 2764
    cell.carddef_reference = 'default:card_model_1'
2682
    cell.card_id = '11'
2765
    cell.card_ids = '11'
2683 2766
    cell.save()
2684 2767
    resp = app.get('/one/')
2685 2768
    ajax_cell_url = PyQuery(resp.text).find('[data-ajax-cell-url]').attr['data-ajax-cell-url']
2686
    resp = app.get(ajax_cell_url)
2769
    extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
2770
    resp = app.get(ajax_cell_url + '?ctx=' + extra_ctx[0])
2687 2771
    file_url = PyQuery(resp.text).find('[download]').attr['href']
2688 2772
    resp = app.get(file_url)
2689 2773
    assert 'download?f=42' in resp.location
2690
-