wcs: card cell & multiple card identifiers (#58862)
This commit is contained in:
parent
09c30d619c
commit
39c7114cf7
|
@ -71,7 +71,7 @@ class WcsCardInfoCellForm(forms.ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = WcsCardInfosCell
|
||||
fields = ('carddef_reference', 'title_type', 'custom_title', 'card_id', 'custom_schema')
|
||||
fields = ('carddef_reference', 'title_type', 'custom_title', 'card_ids', 'custom_schema')
|
||||
widgets = {
|
||||
'custom_schema': forms.HiddenInput(),
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('wcs', '0042_current_forms_custom_title'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name='wcscardinfoscell',
|
||||
old_name='card_id',
|
||||
new_name='card_ids',
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='wcscardinfoscell',
|
||||
name='card_ids',
|
||||
field=models.CharField(blank=True, max_length=1000, verbose_name='Card Identifiers'),
|
||||
),
|
||||
]
|
|
@ -24,7 +24,7 @@ from django.contrib.postgres.fields import JSONField
|
|||
from django.db import models
|
||||
from django.forms import Select
|
||||
from django.forms import models as model_forms
|
||||
from django.template import Context, Template, TemplateSyntaxError, VariableDoesNotExist
|
||||
from django.template import Context, RequestContext, Template, TemplateSyntaxError, VariableDoesNotExist
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.text import slugify
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
@ -899,7 +899,7 @@ class WcsCardsCell(CardMixin, WcsBlurpMixin, CellBase):
|
|||
@register_cell_class
|
||||
class WcsCardInfosCell(CardMixin, CellBase):
|
||||
carddef_reference = models.CharField(_('Card Model'), max_length=150)
|
||||
card_id = models.CharField(_('Card Identifier'), max_length=1000, blank=True)
|
||||
card_ids = models.CharField(_('Card Identifiers'), max_length=1000, blank=True)
|
||||
without_user = models.BooleanField(_('Ignore the logged-in user'), default=False)
|
||||
custom_schema = JSONField(blank=True, default=dict)
|
||||
|
||||
|
@ -961,16 +961,39 @@ class WcsCardInfosCell(CardMixin, CellBase):
|
|||
|
||||
populate_cache()
|
||||
|
||||
def get_card_id(self, context):
|
||||
if self.card_id:
|
||||
@property
|
||||
def global_context_key(self):
|
||||
return '%s-card-ids' % self.get_reference()
|
||||
|
||||
def modify_global_context(self, context, request):
|
||||
if self.global_context_key not in context:
|
||||
card_ids = self.get_card_ids(context, request)
|
||||
context[self.global_context_key] = card_ids
|
||||
|
||||
def get_repeat_template(self, context):
|
||||
return len(context[self.global_context_key])
|
||||
|
||||
def get_card_ids(self, original_context, request):
|
||||
if self.card_ids:
|
||||
try:
|
||||
return Template(self.card_id).render(Context(context))
|
||||
context = RequestContext(request)
|
||||
context.push(original_context)
|
||||
ids = Template(self.card_ids).render(context).split(',')
|
||||
return [i.strip() for i in ids if i.strip()]
|
||||
except (VariableDoesNotExist, TemplateSyntaxError):
|
||||
return None
|
||||
return []
|
||||
|
||||
card_slug = self.carddef_reference.split(':')[1]
|
||||
card_id = '%s_id' % card_slug
|
||||
return context.get(card_id) or None
|
||||
if original_context.get(card_id):
|
||||
return [original_context[card_id]]
|
||||
return []
|
||||
|
||||
def get_card_id(self, context):
|
||||
repeat_index = getattr(self, 'repeat_index', context.get('repeat_index'))
|
||||
if repeat_index is not None:
|
||||
return context[self.global_context_key][repeat_index]
|
||||
return None
|
||||
|
||||
def get_extra_manager_context(self):
|
||||
extra_context = super().get_extra_manager_context()
|
||||
|
@ -992,7 +1015,7 @@ class WcsCardInfosCell(CardMixin, CellBase):
|
|||
|
||||
card_id = self.get_card_id(context)
|
||||
if not card_id:
|
||||
if self.card_id: # template defined, but result is empty or None
|
||||
if self.card_ids: # template defined, but result is empty or None
|
||||
extra_context['card_not_found'] = True
|
||||
return extra_context
|
||||
card_slug = self.carddef_reference.split(':')[1]
|
||||
|
|
|
@ -2110,8 +2110,7 @@ class ConfigJsonCell(JsonCellBase):
|
|||
def make_global(self):
|
||||
return settings.JSON_CELL_TYPES[self.key].get('make_global', False)
|
||||
|
||||
@property
|
||||
def repeat(self):
|
||||
def get_repeat_template(self, context):
|
||||
return settings.JSON_CELL_TYPES[self.key].get('repeat')
|
||||
|
||||
@property
|
||||
|
|
|
@ -108,8 +108,8 @@ def placeholder(context, placeholder_name, **options):
|
|||
context['skeleton'] = ''
|
||||
|
||||
if not context.get('placeholder_search_mode'):
|
||||
for cell in [x for x in context['cells'] if hasattr(x, 'repeat')]:
|
||||
repeat_template = cell.repeat
|
||||
for cell in [x for x in context['cells'] if hasattr(x, 'get_repeat_template')]:
|
||||
repeat_template = cell.get_repeat_template(context)
|
||||
if not repeat_template:
|
||||
continue
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ from requests.models import Response
|
|||
from combo.apps.search.engines import engines
|
||||
from combo.apps.search.models import SearchCell
|
||||
from combo.apps.search.utils import index_site, search_site
|
||||
from combo.apps.wcs.context_processors import Cards
|
||||
from combo.apps.wcs.models import (
|
||||
BackofficeSubmissionCell,
|
||||
CategoriesCell,
|
||||
|
@ -1616,7 +1615,6 @@ def test_cards_cell_render_user(mock_send, context, nocache):
|
|||
cell.carddef_reference = 'default:card_model_1'
|
||||
cell.save()
|
||||
|
||||
context['card_model_1_id'] = 11
|
||||
context['synchronous'] = True # to get fresh content
|
||||
|
||||
assert context['request'].user is None
|
||||
|
@ -1828,6 +1826,9 @@ def test_card_cell_render(mock_send, context):
|
|||
assert '<p>Unknown Card</p>' in result
|
||||
|
||||
context['card_model_1_id'] = 11
|
||||
request = RequestFactory().get('/')
|
||||
cell.modify_global_context(context, request)
|
||||
cell.repeat_index = 0
|
||||
|
||||
# query should fail as nothing is cached
|
||||
cache.clear()
|
||||
|
@ -1897,6 +1898,9 @@ def test_card_cell_render_text_field(mock_send, context):
|
|||
cell.save()
|
||||
|
||||
context['card_model_1_id'] = 11
|
||||
request = RequestFactory().get('/')
|
||||
cell.modify_global_context(context, request)
|
||||
cell.repeat_index = 0
|
||||
context['synchronous'] = True # to get fresh content
|
||||
|
||||
result = cell.render(context)
|
||||
|
@ -1927,6 +1931,9 @@ def test_card_cell_render_email_field(mock_send, context):
|
|||
cell.save()
|
||||
|
||||
context['card_model_1_id'] = 11
|
||||
request = RequestFactory().get('/')
|
||||
cell.modify_global_context(context, request)
|
||||
cell.repeat_index = 0
|
||||
context['synchronous'] = True # to get fresh content
|
||||
|
||||
result = cell.render(context)
|
||||
|
@ -1952,6 +1959,9 @@ def test_card_cell_render_custom_schema(mock_send, context):
|
|||
cell.save()
|
||||
|
||||
context['card_model_1_id'] = 11
|
||||
request = RequestFactory().get('/')
|
||||
cell.modify_global_context(context, request)
|
||||
cell.repeat_index = 0
|
||||
context['synchronous'] = True # to get fresh content
|
||||
|
||||
result = cell.render(context)
|
||||
|
@ -1994,58 +2004,128 @@ def test_card_cell_render_custom_schema(mock_send, context):
|
|||
|
||||
|
||||
@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
|
||||
def test_card_cell_render_identifier(mock_send, context, nocache):
|
||||
page = Page.objects.create(title='xxx', template_name='standard')
|
||||
def test_card_cell_render_identifier(mock_send, nocache, app):
|
||||
page = Page.objects.create(
|
||||
title='xxx', slug='foo', template_name='standard', sub_slug='(?P<card_model_1_id>[a-z0-9]+)'
|
||||
)
|
||||
cell = WcsCardInfosCell(page=page, placeholder='content', order=0)
|
||||
cell.carddef_reference = 'default:card_model_1'
|
||||
cell.save()
|
||||
|
||||
context['card_model_1_id'] = 11
|
||||
context['synchronous'] = True # to get fresh content
|
||||
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()
|
||||
result = cell.render(context)
|
||||
resp = app.get(page.get_online_url() + '11/')
|
||||
assert len(resp.context['cells']) == 1
|
||||
assert resp.context['cells'][0].pk == cell.pk
|
||||
assert resp.context['cells'][0].repeat_index == 0
|
||||
extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
|
||||
cell_resp = app.get(cell_url + '?ctx=' + extra_ctx[0])
|
||||
assert cell_resp.context['repeat_index'] == 0
|
||||
assert 'Card Model 1' in cell_resp
|
||||
assert '<p>Unknown Card</p>' 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 'Card Model 1' in result
|
||||
assert '<p>Unknown Card</p>' not in result
|
||||
|
||||
# with identifier
|
||||
cell.card_id = '42'
|
||||
# with identifiers
|
||||
page.sub_slug = ''
|
||||
page.save()
|
||||
cell.card_ids = '42'
|
||||
cell.save()
|
||||
mock_send.reset_mock()
|
||||
result = cell.render(context)
|
||||
resp = app.get(page.get_online_url())
|
||||
assert len(resp.context['cells']) == 1
|
||||
assert resp.context['cells'][0].pk == cell.pk
|
||||
assert resp.context['cells'][0].repeat_index == 0
|
||||
extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
|
||||
cell_resp = app.get(cell_url + '?ctx=' + extra_ctx[0])
|
||||
assert cell_resp.context['repeat_index'] == 0
|
||||
assert 'Card Model 1' in cell_resp
|
||||
assert '<p>Unknown Card</p>' 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 'Card Model 1' in result
|
||||
assert '<p>Unknown Card</p>' in result
|
||||
|
||||
context['cards'] = Cards()
|
||||
cell.card_id = '{% cards|objects:"card_model_1"|last|get:"id" %}' # syntax error
|
||||
cell.card_ids = '42, , 35'
|
||||
cell.save()
|
||||
mock_send.reset_mock()
|
||||
result = cell.render(context)
|
||||
assert mock_send.call_args_list == []
|
||||
assert result.replace('\n', '') == '' # empty-cell
|
||||
resp = app.get(page.get_online_url())
|
||||
assert len(resp.context['cells']) == 2
|
||||
extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
|
||||
for i in range(0, 2):
|
||||
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 'Card Model 1' in cell_resp
|
||||
assert '<p>Unknown Card</p>' 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
|
||||
|
||||
del context['card_not_found']
|
||||
cell.card_id = '{{ cards|objects:"card_model_1"|last|get:"id" }}'
|
||||
cell.card_ids = '{% cards|objects:"card_model_1"|last|get:"id" %}' # syntax error
|
||||
cell.save()
|
||||
mock_send.reset_mock()
|
||||
result = cell.render(context)
|
||||
resp = app.get(page.get_online_url())
|
||||
assert len(resp.context['cells']) == 1
|
||||
extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
|
||||
cell_resp = app.get(cell_url + '?ctx=' + extra_ctx[0])
|
||||
assert cell_resp.text.replace('\n', '') == '' # empty-cell
|
||||
|
||||
cell.card_ids = '{{ cards|objects:"card_model_1"|last|get:"id" }}'
|
||||
cell.save()
|
||||
mock_send.reset_mock()
|
||||
resp = app.get(page.get_online_url())
|
||||
assert len(resp.context['cells']) == 1
|
||||
assert resp.context['cells'][0].pk == cell.pk
|
||||
assert resp.context['cells'][0].repeat_index == 0
|
||||
extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
|
||||
cell_resp = app.get(cell_url + '?ctx=' + extra_ctx[0])
|
||||
assert cell_resp.context['repeat_index'] == 0
|
||||
assert len(mock_send.call_args_list) == 3
|
||||
# page rendering
|
||||
assert '/api/cards/card_model_1/list' in mock_send.call_args_list[0][0][0].url
|
||||
assert '/api/cards/card_model_1/13/' in mock_send.call_args_list[1][0][0].url
|
||||
assert 'Card Model 1' in result
|
||||
assert '<p>Unknown Card</p>' in result
|
||||
# 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
|
||||
|
||||
# with a card_id template, but result is empty
|
||||
del context['card_model_1_id']
|
||||
cell.card_id = '{{ foo }}'
|
||||
for card_ids in [
|
||||
'{% for card in cards|objects:"card_model_1" %}{{ card.id }},{% endfor %}',
|
||||
'{{ cards|objects:"card_model_1"|getlist:"id"|join:"," }}',
|
||||
]:
|
||||
cell.card_ids = card_ids
|
||||
cell.save()
|
||||
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/%s/' % WCS_CARDS_DATA[i]['id']
|
||||
in mock_send.call_args_list[i * 2 + 2][0][0].url
|
||||
)
|
||||
|
||||
# with a card_ids template, but result is empty
|
||||
cell.card_ids = '{{ foo }}'
|
||||
cell.save()
|
||||
assert cell.get_card_id(context) == ''
|
||||
mock_send.reset_mock()
|
||||
result = cell.render(context)
|
||||
assert mock_send.call_args_list == []
|
||||
assert result.replace('\n', '') == '' # empty-cell
|
||||
resp = app.get(page.get_online_url())
|
||||
assert len(resp.context['cells']) == 1
|
||||
extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
|
||||
cell_resp = app.get(cell_url + '?ctx=' + extra_ctx[0])
|
||||
assert cell_resp.text.replace('\n', '') == '' # empty-cell
|
||||
|
||||
|
||||
@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
|
||||
|
@ -2056,6 +2136,9 @@ def test_card_cell_render_user(mock_send, context, nocache):
|
|||
cell.save()
|
||||
|
||||
context['card_model_1_id'] = 11
|
||||
request = RequestFactory().get('/')
|
||||
cell.modify_global_context(context, request)
|
||||
cell.repeat_index = 0
|
||||
context['synchronous'] = True # to get fresh content
|
||||
|
||||
assert context['request'].user is None
|
||||
|
@ -2679,11 +2762,12 @@ def test_card_file_redirection(mock_send, app):
|
|||
page.save()
|
||||
cell = WcsCardInfosCell(page=page, placeholder='content', order=0)
|
||||
cell.carddef_reference = 'default:card_model_1'
|
||||
cell.card_id = '11'
|
||||
cell.card_ids = '11'
|
||||
cell.save()
|
||||
resp = app.get('/one/')
|
||||
ajax_cell_url = PyQuery(resp.text).find('[data-ajax-cell-url]').attr['data-ajax-cell-url']
|
||||
resp = app.get(ajax_cell_url)
|
||||
extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
|
||||
resp = app.get(ajax_cell_url + '?ctx=' + extra_ctx[0])
|
||||
file_url = PyQuery(resp.text).find('[download]').attr['href']
|
||||
resp = app.get(file_url)
|
||||
assert 'download?f=42' in resp.location
|
||||
|
|
Loading…
Reference in New Issue