Projet

Général

Profil

0002-wcs-build-paths-of-related-cards-for-form-options-58.patch

Lauréline Guérin, 09 décembre 2021 14:57

Télécharger (23,7 ko)

Voir les différences:

Subject: [PATCH 2/5] wcs: build paths of related cards for form options
 (#58833)

 combo/apps/wcs/forms.py                       |  16 +-
 combo/apps/wcs/migrations/0043_card_ids.py    |   2 +-
 .../wcs/migrations/0044_related_card_path.py  |  16 ++
 combo/apps/wcs/models.py                      |  75 ++++-
 .../wcs/manager/card-infos-cell-form.html     |  12 +-
 tests/test_wcs.py                             | 264 +++++++++++++++++-
 6 files changed, 374 insertions(+), 11 deletions(-)
 create mode 100644 combo/apps/wcs/migrations/0044_related_card_path.py
combo/apps/wcs/forms.py
68 68
class WcsCardInfoCellForm(forms.ModelForm):
69 69
    with_user = forms.BooleanField(label=_('Restrict to cards accessible to the user'), required=False)
70 70
    customize_display = forms.BooleanField(label=_('Customize display'), required=False)
71
    related_card_path = forms.ChoiceField(label=_('Card Identifier'), required=False)
71 72

  
72 73
    class Meta:
73 74
        model = WcsCardInfosCell
74
        fields = ('carddef_reference', 'title_type', 'custom_title', 'card_ids', 'custom_schema')
75
        fields = (
76
            'carddef_reference',
77
            'title_type',
78
            'custom_title',
79
            'related_card_path',
80
            'card_ids',
81
            'custom_schema',
82
        )
75 83
        widgets = {
76 84
            'custom_schema': forms.HiddenInput(),
77 85
        }
......
89 97
            del self.fields['customize_display']
90 98
            del self.fields['custom_schema']
91 99

  
100
        self.fields['related_card_path'].choices = [
101
            ('', _('Other Card Identifiers'))
102
        ] + self.instance.get_related_card_paths()
103

  
92 104
    def save(self, *args, **kwargs):
93 105
        super().save(*args, **kwargs)
94 106
        if not self.cleaned_data.get('customize_display'):
95 107
            self.instance.custom_schema = {}
108
        if self.instance.related_card_path:
109
            self.instance.card_ids = ''
96 110
        self.instance.without_user = not self.cleaned_data['with_user']
97 111
        self.instance.save()
98 112
        return self.instance
combo/apps/wcs/migrations/0043_card_ids.py
16 16
        migrations.AlterField(
17 17
            model_name='wcscardinfoscell',
18 18
            name='card_ids',
19
            field=models.CharField(blank=True, max_length=1000, verbose_name='Card Identifiers'),
19
            field=models.CharField(blank=True, max_length=1000, verbose_name='Other Card Identifiers'),
20 20
        ),
21 21
    ]
combo/apps/wcs/migrations/0044_related_card_path.py
1
from django.db import migrations, models
2

  
3

  
4
class Migration(migrations.Migration):
5

  
6
    dependencies = [
7
        ('wcs', '0043_card_ids'),
8
    ]
9

  
10
    operations = [
11
        migrations.AddField(
12
            model_name='wcscardinfoscell',
13
            name='related_card_path',
14
            field=models.CharField(blank=True, max_length=1000, verbose_name='Card Identifier'),
15
        ),
16
    ]
combo/apps/wcs/models.py
768 768
    def wcs_site(self):
769 769
        return self.carddef_reference.split(':')[0]
770 770

  
771
    @property
772
    def card_slug(self):
773
        return self.carddef_reference.split(':')[1]
774

  
771 775
    def get_additional_label(self):
772 776
        if not self.cached_title:
773 777
            return
......
846 850

  
847 851
        populate_cache()
848 852

  
849
    def card_slug(self):
850
        return self.carddef_reference.split(':')[1]
851

  
852 853
    def is_visible(self, **kwargs):
853 854
        user = kwargs.get('user')
854 855
        if self.only_for_user and (not user or user.is_anonymous):
......
899 900
@register_cell_class
900 901
class WcsCardInfosCell(CardMixin, CellBase):
901 902
    carddef_reference = models.CharField(_('Card Model'), max_length=150)
