Projet

Général

Profil

0003-wcs-delete-old-card-cell-models-68140.patch

Lauréline Guérin, 29 août 2022 14:39

Télécharger (58,4 ko)

Voir les différences:

Subject: [PATCH 3/5] wcs: delete old card cell models (#68140)

 combo/apps/wcs/__init__.py                    |  11 +-
 combo/apps/wcs/forms.py                       |  37 +-
 .../apps/wcs/migrations/0053_new_card_cell.py |  25 ++
 combo/apps/wcs/models.py                      | 196 +---------
 .../manager/card-cell-form-appearance.html    |  26 ++
 ...splay.html => card-cell-form-display.html} |  14 +-
 .../card-infos-cell-form-appearance.html      |  26 --
 combo/manager/static/js/combo.manager.js      |   4 +-
 tests/test_manager.py                         |   8 +-
 tests/test_search.py                          |   2 +-
 tests/wcs/test_all.py                         | 336 +-----------------
 tests/wcs/test_card.py                        | 102 +++---
 12 files changed, 143 insertions(+), 644 deletions(-)
 create mode 100644 combo/apps/wcs/migrations/0053_new_card_cell.py
 create mode 100644 combo/apps/wcs/templates/combo/wcs/manager/card-cell-form-appearance.html
 rename combo/apps/wcs/templates/combo/wcs/manager/{card-infos-cell-form-display.html => card-cell-form-display.html} (90%)
 delete mode 100644 combo/apps/wcs/templates/combo/wcs/manager/card-infos-cell-form-appearance.html
combo/apps/wcs/__init__.py
128 128
    def update_db_cache(self):
129 129
        from combo.data.models import CellBase
130 130

  
131
        from .models import (
132
            WcsCardInfosCell,
133
            WcsCardsCell,
134
            WcsCategoryCell,
135
            WcsFormCell,
136
            WcsFormsOfCategoryCell,
137
        )
131
        from .models import WcsCardCell, WcsCategoryCell, WcsFormCell, WcsFormsOfCategoryCell
138 132

  
139 133
        models_to_update = [
140 134
            WcsFormCell,
141 135
            WcsCategoryCell,
142 136
            WcsFormsOfCategoryCell,
143
            WcsCardsCell,
144
            WcsCardInfosCell,
137
            WcsCardCell,
145 138
        ]
146 139
        for cell in CellBase.get_cells(cell_filter=lambda x: x in models_to_update):
147 140
            cell.save()
