diff --git a/combo/apps/wcs/models.py b/combo/apps/wcs/models.py index da39cabf..e52648f7 100644 --- a/combo/apps/wcs/models.py +++ b/combo/apps/wcs/models.py @@ -1029,6 +1029,50 @@ class WcsCardInfosCell(CardMixin, CellBase): def get_repeat_template(self, context): return len(context.get(self.global_context_key) or []) + def get_card_data_from_ids(self, card_id, context): + card_ids = context.get(self.global_context_key) + if not card_ids: + return None + + api_url = '/api/cards/%s/list?full=on' % (self.card_slug) + if self.card_custom_view: + api_url = '/api/cards/%s/list/%s?full=on' % ( + self.card_slug, + self.card_custom_view, + ) + user = self.get_concerned_user(context) + if user and not user.is_anonymous: + user_name_id = user.get_name_id() + if user_name_id: + api_url += '&filter-user-uuid=%s' % user_name_id + api_url += '&%s' % '&'.join(['filter-internal-id=%s' % cid for cid in card_ids]) + synchronous = bool(context.get('synchronous')) + wcs_site = get_wcs_services().get(self.wcs_site) + try: + response = requests.get( + api_url, + remote_service=wcs_site, + user=None if self.without_user else getattr(context.get('request'), 'user', None), + without_user=self.without_user, + cache_duration=5, + raise_if_not_cached=not synchronous, + log_errors=False, + ) + response.raise_for_status() + except RequestException: + if self.card_custom_view: + # if there's a custom view consider the error is a 404 because + # the card was not found in that view, and mark it so. + context['card_not_found'] = True + return None + + if response.status_code == 200: + data = response.json() + for card_data in data.get('data') or []: + if str(card_data.get('id')) == str(card_id): + return card_data + return None + def get_card_data(self, card_slug, card_custom_view, card_id, context, synchronous=False): api_url = '/api/cards/%s/%s/?include-files-content=off' % (card_slug, card_id) if card_custom_view: @@ -1325,7 +1369,7 @@ class WcsCardInfosCell(CardMixin, CellBase): extra_context['card_not_found'] = True return extra_context - card_data = self.get_card_data(self.card_slug, self.card_custom_view, card_id, context) + card_data = self.get_card_data_from_ids(card_id, context) if not card_data: return extra_context diff --git a/tests/test_wcs.py b/tests/test_wcs.py index b6df8594..dc1a1f3d 100644 --- a/tests/test_wcs.py +++ b/tests/test_wcs.py @@ -3243,7 +3243,8 @@ def test_card_cell_render_identifier(mock_send, nocache, app): assert 'Card Model 1' in cell_resp assert '

Unknown Card

' not in cell_resp assert len(mock_send.call_args_list) == 1 - assert '/api/cards/card_model_1/11/' in mock_send.call_args_list[0][0][0].url + assert '/api/cards/card_model_1/list' in mock_send.call_args_list[0][0][0].url + assert '&filter-internal-id=11&' in mock_send.call_args_list[0][0][0].url # with identifiers page.sub_slug = '' @@ -3261,7 +3262,8 @@ def test_card_cell_render_identifier(mock_send, nocache, app): assert 'Card Model 1' in cell_resp assert '

Unknown Card

' in cell_resp assert len(mock_send.call_args_list) == 1 - assert '/api/cards/card_model_1/42/' in mock_send.call_args_list[0][0][0].url + assert '/api/cards/card_model_1/list' in mock_send.call_args_list[0][0][0].url + assert '&filter-internal-id=42&' in mock_send.call_args_list[0][0][0].url cell.card_ids = '42, , 35' cell.save() @@ -3277,8 +3279,9 @@ def test_card_cell_render_identifier(mock_send, nocache, app): assert 'Card Model 1' in cell_resp assert '

Unknown Card