902
    card_ids = models.CharField(_('Card Identifiers'), max_length=1000, blank=True)
903
    related_card_path = models.CharField(_('Card Identifier'), max_length=1000, blank=True)
904
    card_ids = models.CharField(_('Other Card Identifiers'), max_length=1000, blank=True)
903 905
    without_user = models.BooleanField(_('Ignore the logged-in user'), default=False)
904 906
    custom_schema = JSONField(blank=True, default=dict)
905 907

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

  
978
    def get_card_schema(self, card_slug):
979
        wcs_site = get_wcs_services().get(self.wcs_site)
980
        card_schema = get_wcs_json(wcs_site, 'api/cards/%s/@schema' % card_slug, log_errors='warn')
981
        if not card_schema:
982
            return None
983
        if card_schema.get('err') == 1:
984
            return None
985
        return card_schema
986

  
987
    def get_related_card_paths(self):
988
        if not self.carddef_reference:
989
            return []
990

  
991
        def iter_relations(relations, path, label, carddefs_already_seen):
992
            carddefs_already_seen = carddefs_already_seen[:]
993
            for relation in relations:
994
                new_path = '%s/%s%s' % (
995
                    path,
996
                    'reverse:' if relation['reverse'] else '',
997
                    relation['varname'],
998
                )
999
                new_label = '%s/%s%s' % (
1000
                    label,
1001
                    relation['varname'],
1002
                    ' (reverse)' if relation['reverse'] else '',
1003
                )
1004
                if relation['obj'] == 'carddef:%s' % self.card_slug:
1005
                    # target carddef found
1006
                    yield (new_path, new_label)
1007
                if not relation['reverse'] and relation['type'] in ['item', 'computed']:
1008
                    # relation is not multiple, continue to search for matching relations
1009
                    new_card_slug = relation['obj'][8:]  # remove 'carddef:'
1010
                    new_card_schema = self.get_card_schema(new_card_slug)
1011
                    if new_card_slug not in carddefs_already_seen and new_card_schema:
1012
                        carddefs_already_seen.append(new_card_slug)
1013
                        yield from iter_relations(
1014
                            relations=new_card_schema['relations'],
1015
                            path=new_path,
1016
                            label=new_label,
1017
                            carddefs_already_seen=carddefs_already_seen,
1018
                        )
1019

  
1020
        # get cells with explicit ids
1021
        results = []
1022
        for cell in WcsCardInfosCell.objects.filter(page=self.page_id).exclude(pk=self.pk):
1023
            if not cell.slug:
1024
                # no slug
1025
                continue
1026
            if cell.related_card_path:
1027
                # no explicit ids
1028
                continue
1029
            if ',' in cell.card_ids:
1030
                # multiple ids, can not follow relations
1031
                continue
1032
            # follow relations
1033
            results += list(
1034
                iter_relations(
1035
                    relations=cell.cached_json.get('relations') or [],
1036
                    path=cell.slug,
1037
                    label=cell.slug,
1038
                    carddefs_already_seen=[self.card_slug],
1039
                )
1040
            )
1041
        return results
1042

  
976 1043
    def get_card_ids(self, original_context, request):
977 1044
        if self.card_ids:
978 1045
            try:
combo/apps/wcs/templates/combo/wcs/manager/card-infos-cell-form.html
89 89

  
90 90
{% endif %}
91 91

  
92
{# display/hide custom_title field #}
93 92
<script>
93
  {# display/hide custom_title field #}
94 94
  $('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-title_type').on('change', function() {
95 95
    if ($(this).val() == 'manual') {
96 96
      $('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-custom_title').parent().show();
......
99 99
    }
100 100
  });
101 101
  $('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-title_type').change();
102

  
103
  {# display/hide card_ids field #}
104
  $('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-related_card_path').on('change', function() {
105
    if (!$(this).val()) {
106
      $('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-card_ids').parent().show();
107
    } else {
108
      $('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-card_ids').parent().hide();
109
    }
110
  });
111
  $('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-related_card_path').change();
102 112
</script>
103 113
{% endblock %}
tests/test_wcs.py
118 118
    {'title': 'Card Model 1', 'slug': 'card_model_1', 'custom_views': [{'id': 'foo', 'text': 'bar'}]},
119 119
    {'title': 'Card Model 2', 'slug': 'card_model_2'},
120 120
    {'title': 'Card Model 3', 'slug': 'card_model_3'},
121
    {'title': 'Card A', 'slug': 'card_a'},
122
    {'title': 'Card B', 'slug': 'card_b'},
123
    {'title': 'Card C', 'slug': 'card_c'},
124
    {'title': 'Card D', 'slug': 'card_d'},
125
    {'title': 'Card E', 'slug': 'card_e'},
121 126
]
122 127

  
123 128
WCS_CARDS_DATA = {
......
199 204
            {'label': 'Empty', 'varname': None, 'type': 'string'},
200 205
        ],
201 206
    },
207
    'card_a': {
208
        'name': 'Card A',
209
        'fields': [
210
            {'label': 'Card B', 'varname': 'cardb', 'type': 'item'},
211
            {'label': 'Cards B', 'varname': 'cardsb', 'type': 'items'},
212
            {'label': 'Block B', 'varname': 'blockb', 'type': 'block:b'},
213
            {'label': 'Card C', 'varname': 'cardc', 'type': 'item'},
214
        ],
215
        'relations': [
216
            {'obj': 'carddef:card_b', 'varname': 'cardb', 'type': 'item', 'reverse': False},
217
            {'obj': 'carddef:card_b', 'varname': 'cardsb', 'type': 'items', 'reverse': False},
218
            {'obj': 'carddef:card_b', 'varname': 'blockb_cardb', 'type': 'item', 'reverse': False},
219
            {'obj': 'carddef:card_c', 'varname': 'cardc', 'type': 'item', 'reverse': False},
220
            {
221
                'obj': 'carddef:card_z',  # unknown card model
222
                'varname': 'cardz',
223
                'type': 'item',
224
                'reverse': False,
225
            },
226
        ],
227
    },
228
    'card_b': {
229
        'name': 'Card B',
230
        'fields': [],
231
        'relations': [
232
            {'obj': 'carddef:card_a', 'varname': 'cardb', 'type': 'item', 'reverse': True},
233
            {'obj': 'carddef:card_a', 'varname': 'cardsb', 'type': 'items', 'reverse': True},
234
            {'obj': 'carddef:card_a', 'varname': 'blockb_cardb', 'type': 'item', 'reverse': True},
235
            {'obj': 'carddef:card_c', 'varname': 'cardb', 'type': 'item', 'reverse': True},
236
            {'obj': 'carddef:card_c', 'varname': 'cardsb', 'type': 'items', 'reverse': True},
237
            {'obj': 'carddef:card_c', 'varname': 'blockb_cardb', 'type': 'item', 'reverse': True},
238
        ],
239
    },
240
    'card_c': {
241
        'name': 'Card C',
242
        'fields': [
243
            {'label': 'Card B', 'varname': 'cardb', 'type': 'item'},
244
            {'label': 'Cards B', 'varname': 'cardsb', 'type': 'items'},
245
            {'label': 'Block B', 'varname': 'blockb', 'type': 'block:b'},
246
        ],
247
        'relations': [
248
            {'obj': 'carddef:card_b', 'varname': 'cardb', 'type': 'item', 'reverse': False},
249
            {'obj': 'carddef:card_b', 'varname': 'cardsb', 'type': 'items', 'reverse': False},
250
            {'obj': 'carddef:card_b', 'varname': 'blockb_cardb', 'type': 'item', 'reverse': False},
251
            {'obj': 'carddef:card_a', 'varname': 'cardc', 'type': 'item', 'reverse': True},
252
        ],
253
    },
254
    'card_d': {
255
        'name': 'Card D',
256
        'fields': [
257
            {'label': 'Card D', 'varname': 'cardd-foo', 'type': 'item'},
258
            {'label': 'Card E', 'varname': 'carde-foo', 'type': 'item'},
259
        ],
260
        'relations': [
261
            {'obj': 'carddef:card_d', 'varname': 'cardd-foo', 'type': 'item', 'reverse': False},
262
            {'obj': 'carddef:card_d', 'varname': 'cardd-foo', 'type': 'item', 'reverse': True},
263
            {'obj': 'carddef:card_e', 'varname': 'carde-foo', 'type': 'item', 'reverse': False},
264
        ],
265
    },
266
    'card_e': {
267
        'name': 'Card E',
268
        'fields': [
269
            {'label': 'Card D', 'varname': 'cardd-bar', 'type': 'item'},
270
        ],
271
        'relations': [
272
            {'obj': 'carddef:card_d', 'varname': 'cardd-bar', 'type': 'item', 'reverse': False},
273
            {'obj': 'carddef:card_d', 'varname': 'carde-foo', 'type': 'item', 'reverse': True},
274
        ],
275
    },
202 276
}
203 277

  
204 278

  
......
1392 1466
        ('default:card_model_1:foo', 'test : Card Model 1 - bar'),