combo/apps/wcs/forms.py
20 20
from combo.utils.forms import MultiSortWidget
21 21

  
22 22
from .models import (
23
    WcsCardInfosCell,
24
    WcsCardsCell,
23
    WcsCardCell,
25 24
    WcsCareFormsCell,
26 25
    WcsCategoryCell,
27 26
    WcsCurrentDraftsCell,
......
49 48
        fields = ('formdef_reference', 'extra_css_class')
50 49

  
51 50

  
52
class WcsCardsCellForm(forms.ModelForm):
53
    with_user = forms.BooleanField(
54
        label=_('Restrict to cards accessible to the user'), required=False, initial=True
55
    )
56

  
57
    class Meta:
58
        model = WcsCardsCell
59
        fields = ('carddef_reference', 'limit', 'only_for_user')
60

  
61
    def __init__(self, *args, **kwargs):
62
        instance = kwargs['instance']
63
        initial = kwargs.pop('initial', {})
64
        initial['with_user'] = not instance.without_user
65
        super().__init__(initial=initial, *args, **kwargs)
66
        card_models = get_wcs_options('/api/cards/@list', include_custom_views=True)
67
        self.fields['carddef_reference'].widget = forms.Select(choices=card_models)
68

  
69
    def save(self, *args, **kwargs):
70
        super().save(*args, **kwargs)
71
        self.instance.without_user = not self.cleaned_data['with_user']
72
        self.instance.save()
73
        return self.instance
74

  
75

  
76
class WcsCardInfoCellForm(forms.ModelForm):
51
class WcsCardCellForm(forms.ModelForm):
77 52
    with_user = forms.BooleanField(
78 53
        label=_('Restrict to cards accessible to the user'), required=False, initial=True
79 54
    )
80 55
    related_card_path = forms.ChoiceField(label=_('Card(s) to display'), required=False)
81 56

  
82 57
    class Meta:
83
        model = WcsCardInfosCell
58
        model = WcsCardCell
84 59
        fields = (
85 60
            'carddef_reference',
86 61
            'related_card_path',
......
132 107
        return cleaned_data
133 108

  
134 109

  
135
class WcsCardInfoCellAppearanceBaseForm(forms.ModelForm):
110
class WcsCardCellAppearanceBaseForm(forms.ModelForm):
136 111
    def save(self, *args, **kwargs):
137 112
        super().save(*args, **kwargs)
138 113
        if self.instance.title_type != 'manual':
......
141 116
        return self.instance
142 117

  
143 118

  
144
class WcsCardInfoCellDisplayForm(forms.ModelForm):
119
class WcsCardCellDisplayForm(forms.ModelForm):
145 120
    customize_display = forms.BooleanField(label=_('Customize display'), required=False)
146 121

  
147 122
    class Meta:
148
        model = WcsCardInfosCell
123
        model = WcsCardCell
149 124
        fields = (
150 125
            'limit',
151 126
            'display_mode',
combo/apps/wcs/migrations/0053_new_card_cell.py
1
from django.db import migrations
2

  
3

  
4
class Migration(migrations.Migration):
5

  
6
    dependencies = [
7
        ('wcs', '0052_new_card_cell'),
8
    ]
9

  
10
    operations = [
11
        migrations.RemoveField(
12
            model_name='wcscardscell',
13
            name='groups',
14
        ),
15
        migrations.RemoveField(
16
            model_name='wcscardscell',
17
            name='page',
18
        ),
19
        migrations.DeleteModel(
20
            name='WcsCardInfosCell',
21
        ),
22
        migrations.DeleteModel(
23
            name='WcsCardsCell',
24
        ),
25
    ]
combo/apps/wcs/models.py
821 821
        return escape(self.custom_title) or self.cached_title or None
822 822

  
823 823

  
824
@register_cell_class
825
class WcsCardsCell(CardMixin, WcsBlurpMixin, CellBase):
826
    carddef_reference = models.CharField(_('Card Model'), max_length=150)
827
    cached_title = models.CharField(_('Title'), max_length=150)
828
    custom_title = models.CharField(_('Custom Title'), max_length=150, blank=True)
829
    only_for_user = models.BooleanField(_('Limit to cards linked to the logged-in user'), default=False)
830
    without_user = models.BooleanField(_('Ignore the logged-in user'), default=False)
831
    limit = models.PositiveSmallIntegerField(
832
        _('Number of cards per page (default 10)'), null=True, blank=True
833
    )
834

  
835
    default_template_name = 'combo/wcs/cards.html'
836
    variable_name = 'card_objects'
837

  
838
    class Meta:
839
        verbose_name = _('Cards')
840

  
841
    def save(self, *args, **kwargs):
842
        super().save(*args, **kwargs)
843

  
844
        if 'update_fields' in kwargs:
845
            # don't populate the cache
846
            return
847

  
848
        def populate_cache():
849
            if self.carddef_reference:
850
                parts = self.carddef_reference.split(':')
851
                wcs_key, card_slug = parts[:2]
852
                wcs_site = get_wcs_services().get(wcs_key)
853
                card_models = get_wcs_json(wcs_site, 'api/cards/@list')
854

  
855
                if not card_models or card_models.get('err') == 1:
856
                    # can not retrieve data, don't report cell as invalid
857
                    self.mark_as_valid()
858
                    return
859

  
860
                card_found = False
861
                for card in card_models.get('data') or []:
862
                    slug = card['slug']
863

  
864
                    if slug != card_slug:
865
                        continue
866

  
867
                    card_title = card['title']
868

  
869
                    if len(parts) > 2:
870
                        custom_view = None
871

  
872
                        for v in card.get('custom_views') or []:
873
                            if v['id'] == parts[2]:
874
                                custom_view = v
875
                                break
876

  
877
                        if custom_view is None:
878
                            continue
879

  
880
                        card_title = '%s - %s' % (card_title, custom_view['text'])
881

  
882
                    self.cached_title = card_title
883
                    self.save(update_fields=['cached_title'])
884
                    card_found = True
885
                    break
886
                if card_found:
887
                    self.mark_as_valid()
888
                    return
889
                else:
890
                    return self.mark_as_invalid('wcs_card_not_found')
891
            else:
892
                return self.mark_as_invalid('wcs_card_not_defined')
893

  
894
        populate_cache()
895

  
896
    def is_visible(self, request, **kwargs):
897
        user = getattr(request, 'user', None)
898
        if self.only_for_user and (not user or user.is_anonymous):
899
            return False
900
        return super().is_visible(request, **kwargs)
901

  
902
    def get_api_url(self, context):
903
        parts = self.carddef_reference.split(':')
904
        url = '/api/cards/%s/list' % parts[1]
905
        if len(parts) > 2:
906
            url = '%s/%s' % (url, parts[2])
907
        user = self.get_concerned_user(context)
908
        if self.only_for_user and user and not user.is_anonymous and user.get_name_id():
909
            url = '%s?filter-user-uuid=%s' % (url, user.get_name_id())
910
        return url
911

  
912
    def get_cell_extra_context(self, context):
913
        extra_context = super().get_cell_extra_context(context)
914
        extra_context['paginate_by'] = self.limit or 10
915
        extra_context['title'] = self.custom_title or self.cached_title
916

  
917
        pages_with_sub_slug = Page.objects.exclude(sub_slug='')
918
        card_id = '%s_id' % self.carddef_reference.split(':')[1]
919
        matching_pages = [
920
            p for p in pages_with_sub_slug if '<%s>' % card_id in p.sub_slug or p.sub_slug == card_id
921
        ]
922
        if matching_pages:
923
            card_page = matching_pages[0]
924
            extra_context['card_page_base_url'] = card_page.get_online_url()
925

  
926
        try:
927
            extra_context['card_objects'] = list(extra_context['card_objects'][self.wcs_site]['data'])
928
        except (KeyError, TypeError):
929
            # an error occured when getting the data
930
            extra_context['card_objects'] = []
931

  
932
        return extra_context
933

  
934
    def get_default_form_class(self):
935
        from .forms import WcsCardsCellForm
936

  
937
        return WcsCardsCellForm
938

  
939
    def render_for_search(self):
940
        return ''
941

  
942

  
943 824
@register_cell_class
944 825
class WcsCardCell(CardMixin, CellBase):
945 826
    carddef_reference = models.CharField(_('Card Model'), max_length=150)
......
977 858
    cached_title = models.CharField(_('Title'), max_length=150)
978 859
    cached_json = JSONField(blank=True, default=dict)
979 860

  
980
    class Meta:
981
        verbose_name = _('Card(s)')
982

  
983

  
984
@register_cell_class
985
class WcsCardInfosCell(CardMixin, CellBase):
986
    carddef_reference = models.CharField(_('Card Model'), max_length=150)
987
    related_card_path = models.CharField(_('Card Identifier'), max_length=1000, blank=True)
988
    card_ids = models.CharField(_('Other Card Identifiers'), max_length=1000, blank=True)
989
    only_for_user = models.BooleanField(_('Limit to cards linked to the logged-in user'), default=False)
990
    without_user = models.BooleanField(_('Ignore the logged-in user'), default=False)
991
    limit = models.PositiveSmallIntegerField(
992
        _('Number of cards per page (default 10)'), null=True, blank=True
993
    )
994
    custom_schema = JSONField(blank=True, default=dict)
995
    display_mode = models.CharField(
996
        _('Display mode'),
997
        max_length=10,
998
        default='card',
999
        choices=[
1000
            ('card', _('Card')),
1001
            ('table', _('Table')),
1002
        ],
1003
    )
1004

  
1005
    title_type = models.CharField(
1006
        _('Title'),
1007
        max_length=20,
1008
        default='auto',
1009
        blank=False,
1010
        choices=[
1011
            ('auto', _('Default Title (Card Label)')),
1012
            ('manual', _('Custom Title')),
1013
            ('empty', _('No Title')),
1014
        ],
1015
    )
1016
    custom_title = models.CharField(_('Custom Title'), max_length=150, blank=True)
1017

  
1018
    cached_title = models.CharField(_('Title'), max_length=150)
1019
    cached_json = JSONField(blank=True, default=dict)
1020

  
1021 861
    is_enabled = classmethod(is_wcs_enabled)
1022 862

  
1023
    manager_appearance_template = 'combo/wcs/manager/card-infos-cell-form-appearance.html'
863
    manager_appearance_template = 'combo/wcs/manager/card-cell-form-appearance.html'
1024 864

  
1025 865
    class Meta:
1026
        verbose_name = _('Card Information Cell')
866
        verbose_name = _('Card(s)')
1027 867

  
1028 868
    def save(self, *args, **kwargs):
1029 869
        super().save(*args, **kwargs)
......
1265 1105

  
1266 1106
        # get cells with explicit ids
1267 1107
        results = []
1268
        for cell in WcsCardInfosCell.objects.filter(page=self.page_id).exclude(pk=self.pk):
1108
        for cell in WcsCardCell.objects.filter(page=self.page_id).exclude(pk=self.pk):
1269 1109
            if not cell.slug:
1270 1110
                # no slug
1271 1111
                continue
......
1391 1231

  
1392 1232
        first_cell_slug = self.get_related_card_path().split('/', maxsplit=1)[0]
1393 1233
        try:
1394
            first_cell = WcsCardInfosCell.objects.get(page=self.page_id, slug=first_cell_slug)
1395
        except (WcsCardInfosCell.DoesNotExist, WcsCardInfosCell.MultipleObjectsReturned):
1234
            first_cell = WcsCardCell.objects.get(page=self.page_id, slug=first_cell_slug)
1235
        except (WcsCardCell.DoesNotExist, WcsCardCell.MultipleObjectsReturned):
1396 1236
            return []
1397 1237
        if first_cell.related_card_path:
1398 1238
            # no explicit ids
......
1599 1439
        return extra_context
1600 1440

  
1601 1441
    def get_default_form_class(self):
1602
        from .forms import WcsCardInfoCellForm
1442
        from .forms import WcsCardCellForm
1603 1443

  
1604
        return WcsCardInfoCellForm
1444
        return WcsCardCellForm
1605 1445

  
1606 1446
    def get_appearance_fields(self):
1607 1447
        return ['title_type', 'custom_title']
1608 1448

  
1609 1449
    def get_appearance_form_class(self):
1610
        from .forms import WcsCardInfoCellAppearanceBaseForm
1450
        from .forms import WcsCardCellAppearanceBaseForm
1611 1451

  
1612
        return super().get_appearance_form_class(base_options_form_class=WcsCardInfoCellAppearanceBaseForm)
1452
        return super().get_appearance_form_class(base_options_form_class=WcsCardCellAppearanceBaseForm)
1613 1453

  
1614 1454
    def get_manager_tabs(self):
1615
        from .forms import WcsCardInfoCellDisplayForm
1455
        from .forms import WcsCardCellDisplayForm
1616 1456

  
1617 1457
        tabs = super().get_manager_tabs()
1618 1458
        tabs.append(
1619 1459
            {
1620 1460
                'slug': 'display',
1621 1461
                'name': _('Display'),
1622
                'template': 'combo/wcs/manager/card-infos-cell-form-display.html',
1623
                'form': WcsCardInfoCellDisplayForm,
1462
                'template': 'combo/wcs/manager/card-cell-form-display.html',
1463
                'form': WcsCardCellDisplayForm,
1624 1464
            },
1625 1465
        )
1626 1466
        return tabs
......
1647 1487
        return custom_schema
1648 1488

  
1649 1489
    def get_asset_slot_key(self, key):
1490
        # for legacy
1650 1491
        if self.display_mode == 'table':
1651
            # for legacy: card cell with table mode should use assets of old cards cell
1652 1492
            return 'cell:wcs_wcscardscell:%s:%s' % (key, self.get_slug_for_asset())
1653
        return super().get_asset_slot_key(key)
1493
        return 'cell:wcs_wcscardinfoscell:%s:%s' % (key, self.get_slug_for_asset())
1654 1494

  
1655 1495
    def get_asset_slot_templates(self):
1656
        if self.display_mode == 'table' and settings.COMBO_CELL_ASSET_SLOTS.get('wcs_wcscardscell'):
1657
            # for legacy: card cell with table mode should use assets of old cards cell
1658
            return settings.COMBO_CELL_ASSET_SLOTS['wcs_wcscardscell']
1659
        return super().get_asset_slot_templates()
1496
        # for legacy
1497
        if self.display_mode == 'table':
1498
            return settings.COMBO_CELL_ASSET_SLOTS.get('wcs_wcscardscell')
1499
        return settings.COMBO_CELL_ASSET_SLOTS.get('wcs_wcscardinfoscell')
1660 1500

  
1661 1501

  
1662 1502
@register_cell_class
combo/apps/wcs/templates/combo/wcs/manager/card-cell-form-appearance.html
1
{% extends "combo/cell_appearance.html" %}
2

  
3
{% block cell-form-appearance %}
4
  {{ block.super }}
5
  <script>
6
    {# display/hide custom_title field #}
7
    $('#id_cwcs_wcscardcell-{{ cell.pk }}-title_type').on('change', function() {
8
      if ($(this).val() == 'manual') {
9
        $('#id_cwcs_wcscardcell-{{ cell.pk }}-custom_title').parent().show();
10
      } else {
11
        $('#id_cwcs_wcscardcell-{{ cell.pk }}-custom_title').parent().hide();
12
      }
13
    });
14
    $('#id_cwcs_wcscardcell-{{ cell.pk }}-title_type').change();
15

  
16
    {# display/hide card_ids field #}
17
    $('#id_cwcs_wcscardcell-{{ cell.pk }}-related_card_path').on('change', function() {
18
      if (!$(this).val()) {
19
        $('#id_cwcs_wcscardcell-{{ cell.pk }}-card_ids').parent().show();
20
      } else {
21
        $('#id_cwcs_wcscardcell-{{ cell.pk }}-card_ids').parent().hide();
22
      }
23
    });
24
    $('#id_cwcs_wcscardcell-{{ cell.pk }}-related_card_path').change();
25
  </script>
26
{% endblock %}
combo/apps/wcs/templates/combo/wcs/manager/card-infos-cell-form-display.html → combo/apps/wcs/templates/combo/wcs/manager/card-cell-form-display.html
3 3
{{ display_form.as_p }}
4 4
<script>
5 5
  {# display/hide custom_schema fields #}
6
  $('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-display_mode').on('change', function() {
6
  $('#id_cwcs_wcscardcell-{{ cell.pk }}-display_mode').on('change', function() {
7 7
    if ($(this).val() == 'card') {
8
      $('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-customize_display').parent().show();
9
      if ($('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-customize_display').val()) {
10
        $('.wcs-cards-cell--grid', $('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-customize_display').parents('.cell')).show();
8
      $('#id_cwcs_wcscardcell-{{ cell.pk }}-customize_display').parent().show();
9
      if ($('#id_cwcs_wcscardcell-{{ cell.pk }}-customize_display').val()) {
10
        $('.wcs-cards-cell--grid', $('#id_cwcs_wcscardcell-{{ cell.pk }}-customize_display').parents('.cell')).show();
11 11
      }
12 12
    } else {
13
      $('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-customize_display').parent().hide();
14
      $('.wcs-cards-cell--grid', $('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-customize_display').parents('.cell')).hide();
13
      $('#id_cwcs_wcscardcell-{{ cell.pk }}-customize_display').parent().hide();
14
      $('.wcs-cards-cell--grid', $('#id_cwcs_wcscardcell-{{ cell.pk }}-customize_display').parents('.cell')).hide();
15 15
    }
16 16
  });
17
  $('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-display_mode').change();
17
  $('#id_cwcs_wcscardcell-{{ cell.pk }}-display_mode').change();
18 18
</script>
19 19

  
20 20
{% if card_schema %}
combo/apps/wcs/templates/combo/wcs/manager/card-infos-cell-form-appearance.html
1
{% extends "combo/cell_appearance.html" %}
2

  
3
{% block cell-form-appearance %}
4
  {{ block.super }}
5
  <script>
6
    {# display/hide custom_title field #}
7
    $('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-title_type').on('change', function() {
8
      if ($(this).val() == 'manual') {
9
        $('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-custom_title').parent().show();
10
      } else {
11
        $('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-custom_title').parent().hide();
12
      }
13
    });
14
    $('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-title_type').change();
15

  
16
    {# display/hide card_ids field #}
17
    $('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-related_card_path').on('change', function() {
18
      if (!$(this).val()) {
19
        $('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-card_ids').parent().show();
20
      } else {
21
        $('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-card_ids').parent().hide();
22
      }
23
    });
24
    $('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-related_card_path').change();
25
  </script>
26
{% endblock %}
combo/manager/static/js/combo.manager.js
459 459
});
460 460

  
461 461

  
462
// UI to customize the layout of the content of a wcs-card-infos-cell
462
// UI to customize the layout of the content of a wcs-card-cell
463 463
const Card_cell_custom = function(cell) {
464 464
  this.cell = cell;
465 465
  this.gridSchema_default = {
......
849 849

  
850 850
// Active custom card UI for each card cell
851 851
$(function() {
852
  $('.wcs-card-infos-cell').each(function(i, el) {
852
  $('.wcs-card-cell').each(function(i, el) {
853 853
    const custom_card = new Card_cell_custom(el);
854 854
    $(el).on('combo:cellform-reloaded', function() {
855 855
      custom_card.init();
tests/test_manager.py
1040 1040
    resp.form['site_file'] = Upload('site-export.json', site_export, 'application/json')
1041 1041
    with CaptureQueriesContext(connection) as ctx:
1042 1042
        resp = resp.form.submit()
1043
        assert len(ctx.captured_queries) in [314, 315]
1043
        assert len(ctx.captured_queries) in [304, 305]
1044 1044
    assert Page.objects.count() == 4
1045 1045
    assert PageSnapshot.objects.all().count() == 4
1046 1046

  
......
1051 1051
    resp.form['site_file'] = Upload('site-export.json', site_export, 'application/json')
1052 1052
    with CaptureQueriesContext(connection) as ctx:
1053 1053
        resp = resp.form.submit()
1054
        assert len(ctx.captured_queries) == 282
1054
        assert len(ctx.captured_queries) == 274
1055 1055
    assert set(Page.objects.get(slug='one').related_cells['cell_types']) == {'data_textcell', 'data_linkcell'}
1056 1056
    assert Page.objects.count() == 4
1057 1057
    assert LinkCell.objects.count() == 2
......
2447 2447

  
2448 2448
    with CaptureQueriesContext(connection) as ctx:
2449 2449
        resp2 = resp.click('view', index=1)
2450
        assert len(ctx.captured_queries) == 72
2450
        assert len(ctx.captured_queries) == 70
2451 2451
    assert Page.snapshots.latest('pk').related_cells == {'cell_types': ['data_textcell']}
2452 2452
    assert resp2.text.index('Hello world') < resp2.text.index('Foobar3')
2453 2453

  
......
2508 2508
    resp = resp.click('restore', index=6)
2509 2509
    with CaptureQueriesContext(connection) as ctx:
2510 2510
        resp = resp.form.submit().follow()
2511
        assert len(ctx.captured_queries) == 157
2511
        assert len(ctx.captured_queries) == 153
2512 2512

  
2513 2513
    resp2 = resp.click('See online')
2514 2514
    assert resp2.text.index('Foobar1') < resp2.text.index('Foobar2') < resp2.text.index('Foobar3')
tests/test_search.py
1432 1432
    assert IndexedCell.objects.count() == 50
1433 1433
    with CaptureQueriesContext(connection) as ctx:
1434 1434
        index_site()
1435
        assert len(ctx.captured_queries) in (176, 226)  # (3.2, 2.2)
1435
        assert len(ctx.captured_queries) in (174, 224)  # (3.2, 2.2)
1436 1436

  
1437 1437
    SearchCell.objects.create(
1438 1438
        page=page, placeholder='content', order=0, _search_services={'data': ['search1']}
tests/wcs/test_all.py
22 22
    BackofficeSubmissionCell,
23 23
    CategoriesCell,
24 24
    TrackingCodeInputCell,
25
    WcsCardInfosCell,
26
    WcsCardsCell,
25
    WcsCardCell,
27 26
    WcsCareFormsCell,
28 27
    WcsCategoryCell,
29 28
    WcsCurrentDraftsCell,
......
1271 1270
    assert resp.pyquery('[data-tab-slug="appearance"] input[name$="custom_title"]')
1272 1271

  
1273 1272

  
1274
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
1275
def test_manager_cards_cell(mock_send, app, admin_user):
1276
    page = Page.objects.create(title='xxx', slug='test_cards_cell_save_cache', template_name='standard')
1277
    cell = WcsCardsCell.objects.create(page=page, placeholder='content', order=0)
1278
    app = login(app)
1279

  
1280
    resp = app.get('/manage/pages/%s/' % page.pk)
1281
    assert ('data-cell-reference="%s"' % cell.get_reference()) in resp.text
1282
    assert cell.without_user is False
1283
    assert resp.forms[0]['c%s-with_user' % cell.get_reference()].value == 'on'
1284
    resp.forms[0]['c%s-with_user' % cell.get_reference()].value = False
1285
    manager_submit_cell(resp.forms[0])
1286
    cell.refresh_from_db()
1287
    assert cell.without_user is True
1288
    assert resp.forms[0]['c%s-with_user' % cell.get_reference()].value is None
1289

  
1290

  
1291
def test_manager_cards_cell_tabs(app, admin_user):
1292
    page = Page.objects.create(title='xxx', slug='test_cards_cell_save_cache', template_name='standard')
1293
    cell = WcsCardsCell.objects.create(page=page, placeholder='content', order=0)
1294
    login(app)
1295

  
1296
    resp = app.get('/manage/pages/%s/' % page.pk)
1297

  
1298
    assert not resp.pyquery('[data-tab-slug="general"] input[name$="custom_title"]')
1299
    assert not resp.pyquery('#tab-%s-general.pk-tabs--button-marker' % cell.get_reference())
1300
    assert resp.pyquery('[data-tab-slug="appearance"] input[name$="custom_title"]')
1301

  
1302

  
1303
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
1304
def test_cards_cell_setup(mock_send):
1305
    cell = WcsCardsCell()
1306
    form_class = cell.get_default_form_class()
1307
    form = form_class(instance=cell)
1308
    assert form.fields['carddef_reference'].widget.choices == [
1309
        ('default:card_model_1', 'test : Card Model 1'),
1310
        ('default:card_model_1:foo', 'test : Card Model 1 - bar'),
1311
        ('default:card_model_2', 'test : Card Model 2'),
1312
        ('default:card_model_3', 'test : Card Model 3'),
1313
        ('default:card_a', 'test : Card A'),
1314
        ('default:card_b', 'test : Card B'),
1315
        ('default:card_b:a-custom-view', 'test : Card B - foo bar'),
1316
        ('default:card_c', 'test : Card C'),
1317
        ('default:card_d', 'test : Card D'),
1318
        ('default:card_e', 'test : Card E'),
1319
        ('other:card_model_1', 'test2 : Card Model 1'),
1320
        ('other:card_model_1:foo', 'test2 : Card Model 1 - bar'),
1321
        ('other:card_model_2', 'test2 : Card Model 2'),
1322
        ('other:card_model_3', 'test2 : Card Model 3'),
1323
        ('other:card_a', 'test2 : Card A'),
1324
        ('other:card_b', 'test2 : Card B'),
1325
        ('other:card_b:a-custom-view', 'test2 : Card B - foo bar'),
1326
        ('other:card_c', 'test2 : Card C'),
1327
        ('other:card_d', 'test2 : Card D'),
1328
        ('other:card_e', 'test2 : Card E'),
1329
    ]
1330

  
1331

  
1332
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
1333
def test_cards_cell_save_cache(mock_send):
1334
    page = Page.objects.create(title='xxx', slug='test_cards_cell_save_cache', template_name='standard')
1335
    cell = WcsCardsCell(page=page, placeholder='content', order=0)
1336
    assert cell.get_additional_label() is None
1337
    cell.carddef_reference = 'default:card_model_1'
1338
    cell.save()
1339
    assert cell.cached_title == 'Card Model 1'
1340
    assert cell.get_additional_label() == 'Card Model 1'
1341
    # make sure cached attributes are removed from serialized pages
1342
    assert 'cached_' not in json.dumps(page.get_serialized_page())
1343

  
1344
    cell.carddef_reference = 'default:card_model_1:foo'
1345
    cell.save()
1346
    assert cell.cached_title == 'Card Model 1 - bar'
1347
    assert cell.get_additional_label() == 'Card Model 1 - bar'
1348

  
1349
    # check content provided to search engine
1350
    assert cell.render_for_search() == ''
1351

  
1352
    # artificially change title
1353
    WcsCardsCell.objects.filter(pk=cell.pk).update(cached_title='XXX')
1354
    assert WcsCardsCell.objects.get(pk=cell.pk).cached_title == 'XXX'
1355
    # run update db cache
1356
    appconfig = apps.get_app_config('wcs')
1357
    appconfig.update_db_cache()
1358
    assert WcsCardsCell.objects.get(pk=cell.pk).cached_title == 'Card Model 1 - bar'
1359

  
1360

  
1361
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
1362
def test_cards_cell_validity(mock_send):
1363
    page = Page.objects.create(title='xxx', template_name='standard')
1364
    cell = WcsCardsCell.objects.create(page=page, placeholder='content', order=0)
1365
    validity_info = ValidityInfo.objects.latest('pk')
1366
    assert validity_info.invalid_reason_code == 'wcs_card_not_defined'
1367
    assert validity_info.invalid_since is not None
1368

  
1369
    cell.carddef_reference = 'default:card_model_1'
1370
    cell.save()
1371
    assert ValidityInfo.objects.exists() is False
1372

  
1373
    # can not retrieve data, don't set cell as invalid
1374
    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
1375
        mock_resp = Response()
1376
        mock_resp.status_code = 500
1377
        requests_get.return_value = mock_resp
1378
        cell.save()
1379
    assert ValidityInfo.objects.exists() is False
1380
    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
1381
        requests_get.side_effect = ConnectionError()
1382
        cell.save()
1383
    assert ValidityInfo.objects.exists() is False
1384

  
1385
    # can not retrieve carddefs, don't set cell as invalid
1386
    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
1387
        mock_resp = Response()
1388
        mock_resp.status_code = 404
1389
        requests_get.return_value = mock_resp
1390
        cell.save()
1391
    assert ValidityInfo.objects.exists() is False
1392

  
1393
    cell.carddef_reference = 'default:foobar'
1394
    cell.save()
1395
    validity_info = ValidityInfo.objects.latest('pk')
1396
    assert validity_info.invalid_reason_code == 'wcs_card_not_found'
1397
    assert validity_info.invalid_since is not None
1398

  
1399
    cell.carddef_reference = 'default:card_model_1:foo'
1400
    cell.save()
1401
    assert ValidityInfo.objects.exists() is False
1402

  
1403
    cell.carddef_reference = 'default:card_model_1:bar'
1404
    cell.save()
1405
    validity_info = ValidityInfo.objects.latest('pk')
1406
    assert validity_info.invalid_reason_code == 'wcs_card_not_found'
1407
    assert validity_info.invalid_since is not None
1408

  
1409

  
1410
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
1411
def test_cards_cell_load(mock_send):
1412
    page = Page.objects.create(title='xxx', slug='test_cards', template_name='standard')
1413
    cell = WcsCardsCell(page=page, placeholder='content', order=0)
1414
    cell.carddef_reference = 'default:card_model_1'
1415
    cell.save()
1416
    site_export = [page.get_serialized_page()]
1417
    cell.delete()
1418
    assert not Page.objects.get(pk=page.pk).get_cells()
1419
    Page.load_serialized_pages(site_export)
1420
    page = Page.objects.get(slug='test_cards')
1421
    cells = page.get_cells()
1422
    assert len(cells) == 1
1423
    cell = cells[0]
1424
    assert cell.cached_title == 'Card Model 1'
1425

  
1426
    cell.carddef_reference = 'default:card_model_1:foo'
1427
    cell.save()
1428
    site_export = [page.get_serialized_page()]
1429
    cell.delete()
1430
    assert not Page.objects.get(pk=page.pk).get_cells()
1431
    Page.load_serialized_pages(site_export)
1432
    page = Page.objects.get(slug='test_cards')
1433
    cells = page.get_cells()
1434
    assert len(cells) == 1
1435
    cell = cells[0]
1436
    assert cell.cached_title == 'Card Model 1 - bar'
1437

  
1438

  
1439
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
1440
def test_cards_cell_render(mock_send, context):
1441
    page = Page.objects.create(title='xxx', template_name='standard')
1442
    cell = WcsCardsCell(page=page, placeholder='content', order=0)
1443
    cell.carddef_reference = 'default:card_model_1'
1444
    cell.save()
1445

  
1446
    # query should fail as nothing is cached
1447
    cache.clear()
1448
    with pytest.raises(NothingInCacheException):
1449
        result = cell.render(context)
1450

  
1451
    context['synchronous'] = True  # to get fresh content
1452
    context['cell'] = cell
1453

  
1454
    result = cell.render(context)
1455
    assert '<h2>Card Model 1</h2>' in result
1456
    assert 'cards-card_model_1' in result
1457
    assert (
1458
        '<a href="http://127.0.0.1:8999/backoffice/data/card_model_1/11/"><span class="card-title">aa</span></a>'
1459
        in result
1460
    )
1461
    assert (
1462
        '<a href="http://127.0.0.1:8999/backoffice/data/card_model_1/12/"><span class="card-title">bb</span></a>'
1463
        in result
1464
    )
1465
    assert (
1466
        '<a href="http://127.0.0.1:8999/backoffice/data/card_model_1/13/"><span class="card-title">cc</span></a>'
1467
        in result
1468
    )
1469
    assert 'data-paginate-by="10"' in result
1470

  
1471
    # create a page with the correct subslug
1472
    page = Page.objects.create(slug='foo', title='Foo', sub_slug='(?P<card_model_1_id>[a-z0-9]+)')
1473

  
1474
    result = cell.render(context)
1475
    assert '<h2>Card Model 1</h2>' in result
1476
    assert '<a href="/foo/11"><span class="card-title">aa</span></a>' in result
1477
    assert '<a href="/foo/12"><span class="card-title">bb</span></a>' in result
1478
    assert '<a href="/foo/13"><span class="card-title">cc</span></a>' in result
1479

  
1480
    cell.carddef_reference = 'default:card_model_1:foo'
1481
    cell.limit = 42
1482
    cell.save()
1483
    page.sub_slug = 'card_model_1_id'
1484
    page.save()
1485

  
1486
    result = cell.render(context)
1487
    assert '<h2>Card Model 1 - bar</h2>' in result
1488
    assert '<a href="/foo/11"><span class="card-title">aa</span></a>' in result
1489
    assert '<a href="/foo/12"><span class="card-title">bb</span></a>' in result
1490
    assert '<a href="/foo/13"><span class="card-title">cc</span></a>' not in result
1491
    assert 'data-paginate-by="42"' in result
1492

  
1493
    with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
1494
        mock_json = mock.Mock(status_code=200)
1495
        requests_get.return_value = mock_json
1496
        cell.render(context)
1497
    assert len(requests_get.call_args_list) == 1
1498
    assert requests_get.call_args_list[0][0][0] == '/api/cards/card_model_1/list/foo'
1499
    assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://127.0.0.1:8999/'
1500

  
1501
    cell.custom_title = 'Foo bar'
1502
    cell.save()
1503
    result = cell.render(context)
1504
    assert '<h2>Card Model 1 - bar</h2>' not in result
1505
    assert '<h2>Foo bar</h2>' in result
1506

  
1507

  
1508
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
1509
def test_cards_cell_only_for_user(mock_send, context):
1510
    page = Page.objects.create(title='xxx', template_name='standard')
1511
    cell = WcsCardsCell(page=page, placeholder='content', order=0)
1512
    cell.carddef_reference = 'default:card_model_1'
1513
    cell.only_for_user = False
1514
    cell.save()
1515

  
1516
    assert cell.is_visible(request=context['request']) is True
1517
    context['request'].user = MockUserWithNameId()
1518
    assert cell.is_visible(request=context['request']) is True
1519

  
1520
    cell.only_for_user = True
1521
    cell.save()
1522
    context['request'].user = None
1523
    assert cell.is_visible(request=context['request']) is False
1524
    context['request'].user = MockUserWithNameId()
1525
    assert cell.is_visible(request=context['request']) is True
1526

  
1527
    cache.clear()
1528
    context['synchronous'] = True  # to get fresh content
1529
    context['request'].user = None
1530

  
1531
    mock_send.reset_mock()
1532
    cell.render(context)
1533
    assert 'filter-user-uuid' not in mock_send.call_args_list[0][0][0].url
1534

  
1535
    context['request'].user = MockUser()
1536
    mock_send.reset_mock()
1537
    cell.render(context)
1538
    assert 'filter-user-uuid' not in mock_send.call_args_list[0][0][0].url
1539

  
1540
    context['request'].user = MockUserWithNameId()
1541
    mock_send.reset_mock()
1542
    cell.render(context)
1543
    assert 'filter-user-uuid=xyz' in mock_send.call_args_list[0][0][0].url
1544

  
1545

  
1546
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
1547
def test_cards_cell_render_user(mock_send, context, nocache):
1548
    page = Page.objects.create(title='xxx', template_name='standard')
1549
    cell = WcsCardsCell(page=page, placeholder='content', order=0)
1550
    cell.carddef_reference = 'default:card_model_1'
1551
    cell.save()
1552

  
1553
    context['synchronous'] = True  # to get fresh content
1554

  
1555
    assert context['request'].user is None
1556
    mock_send.reset_mock()
1557
    cell.render(context)
1558
    assert 'NameID=&' in mock_send.call_args_list[0][0][0].url
1559
    assert 'email=&' in mock_send.call_args_list[0][0][0].url
1560

  
1561
    context['request'].user = AnonymousUser()
1562
    mock_send.reset_mock()
1563
    cell.render(context)
1564
    assert 'NameID=&' in mock_send.call_args_list[0][0][0].url
1565
    assert 'email=&' in mock_send.call_args_list[0][0][0].url
1566

  
1567
    context['request'].user = MockUser()
1568
    mock_send.reset_mock()
1569
    cell.render(context)
1570
    assert 'email=foo%40example.net' in mock_send.call_args_list[0][0][0].url
1571

  
1572
    context['request'].user = MockUserWithNameId()
1573
    mock_send.reset_mock()
1574
    cell.render(context)
1575
    assert 'NameID=xyz' in mock_send.call_args_list[0][0][0].url
1576

  
1577
    cell.without_user = True
1578
    cell.save()
1579

  
1580
    context['request'].user = None
1581
    mock_send.reset_mock()
1582
    cell.render(context)
1583
    assert 'NameID' not in mock_send.call_args_list[0][0][0].url
1584
    assert 'email' not in mock_send.call_args_list[0][0][0].url
1585

  
1586
    context['request'].user = AnonymousUser()
1587
    mock_send.reset_mock()
1588
    cell.render(context)
1589
    assert 'NameID' not in mock_send.call_args_list[0][0][0].url
1590
    assert 'email' not in mock_send.call_args_list[0][0][0].url
1591

  
1592
    context['request'].user = MockUser()
1593
    mock_send.reset_mock()
1594
    cell.render(context)
1595
    assert 'NameID' not in mock_send.call_args_list[0][0][0].url
1596
    assert 'email' not in mock_send.call_args_list[0][0][0].url
1597

  
1598
    context['request'].user = MockUserWithNameId()
1599
    mock_send.reset_mock()
1600
    cell.render(context)
1601
    assert 'NameID' not in mock_send.call_args_list[0][0][0].url
1602
    assert 'email' not in mock_send.call_args_list[0][0][0].url
1603

  
1604

  
1605 1273
def test_tracking_code_cell(app, nocache):
1606 1274
    page = Page(title='One', slug='index', template_name='standard')
1607 1275
    page.save()
......
2214 1882
            WcsCurrentFormsCell,
2215 1883
            WcsCurrentDraftsCell,
2216 1884
            WcsFormsOfCategoryCell,
2217
            WcsCardInfosCell,
1885
            WcsCardCell,
2218 1886
            BackofficeSubmissionCell,
2219 1887
            CategoriesCell,
2220 1888
            TrackingCodeInputCell,
tests/wcs/test_card.py
12 12
from requests.exceptions import ConnectionError
13 13
from requests.models import Response
14 14

  
15
from combo.apps.wcs.forms import WcsCardInfoCellDisplayForm
16
from combo.apps.wcs.models import WcsCardInfosCell
15
from combo.apps.wcs.forms import WcsCardCellDisplayForm
16
from combo.apps.wcs.models import WcsCardCell
17 17
from combo.data.models import Page, TextCell, ValidityInfo
18 18
from tests.test_manager import login
19 19
from tests.utils import manager_submit_cell
......
28 28
    page = Page.objects.create(
29 29
        title='xxx', slug='test_card_cell_save_cache', template_name='standard', sub_slug='foobar'
30 30
    )
31
    cell = WcsCardInfosCell(page=page, placeholder='content', order=0)
31
    cell = WcsCardCell(page=page, placeholder='content', order=0)
32 32
    form_class = cell.get_default_form_class()
33 33
    form = form_class(instance=cell)
34 34
    assert form.fields['carddef_reference'].widget.choices == [
......
54 54
        ('other:card_e', 'test2 : Card E'),
55 55
    ]
56 56

  
57
    form_display = WcsCardInfoCellDisplayForm(instance=cell)
57
    form_display = WcsCardCellDisplayForm(instance=cell)
58 58
    assert 'customize_display' not in form_display.fields
59 59
    assert 'custom_schema' not in form_display.fields
60 60

  
......
64 64

  
65 65
    cell.carddef_reference = 'default:card_model_1'
66 66
    cell.save()
67
    form_display = WcsCardInfoCellDisplayForm(instance=cell)
67
    form_display = WcsCardCellDisplayForm(instance=cell)
68 68
    assert 'customize_display' in form_display.fields
69 69
    assert 'custom_schema' in form_display.fields
70 70
    assert 'customize_display' not in form_display.initial
......
72 72

  
73 73
    cell.carddef_reference = 'default:card_model_1:foo'
74 74
    cell.save()
75
    form_display = WcsCardInfoCellDisplayForm(instance=cell)
75
    form_display = WcsCardCellDisplayForm(instance=cell)
76 76
    assert 'customize_display' in form_display.fields
77 77
    assert 'custom_schema' in form_display.fields
78 78
    assert 'customize_display' not in form_display.initial
......
83 83

  
84 84
    cell.custom_schema = {'cells': [{'varname': 'foo', 'display_mode': 'value'}]}
85 85
    cell.save()
86
    form_display = WcsCardInfoCellDisplayForm(instance=cell)
86
    form_display = WcsCardCellDisplayForm(instance=cell)
87 87
    assert 'customize_display' in form_display.fields
88 88
    assert 'custom_schema' in form_display.fields
89 89
    assert form_display.initial['customize_display'] is True
......
93 93
        ]
94 94
    }
95 95

  
96
    WcsCardInfosCell.objects.all().delete()
96
    WcsCardCell.objects.all().delete()
97 97

  
98 98
    # check adding a cell from the UI
99 99
    app = login(app)
100 100
    resp = app.get('/manage/pages/%s/' % page.pk)
101
    cell_add_url = [x for x in resp.html.find_all('option') if x.text == 'Card Information Cell'][0].get(
102
        'data-add-url'
103
    )
101
    cell_add_url = [x for x in resp.html.find_all('option') if x.text == 'Card(s)'][0].get('data-add-url')
104 102
    resp = app.get(cell_add_url).follow()
105
    cell = WcsCardInfosCell.objects.all().first()
103
    cell = WcsCardCell.objects.all().first()
106 104
    manager_submit_cell(resp.forms[0])  # will save card model
107 105
    cell.refresh_from_db()
108 106

  
......
188 186

  
189 187

  
190 188
def test_card_cell_custom_schema_migration():
191
    cell = WcsCardInfosCell()
189
    cell = WcsCardCell()
192 190

  
193 191
    cell.custom_schema = {
194 192
        'cells': [{'varname': 'some-field', 'display_mode': 'label', 'cell_size': 'foobar'}]
......
261 259
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
262 260
def test_card_cell_save_cache(mock_send):
263 261
    page = Page.objects.create(title='xxx', slug='test_card_cell_save_cache', template_name='standard')
264
    cell = WcsCardInfosCell(page=page, placeholder='content', order=0)
262
    cell = WcsCardCell(page=page, placeholder='content', order=0)
265 263
    assert cell.get_additional_label() is None
266 264
    cell.carddef_reference = 'default:card_model_1'
267 265
    cell.save()
......
272 270
    assert 'cached_' not in json.dumps(page.get_serialized_page())
273 271

  
274 272
    # artificially change title and json
275
    WcsCardInfosCell.objects.filter(pk=cell.pk).update(cached_title='XXX', cached_json={})
276
    assert WcsCardInfosCell.objects.get(pk=cell.pk).cached_title == 'XXX'
277
    assert WcsCardInfosCell.objects.get(pk=cell.pk).cached_json == {}
273
    WcsCardCell.objects.filter(pk=cell.pk).update(cached_title='XXX', cached_json={})
274
    assert WcsCardCell.objects.get(pk=cell.pk).cached_title == 'XXX'
275
    assert WcsCardCell.objects.get(pk=cell.pk).cached_json == {}
278 276
    # run update db cache
279 277
    appconfig = apps.get_app_config('wcs')
280 278
    appconfig.update_db_cache()
281
    assert WcsCardInfosCell.objects.get(pk=cell.pk).cached_title == 'Card Model 1'
282
    assert WcsCardInfosCell.objects.get(pk=cell.pk).cached_json != {}
279
    assert WcsCardCell.objects.get(pk=cell.pk).cached_title == 'Card Model 1'
280
    assert WcsCardCell.objects.get(pk=cell.pk).cached_json != {}
283 281

  
284 282

  
285 283
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
286 284
def test_card_cell_validity(mock_send):
287 285
    page = Page.objects.create(title='xxx', template_name='standard')
288
    cell = WcsCardInfosCell.objects.create(page=page, placeholder='content', order=0)
286
    cell = WcsCardCell.objects.create(page=page, placeholder='content', order=0)
289 287
    validity_info = ValidityInfo.objects.latest('pk')
290 288
    assert validity_info.invalid_reason_code == 'wcs_card_not_defined'
291 289
    assert validity_info.invalid_since is not None
......
329 327
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
330 328
def test_card_cell_check_validity(mock_send):
331 329
    page = Page.objects.create(title='xxx', template_name='standard')
332
    cell = WcsCardInfosCell.objects.create(
330
    cell = WcsCardCell.objects.create(
333 331
        page=page,
334 332
        placeholder='content',
335 333
        order=0,
336 334
        carddef_reference='default:card_a',
337 335
        card_ids='1',
338 336
    )
339
    cell2 = WcsCardInfosCell.objects.create(
337
    cell2 = WcsCardCell.objects.create(
340 338
        page=page, placeholder='content', order=1, carddef_reference='default:card_b'
341 339
    )
342 340

  
......
370 368
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
371 369
def test_manager_card_cell(mock_send, app, admin_user):
372 370
    page = Page.objects.create(title='xxx', slug='test_cards', template_name='standard', sub_slug='foobar')
373
    cell = WcsCardInfosCell.objects.create(page=page, placeholder='content', order=0)
371
    cell = WcsCardCell.objects.create(page=page, placeholder='content', order=0)
374 372

  
375 373
    app = login(app)
376 374
    resp = app.get('/manage/pages/%s/' % page.pk)
......
414 412
    # add a second cell, related to the first card model
415 413
    cell.related_card_path = ''
416 414
    cell.save()
417
    cell2 = WcsCardInfosCell.objects.create(
415
    cell2 = WcsCardCell.objects.create(
418 416
        page=page, placeholder='content', order=1, carddef_reference='default:card_b'
419 417
    )
420 418
    resp = app.get('/manage/pages/%s/' % page.pk)
......
606 604
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
607 605
def test_manager_card_cell_tabs(mock_send, app, admin_user):
608 606
    page = Page.objects.create(title='xxx', slug='test_cards', template_name='standard', sub_slug='foobar')
609
    cell = WcsCardInfosCell.objects.create(page=page, placeholder='content', order=0)
607
    cell = WcsCardCell.objects.create(page=page, placeholder='content', order=0)
610 608

  
611 609
    app = login(app)
612 610
    resp = app.get('/manage/pages/%s/' % page.pk)
......
629 627
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
630 628
def test_card_cell_load(mock_send):
631 629
    page = Page.objects.create(title='xxx', slug='test_cards', template_name='standard')
632
    cell = WcsCardInfosCell(page=page, placeholder='content', order=0)
630
    cell = WcsCardCell(page=page, placeholder='content', order=0)
633 631
    cell.carddef_reference = 'default:card_model_1'
634 632
    cell.save()
635 633
    site_export = [page.get_serialized_page()]
......
646 644
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
647 645
def test_card_cell_table_mode_render(mock_send, context, app):
648 646
    page = Page.objects.create(title='xxx', template_name='standard')
649
    cell = WcsCardInfosCell.objects.create(
647
    cell = WcsCardCell.objects.create(
650 648
        page=page,
651 649
        placeholder='content',
652 650
        order=0,
......
712 710
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
713 711
def test_card_cell_table_mode_render_all_cards(mock_send, nocache, app):
714 712
    page = Page.objects.create(title='xxx', slug='foo', template_name='standard')
715
    cell = WcsCardInfosCell.objects.create(
713
    cell = WcsCardCell.objects.create(
716 714
        page=page,
717 715
        placeholder='content',
718 716
        order=0,
......
743 741
    page = Page.objects.create(
744 742
        title='xxx', slug='foo', template_name='standard', sub_slug='(?P<card_model_1_id>[a-z0-9]+)'
745 743
    )
746
    cell = WcsCardInfosCell.objects.create(
744
    cell = WcsCardCell.objects.create(
747 745
        page=page,
748 746
        placeholder='content',
749 747
        order=0,
......
817 815
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
818 816
def test_card_cell_table_mode_render_identifier_from_related(mock_send, nocache, app):
819 817
    page = Page.objects.create(title='xxx', slug='foo', template_name='standard')
820
    WcsCardInfosCell.objects.create(
818
    WcsCardCell.objects.create(
821 819
        page=page,
822 820
        placeholder='content',
823 821
        order=0,
......
826 824
        carddef_reference='default:card_a',
827 825
        card_ids='1',
828 826
    )
829
    cell2 = WcsCardInfosCell.objects.create(
827
    cell2 = WcsCardCell.objects.create(
830 828
        page=page, placeholder='content', order=1, slug='slugb', carddef_reference='default:card_b'
831 829
    )
832 830

  
......
876 874
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
877 875
def test_card_cell_table_mode_render_title(mock_send, context):
878 876
    page = Page.objects.create(title='xxx', template_name='standard')
879
    cell = WcsCardInfosCell.objects.create(
877
    cell = WcsCardCell.objects.create(
880 878
        page=page,
881 879
        placeholder='content',
882 880
        order=0,
......
911 909
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
912 910
def test_card_cell_card_mode_render(mock_send, context, app):
913 911
    page = Page.objects.create(title='xxx', template_name='standard')
914
    cell = WcsCardInfosCell.objects.create(
912
    cell = WcsCardCell.objects.create(
915 913
        page=page,
916 914
        placeholder='content',
917 915
        order=0,
......
1057 1055
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
1058 1056
def test_card_cell_card_mode_render_text_field(mock_send, context):
1059 1057
    page = Page.objects.create(title='xxx', template_name='standard')
1060
    cell = WcsCardInfosCell.objects.create(
1058
    cell = WcsCardCell.objects.create(
1061 1059
        page=page,
1062 1060
        placeholder='content',
1063 1061
        order=0,
......
1093 1091
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
1094 1092
def test_card_cell_card_mode_render_email_field(mock_send, context):
1095 1093
    page = Page.objects.create(title='xxx', template_name='standard')
1096
    cell = WcsCardInfosCell.objects.create(
1094
    cell = WcsCardCell.objects.create(
1097 1095
        page=page,
1098 1096
        placeholder='content',
1099 1097
        order=0,
......
1119 1117
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
1120 1118
def test_card_cell_card_mode_render_string_with_url_field(mock_send, context):
1121 1119
    page = Page.objects.create(title='xxx', template_name='standard')
1122
    cell = WcsCardInfosCell.objects.create(
1120
    cell = WcsCardCell.objects.create(
1123 1121
        page=page,
1124 1122
        placeholder='content',
1125 1123
        order=0,
......
1147 1145
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
1148 1146
def test_card_cell_card_mode_render_custom_schema_card_field(mock_send, context):
1149 1147
    page = Page.objects.create(title='xxx', template_name='standard')
1150
    cell = WcsCardInfosCell.objects.create(
1148
    cell = WcsCardCell.objects.create(
1151 1149
        page=page,
1152 1150
        placeholder='content',
1153 1151
        order=0,
......
1297 1295
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
1298 1296
def test_card_cell_card_mode_render_custom_schema_card_empty_field(mock_send, context):
1299 1297
    page = Page.objects.create(title='xxx', template_name='standard')
1300
    cell = WcsCardInfosCell.objects.create(
1298
    cell = WcsCardCell.objects.create(
1301 1299
        page=page,
1302 1300
        placeholder='content',
1303 1301
        order=0,
......
1398 1396
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
1399 1397
def test_card_cell_card_mode_render_custom_schema_custom_entry(mock_send, context, app):
1400 1398
    page = Page.objects.create(title='xxx', template_name='standard')
1401
    cell = WcsCardInfosCell.objects.create(
1399
    cell = WcsCardCell.objects.create(
1402 1400
        page=page,
1403 1401
        placeholder='content',
1404 1402
        order=0,
......
1515 1513
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
1516 1514
def test_card_cell_card_mode_render_custom_schema_link_entry(mock_send, context, app):
1517 1515
    page = Page.objects.create(title='xxx', template_name='standard')
1518
    cell = WcsCardInfosCell.objects.create(
1516
    cell = WcsCardCell.objects.create(
1519 1517
        page=page,
1520 1518
        placeholder='content',
1521 1519
        order=0,
......
1573 1571
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
1574 1572
def test_card_cell_card_mode_render_all_cards(mock_send, nocache, app):
1575 1573
    page = Page.objects.create(title='xxx', slug='foo', template_name='standard')
1576
    cell = WcsCardInfosCell.objects.create(
1574
    cell = WcsCardCell.objects.create(
1577 1575
        page=page,
1578 1576
        placeholder='content',
1579 1577
        order=0,
......
1611 1609
    page = Page.objects.create(
1612 1610
        title='xxx', slug='foo', template_name='standard', sub_slug='(?P<card_model_1_id>[a-z0-9]+)'
1613 1611
    )
1614
    cell = WcsCardInfosCell.objects.create(
1612
    cell = WcsCardCell.objects.create(
1615 1613
        page=page, placeholder='content', order=0, carddef_reference='default:card_model_1'
1616 1614
    )
1617 1615

  
......
1746 1744
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
1747 1745
def test_card_cell_card_mode_render_identifier_from_related(mock_send, nocache, app):
1748 1746
    page = Page.objects.create(title='xxx', slug='foo', template_name='standard')
1749
    cell = WcsCardInfosCell.objects.create(
1747
    cell = WcsCardCell.objects.create(
1750 1748
        page=page,
1751 1749
        placeholder='content',
1752 1750
        order=0,
......
1755 1753
        carddef_reference='default:card_a',
1756 1754
        card_ids='1',
1757 1755
    )
1758
    cell2 = WcsCardInfosCell.objects.create(
1756
    cell2 = WcsCardCell.objects.create(
1759 1757
        page=page, placeholder='content', order=1, slug='slugb', carddef_reference='default:card_b'
1760 1758
    )
1761 1759

  
......
1819 1817
    failing(urls=[])
1820 1818

  
1821 1819
    # another cell with the same slug
1822
    cell3 = WcsCardInfosCell.objects.create(page=page, placeholder='content', order=2, slug='sluga')
1820
    cell3 = WcsCardCell.objects.create(page=page, placeholder='content', order=2, slug='sluga')
1823 1821
    cell2.related_card_path = 'sluga/foo'
1824 1822
    cell2.save()
1825 1823
    failing(urls=[])
......
1850 1848
    cell.related_path = ''
1851 1849
    cell.save()
1852 1850

  
1853
    # another cell as the same slug, but not a WcsCardInfosCell
1851
    # another cell as the same slug, but not a WcsCardCell
1854 1852
    cell3 = TextCell.objects.create(page=page, placeholder='content', order=2, slug='sluga')
1855 1853

  
1856 1854
    # direct and single relation (item)
......
2285 2283
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
2286 2284
def test_card_cell_only_for_user(mock_send, context, carddef_reference):
2287 2285
    page = Page.objects.create(title='xxx', template_name='standard')
2288
    cell = WcsCardInfosCell.objects.create(
2286
    cell = WcsCardCell.objects.create(
2289 2287
        page=page,
2290 2288
        placeholder='content',
2291 2289
        order=0,
......
2332 2330
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
2333 2331
def test_card_cell_render_user(mock_send, context, nocache, carddef_reference):
2334 2332
    page = Page.objects.create(title='xxx', template_name='standard')
2335
    cell = WcsCardInfosCell.objects.create(
2333
    cell = WcsCardCell.objects.create(
2336 2334
        page=page,
2337 2335
        placeholder='content',
2338 2336
        order=0,
......
2392 2390
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
2393 2391
def test_cell_condition(mock_send, nocache, app):
2394 2392
    page = Page.objects.create(title='xxx', slug='foo', template_name='standard')
2395
    cell = WcsCardInfosCell.objects.create(
2393
    cell = WcsCardCell.objects.create(
2396 2394
        page=page,
2397 2395
        placeholder='content',
2398 2396
        order=0,
......
2453 2451
def test_card_file_redirection(mock_send, app):
2454 2452
    page = Page(title='One', slug='one', template_name='standard')
2455 2453
    page.save()
2456
    cell = WcsCardInfosCell(page=page, placeholder='content', order=0)
2454
    cell = WcsCardCell(page=page, placeholder='content', order=0)
2457 2455
    cell.carddef_reference = 'default:card_model_1'
2458 2456
    cell.card_ids = '11'
2459 2457
    cell.save()
......
2476 2474
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
2477 2475
def test_card_cell_assets(mock_send, settings, app, admin_user):
2478 2476
    page = Page.objects.create(title='xxx', slug='test_cell_assets', template_name='standard')
2479
    cell1 = WcsCardInfosCell.objects.create(
2477
    cell1 = WcsCardCell.objects.create(
2480 2478
        page=page,
2481 2479
        placeholder='content',
2482 2480
        order=0,
......
2484 2482
        display_mode='card',
2485 2483
        slug='slug1',
2486 2484
    )
2487
    cell2 = WcsCardInfosCell.objects.create(
2485
    cell2 = WcsCardCell.objects.create(
2488 2486
        page=page,
2489 2487
        placeholder='content',
2490 2488
        order=0,
2491
-