' in cell_resp assert len(mock_send.call_args_list) == 2 - assert '/api/cards/card_model_1/42/' in mock_send.call_args_list[0][0][0].url - assert '/api/cards/card_model_1/35/' in mock_send.call_args_list[1][0][0].url + for i in range(0, 2): + assert '/api/cards/card_model_1/list' in mock_send.call_args_list[i][0][0].url + assert '&filter-internal-id=42&filter-internal-id=35&' in mock_send.call_args_list[i][0][0].url cell.card_ids = '{% cards|objects:"card_model_1"|last|get:"id" %}' # syntax error cell.save() @@ -3304,7 +3307,8 @@ def test_card_cell_render_identifier(mock_send, nocache, app): assert '/api/cards/card_model_1/list' in mock_send.call_args_list[0][0][0].url # cell rendering assert '/api/cards/card_model_1/list' in mock_send.call_args_list[1][0][0].url - assert '/api/cards/card_model_1/13/' in mock_send.call_args_list[2][0][0].url + assert '/api/cards/card_model_1/list' in mock_send.call_args_list[2][0][0].url + assert '&filter-internal-id=13&' in mock_send.call_args_list[2][0][0].url def test_card_ids(): mock_send.reset_mock() @@ -3320,12 +3324,12 @@ def test_card_cell_render_identifier(mock_send, nocache, app): # page rendering assert '/api/cards/card_model_1/list' in mock_send.call_args_list[0][0][0].url # cell rendering + card_ids = [c['id'] for c in WCS_CARDS_DATA['card_model_1']] + filters = '&%s&' % '&'.join('filter-internal-id=%s' % cid for cid in card_ids) 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/%s/' % WCS_CARDS_DATA['card_model_1'][i]['id'] - in mock_send.call_args_list[i * 2 + 2][0][0].url - ) + assert '/api/cards/card_model_1/list' in mock_send.call_args_list[i * 2 + 2][0][0].url + assert filters in mock_send.call_args_list[i * 2 + 2][0][0].url for card_ids in [ '{% for card in cards|objects:"card_model_1" %}{{ card.id }},{% endfor %}', @@ -3398,8 +3402,11 @@ def test_card_cell_render_identifier_from_related(mock_send, nocache, app): cell_resp = app.get(cell2_url + '?ctx=' + extra_ctx[1]) assert cell_resp.context['repeat_index'] == 0 assert len(mock_send.call_args_list) == len(urls) - for j, url in enumerate(urls): - assert url in mock_send.call_args_list[j][0][0].url + for j, url_parts in enumerate(urls): + if not isinstance(url_parts, tuple): + url_parts = (url_parts,) + for url_part in url_parts: + assert url_part in mock_send.call_args_list[j][0][0].url def multiple(urls): resp = app.get(page.get_online_url()) @@ -3413,11 +3420,11 @@ def test_card_cell_render_identifier_from_related(mock_send, nocache, app): cell_resp = app.get(cell2_url + '?ctx=' + extra_ctx[i + 1]) assert cell_resp.context['repeat_index'] == i assert len(mock_send.call_args_list) == len(urls) - for j, url in enumerate(urls): - if isinstance(url, list): - assert url[i] in mock_send.call_args_list[j][0][0].url - else: - assert url in mock_send.call_args_list[j][0][0].url + for j, url_parts in enumerate(urls): + if not isinstance(url_parts, tuple): + url_parts = (url_parts,) + for url_part in url_parts: + assert url_part in mock_send.call_args_list[j][0][0].url # no cell with this slug cell2.related_card_path = 'slugz/cardb' @@ -3467,7 +3474,7 @@ def test_card_cell_render_identifier_from_related(mock_send, nocache, app): # get first cell data '/api/cards/card_a/1/', # and follow cardb relation - '/api/cards/card_b/1/', + ('/api/cards/card_b/list', '&filter-internal-id=1&'), ] ) cell3.delete() # reset @@ -3483,7 +3490,7 @@ def test_card_cell_render_identifier_from_related(mock_send, nocache, app): # follow cardc relation '/api/cards/card_c/6/', # and follow cardb relation - '/api/cards/card_b/7/', + ('/api/cards/card_b/list', '&filter-internal-id=7&'), ] ) @@ -3503,7 +3510,7 @@ def test_card_cell_render_identifier_from_related(mock_send, nocache, app): # follow cardc relation '/api/cards/card_c/6/', # and follow cardb relation - '/api/cards/card_b/7/', + ('/api/cards/card_b/list', '&filter-internal-id=7&'), ] resp = app.get(page.get_online_url()) assert len(resp.context['cells']) == 2 @@ -3515,8 +3522,11 @@ def test_card_cell_render_identifier_from_related(mock_send, nocache, app): cell_resp = app.get(cell2_url + '?ctx=' + extra_ctx[0]) assert cell_resp.context['repeat_index'] == 0 assert len(mock_send.call_args_list) == len(urls) - for j, url in enumerate(urls): - assert url in mock_send.call_args_list[j][0][0].url + for j, url_parts in enumerate(urls): + if not isinstance(url_parts, tuple): + url_parts = (url_parts,) + for url_part in url_parts: + assert url_part in mock_send.call_args_list[j][0][0].url # reset cell.order = 0 # reset @@ -3536,7 +3546,7 @@ def test_card_cell_render_identifier_from_related(mock_send, nocache, app): # follow cardc relation '/api/cards/card_c/6/', # and follow cardb relation - '/api/cards/card_b/a-custom-view/7/', + ('/api/cards/card_b/list/a-custom-view', '&filter-internal-id=7&'), ] ) @@ -3549,7 +3559,7 @@ def test_card_cell_render_identifier_from_related(mock_send, nocache, app): # get first cell data '/api/cards/card_a/1/', # and follow cardb relation - ['/api/cards/card_b/2/', '/api/cards/card_b/3/'], + ('/api/cards/card_b/list', '&filter-internal-id=2&filter-internal-id=3&'), ] ) @@ -3564,7 +3574,7 @@ def test_card_cell_render_identifier_from_related(mock_send, nocache, app): # follow cardc relation '/api/cards/card_c/6/', # and follow cardb relation - ['/api/cards/card_b/8/', '/api/cards/card_b/9/'], + ('/api/cards/card_b/list', '&filter-internal-id=8&filter-internal-id=9&'), ] ) @@ -3576,7 +3586,7 @@ def test_card_cell_render_identifier_from_related(mock_send, nocache, app): # get first cell data '/api/cards/card_a/1/', # and follow cardb relation - ['/api/cards/card_b/4/', '/api/cards/card_b/5/'], + ('/api/cards/card_b/list', '&filter-internal-id=4&filter-internal-id=5&'), ] ) @@ -3591,7 +3601,7 @@ def test_card_cell_render_identifier_from_related(mock_send, nocache, app): # follow cardc relation '/api/cards/card_c/6/', # and follow cardb relation - ['/api/cards/card_b/10/', '/api/cards/card_b/11/'], + ('/api/cards/card_b/list', '&filter-internal-id=10&filter-internal-id=11&'), ] ) @@ -3753,7 +3763,10 @@ def test_card_cell_render_identifier_from_related(mock_send, nocache, app): # get list of card_a with cardb=1 '/api/cards/card_a/list?orig=combo&filter-cardb=1', # and follow carda reverse relation - ['/api/cards/card_a/%s/' % i for i in range(1, 5)], + ( + '/api/cards/card_a/list', + '&filter-internal-id=1&filter-internal-id=2&filter-internal-id=3&filter-internal-id=4&', + ), ] ) @@ -3767,7 +3780,10 @@ def test_card_cell_render_identifier_from_related(mock_send, nocache, app): # get list of card_a with cardsb=1 '/api/cards/card_a/list?orig=combo&filter-cardsb=1', # and follow carda reverse relation - ['/api/cards/card_a/%s/' % i for i in range(1, 5)], + ( + '/api/cards/card_a/list', + '&filter-internal-id=1&filter-internal-id=2&filter-internal-id=3&filter-internal-id=4&', + ), ] ) @@ -3781,7 +3797,10 @@ def test_card_cell_render_identifier_from_related(mock_send, nocache, app): # get list of card_a with cardsb=1 '/api/cards/card_a/list?orig=combo&filter-blockb_cardb=1', # and follow carda reverse relation - ['/api/cards/card_a/%s/' % i for i in range(1, 5)], + ( + '/api/cards/card_a/list', + '&filter-internal-id=1&filter-internal-id=2&filter-internal-id=3&filter-internal-id=4&', + ), ] ) @@ -3823,7 +3842,7 @@ def test_card_cell_render_identifier_from_related(mock_send, nocache, app): # get list of card_f with cardf=42 '/api/cards/card_f/list?orig=combo&filter-cardh=42', # and follow cardf reverse relation - ['/api/cards/card_f/41/'], + ('/api/cards/card_f/list', '&filter-internal-id=41&'), ] ) @@ -3842,7 +3861,7 @@ def test_card_cell_render_identifier_from_related(mock_send, nocache, app): # get list of card_g with cardf=44 '/api/cards/card_g/list?orig=combo&filter-cardh=44', # and follow cardf reverse relation - ['/api/cards/card_g/43/'], + ('/api/cards/card_g/list', '&filter-internal-id=43&'), ] )