1393 1467
        ('default:card_model_2', 'test : Card Model 2'),
1394 1468
        ('default:card_model_3', 'test : Card Model 3'),
1469
        ('default:card_a', 'test : Card A'),
1470
        ('default:card_b', 'test : Card B'),
1471
        ('default:card_c', 'test : Card C'),
1472
        ('default:card_d', 'test : Card D'),
1473
        ('default:card_e', 'test : Card E'),
1395 1474
        ('other:card_model_1', 'test2 : Card Model 1'),
1396 1475
        ('other:card_model_1:foo', 'test2 : Card Model 1 - bar'),
1397 1476
        ('other:card_model_2', 'test2 : Card Model 2'),
1398 1477
        ('other:card_model_3', 'test2 : Card Model 3'),
1478
        ('other:card_a', 'test2 : Card A'),
1479
        ('other:card_b', 'test2 : Card B'),
1480
        ('other:card_c', 'test2 : Card C'),
1481
        ('other:card_d', 'test2 : Card D'),
1482
        ('other:card_e', 'test2 : Card E'),
1399 1483
    ]
1400 1484

  
1401 1485

  
......
1666 1750
        ('default:card_model_1', 'test : Card Model 1'),
1667 1751
        ('default:card_model_2', 'test : Card Model 2'),
1668 1752
        ('default:card_model_3', 'test : Card Model 3'),
1753
        ('default:card_a', 'test : Card A'),
1754
        ('default:card_b', 'test : Card B'),
1755
        ('default:card_c', 'test : Card C'),
1756
        ('default:card_d', 'test : Card D'),
1757
        ('default:card_e', 'test : Card E'),
1669 1758
        ('other:card_model_1', 'test2 : Card Model 1'),
1670 1759
        ('other:card_model_2', 'test2 : Card Model 2'),
1671 1760
        ('other:card_model_3', 'test2 : Card Model 3'),
1761
        ('other:card_a', 'test2 : Card A'),
1762
        ('other:card_b', 'test2 : Card B'),
1763
        ('other:card_c', 'test2 : Card C'),
1764
        ('other:card_d', 'test2 : Card D'),
1765
        ('other:card_e', 'test2 : Card E'),
1672 1766
    ]
1673 1767
    assert 'customize_display' not in form.fields
1674 1768
    assert 'custom_schema' not in form.fields
......
1773 1867
@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
1774 1868
def test_manager_card_cell(mock_send, app, admin_user):
1775 1869
    page = Page.objects.create(title='xxx', slug='test_cards', template_name='standard')
1776
    cell = WcsCardInfosCell(page=page, placeholder='content', order=0)
1870
    cell = WcsCardInfosCell.objects.create(page=page, placeholder='content', order=0)
1777 1871

  
1778 1872
    app = login(app)
1779 1873
    resp = app.get('/manage/pages/%s/' % page.pk)
......
1793 1887
    assert cell.without_user is True
1794 1888
    assert resp.forms[0]['c%s-with_user' % cell.get_reference()].value is None
1795 1889

  
1890
    # card with relations
1891
    cell.carddef_reference = 'default:card_a'
1892
    cell.save()
1893
    resp = app.get('/manage/pages/%s/' % page.pk)
1894
    # but only one cell on the page, no relations to follow
1895
    assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [
1896
        ('', True, 'Other Card Identifiers')
1897
    ]
1898

  
1899
    # add a second cell, related to the first card model
1900
    cell2 = WcsCardInfosCell.objects.create(
1901
        page=page, placeholder='content', order=1, carddef_reference='default:card_b'
1902
    )
1903
    resp = app.get('/manage/pages/%s/' % page.pk)
1904
    # still no relation to follow
