From 25da1b91b77999367b5c60c2210176472de34834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= Date: Tue, 9 Aug 2022 15:31:59 +0200 Subject: [PATCH] wcs: option to list all cards (#68037) --- combo/apps/wcs/forms.py | 1 + combo/apps/wcs/models.py | 29 +++++++++++++----- tests/test_wcs.py | 65 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 7 deletions(-) diff --git a/combo/apps/wcs/forms.py b/combo/apps/wcs/forms.py index 1813086a..99e1c5ee 100644 --- a/combo/apps/wcs/forms.py +++ b/combo/apps/wcs/forms.py @@ -126,6 +126,7 @@ class WcsCardInfoCellForm(forms.ModelForm): if not self.instance.card_ids and not self.instance.related_card_path: self.initial['related_card_path'] = '--' self.fields['related_card_path'].choices += [ + ('__all__', _('All cards')), ('', _('Other Card Identifiers')), ] + self.instance.get_related_card_paths() diff --git a/combo/apps/wcs/models.py b/combo/apps/wcs/models.py index 64de63bd..6c4a61c4 100644 --- a/combo/apps/wcs/models.py +++ b/combo/apps/wcs/models.py @@ -1019,9 +1019,9 @@ class WcsCardInfosCell(CardMixin, CellBase): return super().is_visible(request, **kwargs) def check_validity(self): - if self.related_card_path: + if self.get_related_card_path(): relations = [r[0] for r in self.get_related_card_paths()] - if self.related_card_path not in relations: + if self.get_related_card_path() not in relations: self.mark_as_invalid('wcs_card_relation_not_found') return @@ -1039,6 +1039,16 @@ class WcsCardInfosCell(CardMixin, CellBase): def get_repeat_template(self, context): return len(context.get(self.global_context_key) or []) + def get_related_card_path(self): + if self.related_card_path == '__all__': + return '' + return self.related_card_path + + def must_get_all(self): + if self.related_card_path == '__all__': + return True + return False + def get_cards_from_ids(self, card_ids, context, synchronous=False): # if check_user, get all cards from ids in context, with correct filter-user-uuid and without_user value # use custom view if requested @@ -1051,7 +1061,8 @@ class WcsCardInfosCell(CardMixin, CellBase): user = self.get_concerned_user(context) if self.only_for_user and user and not user.is_anonymous and user.get_name_id(): api_url += '&filter-user-uuid=%s' % user.get_name_id() - api_url += '&%s' % '&'.join(['filter-internal-id=%s' % cid for cid in card_ids]) + if not self.must_get_all(): + api_url += '&%s' % '&'.join(['filter-internal-id=%s' % cid for cid in card_ids]) if not synchronous: synchronous = bool(context.get('synchronous')) wcs_site = get_wcs_services().get(self.wcs_site) @@ -1318,7 +1329,7 @@ class WcsCardInfosCell(CardMixin, CellBase): parts=parts[1:], ) - first_cell_slug = self.related_card_path.split('/')[0] + first_cell_slug = self.get_related_card_path().split('/', maxsplit=1)[0] try: first_cell = WcsCardInfosCell.objects.get(page=self.page_id, slug=first_cell_slug) except (WcsCardInfosCell.DoesNotExist, WcsCardInfosCell.MultipleObjectsReturned): @@ -1346,7 +1357,7 @@ class WcsCardInfosCell(CardMixin, CellBase): if not card_data: # card data not found return [] - parts = self.related_card_path.split('/')[1:] + parts = self.get_related_card_path().split('/')[1:] return follow_data( card_data=card_data, relations=first_cell.cached_json['relations'], @@ -1368,7 +1379,7 @@ class WcsCardInfosCell(CardMixin, CellBase): # not configured return [] - if self.related_card_path: + if self.get_related_card_path(): # look at other cells to get related ids card_ids = self.get_card_ids_from_related(original_context, request) if card_ids == []: @@ -1386,6 +1397,10 @@ class WcsCardInfosCell(CardMixin, CellBase): ) return self.filter_card_ids(card_ids, original_context) + if self.must_get_all(): + # get all cards + return [c['id'] for c in self.get_cards_from_ids([], original_context, synchronous=True)] + if self.card_ids: # card ids template is defined return self.get_card_ids_from_template(self.card_ids, original_context, request) @@ -1430,7 +1445,7 @@ class WcsCardInfosCell(CardMixin, CellBase): card_id = self.get_card_id(context) if not card_id: if self.card_ids or self.related_card_path: - # template or related_card_path defined, but result is empty or None + # all cards, template or related_card_path defined, but result is empty or None extra_context['card_not_found'] = True return extra_context diff --git a/tests/test_wcs.py b/tests/test_wcs.py index a8ed6670..df8fa1e7 100644 --- a/tests/test_wcs.py +++ b/tests/test_wcs.py @@ -2372,10 +2372,23 @@ def test_manager_card_cell(mock_send, app, admin_user): # but only one cell on the page, no relations to follow assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [ ('--', True, 'Identifier from page URL'), + ('__all__', False, 'All cards'), + ('', False, 'Other Card Identifiers'), + ] + + # all cards + cell.related_card_path = '__all__' + cell.save() + resp = app.get('/manage/pages/%s/' % page.pk) + assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [ + ('--', False, 'Identifier from page URL'), + ('__all__', True, 'All cards'), ('', False, 'Other Card Identifiers'), ] # add a second cell, related to the first card model + cell.related_card_path = '' + cell.save() cell2 = WcsCardInfosCell.objects.create( page=page, placeholder='content', order=1, carddef_reference='default:card_b' ) @@ -2383,11 +2396,13 @@ def test_manager_card_cell(mock_send, app, admin_user): # still no relation to follow assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [ ('--', True, 'Identifier from page URL'), + ('__all__', False, 'All cards'), ('', False, 'Other Card Identifiers'), ] # no cell with id and slug assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [ ('--', True, 'Identifier from page URL'), + ('__all__', False, 'All cards'), ('', False, 'Other Card Identifiers'), ] @@ -2398,11 +2413,13 @@ def test_manager_card_cell(mock_send, app, admin_user): # still no relation to follow assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [ ('--', True, 'Identifier from page URL'), + ('__all__', False, 'All cards'), ('', False, 'Other Card Identifiers'), ] # multiple relations to follow assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [ ('--', True, 'Identifier from page URL'), + ('__all__', False, 'All cards'), ('', False, 'Other Card Identifiers'), ('sluga/cardb', False, 'sluga/cardb'), ('sluga/cardsb', False, 'sluga/cardsb'), @@ -2419,11 +2436,13 @@ def test_manager_card_cell(mock_send, app, admin_user): # still no relation to follow assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [ ('--', False, 'Identifier from page URL'), + ('__all__', False, 'All cards'), ('', True, 'Other Card Identifiers'), ] # can not user cell with multiple ids as reference assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [ ('--', True, 'Identifier from page URL'), + ('__all__', False, 'All cards'), ('', False, 'Other Card Identifiers'), ] @@ -2436,6 +2455,7 @@ def test_manager_card_cell(mock_send, app, admin_user): # multiple relations to follow assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [ ('--', True, 'Identifier from page URL'), + ('__all__', False, 'All cards'), ('', False, 'Other Card Identifiers'), ('slugb/reverse:cardb', False, 'slugb/cardb (reverse)'), ('slugb/reverse:cardsb', False, 'slugb/cardsb (reverse)'), @@ -2444,6 +2464,7 @@ def test_manager_card_cell(mock_send, app, admin_user): # still multiple relations to follow assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [ ('--', True, 'Identifier from page URL'), + ('__all__', False, 'All cards'), ('', False, 'Other Card Identifiers'), ('sluga/cardb', False, 'sluga/cardb'), ('sluga/cardsb', False, 'sluga/cardsb'), @@ -2464,11 +2485,13 @@ def test_manager_card_cell(mock_send, app, admin_user): # no more relation to follow assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [ ('--', True, 'Identifier from page URL'), + ('__all__', False, 'All cards'), ('', False, 'Other Card Identifiers'), ] # still multiple relations to follow assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [ ('--', False, 'Identifier from page URL'), + ('__all__', False, 'All cards'), ('', False, 'Other Card Identifiers'), ('sluga/cardb', True, 'sluga/cardb'), ('sluga/cardsb', False, 'sluga/cardsb'), @@ -2493,12 +2516,14 @@ def test_manager_card_cell(mock_send, app, admin_user): resp = app.get('/manage/pages/%s/' % page.pk) assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [ ('--', True, 'Identifier from page URL'), + ('__all__', False, 'All cards'), ('', False, 'Other Card Identifiers'), ('slugd/cardd-foo/carde-foo', False, 'slugd/cardd-foo/carde-foo'), ('slugd/carde-foo', False, 'slugd/carde-foo'), ] assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [ ('--', True, 'Identifier from page URL'), + ('__all__', False, 'All cards'), ('', False, 'Other Card Identifiers'), ('sluge/cardd-bar', False, 'sluge/cardd-bar'), ('sluge/reverse:carde-foo', False, 'sluge/carde-foo (reverse)'), @@ -2514,6 +2539,7 @@ def test_manager_card_cell(mock_send, app, admin_user): resp = app.get('/manage/pages/%s/' % page.pk) assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [ ('--', True, 'Identifier from page URL'), + ('__all__', False, 'All cards'), ('', False, 'Other Card Identifiers'), ('slugd-bis/cardd-foo', False, 'slugd-bis/cardd-foo'), ('slugd-bis/reverse:cardd-foo', False, 'slugd-bis/cardd-foo (reverse)'), @@ -2522,6 +2548,7 @@ def test_manager_card_cell(mock_send, app, admin_user): ] assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [ ('--', True, 'Identifier from page URL'), + ('__all__', False, 'All cards'), ('', False, 'Other Card Identifiers'), ('slugd/cardd-foo', False, 'slugd/cardd-foo'), ('slugd/reverse:cardd-foo', False, 'slugd/cardd-foo (reverse)'), @@ -2539,11 +2566,13 @@ def test_manager_card_cell(mock_send, app, admin_user): resp = app.get('/manage/pages/%s/' % page.pk) assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [ ('--', True, 'Identifier from page URL'), + ('__all__', False, 'All cards'), ('', False, 'Other Card Identifiers'), ('sluge-bis/cardd-bar/carde-foo', False, 'sluge-bis/cardd-bar/carde-foo'), ] assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [ ('--', True, 'Identifier from page URL'), + ('__all__', False, 'All cards'), ('', False, 'Other Card Identifiers'), ('sluge/cardd-bar/carde-foo', False, 'sluge/cardd-bar/carde-foo'), ] @@ -3226,6 +3255,42 @@ def test_card_cell_render_custom_schema_link_entry(mock_send, context, app): ) +@mock.patch('requests.Session.send', side_effect=mocked_requests_send) +def test_card_cell_render_all_cards(mock_send, nocache, app): + page = Page.objects.create(title='xxx', slug='foo', template_name='standard') + cell = WcsCardInfosCell.objects.create( + page=page, + placeholder='content', + order=0, + carddef_reference='default:card_model_1', + related_card_path='__all__', + ) + + cell_url = reverse( + 'combo-public-ajax-page-cell', + kwargs={'page_pk': page.pk, 'cell_reference': cell.get_reference()}, + ) + + # check url called + mock_send.reset_mock() + resp = app.get(page.get_online_url()) + assert len(resp.context['cells']) == 3 + extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text) + for i in range(0, 3): + assert resp.context['cells'][i].pk == cell.pk + assert resp.context['cells'][i].repeat_index == i + cell_resp = app.get(cell_url + '?ctx=' + extra_ctx[i]) + assert cell_resp.context['repeat_index'] == i + assert len(mock_send.call_args_list) == 7 + # page rendering + assert '/api/cards/card_model_1/list' in mock_send.call_args_list[0][0][0].url + # cell rendering + for i in range(0, 3): + assert '/api/cards/card_model_1/list' in mock_send.call_args_list[i * 2 + 1][0][0].url + assert '/api/cards/card_model_1/list' in mock_send.call_args_list[i * 2 + 2][0][0].url + assert 'filter-internal-id' not in mock_send.call_args_list[i * 2 + 2][0][0].url + + @mock.patch('requests.Session.send', side_effect=mocked_requests_send) def test_card_cell_render_identifier(mock_send, nocache, app): page = Page.objects.create(