1905
    assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [
1906
        ('', True, 'Other Card Identifiers')
1907
    ]
1908
    # no cell with id and slug
1909
    assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
1910
        ('', True, 'Other Card Identifiers')
1911
    ]
1912

  
1913
    # set a slug on first cell
1914
    cell.slug = 'sluga'
1915
    cell.save()
1916
    resp = app.get('/manage/pages/%s/' % page.pk)
1917
    # still no relation to follow
1918
    assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [
1919
        ('', True, 'Other Card Identifiers')
1920
    ]
1921
    # multiple relations to follow
1922
    assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
1923
        ('', True, 'Other Card Identifiers'),
1924
        ('sluga/cardb', False, 'sluga/cardb'),
1925
        ('sluga/cardsb', False, 'sluga/cardsb'),
1926
        ('sluga/blockb_cardb', False, 'sluga/blockb_cardb'),
1927
        ('sluga/cardc/cardb', False, 'sluga/cardc/cardb'),
1928
        ('sluga/cardc/cardsb', False, 'sluga/cardc/cardsb'),
1929
        ('sluga/cardc/blockb_cardb', False, 'sluga/cardc/blockb_cardb'),
1930
    ]
1931

  
1932
    # set a list of ids on first cell
1933
    cell.card_ids = '{{ cards|objects:"card_model_1"|getlist:"id"|join:"," }}'
1934
    cell.save()
1935
    resp = app.get('/manage/pages/%s/' % page.pk)
1936
    # still no relation to follow
1937
    assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [
1938
        ('', True, 'Other Card Identifiers')
1939
    ]
1940
    # can not user cell with multiple ids as reference
1941
    assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
1942
        ('', True, 'Other Card Identifiers')
1943
    ]
1944

  
1945
    # define a slug on second cell
1946
    cell.card_ids = ''
1947
    cell.save()
1948
    cell2.slug = 'slugb'
1949
    cell2.save()
1950
    resp = app.get('/manage/pages/%s/' % page.pk)
1951
    # multiple relations to follow
1952
    assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [
1953
        ('', True, 'Other Card Identifiers'),
1954
        ('slugb/reverse:cardb', False, 'slugb/cardb (reverse)'),
1955
        ('slugb/reverse:cardsb', False, 'slugb/cardsb (reverse)'),
1956
        ('slugb/reverse:blockb_cardb', False, 'slugb/blockb_cardb (reverse)'),
1957
    ]
1958
    # still multiple relations to follow
1959
    assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
1960
        ('', True, 'Other Card Identifiers'),
1961
        ('sluga/cardb', False, 'sluga/cardb'),
1962
        ('sluga/cardsb', False, 'sluga/cardsb'),
1963
        ('sluga/blockb_cardb', False, 'sluga/blockb_cardb'),
1964
        ('sluga/cardc/cardb', False, 'sluga/cardc/cardb'),
1965
        ('sluga/cardc/cardsb', False, 'sluga/cardc/cardsb'),
1966
        ('sluga/cardc/blockb_cardb', False, 'sluga/cardc/blockb_cardb'),
1967
    ]
1968

  
1969
    # set a related_path on cell2
1970
    resp.forms[1]['c%s-related_card_path' % cell2.get_reference()] = 'sluga/cardb'
1971
    resp.forms[1]['c%s-card_ids' % cell2.get_reference()] = 'foobar'
1972
    resp = resp.forms[1].submit()
1973
    cell2.refresh_from_db()
1974
    assert cell2.related_card_path == 'sluga/cardb'
1975
    assert cell2.card_ids == ''
1976
    resp = app.get('/manage/pages/%s/' % page.pk)
1977
    # no more relation to follow
1978
    assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [
1979
        ('', True, 'Other Card Identifiers')
1980
    ]
1981
    # still multiple relations to follow
1982
    assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
1983
        ('', False, 'Other Card Identifiers'),
1984
        ('sluga/cardb', True, 'sluga/cardb'),
1985
        ('sluga/cardsb', False, 'sluga/cardsb'),
1986
        ('sluga/blockb_cardb', False, 'sluga/blockb_cardb'),
1987
        ('sluga/cardc/cardb', False, 'sluga/cardc/cardb'),
1988
        ('sluga/cardc/cardsb', False, 'sluga/cardc/cardsb'),
1989
        ('sluga/cardc/blockb_cardb', False, 'sluga/cardc/blockb_cardb'),
1990
    ]
1991

  
1992
    # check circular relations
1993
    cell.slug = 'sluge'
1994
    cell.carddef_reference = 'default:card_e'
1995
    cell.save()
1996
    cell2.carddef_reference = 'default:card_d'
1997
    cell2.slug = 'slugd'
1998
    cell2.related_card_path = ''
1999
    cell2.save()
2000
    resp = app.get('/manage/pages/%s/' % page.pk)
2001
    assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [
2002
        ('', True, 'Other Card Identifiers'),
2003
        ('slugd/cardd-foo/carde-foo', False, 'slugd/cardd-foo/carde-foo'),
2004
        ('slugd/carde-foo', False, 'slugd/carde-foo'),
2005
    ]
2006
    assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
2007
        ('', True, 'Other Card Identifiers'),
2008
        ('sluge/cardd-bar', False, 'sluge/cardd-bar'),
2009
        ('sluge/reverse:carde-foo', False, 'sluge/carde-foo (reverse)'),
2010
    ]
2011

  
2012
    cell.slug = 'slugd'
2013
    cell.carddef_reference = 'default:card_d'
2014
    cell.save()
2015
    cell2.carddef_reference = 'default:card_d'
2016
    cell2.slug = 'slugd-bis'
2017
    cell2.related_card_path = ''
2018
    cell2.save()
2019
    resp = app.get('/manage/pages/%s/' % page.pk)
2020
    assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [
2021
        ('', True, 'Other Card Identifiers'),
2022
        ('slugd-bis/cardd-foo', False, 'slugd-bis/cardd-foo'),
2023
        ('slugd-bis/reverse:cardd-foo', False, 'slugd-bis/cardd-foo (reverse)'),
2024
        ('slugd-bis/carde-foo/cardd-bar', False, 'slugd-bis/carde-foo/cardd-bar'),
2025
        ('slugd-bis/carde-foo/reverse:carde-foo', False, 'slugd-bis/carde-foo/carde-foo (reverse)'),
2026
    ]
2027
    assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
2028
        ('', True, 'Other Card Identifiers'),
2029
        ('slugd/cardd-foo', False, 'slugd/cardd-foo'),
2030
        ('slugd/reverse:cardd-foo', False, 'slugd/cardd-foo (reverse)'),
2031
        ('slugd/carde-foo/cardd-bar', False, 'slugd/carde-foo/cardd-bar'),
2032
        ('slugd/carde-foo/reverse:carde-foo', False, 'slugd/carde-foo/carde-foo (reverse)'),
2033
    ]
2034

  
2035
    cell.slug = 'sluge'
2036
    cell.carddef_reference = 'default:card_e'
2037
    cell.save()
2038
    cell2.carddef_reference = 'default:card_e'
2039
    cell2.slug = 'sluge-bis'
2040
    cell2.related_card_path = ''
2041
    cell2.save()
2042
    resp = app.get('/manage/pages/%s/' % page.pk)
2043
    assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [
2044
        ('', True, 'Other Card Identifiers'),
2045
        ('sluge-bis/cardd-bar/carde-foo', False, 'sluge-bis/cardd-bar/carde-foo'),
2046
    ]
2047
    assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
2048
        ('', True, 'Other Card Identifiers'),
2049
        ('sluge/cardd-bar/carde-foo', False, 'sluge/cardd-bar/carde-foo'),
2050
    ]
2051

  
1796 2052

  
1797 2053
@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
1798 2054
def test_card_cell_load(mock_send):
......
2009 2265
    page = Page.objects.create(
2010 2266
        title='xxx', slug='foo', template_name='standard', sub_slug='(?P<card_model_1_id>[a-z0-9]+)'
2011 2267
    )
2012
    cell = WcsCardInfosCell(page=page, placeholder='content', order=0)
2013
    cell.carddef_reference = 'default:card_model_1'
2014
    cell.save()
2268
    cell = WcsCardInfosCell.objects.create(
2269
        page=page, placeholder='content', order=0, carddef_reference='default:card_model_1'
2270
    )
2015 2271

  
2016 2272
    cell_url = reverse(
2017 2273
        'combo-public-ajax-page-cell',
2018
-