3397 lines
124 KiB
Python
3397 lines
124 KiB
Python
import json
|
|
import re
|
|
import sys
|
|
from io import StringIO
|
|
from unittest import mock
|
|
|
|
import pytest
|
|
from django.apps import apps
|
|
from django.contrib.auth.models import AnonymousUser
|
|
from django.core.cache import cache
|
|
from django.core.management import call_command
|
|
from django.test.client import RequestFactory
|
|
from django.urls import reverse
|
|
from pyquery import PyQuery
|
|
from requests.exceptions import ConnectionError
|
|
from requests.models import Response
|
|
|
|
from combo.apps.wcs.forms import WcsCardCellDisplayForm
|
|
from combo.apps.wcs.models import WcsCardCell
|
|
from combo.data.models import Page, PageSnapshot, TextCell, ValidityInfo
|
|
from combo.data.utils import import_site
|
|
from tests.test_manager import login
|
|
from tests.utils import manager_submit_cell
|
|
|
|
from .utils import WCS_CARDS_DATA, MockedRequestResponse, MockUser, MockUserWithNameId, mocked_requests_send
|
|
|
|
pytestmark = pytest.mark.django_db
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_setup(mock_send, app, admin_user):
|
|
page = Page.objects.create(
|
|
title='xxx', slug='test_card_cell_save_cache', template_name='standard', sub_slug='foobar'
|
|
)
|
|
cell = WcsCardCell(page=page, placeholder='content', order=0)
|
|
form_class = cell.get_default_form_class()
|
|
form = form_class(instance=cell)
|
|
assert form.fields['carddef_reference'].widget.choices == [
|
|
('default:card_model_1', 'test : Card Model 1'),
|
|
('default:card_model_1:foo', 'test : Card Model 1 - bar'),
|
|
('default:card_model_2', 'test : Card Model 2'),
|
|
('default:card_model_3', 'test : Card Model 3'),
|
|
('default:card_a', 'test : Card A'),
|
|
('default:card_b', 'test : Card B'),
|
|
('default:card_b:a-custom-view', 'test : Card B - foo bar'),
|
|
('default:card_c', 'test : Card C'),
|
|
('default:card_d', 'test : Card D'),
|
|
('default:card_e', 'test : Card E'),
|
|
('other:card_model_1', 'test2 : Card Model 1'),
|
|
('other:card_model_1:foo', 'test2 : Card Model 1 - bar'),
|
|
('other:card_model_2', 'test2 : Card Model 2'),
|
|
('other:card_model_3', 'test2 : Card Model 3'),
|
|
('other:card_a', 'test2 : Card A'),
|
|
('other:card_b', 'test2 : Card B'),
|
|
('other:card_b:a-custom-view', 'test2 : Card B - foo bar'),
|
|
('other:card_c', 'test2 : Card C'),
|
|
('other:card_d', 'test2 : Card D'),
|
|
('other:card_e', 'test2 : Card E'),
|
|
]
|
|
|
|
form_display = WcsCardCellDisplayForm(instance=cell)
|
|
assert 'customize_display' not in form_display.fields
|
|
assert 'custom_schema' not in form_display.fields
|
|
|
|
cell.save()
|
|
assert 'customize_display' not in form_display.fields
|
|
assert 'custom_schema' not in form_display.fields
|
|
|
|
cell.carddef_reference = 'default:card_model_1'
|
|
cell.save()
|
|
form_display = WcsCardCellDisplayForm(instance=cell)
|
|
assert 'customize_display' in form_display.fields
|
|
assert 'custom_schema' in form_display.fields
|
|
assert 'customize_display' not in form_display.initial
|
|
assert form_display.initial['custom_schema'] == {}
|
|
|
|
cell.carddef_reference = 'default:card_model_1:foo'
|
|
cell.save()
|
|
form_display = WcsCardCellDisplayForm(instance=cell)
|
|
assert 'customize_display' in form_display.fields
|
|
assert 'custom_schema' in form_display.fields
|
|
assert 'customize_display' not in form_display.initial
|
|
assert form_display.initial['custom_schema'] == {}
|
|
|
|
cell.carddef_reference = 'default:card_model_1'
|
|
cell.save()
|
|
|
|
cell.custom_schema = {'cells': [{'varname': 'foo', 'display_mode': 'value'}]}
|
|
cell.save()
|
|
form_display = WcsCardCellDisplayForm(instance=cell)
|
|
assert 'customize_display' in form_display.fields
|
|
assert 'custom_schema' in form_display.fields
|
|
assert form_display.initial['customize_display'] is True
|
|
assert form_display.initial['custom_schema'] == {
|
|
'grid_class': 'fx-grid--auto',
|
|
'cells': [
|
|
{'varname': 'foo', 'field_content': 'value', 'display_mode': 'text', 'empty_value': '@empty@'}
|
|
],
|
|
}
|
|
|
|
WcsCardCell.objects.all().delete()
|
|
|
|
# check adding a cell from the UI
|
|
app = login(app)
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
cell_add_url = [x for x in resp.html.find_all('option') if x.text == 'Card(s)'][0].get('data-add-url')
|
|
resp = app.get(cell_add_url).follow()
|
|
cell = WcsCardCell.objects.all().first()
|
|
manager_submit_cell(resp.forms[0]) # will save card model
|
|
cell.refresh_from_db()
|
|
|
|
# check getting back to uncustomized display reset the schema
|
|
cell.custom_schema = {
|
|
'grid_class': 'fx-grid--auto',
|
|
'cells': [
|
|
{'varname': 'foo', 'field_content': 'value', 'display_mode': 'text', 'empty_value': '@empty@'}
|
|
],
|
|
}
|
|
cell.save()
|
|
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
assert resp.forms[0]['c%s-customize_display' % cell.get_reference()].value == 'on'
|
|
resp.forms[0]['c%s-customize_display' % cell.get_reference()].value = False
|
|
manager_submit_cell(resp.forms[0])
|
|
cell.refresh_from_db()
|
|
assert cell.custom_schema == {}
|
|
|
|
cell.custom_schema = {
|
|
'grid_class': 'fx-grid--auto',
|
|
'cells': [
|
|
{'varname': 'foo', 'field_content': 'value', 'display_mode': 'text', 'empty_value': '@empty@'}
|
|
],
|
|
}
|
|
cell.save()
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
assert resp.forms[0]['c%s-display_mode' % cell.get_reference()].value == 'card'
|
|
resp.forms[0]['c%s-display_mode' % cell.get_reference()].value = 'table'
|
|
manager_submit_cell(resp.forms[0])
|
|
cell.refresh_from_db()
|
|
assert cell.custom_schema == {
|
|
'grid_class': 'fx-grid--auto',
|
|
'cells': [
|
|
{'varname': 'foo', 'field_content': 'value', 'display_mode': 'text', 'empty_value': '@empty@'}
|
|
],
|
|
}
|
|
|
|
assert cell.related_card_path == '__all__'
|
|
assert cell.card_ids == ''
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].value == '__all__'
|
|
resp.forms[0]['c%s-related_card_path' % cell.get_reference()].value = '--'
|
|
resp.forms[0]['c%s-card_ids' % cell.get_reference()].value = '42'
|
|
manager_submit_cell(resp.forms[0])
|
|
cell.refresh_from_db()
|
|
assert cell.related_card_path == ''
|
|
assert cell.card_ids == ''
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].value == '--'
|
|
resp.forms[0]['c%s-related_card_path' % cell.get_reference()].value = ''
|
|
resp.forms[0]['c%s-card_ids' % cell.get_reference()].value = '42'
|
|
manager_submit_cell(resp.forms[0])
|
|
cell.refresh_from_db()
|
|
assert cell.related_card_path == ''
|
|
assert cell.card_ids == '42'
|
|
|
|
# current page has a sub_slug, '--' option is present
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
assert '--' in [o[0] for o in resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options]
|
|
|
|
# current_page has no sub_slug, but parent page has one
|
|
parent_page = Page.objects.create(
|
|
title='parent', slug='parent', template_name='standard', sub_slug='foobar'
|
|
)
|
|
page.parent = parent_page
|
|
page.sub_slug = ''
|
|
page.save()
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
assert '--' in [o[0] for o in resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options]
|
|
|
|
# no sub_slug
|
|
parent_page.sub_slug = ''
|
|
parent_page.save()
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
assert '--' not in [o[0] for o in resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options]
|
|
assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].value == ''
|
|
resp.forms[0]['c%s-card_ids' % cell.get_reference()].value = ''
|
|
resp = resp.forms[0].submit()
|
|
assert resp.context['form'].errors == {'card_ids': ['This field is required.']}
|
|
|
|
# check custom_title
|
|
for title_type in ['auto', 'empty']:
|
|
cell.custom_title = 'foo bar'
|
|
cell.save()
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
resp.forms[0]['c%s-title_type' % cell.get_reference()].value = title_type
|
|
resp = resp.forms[0].submit()
|
|
cell.refresh_from_db()
|
|
assert cell.custom_title == ''
|
|
|
|
|
|
def test_card_cell_custom_schema_migration():
|
|
cell = WcsCardCell(display_mode='table')
|
|
|
|
cell.custom_schema = {'cells': [{'varname': 'some-field', 'empty_value': '@empty@'}]}
|
|
assert cell.get_custom_schema() == {
|
|
'grid_headers': False,
|
|
'cells': [
|
|
{
|
|
'varname': 'some-field',
|
|
'empty_value': '',
|
|
}
|
|
],
|
|
}
|
|
|
|
cell.custom_schema = {
|
|
'cells': [{'varname': 'some-field', 'display_mode': 'label', 'cell_size': 'foobar'}]
|
|
}
|
|
assert cell.get_custom_schema() == {
|
|
'grid_headers': False,
|
|
'cells': [
|
|
{
|
|
'varname': 'some-field',
|
|
'display_mode': 'label',
|
|
'cell_size': 'foobar',
|
|
}
|
|
],
|
|
}
|
|
|
|
cell.display_mode = 'card'
|
|
cell.custom_schema = {
|
|
'cells': [{'varname': 'some-field', 'display_mode': 'label', 'cell_size': 'foobar'}]
|
|
}
|
|
assert cell.get_custom_schema() == {
|
|
'grid_class': 'fx-grid--auto',
|
|
'cells': [
|
|
{
|
|
'varname': 'some-field',
|
|
'field_content': 'label',
|
|
'display_mode': 'text',
|
|
'empty_value': '@empty@',
|
|
'cell_size': 'foobar',
|
|
}
|
|
],
|
|
}
|
|
cell.custom_schema = {'cells': [{'varname': 'some-field', 'display_mode': 'value'}]}
|
|
assert cell.get_custom_schema() == {
|
|
'grid_class': 'fx-grid--auto',
|
|
'cells': [
|
|
{
|
|
'varname': 'some-field',
|
|
'field_content': 'value',
|
|
'display_mode': 'text',
|
|
'empty_value': '@empty@',
|
|
}
|
|
],
|
|
}
|
|
cell.custom_schema = {'cells': [{'varname': 'some-field', 'display_mode': 'label-and-value'}]}
|
|
assert cell.get_custom_schema() == {
|
|
'grid_class': 'fx-grid--auto',
|
|
'cells': [
|
|
{
|
|
'varname': 'some-field',
|
|
'field_content': 'label-and-value',
|
|
'display_mode': 'text',
|
|
'empty_value': '@empty@',
|
|
}
|
|
],
|
|
}
|
|
cell.custom_schema = {'cells': [{'varname': 'some-field'}]}
|
|
assert cell.get_custom_schema() == {
|
|
'grid_class': 'fx-grid--auto',
|
|
'cells': [
|
|
{
|
|
'varname': 'some-field',
|
|
'field_content': 'label-and-value',
|
|
'display_mode': 'text',
|
|
'empty_value': '@empty@',
|
|
}
|
|
],
|
|
}
|
|
cell.custom_schema = {'cells': [{'varname': 'some-field', 'display_mode': 'title'}]}
|
|
assert cell.get_custom_schema() == {
|
|
'grid_class': 'fx-grid--auto',
|
|
'cells': [
|
|
{
|
|
'varname': 'some-field',
|
|
'field_content': 'value',
|
|
'display_mode': 'title',
|
|
'empty_value': '@empty@',
|
|
}
|
|
],
|
|
}
|
|
|
|
cell.custom_schema = {
|
|
'cells': [
|
|
{'varname': '@custom@', 'template': 'foobar', 'display_mode': 'label', 'cell_size': 'foobar'}
|
|
]
|
|
}
|
|
assert cell.get_custom_schema() == {
|
|
'grid_class': 'fx-grid--auto',
|
|
'cells': [
|
|
{'varname': '@custom@', 'template': 'foobar', 'display_mode': 'label', 'cell_size': 'foobar'}
|
|
],
|
|
}
|
|
cell.custom_schema = {'cells': [{'varname': '@custom@', 'template': 'foobar', 'display_mode': 'value'}]}
|
|
assert cell.get_custom_schema() == {
|
|
'grid_class': 'fx-grid--auto',
|
|
'cells': [{'varname': '@custom@', 'template': 'foobar', 'display_mode': 'text'}],
|
|
}
|
|
cell.custom_schema = {'cells': [{'varname': '@custom@', 'template': 'foobar', 'display_mode': 'title'}]}
|
|
assert cell.get_custom_schema() == {
|
|
'grid_class': 'fx-grid--auto',
|
|
'cells': [{'varname': '@custom@', 'template': 'foobar', 'display_mode': 'title'}],
|
|
}
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_save_cache(mock_send):
|
|
page = Page.objects.create(title='xxx', slug='test_card_cell_save_cache', template_name='standard')
|
|
cell = WcsCardCell(page=page, placeholder='content', order=0)
|
|
assert cell.get_additional_label() is None
|
|
cell.carddef_reference = 'default:card_model_1'
|
|
cell.save()
|
|
assert cell.cached_title == 'Card Model 1'
|
|
assert cell.cached_json != {}
|
|
assert cell.get_additional_label() == 'Card Model 1'
|
|
# make sure cached attributes are removed from serialized pages
|
|
assert 'cached_' not in json.dumps(page.get_serialized_page())
|
|
|
|
# artificially change title and json
|
|
WcsCardCell.objects.filter(pk=cell.pk).update(cached_title='XXX', cached_json={})
|
|
assert WcsCardCell.objects.get(pk=cell.pk).cached_title == 'XXX'
|
|
assert WcsCardCell.objects.get(pk=cell.pk).cached_json == {}
|
|
# run update db cache
|
|
appconfig = apps.get_app_config('wcs')
|
|
appconfig.update_db_cache()
|
|
assert WcsCardCell.objects.get(pk=cell.pk).cached_title == 'Card Model 1'
|
|
assert WcsCardCell.objects.get(pk=cell.pk).cached_json != {}
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_validity(mock_send):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardCell.objects.create(page=page, placeholder='content', order=0)
|
|
validity_info = ValidityInfo.objects.latest('pk')
|
|
assert validity_info.invalid_reason_code == 'wcs_card_not_defined'
|
|
assert validity_info.invalid_since is not None
|
|
|
|
cell.carddef_reference = 'default:card_model_1'
|
|
cell.save()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
# can not retrieve data, don't set cell as invalid
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_resp = Response()
|
|
mock_resp.status_code = 500
|
|
requests_get.return_value = mock_resp
|
|
cell.save()
|
|
assert ValidityInfo.objects.exists() is False
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
requests_get.side_effect = ConnectionError()
|
|
cell.save()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
# can not retrieve carddefs, don't set cell as invalid
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_resp = Response()
|
|
mock_resp.status_code = 404
|
|
requests_get.return_value = mock_resp
|
|
cell.save()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_resp = Response()
|
|
mock_resp.json = lambda *a, **k: {'err': 1, 'err_class': 'Page not found'}
|
|
mock_resp.status_code = 404
|
|
requests_get.return_value = mock_resp
|
|
cell.carddef_reference = 'default:foobar'
|
|
cell.save()
|
|
validity_info = ValidityInfo.objects.latest('pk')
|
|
assert validity_info.invalid_reason_code == 'wcs_card_not_found'
|
|
assert validity_info.invalid_since is not None
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_check_validity(mock_send):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
carddef_reference='default:card_a',
|
|
related_card_path='',
|
|
card_ids='1',
|
|
)
|
|
cell2 = WcsCardCell.objects.create(
|
|
page=page, placeholder='content', order=1, carddef_reference='default:card_b'
|
|
)
|
|
|
|
# no related_card_path
|
|
cell2.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
# correct related_card_path but sluga is not defined
|
|
cell2.related_card_path = 'sluga/cardb'
|
|
cell2.save()
|
|
cell2.check_validity()
|
|
validity_info = ValidityInfo.objects.latest('pk')
|
|
assert validity_info.invalid_reason_code == 'wcs_card_relation_not_found'
|
|
assert validity_info.invalid_since is not None
|
|
|
|
# sluga is now defined
|
|
cell.slug = 'sluga'
|
|
cell.save()
|
|
cell2.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
# bad related_card_path
|
|
cell2.related_card_path = 'sluga/foobar'
|
|
cell2.save()
|
|
cell2.check_validity()
|
|
validity_info = ValidityInfo.objects.latest('pk')
|
|
assert validity_info.invalid_reason_code == 'wcs_card_relation_not_found'
|
|
assert validity_info.invalid_since is not None
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_manager_card_cell(mock_send, app, admin_user):
|
|
page = Page.objects.create(title='xxx', slug='test_cards', template_name='standard', sub_slug='foobar')
|
|
cell = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
related_card_path='',
|
|
)
|
|
|
|
app = login(app)
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
assert 'application/json' not in resp
|
|
|
|
cell.carddef_reference = 'default:card_model_1'
|
|
cell.save()
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
assert '<script id="cell-%s-card-schema-default:card_model_1" type="application/json">' % cell.pk in resp
|
|
|
|
assert ('data-cell-reference="%s"' % cell.get_reference()) in resp.text
|
|
assert cell.without_user is False
|
|
assert resp.forms[0]['c%s-with_user' % cell.get_reference()].value == 'on'
|
|
resp.forms[0]['c%s-with_user' % cell.get_reference()].value = False
|
|
manager_submit_cell(resp.forms[0])
|
|
cell.refresh_from_db()
|
|
assert cell.without_user is True
|
|
assert resp.forms[0]['c%s-with_user' % cell.get_reference()].value is None
|
|
|
|
# card with relations
|
|
cell.carddef_reference = 'default:card_a'
|
|
cell.save()
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
# but only one cell on the page, no relations to follow
|
|
assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [
|
|
('__all__', False, 'All cards'),
|
|
('--', True, 'Card whose identifier is in the URL'),
|
|
('', False, 'Template'),
|
|
]
|
|
|
|
# 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 == [
|
|
('__all__', True, 'All cards'),
|
|
('--', False, 'Card whose identifier is in the URL'),
|
|
('', False, 'Template'),
|
|
]
|
|
|
|
# add a second cell, related to the first card model
|
|
cell.related_card_path = ''
|
|
cell.save()
|
|
cell2 = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=1,
|
|
carddef_reference='default:card_b',
|
|
related_card_path='',
|
|
)
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
# still no relation to follow
|
|
assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [
|
|
('__all__', False, 'All cards'),
|
|
('--', True, 'Card whose identifier is in the URL'),
|
|
('', False, 'Template'),
|
|
]
|
|
# no cell with id and slug
|
|
assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
|
|
('__all__', False, 'All cards'),
|
|
('--', True, 'Card whose identifier is in the URL'),
|
|
('', False, 'Template'),
|
|
]
|
|
|
|
# set a slug on first cell
|
|
cell.slug = 'sluga'
|
|
cell.save()
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
# still no relation to follow
|
|
assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [
|
|
('__all__', False, 'All cards'),
|
|
('--', True, 'Card whose identifier is in the URL'),
|
|
('', False, 'Template'),
|
|
]
|
|
# multiple relations to follow
|
|
assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
|
|
('__all__', False, 'All cards'),
|
|
('--', True, 'Card whose identifier is in the URL'),
|
|
('sluga/cardb', False, 'Linked card: "Card B"'),
|
|
('sluga/cardsb', False, 'Linked cards: "Cards B"'),
|
|
('sluga/blockb_cardb', False, 'Linked card: "Block B - Card B"'),
|
|
('sluga/cardc/cardb', False, 'Linked card: "Card C" -> "Card B"'),
|
|
('sluga/cardc/cardsb', False, 'Linked cards: "Card C" -> "Cards B"'),
|
|
('sluga/cardc/blockb_cardb', False, 'Linked card: "Card C" -> "Block B - Card B"'),
|
|
('', False, 'Template'),
|
|
]
|
|
|
|
# set a list of ids on first cell
|
|
cell.card_ids = '{{ cards|objects:"card_model_1"|getlist:"id"|join:"," }}'
|
|
cell.save()
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
# still no relation to follow
|
|
assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [
|
|
('__all__', False, 'All cards'),
|
|
('--', False, 'Card whose identifier is in the URL'),
|
|
('', True, 'Template'),
|
|
]
|
|
# can not user cell with multiple ids as reference
|
|
assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
|
|
('__all__', False, 'All cards'),
|
|
('--', True, 'Card whose identifier is in the URL'),
|
|
('', False, 'Template'),
|
|
]
|
|
|
|
# define a slug on second cell
|
|
cell.card_ids = ''
|
|
cell.save()
|
|
cell2.slug = 'slugb'
|
|
cell2.save()
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
# multiple relations to follow
|
|
assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [
|
|
('__all__', False, 'All cards'),
|
|
('--', True, 'Card whose identifier is in the URL'),
|
|
('slugb/reverse:cardb', False, 'Linked cards: "Card B" (reverse relation)'),
|
|
('slugb/reverse:cardsb', False, 'Linked cards: "Cards B" (reverse relation)'),
|
|
('slugb/reverse:blockb_cardb', False, 'Linked cards: "Block B - Card B" (reverse relation)'),
|
|
('', False, 'Template'),
|
|
]
|
|
# still multiple relations to follow
|
|
assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
|
|
('__all__', False, 'All cards'),
|
|
('--', True, 'Card whose identifier is in the URL'),
|
|
('sluga/cardb', False, 'Linked card: "Card B"'),
|
|
('sluga/cardsb', False, 'Linked cards: "Cards B"'),
|
|
('sluga/blockb_cardb', False, 'Linked card: "Block B - Card B"'),
|
|
('sluga/cardc/cardb', False, 'Linked card: "Card C" -> "Card B"'),
|
|
('sluga/cardc/cardsb', False, 'Linked cards: "Card C" -> "Cards B"'),
|
|
('sluga/cardc/blockb_cardb', False, 'Linked card: "Card C" -> "Block B - Card B"'),
|
|
('', False, 'Template'),
|
|
]
|
|
|
|
# set a related_path on cell2
|
|
resp.forms[1]['c%s-related_card_path' % cell2.get_reference()] = 'sluga/cardb'
|
|
resp.forms[1]['c%s-card_ids' % cell2.get_reference()] = 'foobar'
|
|
resp = resp.forms[1].submit()
|
|
cell2.refresh_from_db()
|
|
assert cell2.related_card_path == 'sluga/cardb'
|
|
assert cell2.card_ids == ''
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
# no more relation to follow
|
|
assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [
|
|
('__all__', False, 'All cards'),
|
|
('--', True, 'Card whose identifier is in the URL'),
|
|
('', False, 'Template'),
|
|
]
|
|
# still multiple relations to follow
|
|
assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
|
|
('__all__', False, 'All cards'),
|
|
('--', False, 'Card whose identifier is in the URL'),
|
|
('sluga/cardb', True, 'Linked card: "Card B"'),
|
|
('sluga/cardsb', False, 'Linked cards: "Cards B"'),
|
|
('sluga/blockb_cardb', False, 'Linked card: "Block B - Card B"'),
|
|
('sluga/cardc/cardb', False, 'Linked card: "Card C" -> "Card B"'),
|
|
('sluga/cardc/cardsb', False, 'Linked cards: "Card C" -> "Cards B"'),
|
|
('sluga/cardc/blockb_cardb', False, 'Linked card: "Card C" -> "Block B - Card B"'),
|
|
('', False, 'Template'),
|
|
]
|
|
resp.forms[1].submit()
|
|
cell2.refresh_from_db()
|
|
assert cell2.related_card_path == 'sluga/cardb'
|
|
assert cell2.card_ids == ''
|
|
|
|
# check circular relations
|
|
cell.slug = 'sluge'
|
|
cell.carddef_reference = 'default:card_e'
|
|
cell.save()
|
|
cell2.carddef_reference = 'default:card_d'
|
|
cell2.slug = 'slugd'
|
|
cell2.related_card_path = ''
|
|
cell2.save()
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [
|
|
('__all__', False, 'All cards'),
|
|
('--', True, 'Card whose identifier is in the URL'),
|
|
('slugd/cardd-foo/carde-foo', False, 'Linked card: "Card D" -> "Card E"'),
|
|
('slugd/carde-foo', False, 'Linked card: "Card E"'),
|
|
('', False, 'Template'),
|
|
]
|
|
assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
|
|
('__all__', False, 'All cards'),
|
|
('--', True, 'Card whose identifier is in the URL'),
|
|
('sluge/cardd-bar', False, 'Linked card: "Card D"'),
|
|
('sluge/reverse:carde-foo', False, 'Linked cards: "Card E" (reverse relation)'),
|
|
('', False, 'Template'),
|
|
]
|
|
|
|
cell.slug = 'slugd'
|
|
cell.carddef_reference = 'default:card_d'
|
|
cell.save()
|
|
cell2.carddef_reference = 'default:card_d'
|
|
cell2.slug = 'slugd-bis'
|
|
cell2.related_card_path = ''
|
|
cell2.save()
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [
|
|
('__all__', False, 'All cards'),
|
|
('--', True, 'Card whose identifier is in the URL'),
|
|
('slugd-bis/cardd-foo', False, 'Linked card: "Card D"'),
|
|
('slugd-bis/reverse:cardd-foo', False, 'Linked cards: "Card D" (reverse relation)'),
|
|
('slugd-bis/carde-foo/cardd-bar', False, 'Linked card: "Card E" -> "Card D"'),
|
|
(
|
|
'slugd-bis/carde-foo/reverse:carde-foo',
|
|
False,
|
|
'Linked cards: "Card E" -> "Card E" (reverse relation)',
|
|
),
|
|
('', False, 'Template'),
|
|
]
|
|
assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
|
|
('__all__', False, 'All cards'),
|
|
('--', True, 'Card whose identifier is in the URL'),
|
|
('slugd/cardd-foo', False, 'Linked card: "Card D"'),
|
|
('slugd/reverse:cardd-foo', False, 'Linked cards: "Card D" (reverse relation)'),
|
|
('slugd/carde-foo/cardd-bar', False, 'Linked card: "Card E" -> "Card D"'),
|
|
('slugd/carde-foo/reverse:carde-foo', False, 'Linked cards: "Card E" -> "Card E" (reverse relation)'),
|
|
('', False, 'Template'),
|
|
]
|
|
|
|
cell.slug = 'sluge'
|
|
cell.carddef_reference = 'default:card_e'
|
|
cell.save()
|
|
cell2.carddef_reference = 'default:card_e'
|
|
cell2.slug = 'sluge-bis'
|
|
cell2.related_card_path = ''
|
|
cell2.save()
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [
|
|
('__all__', False, 'All cards'),
|
|
('--', True, 'Card whose identifier is in the URL'),
|
|
('sluge-bis/cardd-bar/carde-foo', False, 'Linked card: "Card D" -> "Card E"'),
|
|
('', False, 'Template'),
|
|
]
|
|
assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
|
|
('__all__', False, 'All cards'),
|
|
('--', True, 'Card whose identifier is in the URL'),
|
|
('sluge/cardd-bar/carde-foo', False, 'Linked card: "Card D" -> "Card E"'),
|
|
('', False, 'Template'),
|
|
]
|
|
|
|
# many cells with slug
|
|
WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=2,
|
|
carddef_reference='default:card_e',
|
|
slug="sluge-again",
|
|
card_ids="42",
|
|
related_card_path='',
|
|
)
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [
|
|
('__all__', False, 'All cards'),
|
|
('--', True, 'Card whose identifier is in the URL'),
|
|
('sluge-bis/cardd-bar/carde-foo', False, 'Linked card (From cell sluge-bis): "Card D" -> "Card E"'),
|
|
(
|
|
'sluge-again/cardd-bar/carde-foo',
|
|
False,
|
|
'Linked card (From cell sluge-again): "Card D" -> "Card E"',
|
|
),
|
|
('', False, 'Template'),
|
|
]
|
|
assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
|
|
('__all__', False, 'All cards'),
|
|
('--', True, 'Card whose identifier is in the URL'),
|
|
('sluge/cardd-bar/carde-foo', False, 'Linked card (From cell sluge): "Card D" -> "Card E"'),
|
|
(
|
|
'sluge-again/cardd-bar/carde-foo',
|
|
False,
|
|
'Linked card (From cell sluge-again): "Card D" -> "Card E"',
|
|
),
|
|
('', False, 'Template'),
|
|
]
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_manager_card_cell_tabs(mock_send, app, admin_user):
|
|
page = Page.objects.create(title='xxx', slug='test_cards', template_name='standard', sub_slug='foobar')
|
|
cell = WcsCardCell.objects.create(page=page, placeholder='content', order=0)
|
|
|
|
app = login(app)
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
assert not resp.pyquery('[data-tab-slug="general"] select[name$="title_type"]')
|
|
assert not resp.pyquery('[data-tab-slug="general"] input[name$="custom_title"]')
|
|
assert not resp.pyquery('[data-tab-slug="general"] input[name$="limit"]')
|
|
assert not resp.pyquery('#tab-%s-general.pk-tabs--button-marker' % cell.get_reference())
|
|
assert resp.pyquery('[data-tab-slug="appearance"] select[name$="title_type"]')
|
|
assert resp.pyquery('[data-tab-slug="appearance"] input[name$="custom_title"]')
|
|
assert not resp.pyquery('[data-tab-slug="appearance"] input[name$="customize_display"]')
|
|
assert resp.pyquery('[data-tab-slug="display"] input[name$="limit"]')
|
|
|
|
cell.carddef_reference = 'default:card_model_1'
|
|
cell.save()
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
assert resp.pyquery('#tab-%s-general.pk-tabs--button-marker' % cell.get_reference())
|
|
assert resp.pyquery('[data-tab-slug="display"] input[name$="customize_display"]')
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_load(mock_send):
|
|
page = Page.objects.create(title='xxx', slug='test_cards', template_name='standard')
|
|
cell = WcsCardCell(page=page, placeholder='content', order=0)
|
|
cell.carddef_reference = 'default:card_model_1'
|
|
cell.save()
|
|
site_export = [page.get_serialized_page()]
|
|
cell.delete()
|
|
assert not Page.objects.get(pk=page.pk).get_cells()
|
|
Page.load_serialized_pages(site_export)
|
|
page = Page.objects.get(slug='test_cards')
|
|
cells = page.get_cells()
|
|
assert len(cells) == 1
|
|
cell = cells[0]
|
|
assert cell.cached_title == 'Card Model 1'
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_table_mode_render(mock_send, context, app):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
display_mode='table',
|
|
carddef_reference='default:card_model_1',
|
|
related_card_path='',
|
|
)
|
|
|
|
context['card_model_1_id'] = 11
|
|
request = RequestFactory().get('/')
|
|
context['synchronous'] = True # to get fresh content
|
|
cell.modify_global_context(context, request)
|
|
|
|
result = cell.render(context)
|
|
assert '<h2>Card Model 1</h2>' in result
|
|
assert 'cards-card_model_1' in result
|
|
assert (
|
|
'<a href="http://127.0.0.1:8999/backoffice/data/card_model_1/11/"><span class="card-title">aa</span></a>'
|
|
in result
|
|
)
|
|
assert (
|
|
'<a href="http://127.0.0.1:8999/backoffice/data/card_model_1/12/"><span class="card-title">bb</span></a>'
|
|
in result
|
|
)
|
|
assert (
|
|
'<a href="http://127.0.0.1:8999/backoffice/data/card_model_1/13/"><span class="card-title">cc</span></a>'
|
|
in result
|
|
)
|
|
assert 'data-paginate-by="10"' in result
|
|
|
|
# create a page with the correct subslug
|
|
page = Page.objects.create(slug='foo', title='Foo', sub_slug='(?P<card_model_1_id>[a-z0-9]+)')
|
|
|
|
result = cell.render(context)
|
|
assert '<h2>Card Model 1</h2>' in result
|
|
assert '<a href="/foo/11/"><span class="card-title">aa</span></a>' in result
|
|
assert '<a href="/foo/12/"><span class="card-title">bb</span></a>' in result
|
|
assert '<a href="/foo/13/"><span class="card-title">cc</span></a>' in result
|
|
|
|
cell.carddef_reference = 'default:card_model_1:foo'
|
|
cell.limit = 42
|
|
cell.save()
|
|
page.sub_slug = 'card_model_1_id'
|
|
page.save()
|
|
|
|
result = cell.render(context)
|
|
assert '<h2>Card Model 1</h2>' in result
|
|
assert '<a href="/foo/11/"><span class="card-title">aa</span></a>' in result
|
|
assert '<a href="/foo/12/"><span class="card-title">bb</span></a>' in result
|
|
assert '<a href="/foo/13/"><span class="card-title">cc</span></a>' not in result
|
|
assert 'data-paginate-by="42"' in result
|
|
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
requests_get.return_value = MockedRequestResponse(content=json.dumps({'data': []}))
|
|
cell.render(context)
|
|
assert len(requests_get.call_args_list) == 1
|
|
assert (
|
|
requests_get.call_args_list[0][0][0]
|
|
== '/api/cards/card_model_1/list/foo?full=on&filter-internal-id=11'
|
|
)
|
|
assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://127.0.0.1:8999/'
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_table_mode_render_custom_schema_card_field(mock_send, context):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
carddef_reference='default:card_model_1',
|
|
custom_schema={'cells': [{'varname': 'fielda'}]},
|
|
display_mode='table',
|
|
related_card_path='__all__',
|
|
)
|
|
|
|
request = RequestFactory().get('/')
|
|
context['synchronous'] = True # to get fresh content
|
|
cell.modify_global_context(context, request)
|
|
|
|
# only one cell, render as ul/li
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('table tr td') == []
|
|
assert len(PyQuery(result).find('ul li')) == 3
|
|
assert [PyQuery(li).text() for li in PyQuery(result).find('ul li')[:1]] == ['<i>a</i>']
|
|
|
|
# more than one cell, render as table
|
|
cell.custom_schema['cells'] += [
|
|
{'varname': 'fieldb'},
|
|
]
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('ul li') == []
|
|
assert len(PyQuery(result).find('table tr td')) == 2 * 3
|
|
assert [PyQuery(td).text() for td in PyQuery(result).find('table tr td')[:2]] == ['<i>a</i>', 'yes']
|
|
|
|
cell.custom_schema['cells'] += [
|
|
{'varname': 'fieldc'},
|
|
{'varname': 'related'},
|
|
{'varname': 'fieldd'},
|
|
{'varname': 'fielde'},
|
|
{'varname': 'fieldf'},
|
|
{'varname': 'fieldg'},
|
|
{'varname': 'fieldh'},
|
|
{'varname': 'fieldi'},
|
|
{'varname': 'unknown'},
|
|
{'varname': 'user:name'},
|
|
{'varname': 'user:email'},
|
|
{'varname': 'user:first_name'},
|
|
{'varname': 'user:last_name'},
|
|
{'varname': 'user:unknown'},
|
|
{}, # missing varname
|
|
]
|
|
cell.save()
|
|
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('ul li') == []
|
|
assert len(PyQuery(result).find('table tr td')) == 14 * 3
|
|
assert [PyQuery(td).text() for td in PyQuery(result).find('table tr:first-child td')] == [
|
|
'<i>a</i>',
|
|
'yes',
|
|
'Sept. 28, 2020',
|
|
'Foo Bar',
|
|
'file.pdf',
|
|
"lorem<strong>ipsum hello'world", # no multiline support for now
|
|
"lorem<strong>ipsum hello world",
|
|
'test@localhost',
|
|
'https://www.example.net/',
|
|
"loremipsum\nhello'world",
|
|
'User Foo Bar',
|
|
'foo@bar.com',
|
|
'User',
|
|
'Foo Bar',
|
|
]
|
|
assert PyQuery(result).find('table tr:first-child td:nth-child(8) a').text().strip() == 'test@localhost'
|
|
assert (
|
|
PyQuery(result).find('table tr:first-child td:nth-child(8) a').attr['href'] == 'mailto:test@localhost'
|
|
)
|
|
assert (
|
|
PyQuery(result).find('table tr:first-child td:nth-child(9) a').text().strip()
|
|
== 'https://www.example.net/'
|
|
)
|
|
assert (
|
|
PyQuery(result).find('table tr:first-child td:nth-child(9) a').attr['href']
|
|
== 'https://www.example.net/'
|
|
)
|
|
assert PyQuery(result).find('table tr:first-child td:nth-child(10) p:first-child').text() == 'loremipsum'
|
|
assert (
|
|
PyQuery(result).find('table tr:first-child td:nth-child(10) p:first-child strong').text() == 'ipsum'
|
|
)
|
|
assert PyQuery(result).find('table tr:first-child td:nth-child(10) p:last-child').text() == "hello'world"
|
|
assert PyQuery(result).find('table tr:first-child td:nth-child(12) a').text().strip() == 'foo@bar.com'
|
|
assert (
|
|
PyQuery(result).find('table tr:first-child td:nth-child(12) a').attr['href'] == 'mailto:foo@bar.com'
|
|
)
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
@pytest.mark.parametrize('nb_cells', [1, 2])
|
|
def test_card_cell_table_mode_render_custom_schema_card_empty_field(mock_send, context, nb_cells):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
carddef_reference='default:card_model_1',
|
|
custom_schema={'cells': [{'varname': 'empty', 'empty_value': ''}]},
|
|
display_mode='table',
|
|
related_card_path='__all__',
|
|
)
|
|
if nb_cells > 1:
|
|
cell.custom_schema['cells'] += [
|
|
{'varname': 'fieldb'},
|
|
]
|
|
cell.save()
|
|
|
|
request = RequestFactory().get('/')
|
|
context['synchronous'] = True # to get fresh content
|
|
cell.modify_global_context(context, request)
|
|
|
|
def test(value):
|
|
result = cell.render(context)
|
|
if nb_cells > 1:
|
|
assert PyQuery(result).find('ul li') == []
|
|
assert PyQuery(result).find('table tr:first-child td:first-child').text() == value
|
|
else:
|
|
assert PyQuery(result).find('table tr td') == []
|
|
assert PyQuery(result).find('ul li:first-child').text() == value
|
|
|
|
test('')
|
|
|
|
cell.custom_schema['cells'][0] = {
|
|
'varname': 'empty',
|
|
'empty_value': 'Custom text',
|
|
}
|
|
cell.save()
|
|
test('Custom text')
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
@pytest.mark.parametrize('nb_cells', [1, 2])
|
|
def test_card_cell_table_mode_render_custom_schema_custom_entry(mock_send, context, nb_cells):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
carddef_reference='default:card_model_1',
|
|
custom_schema={
|
|
'cells': [
|
|
{'varname': '@custom@', 'template': "<b>Foo</b> bar'baz {{ card.fields.fielde }}"},
|
|
]
|
|
},
|
|
display_mode='table',
|
|
related_card_path='__all__',
|
|
)
|
|
if nb_cells > 1:
|
|
cell.custom_schema['cells'] += [
|
|
{'varname': 'fieldb'},
|
|
]
|
|
cell.save()
|
|
|
|
request = RequestFactory().get('/')
|
|
cell.modify_global_context(context, request)
|
|
context['synchronous'] = True # to get fresh content
|
|
|
|
def test(value):
|
|
result = cell.render(context)
|
|
if nb_cells > 1:
|
|
assert PyQuery(result).find('ul li') == []
|
|
assert PyQuery(result).find('table tr:first-child td:first-child').text() == value
|
|
else:
|
|
assert PyQuery(result).find('table tr td') == []
|
|
assert PyQuery(result).find('ul li:first-child').text() == value
|
|
|
|
test("<b>Foo</b> bar'baz lorem<strong>ipsum hello'world")
|
|
|
|
# test context
|
|
cell.custom_schema['cells'][0][
|
|
'template'
|
|
] = '{{ card.fields.fielda }} - {{ card.fields.related }} ({{ card.fields.related_structured.id }})'
|
|
cell.save()
|
|
test('<i>a</i> - Foo Bar (42)')
|
|
|
|
# test filters in template
|
|
cell.custom_schema['cells'][0]['template'] = '{{ card.fields.related|split:" "|join:"," }}'
|
|
cell.save()
|
|
test('Foo,Bar')
|
|
|
|
# test available context
|
|
cell.custom_schema['cells'][0][
|
|
'template'
|
|
] = 'Foo bar baz {% make_public_url url="http://127.0.0.1:8999/" %}'
|
|
cell.save()
|
|
result = cell.render(context)
|
|
if nb_cells > 1:
|
|
assert '/api/wcs/file/' in PyQuery(result).find('table tr:first-child td:first-child').text()
|
|
else:
|
|
assert '/api/wcs/file/' in PyQuery(result).find('ul li:first-child').text()
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
@pytest.mark.parametrize('nb_cells', [1, 2])
|
|
def test_card_cell_table_mode_render_custom_schema_link_entry(mock_send, context, nb_cells):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
carddef_reference='default:card_model_1',
|
|
custom_schema={
|
|
'cells': [
|
|
{
|
|
'varname': '@link@',
|
|
'url_template': '/foo/bar/{{ card.fields.related_structured.id }}/',
|
|
'template': '{{ card.fields.fielda }} - {{ card.fields.related }}',
|
|
'display_mode': 'link',
|
|
},
|
|
]
|
|
},
|
|
display_mode='table',
|
|
related_card_path='__all__',
|
|
)
|
|
if nb_cells > 1:
|
|
cell.custom_schema['cells'] += [
|
|
{'varname': 'fieldb'},
|
|
]
|
|
cell.save()
|
|
|
|
request = RequestFactory().get('/')
|
|
cell.modify_global_context(context, request)
|
|
context['synchronous'] = True # to get fresh content
|
|
|
|
def test(value, href, class_name):
|
|
result = cell.render(context)
|
|
if nb_cells > 1:
|
|
assert PyQuery(result).find('ul li') == []
|
|
assert PyQuery(result).find('table tr:first-child td:first-child a').text() == value
|
|
assert PyQuery(result).find('table tr:first-child td:first-child a').attr['href'] == href
|
|
assert PyQuery(result).find('table tr:first-child td:first-child a').attr['class'] == class_name
|
|
else:
|
|
assert PyQuery(result).find('table tr td') == []
|
|
assert PyQuery(result).find('ul li:first-child a').text() == value
|
|
assert PyQuery(result).find('ul li:first-child a').attr['href'] == href
|
|
assert PyQuery(result).find('ul li:first-child a').attr['class'] == class_name
|
|
|
|
test('<i>a</i> - Foo Bar', '/foo/bar/42/', None)
|
|
|
|
cell.custom_schema['cells'][0]['display_mode'] = 'button'
|
|
cell.save()
|
|
test('<i>a</i> - Foo Bar', '/foo/bar/42/', 'pk-button')
|
|
|
|
# empty label or empty url: no link in output
|
|
cell.custom_schema['cells'][0]['url_template'] = '{{ None|default:"" }}'
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('ul li a') == []
|
|
assert PyQuery(result).find('table tr td a') == []
|
|
cell.custom_schema['cells'][0]['url_template'] = 'foo/bar'
|
|
cell.custom_schema['cells'][0]['template'] = '{{ None|default:"" }}'
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('ul li a') == []
|
|
assert PyQuery(result).find('table tr td a') == []
|
|
|
|
# check with page link
|
|
root_page = Page.objects.create(title='Root', slug='root', template_name='standard')
|
|
page1 = Page.objects.create(
|
|
title='Card',
|
|
slug='card',
|
|
template_name='standard',
|
|
sub_slug='card_model_1_id',
|
|
parent=root_page,
|
|
)
|
|
other_root_page = Page.objects.create(title='Other root', slug='other-root', template_name='standard')
|
|
page2 = Page.objects.create(
|
|
title='Card (bis)',
|
|
slug='card-bis',
|
|
template_name='standard',
|
|
sub_slug='card_model_1_id',
|
|
parent=other_root_page,
|
|
)
|
|
|
|
cell.custom_schema['cells'][0]['url_template'] = ''
|
|
cell.custom_schema['cells'][0]['page'] = page1.pk
|
|
cell.custom_schema['cells'][0]['template'] = '{{ card.fields.fielda }} - {{ card.fields.related }}'
|
|
cell.save()
|
|
test('<i>a</i> - Foo Bar', '/root/card/11/', 'pk-button')
|
|
|
|
cell.custom_schema['cells'][0]['page'] = page2.pk
|
|
cell.save()
|
|
test('<i>a</i> - Foo Bar', '/other-root/card-bis/11/', 'pk-button')
|
|
|
|
# empty label or empty url: no link in output
|
|
cell.custom_schema['cells'][0]['page'] = 0
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('ul li a') == []
|
|
assert PyQuery(result).find('table tr td a') == []
|
|
cell.custom_schema['cells'][0]['page'] = page1.pk
|
|
cell.custom_schema['cells'][0]['template'] = '{{ None|default:"" }}'
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('ul li a') == []
|
|
assert PyQuery(result).find('table tr td a') == []
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
@pytest.mark.parametrize('with_headers', [True, False])
|
|
def test_card_cell_table_mode_render_with_headers(mock_send, context, with_headers):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
carddef_reference='default:card_model_1',
|
|
custom_schema={
|
|
'grid_headers': with_headers,
|
|
'cells': [
|
|
{'varname': '@custom@', 'template': "foo bar"},
|
|
{'varname': '@custom@', 'template': "foo bar bis", "header": "My Custom Header"},
|
|
{'varname': '@custom@', 'template': ""}, # not displayed
|
|
{'varname': 'fieldb'},
|
|
{'varname': 'user:name'},
|
|
{'varname': 'user:email'},
|
|
{'varname': 'user:first_name'},
|
|
{'varname': 'user:last_name'},
|
|
{'varname': '@link@', 'template': "Foo", 'url_template': 'http://foo/bar', 'header': 'Link'},
|
|
{'varname': '@link@', 'template': "Bar", 'url_template': '{# empty #}', 'header': 'Link Bis'},
|
|
{
|
|
'varname': '@link@',
|
|
'template': "",
|
|
'url_template': 'http://foo/bar',
|
|
'header': 'Link Not Displayed',
|
|
},
|
|
{
|
|
'varname': '@link@',
|
|
'template': "Bar",
|
|
'url_template': '',
|
|
'header': 'Link Bis Not Displayed',
|
|
},
|
|
{'varname': 'user:unknown'},
|
|
],
|
|
},
|
|
display_mode='table',
|
|
related_card_path='__all__',
|
|
)
|
|
|
|
request = RequestFactory().get('/')
|
|
cell.modify_global_context(context, request)
|
|
context['synchronous'] = True # to get fresh content
|
|
|
|
result = cell.render(context)
|
|
if with_headers:
|
|
assert len(PyQuery(result).find('table thead th')) == 9
|
|
assert PyQuery(result).find('table thead th:nth-child(1)').text() == ''
|
|
assert PyQuery(result).find('table thead th:nth-child(2)').text() == 'My Custom Header'
|
|
assert PyQuery(result).find('table thead th:nth-child(3)').text() == 'Field B'
|
|
assert PyQuery(result).find('table thead th:nth-child(4)').text() == 'Name'
|
|
assert PyQuery(result).find('table thead th:nth-child(5)').text() == 'Email'
|
|
assert PyQuery(result).find('table thead th:nth-child(6)').text() == 'First name'
|
|
assert PyQuery(result).find('table thead th:nth-child(7)').text() == 'Last name'
|
|
assert PyQuery(result).find('table thead th:nth-child(8)').text() == 'Link'
|
|
assert PyQuery(result).find('table thead th:nth-child(9)').text() == 'Link Bis'
|
|
else:
|
|
assert PyQuery(result).find('table thead') == []
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_table_mode_render_all_cards(mock_send, nocache, app):
|
|
page = Page.objects.create(title='xxx', slug='foo', template_name='standard')
|
|
cell = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
display_mode='table',
|
|
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']) == 1
|
|
extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
|
|
app.get(cell_url + '?ctx=' + extra_ctx[0])
|
|
assert len(mock_send.call_args_list) == 1
|
|
# cell rendering
|
|
assert '/api/cards/card_model_1/list' in mock_send.call_args_list[0][0][0].url
|
|
assert 'filter-internal-id' not in mock_send.call_args_list[0][0][0].url
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_table_mode_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 = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
display_mode='table',
|
|
carddef_reference='default:card_model_1',
|
|
related_card_path='',
|
|
)
|
|
|
|
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() + '11/')
|
|
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 len(mock_send.call_args_list) == 1
|
|
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 = ''
|
|
page.save()
|
|
cell.card_ids = '42'
|
|
cell.save()
|
|
mock_send.reset_mock()
|
|
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 len(mock_send.call_args_list) == 1
|
|
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()
|
|
mock_send.reset_mock()
|
|
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 len(mock_send.call_args_list) == 1
|
|
assert '/api/cards/card_model_1/list' in mock_send.call_args_list[0][0][0].url
|
|
assert '&filter-internal-id=42&filter-internal-id=35&' in mock_send.call_args_list[0][0][0].url
|
|
|
|
cell.card_ids = '{% cards|objects:"card_model_1"|last|get:"id" %}' # syntax error
|
|
cell.save()
|
|
mock_send.reset_mock()
|
|
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 'empty-message' in cell_resp
|
|
|
|
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
|
|
extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
|
|
cell_resp = app.get(cell_url + '?ctx=' + extra_ctx[0])
|
|
assert len(mock_send.call_args_list) == 2
|
|
# cell rendering
|
|
assert '/api/cards/card_model_1/list' in mock_send.call_args_list[0][0][0].url
|
|
assert '/api/cards/card_model_1/list' in mock_send.call_args_list[1][0][0].url
|
|
assert '&filter-internal-id=13&' in mock_send.call_args_list[1][0][0].url
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_table_mode_render_identifier_from_related(mock_send, nocache, app):
|
|
page = Page.objects.create(title='xxx', slug='foo', template_name='standard')
|
|
WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
display_mode='table',
|
|
slug='sluga',
|
|
carddef_reference='default:card_a',
|
|
card_ids='1',
|
|
related_card_path='',
|
|
)
|
|
cell2 = WcsCardCell.objects.create(
|
|
page=page, placeholder='content', order=1, slug='slugb', carddef_reference='default:card_b'
|
|
)
|
|
|
|
cell2_url = reverse(
|
|
'combo-public-ajax-page-cell',
|
|
kwargs={'page_pk': page.pk, 'cell_reference': cell2.get_reference()},
|
|
)
|
|
|
|
# just do a simple test to check url calls
|
|
def check(urls):
|
|
resp = app.get(page.get_online_url())
|
|
assert len(resp.context['cells']) == 2
|
|
extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
|
|
mock_send.reset_mock()
|
|
app.get(cell2_url + '?ctx=' + extra_ctx[1])
|
|
assert len(mock_send.call_args_list) == len(urls)
|
|
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
|
|
|
|
# direct and single relation (item)
|
|
cell2.related_card_path = 'sluga/cardb'
|
|
cell2.save()
|
|
urls = [
|
|
# get first cell data
|
|
'/api/cards/card_a/1/',
|
|
# and follow cardb relation
|
|
'/api/cards/card_b/1/', # get card
|
|
]
|
|
check(urls)
|
|
|
|
# direct and multiple relation (items)
|
|
cell2.carddef_reference = 'default:card_b' # reset
|
|
cell2.related_card_path = 'sluga/cardsb'
|
|
cell2.save()
|
|
urls = [
|
|
# get first cell data
|
|
'/api/cards/card_a/1/',
|
|
# and follow cardb relation
|
|
('/api/cards/card_b/list', '&filter-internal-id=2&filter-internal-id=3&'), # get cards
|
|
]
|
|
check(urls)
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_table_mode_render_title(mock_send, context):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
display_mode='table',
|
|
carddef_reference='default:card_model_1',
|
|
title_type='auto',
|
|
)
|
|
|
|
context['synchronous'] = True # to get fresh content
|
|
|
|
result = cell.render(context)
|
|
assert '<h2>Card Model 1</h2>' in result
|
|
|
|
context.pop('title')
|
|
cell.title_type = 'empty'
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert '<h2>' not in result
|
|
|
|
cell.title_type = 'manual'
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert '<h2>Card Model 1</h2>' in result
|
|
|
|
context.pop('title')
|
|
cell.custom_title = 'Foo bar !'
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert '<h2>Foo bar !</h2>' in result
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_card_mode_render(mock_send, context, app):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
display_mode='card',
|
|
title_type='manual',
|
|
custom_title='Foo bar {{ card.fields.title }}',
|
|
related_card_path='',
|
|
)
|
|
|
|
# carddef_reference is not defined
|
|
context['card_model_1_id'] = 11
|
|
request = RequestFactory().get('/')
|
|
cell.modify_global_context(context, request)
|
|
context['synchronous'] = True # to get fresh content
|
|
|
|
result = cell.render(context)
|
|
assert '<h2>Card Model 1</h2>' not in result
|
|
assert '<p>Unknown Card</p>' in result
|
|
|
|
# card id not in context
|
|
cell.carddef_reference = 'default:card_model_1'
|
|
cell.save()
|
|
del context['card_model_1_id']
|
|
assert 'card_model_1_id' not in context
|
|
result = cell.render(context)
|
|
assert '<h2>Card Model 1</h2>' in result # default value
|
|
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
|
|
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_resp = Response()
|
|
mock_resp.status_code = 500
|
|
requests_get.return_value = mock_resp
|
|
result = cell.render(context)
|
|
assert '<h2>Card Model 1</h2>' in result # default value
|
|
assert '<p>Unknown Card</p>' in result
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
requests_get.side_effect = ConnectionError()
|
|
result = cell.render(context)
|
|
assert '<h2>Card Model 1</h2>' in result # default value
|
|
assert '<p>Unknown Card</p>' in result
|
|
|
|
context.pop('title')
|
|
cell.title_type = 'auto'
|
|
cell.save()
|
|
mock_send.reset_mock()
|
|
result = cell.render(context)
|
|
assert '<h2>Card Model 1 - aa</h2>' in result
|
|
assert PyQuery(result).find('.label:contains("Field A") + .value').text() == '<i>a</i>'
|
|
assert PyQuery(result).find('.label:contains("Field B") + .value').text() == 'yes'
|
|
assert PyQuery(result).find('.label:contains("Field C") + .value').text() == 'Sept. 28, 2020'
|
|
assert PyQuery(result).find('.label:contains("Related") + .value').text() == 'Foo Bar'
|
|
assert 'related_raw' not in result
|
|
assert 'related_structured' not in result
|
|
assert PyQuery(result).find('.label:contains("Field D") + .value a').text() == 'file.pdf'
|
|
|
|
context.pop('title')
|
|
cell.title_type = 'manual'
|
|
cell.custom_title = '<b>Foo bar {{ card.fields.fielda }}</b>'
|
|
cell.save()
|
|
assert cell.get_additional_label() == '<b>Foo bar {{ card.fields.fielda }}</b>'
|
|
result = cell.render(context)
|
|
assert '<h2><b>Foo bar <i>a</i></b></h2>' in result
|
|
|
|
context.pop('title')
|
|
cell.custom_title = '{{ foobar }}'
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert '<h2>Card Model 1 - aa</h2>' in result # empty value from template, default value
|
|
|
|
context.pop('title')
|
|
cell.custom_title = '{% if %}'
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert '<h2>Card Model 1 - aa</h2>' in result # template error, default value
|
|
|
|
context.pop('title')
|
|
cell.title_type = 'empty'
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert '<h2>' not in result
|
|
|
|
# test available context
|
|
cell.title_type = 'manual'
|
|
cell.custom_title = 'X{{ site_base }}Y'
|
|
cell.card_ids = '11'
|
|
cell.save()
|
|
resp = app.get(page.get_online_url())
|
|
assert len(resp.context['cells']) == 1
|
|
extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
|
|
cell_url = reverse(
|
|
'combo-public-ajax-page-cell',
|
|
kwargs={'page_pk': page.pk, 'cell_reference': cell.get_reference()},
|
|
)
|
|
cell_resp = app.get(cell_url + '?ctx=' + extra_ctx[0])
|
|
assert '<h2>Xhttp://testserverY</h2>' in cell_resp
|
|
|
|
cell.card_ids = '{{ cards|objects:"card_model_1"|getlist:"id"|join:"," }}'
|
|
cell.title_type = 'manual'
|
|
cell.custom_title = 'Foo bar X{{ repeat_index }}Y'
|
|
cell.save()
|
|
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):
|
|
cell_resp = app.get(cell_url + '?ctx=' + extra_ctx[i])
|
|
assert '<h2>Foo bar X%sY</h2>' % i in cell_resp
|
|
# again, without ajax: urls are already in cache
|
|
resp = app.get(page.get_online_url())
|
|
assert len(resp.context['cells']) == 3
|
|
for i in range(0, 3):
|
|
assert '<h2>Foo bar X%sY</h2>' % i in resp
|
|
assert 'data-paginate-by="10"' in resp
|
|
|
|
cell.limit = 42
|
|
cell.save()
|
|
resp = app.get(page.get_online_url())
|
|
assert len(resp.context['cells']) == 3
|
|
for i in range(0, 3):
|
|
assert '<h2>Foo bar X%sY</h2>' % i in resp
|
|
assert 'data-paginate-by="42"' in resp
|
|
|
|
# using custom view
|
|
cell.carddef_reference = 'default:card_model_1:foo'
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert 'Foo bar X0Y' in result
|
|
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_resp = Response()
|
|
mock_resp.status_code = 404
|
|
requests_get.return_value = mock_resp
|
|
result = cell.render(context)
|
|
|
|
# nothing, hide cell
|
|
assert not result.strip()
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_card_mode_render_text_field(mock_send, context):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
display_mode='card',
|
|
carddef_reference='default:card_model_1',
|
|
)
|
|
|
|
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)
|
|
|
|
# field E is split in paragraphs
|
|
assert (
|
|
PyQuery(result).find('.label:contains("Field E") + .value p:first-child').text().strip()
|
|
== 'lorem<strong>ipsum'
|
|
)
|
|
assert (
|
|
PyQuery(result).find('.label:contains("Field E") + .value p:last-child').text().strip()
|
|
== "hello'world"
|
|
)
|
|
|
|
# field F is put in a <pre>
|
|
assert (
|
|
PyQuery(result).find('.label:contains("Field F") + .value pre').text()
|
|
== 'lorem<strong>ipsum hello world'
|
|
)
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_card_mode_render_email_field(mock_send, context):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
display_mode='card',
|
|
carddef_reference='default:card_model_1',
|
|
)
|
|
|
|
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)
|
|
|
|
assert PyQuery(result).find('.label:contains("Field G") + .value a').text() == 'test@localhost'
|
|
|
|
assert (
|
|
PyQuery(result).find('.label:contains("Field G") + .value a').attr['href'] == 'mailto:test@localhost'
|
|
)
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_card_mode_render_string_with_url_field(mock_send, context):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
display_mode='card',
|
|
carddef_reference='default:card_model_1',
|
|
custom_title='Foo bar {{ card.fields.title }}',
|
|
)
|
|
|
|
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)
|
|
|
|
assert PyQuery(result).find('.label:contains("Field H") + .value a').text() == 'https://www.example.net/'
|
|
|
|
assert (
|
|
PyQuery(result).find('.label:contains("Field H") + .value a').attr['href']
|
|
== 'https://www.example.net/'
|
|
)
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_card_mode_render_custom_schema_card_field(mock_send, context):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
carddef_reference='default:card_model_1',
|
|
custom_schema={'cells': [{'varname': 'fielda', 'field_content': 'value', 'display_mode': 'title'}]},
|
|
)
|
|
|
|
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)
|
|
assert PyQuery(result).find('h3').text() == '<i>a</i>'
|
|
|
|
cell.custom_schema['cells'][0] = {
|
|
'varname': 'fielda',
|
|
'field_content': 'value',
|
|
'display_mode': 'subtitle',
|
|
}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('h4').text() == '<i>a</i>'
|
|
|
|
cell.custom_schema['cells'][0] = {'varname': 'fielda', 'field_content': 'label', 'display_mode': 'title'}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('h3').text() == 'Field A'
|
|
|
|
cell.custom_schema['cells'][0] = {
|
|
'varname': 'fielda',
|
|
'field_content': 'label',
|
|
'display_mode': 'subtitle',
|
|
}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('h4').text() == 'Field A'
|
|
|
|
cell.custom_schema['cells'][0] = {'varname': 'fielda', 'field_content': 'label', 'display_mode': 'text'}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('.label').text() == 'Field A'
|
|
|
|
cell.custom_schema['cells'][0] = {'varname': 'fielda', 'field_content': 'value', 'display_mode': 'text'}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('.value').text() == '<i>a</i>'
|
|
|
|
cell.custom_schema['cells'][0] = {
|
|
'varname': 'fielda',
|
|
'field_content': 'label-and-value',
|
|
'display_mode': 'text',
|
|
}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('.label').text() == 'Field A'
|
|
assert PyQuery(result).find('.value').text() == '<i>a</i>'
|
|
|
|
cell.custom_schema['cells'][0] = {
|
|
'varname': 'fieldb',
|
|
'field_content': 'label-and-value',
|
|
'display_mode': 'text',
|
|
}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('.label').text() == 'Field B'
|
|
assert PyQuery(result).find('.value').text() == 'yes'
|
|
|
|
cell.custom_schema['cells'][0] = {
|
|
'varname': 'fieldc',
|
|
'field_content': 'label-and-value',
|
|
'display_mode': 'text',
|
|
}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('.label').text() == 'Field C'
|
|
assert PyQuery(result).find('.value').text() == 'Sept. 28, 2020'
|
|
|
|
cell.custom_schema['cells'][0] = {
|
|
'varname': 'related',
|
|
'field_content': 'label-and-value',
|
|
'display_mode': 'text',
|
|
}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('.label').text() == 'Related'
|
|
assert PyQuery(result).find('.value').text() == 'Foo Bar'
|
|
|
|
cell.custom_schema['cells'][0] = {
|
|
'varname': 'fieldd',
|
|
'field_content': 'label-and-value',
|
|
'display_mode': 'text',
|
|
}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('.label').text() == 'Field D'
|
|
assert PyQuery(result).find('.value').text() == 'file.pdf'
|
|
|
|
cell.custom_schema['cells'][0] = {
|
|
'varname': 'fielde',
|
|
'field_content': 'label-and-value',
|
|
'display_mode': 'text',
|
|
}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
# check multiline text field is rendered with multiple paragraphs
|
|
# (first line "lorem<strong>ipsum" and last line ("hello'world")
|
|
# and the content is kept properly escaped.
|
|
assert PyQuery(result).find('.label').text() == 'Field E'
|
|
assert PyQuery(result).find('.value p:first-child').text().strip() == 'lorem<strong>ipsum'
|
|
assert PyQuery(result).find('.value p:last-child').text().strip() == "hello'world"
|
|
|
|
cell.custom_schema['cells'][0] = {
|
|
'varname': 'fieldf',
|
|
'field_content': 'label-and-value',
|
|
'display_mode': 'text',
|
|
}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('.label').text() == 'Field F'
|
|
assert PyQuery(result).find('.value pre').text() == 'lorem<strong>ipsum hello world'
|
|
|
|
cell.custom_schema['cells'][0] = {
|
|
'varname': 'fieldi',
|
|
'field_content': 'label-and-value',
|
|
'display_mode': 'text',
|
|
}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('.label').text() == 'Field I'
|
|
assert PyQuery(result).find('.value p:first-child').text() == 'loremipsum'
|
|
assert PyQuery(result).find('.value p:first-child strong').text() == 'ipsum'
|
|
assert PyQuery(result).find('.value p:last-child').text() == "hello'world"
|
|
|
|
cell.custom_schema['cells'][0] = {
|
|
'varname': 'fieldi',
|
|
'field_content': 'value',
|
|
'display_mode': 'title',
|
|
}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('h3').text() == "loremipsumhello'world"
|
|
assert PyQuery(result).find('h3 p') == [] # content was stripped
|
|
|
|
cell.custom_schema['cells'][0] = {
|
|
'varname': 'fieldg',
|
|
'field_content': 'label-and-value',
|
|
'display_mode': 'text',
|
|
}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('.label').text() == 'Field G'
|
|
assert PyQuery(result).find('.value a').text() == 'test@localhost'
|
|
assert PyQuery(result).find('.value a').attr['href'] == 'mailto:test@localhost'
|
|
|
|
cell.custom_schema['cells'][0] = {
|
|
'varname': 'fieldh',
|
|
'field_content': 'label-and-value',
|
|
'display_mode': 'text',
|
|
}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('.label').text() == 'Field H'
|
|
assert PyQuery(result).find('.value a').text() == 'https://www.example.net/'
|
|
assert PyQuery(result).find('.value a').attr['href'] == 'https://www.example.net/'
|
|
|
|
# wrong configuration, missing varname
|
|
cell.custom_schema['cells'][0] = {
|
|
'field_content': 'label-and-value',
|
|
'display_mode': 'text',
|
|
}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('.label') == []
|
|
assert PyQuery(result).find('.value') == []
|
|
|
|
# user fields
|
|
cell.custom_schema['cells'] = [
|
|
{
|
|
'varname': 'user:name',
|
|
'field_content': 'label-and-value',
|
|
'display_mode': 'text',
|
|
},
|
|
{
|
|
'varname': 'user:email',
|
|
'field_content': 'label-and-value',
|
|
'display_mode': 'text',
|
|
},
|
|
{
|
|
'varname': 'user:first_name',
|
|
'field_content': 'label-and-value',
|
|
'display_mode': 'text',
|
|
},
|
|
{
|
|
'varname': 'user:last_name',
|
|
'field_content': 'label-and-value',
|
|
'display_mode': 'text',
|
|
},
|
|
{
|
|
'varname': 'user:unknown',
|
|
'field_content': 'label-and-value',
|
|
'display_mode': 'text',
|
|
},
|
|
]
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert len(PyQuery(result).find('.cell--body > div > div')) == 4
|
|
assert PyQuery(result).find('.cell--body > div > div:nth-child(1) .label').text() == 'Name'
|
|
assert PyQuery(result).find('.cell--body > div > div:nth-child(1) .value').text() == 'User Foo Bar'
|
|
assert PyQuery(result).find('.cell--body > div > div:nth-child(2) .label').text() == 'Email'
|
|
assert PyQuery(result).find('.cell--body > div > div:nth-child(2) .value a').text() == 'foo@bar.com'
|
|
assert (
|
|
PyQuery(result).find('.cell--body > div > div:nth-child(2) .value a').attr['href']
|
|
== 'mailto:foo@bar.com'
|
|
)
|
|
assert PyQuery(result).find('.cell--body > div > div:nth-child(3) .label').text() == 'First name'
|
|
assert PyQuery(result).find('.cell--body > div > div:nth-child(3) .value').text() == 'User'
|
|
assert PyQuery(result).find('.cell--body > div > div:nth-child(4) .label').text() == 'Last name'
|
|
assert PyQuery(result).find('.cell--body > div > div:nth-child(4) .value').text() == 'Foo Bar'
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_card_mode_render_custom_schema_card_empty_field(mock_send, context):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
carddef_reference='default:card_model_1',
|
|
custom_schema={
|
|
'cells': [
|
|
{
|
|
'varname': 'empty',
|
|
'field_content': 'label-and-value',
|
|
'display_mode': 'text',
|
|
'empty_value': '@skip@',
|
|
}
|
|
]
|
|
},
|
|
)
|
|
|
|
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)
|
|
assert len(PyQuery(result).find('.cell--body > div > div')) == 0
|
|
assert PyQuery(result).find('.label') == []
|
|
assert PyQuery(result).find('.value') == []
|
|
|
|
cell.custom_schema['cells'][0] = {
|
|
'varname': 'empty',
|
|
'field_content': 'label-and-value',
|
|
'display_mode': 'text',
|
|
'empty_value': '@empty@',
|
|
}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert len(PyQuery(result).find('.cell--body > div > div')) == 1
|
|
assert PyQuery(result).find('.label').text() == 'Empty'
|
|
assert PyQuery(result).find('.value').text() == ''
|
|
|
|
cell.custom_schema['cells'][0] = {
|
|
'varname': 'empty',
|
|
'field_content': 'label-and-value',
|
|
'display_mode': 'text',
|
|
'empty_value': 'Custom text',
|
|
}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert len(PyQuery(result).find('.cell--body > div > div')) == 1
|
|
assert PyQuery(result).find('.label').text() == 'Empty'
|
|
assert PyQuery(result).find('.value').text() == 'Custom text'
|
|
|
|
for field_content in ['label', 'value']:
|
|
for display_mode in ['text', 'title', 'subtitle']:
|
|
if display_mode == 'title':
|
|
html_tag = 'h3'
|
|
elif display_mode == 'subtitle':
|
|
html_tag = 'h4'
|
|
elif display_mode == 'text' and field_content == 'label':
|
|
html_tag = '.label'
|
|
elif display_mode == 'text' and field_content == 'value':
|
|
html_tag = '.value'
|
|
cell.custom_schema['cells'][0] = {
|
|
'varname': 'empty',
|
|
'field_content': field_content,
|
|
'display_mode': display_mode,
|
|
'empty_value': '@skip@',
|
|
}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert len(PyQuery(result).find('.cell--body > div > div')) == 0
|
|
assert PyQuery(result).find(html_tag) == []
|
|
|
|
cell.custom_schema['cells'][0] = {
|
|
'varname': 'empty',
|
|
'field_content': field_content,
|
|
'display_mode': display_mode,
|
|
'empty_value': '@empty@',
|
|
}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert len(PyQuery(result).find('.cell--body > div > div')) == 1
|
|
assert PyQuery(result).find(html_tag).text() == ('Empty' if field_content == 'label' else '')
|
|
|
|
cell.custom_schema['cells'][0] = {
|
|
'varname': 'empty',
|
|
'field_content': field_content,
|
|
'display_mode': display_mode,
|
|
'empty_value': 'Custom text',
|
|
}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert len(PyQuery(result).find('.cell--body > div > div')) == 1
|
|
assert PyQuery(result).find(html_tag).text() == (
|
|
'Empty' if field_content == 'label' else 'Custom text'
|
|
)
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_card_mode_render_custom_schema_custom_entry(mock_send, context, app):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
carddef_reference='default:card_model_1',
|
|
custom_schema={
|
|
'cells': [
|
|
{
|
|
'varname': '@custom@',
|
|
'template': "<b>Foo</b> bar'baz {{ card.fields.fielde }}",
|
|
'display_mode': 'title',
|
|
},
|
|
]
|
|
},
|
|
related_card_path='',
|
|
)
|
|
|
|
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)
|
|
assert '<b>Foo</b>' in result
|
|
assert PyQuery(result).find('h3').text() == "<b>Foo</b> bar'baz lorem<strong>ipsum hello'world"
|
|
|
|
# test context
|
|
cell.custom_schema['cells'][0][
|
|
'template'
|
|
] = '{{ card.fields.fielda }} - {{ card.fields.related }} ({{ card.fields.related_structured.id }})'
|
|
cell.custom_schema['cells'][0]['display_mode'] = 'subtitle'
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('h4').text() == '<i>a</i> - Foo Bar (42)'
|
|
|
|
# test display_mode & filters in template
|
|
cell.custom_schema = {
|
|
'cells': [
|
|
{'varname': '@custom@', 'template': 'Foo bar baz', 'display_mode': 'label'},
|
|
{
|
|
'varname': '@custom@',
|
|
'template': '{{ card.fields.related|split:" "|join:"," }}',
|
|
'display_mode': 'text',
|
|
},
|
|
]
|
|
}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('.label').text() == 'Foo bar baz'
|
|
assert PyQuery(result).find('.value').text() == 'Foo,Bar'
|
|
|
|
# test available context
|
|
cell.card_ids = '11'
|
|
cell.custom_schema = {
|
|
'cells': [
|
|
{
|
|
'varname': '@custom@',
|
|
'template': 'Foo bar baz {% make_public_url url="http://127.0.0.1:8999/" %}',
|
|
'display_mode': 'label',
|
|
},
|
|
]
|
|
}
|
|
cell.save()
|
|
resp = app.get(page.get_online_url())
|
|
assert len(resp.context['cells']) == 1
|
|
extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
|
|
cell_url = reverse(
|
|
'combo-public-ajax-page-cell',
|
|
kwargs={'page_pk': page.pk, 'cell_reference': cell.get_reference()},
|
|
)
|
|
cell_resp = app.get(cell_url + '?ctx=' + extra_ctx[0])
|
|
assert '/api/wcs/file/' in PyQuery(cell_resp.text).find('.label').text()
|
|
|
|
cell.custom_schema = {
|
|
'cells': [
|
|
{'varname': '@custom@', 'template': 'Foo bar baz X{{ site_base }}Y', 'display_mode': 'label'},
|
|
]
|
|
}
|
|
cell.save()
|
|
resp = app.get(page.get_online_url())
|
|
assert len(resp.context['cells']) == 1
|
|
extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
|
|
cell_url = reverse(
|
|
'combo-public-ajax-page-cell',
|
|
kwargs={'page_pk': page.pk, 'cell_reference': cell.get_reference()},
|
|
)
|
|
cell_resp = app.get(cell_url + '?ctx=' + extra_ctx[0])
|
|
assert PyQuery(cell_resp.text).find('.label').text() == 'Foo bar baz Xhttp://testserverY'
|
|
|
|
cell.card_ids = '{{ cards|objects:"card_model_1"|getlist:"id"|join:"," }}'
|
|
cell.custom_schema = {
|
|
'cells': [
|
|
{'varname': '@custom@', 'template': 'Foo bar baz X{{ repeat_index }}Y', 'display_mode': 'label'},
|
|
]
|
|
}
|
|
cell.save()
|
|
resp = app.get(page.get_online_url())
|
|
assert len(resp.context['cells']) == 3
|
|
extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
|
|
cell_url = reverse(
|
|
'combo-public-ajax-page-cell',
|
|
kwargs={'page_pk': page.pk, 'cell_reference': cell.get_reference()},
|
|
)
|
|
for i in range(0, 3):
|
|
cell_resp = app.get(cell_url + '?ctx=' + extra_ctx[i])
|
|
assert PyQuery(cell_resp.text).find('.label').text() == 'Foo bar baz X%sY' % i
|
|
|
|
# custom schema but empty
|
|
cell.custom_schema = {'cells': []}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('div.cell--body') == []
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_card_mode_render_custom_schema_link_entry(mock_send, context, app):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
carddef_reference='default:card_model_1',
|
|
custom_schema={
|
|
'cells': [
|
|
{
|
|
'varname': '@link@',
|
|
'url_template': '/foo/bar/{{ card.fields.related_structured.id }}/',
|
|
'template': '{{ card.fields.fielda }} - {{ card.fields.related }}',
|
|
'display_mode': 'link',
|
|
},
|
|
]
|
|
},
|
|
related_card_path='',
|
|
)
|
|
|
|
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)
|
|
assert PyQuery(result).find('.value a').text() == '<i>a</i> - Foo Bar'
|
|
assert PyQuery(result).find('.value a').attr['href'] == '/foo/bar/42/'
|
|
assert PyQuery(result).find('.value a').attr['class'] is None
|
|
|
|
cell.custom_schema['cells'][0]['display_mode'] = 'button'
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('.value a').text() == '<i>a</i> - Foo Bar'
|
|
assert PyQuery(result).find('.value a').attr['href'] == '/foo/bar/42/'
|
|
assert PyQuery(result).find('.value a').attr['class'] == 'pk-button'
|
|
|
|
cell.custom_schema['cells'][0][
|
|
'url_template'
|
|
] = '{{ site_base }}/foo/bar/{{ card.fields.related_structured.id }}/'
|
|
cell.custom_schema['cells'][0]['template'] = '<b>{{ card.fields.fielda }}</b> - {{ card.fields.related }}'
|
|
cell.card_ids = '11'
|
|
cell.save()
|
|
resp = app.get(page.get_online_url())
|
|
assert len(resp.context['cells']) == 1
|
|
extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
|
|
cell_url = reverse(
|
|
'combo-public-ajax-page-cell',
|
|
kwargs={'page_pk': page.pk, 'cell_reference': cell.get_reference()},
|
|
)
|
|
cell_resp = app.get(cell_url + '?ctx=' + extra_ctx[0])
|
|
assert (
|
|
'<div class="value"><a href="http://testserver/foo/bar/42/" class="pk-button"><b><i>a</i></b> - Foo Bar</a></div>'
|
|
in cell_resp
|
|
)
|
|
|
|
# empty label or empty url: no link in output
|
|
cell.custom_schema['cells'][0]['url_template'] = '{{ None|default:"" }}'
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('.value a') == []
|
|
cell.custom_schema['cells'][0]['url_template'] = 'foo/bar'
|
|
cell.custom_schema['cells'][0]['template'] = '{{ None|default:"" }}'
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('.value a') == []
|
|
|
|
# check with page link
|
|
root_page = Page.objects.create(title='Root', slug='root', template_name='standard')
|
|
page1 = Page.objects.create(
|
|
title='Card',
|
|
slug='card',
|
|
template_name='standard',
|
|
sub_slug='card_model_1_id',
|
|
parent=root_page,
|
|
)
|
|
other_root_page = Page.objects.create(title='Other root', slug='other-root', template_name='standard')
|
|
page2 = Page.objects.create(
|
|
title='Card (bis)',
|
|
slug='card-bis',
|
|
template_name='standard',
|
|
sub_slug='card_model_1_id',
|
|
parent=other_root_page,
|
|
)
|
|
|
|
cell.custom_schema['cells'][0]['url_template'] = ''
|
|
cell.custom_schema['cells'][0]['page'] = page1.pk
|
|
cell.custom_schema['cells'][0]['template'] = 'Foo'
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('.value a').attr['href'] == '/root/card/11/'
|
|
|
|
cell.custom_schema['cells'][0]['page'] = page2.pk
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('.value a').attr['href'] == '/other-root/card-bis/11/'
|
|
|
|
# empty label or empty url: no link in output
|
|
cell.custom_schema['cells'][0]['page'] = 0
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('.value a') == []
|
|
cell.custom_schema['cells'][0]['page'] = page1.pk
|
|
cell.custom_schema['cells'][0]['template'] = '{{ None|default:"" }}'
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert PyQuery(result).find('.value a') == []
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_card_mode_render_all_cards(mock_send, nocache, app):
|
|
page = Page.objects.create(title='xxx', slug='foo', template_name='standard')
|
|
cell = WcsCardCell.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_card_mode_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 = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
carddef_reference='default:card_model_1',
|
|
related_card_path='',
|
|
)
|
|
|
|
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() + '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
|
|
|
|
# with identifiers
|
|
page.sub_slug = ''
|
|
page.save()
|
|
cell.card_ids = '42'
|
|
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 '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
|
|
|
|
cell.card_ids = '42, , 35'
|
|
cell.save()
|
|
mock_send.reset_mock()
|
|
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
|
|
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()
|
|
mock_send.reset_mock()
|
|
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
|
|
# 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
|
|
|
|
def test_card_ids():
|
|
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
|
|
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/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 %}',
|
|
'{{ cards|objects:"card_model_1"|getlist:"id"|join:"," }}',
|
|
]:
|
|
cell.card_ids = card_ids
|
|
cell.save()
|
|
test_card_ids()
|
|
|
|
cell.card_ids = '{{ var1 }}'
|
|
cell.save()
|
|
page.extra_variables = {'var1': card_ids}
|
|
page.save()
|
|
test_card_ids()
|
|
page.extra_variables = {}
|
|
page.save()
|
|
|
|
# with a card_ids template, but result is empty
|
|
cell.card_ids = '{{ foo }}'
|
|
cell.save()
|
|
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('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_card_mode_render_identifier_from_related(mock_send, nocache, app):
|
|
page = Page.objects.create(title='xxx', slug='foo', template_name='standard')
|
|
cell = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
display_mode='card',
|
|
slug='sluga',
|
|
carddef_reference='default:card_a',
|
|
related_card_path='',
|
|
card_ids='1',
|
|
)
|
|
cell2 = WcsCardCell.objects.create(
|
|
page=page, placeholder='content', order=1, slug='slugb', carddef_reference='default:card_b'
|
|
)
|
|
|
|
cell2_url = reverse(
|
|
'combo-public-ajax-page-cell',
|
|
kwargs={'page_pk': page.pk, 'cell_reference': cell2.get_reference()},
|
|
)
|
|
|
|
def failing(urls):
|
|
resp = app.get(page.get_online_url())
|
|
assert len(resp.context['cells']) >= 2
|
|
for i in range(0, len(resp.context['cells']) - 1):
|
|
assert resp.context['cells'][i].pk == cell.pk
|
|
assert resp.context['cells'][-1].pk == cell2.pk
|
|
extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
|
|
mock_send.reset_mock()
|
|
cell_resp = app.get(cell2_url + '?ctx=' + extra_ctx[-1])
|
|
assert cell_resp.text.replace('\n', '') == '' # empty-cell
|
|
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
|
|
|
|
def single(urls):
|
|
resp = app.get(page.get_online_url())
|
|
assert len(resp.context['cells']) == 2
|
|
assert resp.context['cells'][0].pk == cell.pk
|
|
assert resp.context['cells'][1].pk == cell2.pk
|
|
assert resp.context['cells'][1].repeat_index == 0
|
|
extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
|
|
mock_send.reset_mock()
|
|
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_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())
|
|
assert len(resp.context['cells']) >= 2
|
|
assert resp.context['cells'][0].pk == cell.pk
|
|
extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
|
|
for i in range(0, len(resp.context['cells']) - 1):
|
|
assert resp.context['cells'][i + 1].pk == cell2.pk
|
|
assert resp.context['cells'][i + 1].repeat_index == i
|
|
mock_send.reset_mock()
|
|
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_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'
|
|
cell2.save()
|
|
failing(urls=[])
|
|
|
|
# another cell with the same slug
|
|
cell3 = WcsCardCell.objects.create(page=page, placeholder='content', order=2, slug='sluga')
|
|
cell2.related_card_path = 'sluga/foo'
|
|
cell2.save()
|
|
failing(urls=[])
|
|
cell3.delete()
|
|
|
|
# multiple ids configured on first cell
|
|
cell.card_ids = '{{ cards|objects:"card_a"|getlist:"id"|join:"," }}'
|
|
cell.save()
|
|
failing(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_a/list',
|
|
]
|
|
)
|
|
|
|
# related_card_path configured on first cell
|
|
cell.card_ids = '1' # reset
|
|
cell.related_path = 'foobar'
|
|
cell.save()
|
|
failing(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_a/1/',
|
|
]
|
|
)
|
|
|
|
# reset
|
|
cell.related_path = ''
|
|
cell.save()
|
|
|
|
# another cell as the same slug, but not a WcsCardCell
|
|
cell3 = TextCell.objects.create(page=page, placeholder='content', order=2, slug='sluga')
|
|
|
|
# direct and single relation (item)
|
|
cell2.related_card_path = 'sluga/cardb'
|
|
cell2.save()
|
|
single(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_a/1/',
|
|
# and follow cardb relation
|
|
'/api/cards/card_b/1/', # check user access
|
|
'/api/cards/card_b/1/', # get card
|
|
]
|
|
)
|
|
cell3.delete() # reset
|
|
|
|
cell2.related_card_path = 'sluga/cardc/cardb'
|
|
cell2.save()
|
|
single(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_a/1/',
|
|
# get card_c schema
|
|
'/api/cards/card_c/@schema',
|
|
# follow cardc relation
|
|
'/api/cards/card_c/6/',
|
|
# and follow cardb relation
|
|
'/api/cards/card_b/7/', # check user access
|
|
'/api/cards/card_b/7/', # get card
|
|
]
|
|
)
|
|
|
|
# change cell ordering - cell with slug is after cell with related
|
|
cell.order = 42
|
|
cell.save()
|
|
# no error, but it does not work as expected: both cells has slug.
|
|
app.get(page.get_online_url(), status=200)
|
|
# remove slug of second cell
|
|
cell2.slug = ''
|
|
cell2.save()
|
|
urls = [
|
|
# get first cell data
|
|
'/api/cards/card_a/1/',
|
|
# get card_c schema
|
|
'/api/cards/card_c/@schema',
|
|
# follow cardc relation
|
|
'/api/cards/card_c/6/',
|
|
# and follow cardb relation
|
|
'/api/cards/card_b/7/', # check user access
|
|
'/api/cards/card_b/7/', # get card
|
|
]
|
|
resp = app.get(page.get_online_url())
|
|
assert len(resp.context['cells']) == 2
|
|
assert resp.context['cells'][0].pk == cell2.pk
|
|
assert resp.context['cells'][0].repeat_index == 0
|
|
assert resp.context['cells'][1].pk == cell.pk
|
|
extra_ctx = re.findall(r'data-extra-context="(.*)"', resp.text)
|
|
mock_send.reset_mock()
|
|
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_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
|
|
cell.save()
|
|
cell2.slug = 'slugb'
|
|
cell2.save()
|
|
|
|
# test with custom_view
|
|
cell2.carddef_reference = 'default:card_b:a-custom-view'
|
|
cell2.save()
|
|
single(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_a/1/',
|
|
# get card_c schema
|
|
'/api/cards/card_c/@schema',
|
|
# follow cardc relation
|
|
'/api/cards/card_c/6/',
|
|
# and follow cardb relation
|
|
'/api/cards/card_b/a-custom-view/7/', # check user access
|
|
'/api/cards/card_b/a-custom-view/7/', # get card
|
|
]
|
|
)
|
|
|
|
# direct and multiple relation (items)
|
|
cell2.carddef_reference = 'default:card_b' # reset
|
|
cell2.related_card_path = 'sluga/cardsb'
|
|
cell2.save()
|
|
multiple(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_a/1/',
|
|
# and follow cardb relation
|
|
('/api/cards/card_b/list', '&filter-internal-id=2&filter-internal-id=3&'), # check user access
|
|
('/api/cards/card_b/list', '&filter-internal-id=2&filter-internal-id=3&'), # get card
|
|
]
|
|
)
|
|
|
|
cell2.related_card_path = 'sluga/cardc/cardsb'
|
|
cell2.save()
|
|
multiple(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_a/1/',
|
|
# get card_c schema
|
|
'/api/cards/card_c/@schema',
|
|
# follow cardc relation
|
|
'/api/cards/card_c/6/',
|
|
# and follow cardb relation
|
|
('/api/cards/card_b/list', '&filter-internal-id=8&filter-internal-id=9&'), # check user access
|
|
('/api/cards/card_b/list', '&filter-internal-id=8&filter-internal-id=9&'), # get card
|
|
]
|
|
)
|
|
|
|
# direct and multiple relation through a block
|
|
cell2.related_card_path = 'sluga/blockb_cardb'
|
|
cell2.save()
|
|
multiple(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_a/1/',
|
|
# and follow cardb relation
|
|
('/api/cards/card_b/list', '&filter-internal-id=4&filter-internal-id=5&'), # check user access
|
|
('/api/cards/card_b/list', '&filter-internal-id=4&filter-internal-id=5&'), # get card
|
|
]
|
|
)
|
|
|
|
cell2.related_card_path = 'sluga/cardc/blockb_cardb'
|
|
cell2.save()
|
|
multiple(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_a/1/',
|
|
# get card_c schema
|
|
'/api/cards/card_c/@schema',
|
|
# follow cardc relation
|
|
'/api/cards/card_c/6/',
|
|
# and follow cardb relation
|
|
('/api/cards/card_b/list', '&filter-internal-id=10&filter-internal-id=11&'), # check user access
|
|
('/api/cards/card_b/list', '&filter-internal-id=10&filter-internal-id=11&'), # get card
|
|
]
|
|
)
|
|
|
|
# unknown part in related_card_path
|
|
cell2.related_card_path = 'sluga/foobar'
|
|
cell2.save()
|
|
failing(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_a/1/',
|
|
]
|
|
)
|
|
cell2.related_card_path = 'sluga/cardc/foobar'
|
|
cell2.save()
|
|
failing(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_a/1/',
|
|
# get card_c schema
|
|
'/api/cards/card_c/@schema',
|
|
# follow cardc relation
|
|
'/api/cards/card_c/6/',
|
|
]
|
|
)
|
|
|
|
# card data not found
|
|
cell.card_ids = '42'
|
|
cell.save()
|
|
cell2.related_card_path = 'sluga/cardb'
|
|
cell2.save()
|
|
failing(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_a/42/',
|
|
]
|
|
)
|
|
|
|
cell.card_ids = '2'
|
|
cell.save()
|
|
cell2.related_card_path = 'sluga/cardc/cardb'
|
|
cell2.save()
|
|
failing(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_a/2/',
|
|
# get card_c schema
|
|
'/api/cards/card_c/@schema',
|
|
# follow cardc relation
|
|
'/api/cards/card_c/61/',
|
|
]
|
|
)
|
|
# reset
|
|
cell.card_ids = '1'
|
|
cell.save()
|
|
|
|
# last part has not the correct card slug
|
|
cell2.related_card_path = 'sluga/cardc'
|
|
cell2.save()
|
|
failing(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_a/1/',
|
|
]
|
|
)
|
|
|
|
# unknown schema
|
|
cell2.related_card_path = 'sluga/cardz/cardb'
|
|
cell2.save()
|
|
failing(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_a/1/',
|
|
# get card_z schema
|
|
'/api/cards/card_z/@schema',
|
|
]
|
|
)
|
|
|
|
# multiple relation of multiple relation
|
|
cell2.related_card_path = 'sluga/cardsb/reverse:cardb'
|
|
cell2.save()
|
|
failing(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_a/1/',
|
|
]
|
|
)
|
|
|
|
# field not found
|
|
cell.card_ids = '3'
|
|
cell.save()
|
|
cell2.related_card_path = 'sluga/cardb'
|
|
cell2.save()
|
|
failing(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_a/3/',
|
|
]
|
|
)
|
|
cell2.related_card_path = 'sluga/cardc/cardb'
|
|
cell2.save()
|
|
failing(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_a/3/',
|
|
]
|
|
)
|
|
|
|
# field empty
|
|
cell.card_ids = '4'
|
|
cell.save()
|
|
cell2.related_card_path = 'sluga/cardb'
|
|
cell2.save()
|
|
failing(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_a/4/',
|
|
]
|
|
)
|
|
|
|
# field not found in block
|
|
cell.card_ids = '3'
|
|
cell.save()
|
|
cell2.related_card_path = 'sluga/blockb_cardb'
|
|
cell2.save()
|
|
failing(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_a/3/',
|
|
]
|
|
)
|
|
|
|
# field empty in block
|
|
cell.card_ids = '4'
|
|
cell.save()
|
|
cell2.related_card_path = 'sluga/blockb_cardb'
|
|
cell2.save()
|
|
failing(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_a/4/',
|
|
]
|
|
)
|
|
|
|
# reverse relation of item
|
|
cell.carddef_reference = 'default:card_b'
|
|
cell.slug = 'slugb'
|
|
cell.card_ids = '1'
|
|
cell.related_card_path = ''
|
|
cell.save()
|
|
cell2.carddef_reference = 'default:card_a'
|
|
cell2.slug = 'sluga'
|
|
cell2.card_ids = ''
|
|
cell2.related_card_path = 'slugb/reverse:cardb'
|
|
cell2.save()
|
|
multiple(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_b/1/',
|
|
# get list of card_a with cardb=1
|
|
'/api/cards/card_a/list?orig=combo&filter-cardb=1',
|
|
# and follow carda reverse relation
|
|
# check user access
|
|
(
|
|
'/api/cards/card_a/list',
|
|
'&filter-internal-id=1&filter-internal-id=2&filter-internal-id=3&filter-internal-id=4&',
|
|
),
|
|
# get card
|
|
(
|
|
'/api/cards/card_a/list',
|
|
'&filter-internal-id=1&filter-internal-id=2&filter-internal-id=3&filter-internal-id=4&',
|
|
),
|
|
]
|
|
)
|
|
|
|
# reverse relation of items
|
|
cell2.related_card_path = 'slugb/reverse:cardsb'
|
|
cell2.save()
|
|
multiple(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_b/1/',
|
|
# get list of card_a with cardsb=1
|
|
'/api/cards/card_a/list?orig=combo&filter-cardsb=1',
|
|
# and follow carda reverse relation
|
|
# check user access
|
|
(
|
|
'/api/cards/card_a/list',
|
|
'&filter-internal-id=1&filter-internal-id=2&filter-internal-id=3&filter-internal-id=4&',
|
|
),
|
|
# get card
|
|
(
|
|
'/api/cards/card_a/list',
|
|
'&filter-internal-id=1&filter-internal-id=2&filter-internal-id=3&filter-internal-id=4&',
|
|
),
|
|
]
|
|
)
|
|
|
|
# reverse relation of item through a block
|
|
cell2.related_card_path = 'slugb/reverse:blockb_cardb'
|
|
cell2.save()
|
|
multiple(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_b/1/',
|
|
# get list of card_a with cardsb=1
|
|
'/api/cards/card_a/list?orig=combo&filter-blockb_cardb=1',
|
|
# and follow carda reverse relation
|
|
# check user access
|
|
(
|
|
'/api/cards/card_a/list',
|
|
'&filter-internal-id=1&filter-internal-id=2&filter-internal-id=3&filter-internal-id=4&',
|
|
),
|
|
# get card
|
|
(
|
|
'/api/cards/card_a/list',
|
|
'&filter-internal-id=1&filter-internal-id=2&filter-internal-id=3&filter-internal-id=4&',
|
|
),
|
|
]
|
|
)
|
|
|
|
# unknown part in related_card_path
|
|
cell2.related_card_path = 'slugb/foobar'
|
|
cell2.save()
|
|
failing(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_b/1/',
|
|
]
|
|
)
|
|
|
|
# multiple relation of multiple relation
|
|
cell2.related_card_path = 'slugb/reverse:cardb/cardsb'
|
|
cell2.save()
|
|
failing(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_b/1/',
|
|
]
|
|
)
|
|
|
|
# reverse relation with many models using the same varname
|
|
cell.carddef_reference = 'default:card_h'
|
|
cell.slug = 'slugh'
|
|
cell.card_ids = '42'
|
|
cell.related_card_path = ''
|
|
cell.save()
|
|
cell2.carddef_reference = 'default:card_f'
|
|
cell2.slug = 'slugf'
|
|
cell2.card_ids = ''
|
|
cell2.related_card_path = 'slugh/reverse:cardh'
|
|
cell2.save()
|
|
multiple(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_h/42/',
|
|
# 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/', # check user access
|
|
'/api/cards/card_f/41/', # get card
|
|
]
|
|
)
|
|
|
|
cell.card_ids = '44'
|
|
cell.related_card_path = ''
|
|
cell.save()
|
|
cell2.carddef_reference = 'default:card_g'
|
|
cell2.slug = 'slugg'
|
|
cell2.card_ids = ''
|
|
cell2.related_card_path = 'slugh/reverse:cardh'
|
|
cell2.save()
|
|
multiple(
|
|
urls=[
|
|
# get first cell data
|
|
'/api/cards/card_h/44/',
|
|
# 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/', # check user access
|
|
'/api/cards/card_g/43/', # get card
|
|
]
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize('carddef_reference', ['default:card_model_1', 'default:card_model_1:foo'])
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_only_for_user(mock_send, context, carddef_reference):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
carddef_reference=carddef_reference,
|
|
only_for_user=False,
|
|
related_card_path='',
|
|
)
|
|
|
|
context['card_model_1_id'] = 11
|
|
request = RequestFactory().get('/')
|
|
cell.modify_global_context(context, request)
|
|
cell.repeat_index = 0
|
|
|
|
assert cell.is_visible(request=context['request']) is True
|
|
context['request'].user = MockUserWithNameId()
|
|
assert cell.is_visible(request=context['request']) is True
|
|
|
|
cell.only_for_user = True
|
|
cell.save()
|
|
context['request'].user = None
|
|
assert cell.is_visible(request=context['request']) is False
|
|
context['request'].user = MockUserWithNameId()
|
|
assert cell.is_visible(request=context['request']) is True
|
|
|
|
cache.clear()
|
|
context['synchronous'] = True # to get fresh content
|
|
context['request'].user = None
|
|
|
|
mock_send.reset_mock()
|
|
cell.render(context)
|
|
assert 'filter-user-uuid' not in mock_send.call_args_list[0][0][0].url
|
|
|
|
context['request'].user = MockUser()
|
|
mock_send.reset_mock()
|
|
cell.render(context)
|
|
assert 'filter-user-uuid' not in mock_send.call_args_list[0][0][0].url
|
|
|
|
context['request'].user = MockUserWithNameId()
|
|
mock_send.reset_mock()
|
|
cell.render(context)
|
|
assert 'filter-user-uuid=xyz' in mock_send.call_args_list[0][0][0].url
|
|
|
|
|
|
@pytest.mark.parametrize('carddef_reference', ['default:card_model_1', 'default:card_model_1:foo'])
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_render_user(mock_send, context, nocache, carddef_reference):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
carddef_reference=carddef_reference,
|
|
related_card_path='',
|
|
)
|
|
|
|
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
|
|
mock_send.reset_mock()
|
|
cell.render(context)
|
|
assert 'NameID=&' in mock_send.call_args_list[0][0][0].url
|
|
assert 'email=&' in mock_send.call_args_list[0][0][0].url
|
|
|
|
context['request'].user = AnonymousUser()
|
|
mock_send.reset_mock()
|
|
cell.render(context)
|
|
assert 'NameID=&' in mock_send.call_args_list[0][0][0].url
|
|
assert 'email=&' in mock_send.call_args_list[0][0][0].url
|
|
|
|
context['request'].user = MockUser()
|
|
mock_send.reset_mock()
|
|
cell.render(context)
|
|
assert 'email=foo%40example.net' in mock_send.call_args_list[0][0][0].url
|
|
|
|
context['request'].user = MockUserWithNameId()
|
|
mock_send.reset_mock()
|
|
cell.render(context)
|
|
assert 'NameID=xyz' in mock_send.call_args_list[0][0][0].url
|
|
|
|
cell.without_user = True
|
|
cell.save()
|
|
|
|
context['request'].user = None
|
|
mock_send.reset_mock()
|
|
cell.render(context)
|
|
assert 'NameID' not in mock_send.call_args_list[0][0][0].url
|
|
assert 'email' not in mock_send.call_args_list[0][0][0].url
|
|
|
|
context['request'].user = MockUser()
|
|
mock_send.reset_mock()
|
|
cell.render(context)
|
|
assert 'NameID' not in mock_send.call_args_list[0][0][0].url
|
|
assert 'email' not in mock_send.call_args_list[0][0][0].url
|
|
|
|
context['request'].user = MockUserWithNameId()
|
|
mock_send.reset_mock()
|
|
cell.render(context)
|
|
assert 'NameID' not in mock_send.call_args_list[0][0][0].url
|
|
assert 'email' not in mock_send.call_args_list[0][0][0].url
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_cell_condition(mock_send, nocache, app):
|
|
page = Page.objects.create(title='xxx', slug='foo', template_name='standard')
|
|
cell = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
carddef_reference='default:card_model_1',
|
|
related_card_path='',
|
|
card_ids='{{ cards|objects:"card_model_1"|last|get:"id" }}',
|
|
)
|
|
|
|
cell.condition = 'cards|objects:"card_model_1"|getlist:"id"|list'
|
|
cell.save()
|
|
resp = app.get(page.get_online_url())
|
|
assert len(resp.context['cells']) == 1
|
|
|
|
cell.condition = 'cards|objects:"card_model_1"|getlist:"id"|get:42'
|
|
cell.save()
|
|
resp = app.get(page.get_online_url())
|
|
assert len(resp.context.get('cells') or []) == 0
|
|
|
|
page.extra_variables = {'var1': '{{ cards|objects:"card_model_1"|getlist:"id"|list }}'}
|
|
page.save()
|
|
cell.condition = 'var1'
|
|
cell.save()
|
|
resp = app.get(page.get_online_url())
|
|
assert len(resp.context['cells']) == 1
|
|
|
|
page.extra_variables = {'var1': '{{ cards|objects:"card_model_1"|getlist:"id"|get:42|default:"" }}'}
|
|
page.save()
|
|
resp = app.get(page.get_online_url())
|
|
assert len(resp.context.get('cells') or []) == 0
|
|
|
|
page.extra_variables = {
|
|
'var1': '{{ cards|objects:"unknown"|first|get:"id"|default:"" }}',
|
|
'var2': '{{ cards|objects:"card_model_1"|first|get:"id"|default:"" }}',
|
|
}
|
|
page.save()
|
|
cell.condition = 'not var1'
|
|
cell.save()
|
|
resp = app.get(page.get_online_url())
|
|
assert len(resp.context['cells']) == 1
|
|
cell.condition = 'var2'
|
|
cell.save()
|
|
resp = app.get(page.get_online_url())
|
|
assert len(resp.context['cells']) == 1
|
|
cell.condition = 'not var2'
|
|
cell.save()
|
|
resp = app.get(page.get_online_url())
|
|
assert len(resp.context.get('cells') or []) == 0
|
|
cell.condition = 'not var1 and not var2'
|
|
cell.save()
|
|
resp = app.get(page.get_online_url())
|
|
assert len(resp.context.get('cells') or []) == 0
|
|
cell.condition = 'not var1 and var2'
|
|
cell.save()
|
|
resp = app.get(page.get_online_url())
|
|
assert len(resp.context['cells']) == 1
|
|
|
|
# wrong condition
|
|
cell.condition = 'cards|objects:"card_model_1"|first|filter_by:"fielda"|filter_value:"foo"'
|
|
cell.save()
|
|
resp = app.get(page.get_online_url())
|
|
assert len(resp.context.get('cells') or []) == 0
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_file_redirection(mock_send, app):
|
|
page = Page(title='One', slug='one', template_name='standard')
|
|
page.save()
|
|
cell = WcsCardCell(page=page, placeholder='content', order=0)
|
|
cell.carddef_reference = 'default:card_model_1'
|
|
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']
|
|
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
|
|
assert '&signature=' in resp.location
|
|
|
|
# invalid crypto
|
|
resp = app.get(file_url[:-2] + 'X/', status=403)
|
|
|
|
# invalid session key
|
|
resp = app.get(file_url.replace('file/', 'file/X'), status=403)
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_assets(mock_send, settings, app, admin_user):
|
|
page = Page.objects.create(title='xxx', slug='test_cell_assets', template_name='standard')
|
|
cell1 = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
carddef_reference='default:card_model_1',
|
|
display_mode='card',
|
|
slug='slug1',
|
|
)
|
|
cell2 = WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
carddef_reference='default:card_model_1',
|
|
display_mode='table',
|
|
slug='slug2',
|
|
)
|
|
|
|
app = login(app)
|
|
settings.COMBO_CELL_ASSET_SLOTS = {}
|
|
resp = app.get('/manage/assets/')
|
|
assert 'have any asset yet.' in resp.text
|
|
|
|
settings.COMBO_CELL_ASSET_SLOTS = {
|
|
'wcs_wcscardscell': {
|
|
'logo': {
|
|
'prefix': 'Logo',
|
|
},
|
|
},
|
|
'wcs_wcscardinfoscell': {
|
|
'picture': {
|
|
'prefix': 'Picture',
|
|
},
|
|
},
|
|
}
|
|
resp = app.get('/manage/assets/')
|
|
assert 'Picture — %s' % cell1.get_label_for_asset() in resp.text
|
|
assert 'Logo — %s' % cell2.get_label_for_asset() in resp.text
|
|
|
|
|
|
def test_page_snapshot_with_old_card_cells():
|
|
"""
|
|
page_serialization = {
|
|
'cells': [{
|
|
'model': 'data.parentcontentcell',
|
|
'fields': {
|
|
'slug': '',
|
|
'order': 0,
|
|
'groups': [],
|
|
'public': True,
|
|
'condition': None,
|
|
'placeholder': 'footer',
|
|
'template_name': None,
|
|
'extra_css_class': '',
|
|
'last_update_timestamp': '2022-08-08T13:55:29.599Z',
|
|
'restricted_to_unlogged': False,
|
|
'page': 14
|
|
}
|
|
}, {
|
|
'model': 'wcs.wcscardinfoscell',
|
|
'fields': {
|
|
'slug': 'enfant',
|
|
'limit': None,
|
|
'order': 1,
|
|
'groups': [],
|
|
'public': True,
|
|
'card_ids': '',
|
|
'condition': '',
|
|
'title_type': 'auto',
|
|
'placeholder': 'content',
|
|
'custom_title': '',
|
|
'display_mode': 'card',
|
|
'without_user': False,
|
|
'custom_schema': {},
|
|
'only_for_user': False,
|
|
'template_name': None,
|
|
'extra_css_class': '',
|
|
'carddef_reference': 'eservices:test-related-enfant',
|
|
'related_card_path': '',
|
|
'last_update_timestamp': '2022-08-11T13:57:43.362Z',
|
|
'restricted_to_unlogged': False,
|
|
'page': 14
|
|
}
|
|
}, {
|
|
'model': 'wcs.wcscardinfoscell',
|
|
'fields': {
|
|
'slug': '',
|
|
'limit': None,
|
|
'order': 2,
|
|
'groups': [],
|
|
'public': True,
|
|
'card_ids': '',
|
|
'condition': '',
|
|
'title_type': 'auto',
|
|
'placeholder': 'content',
|
|
'custom_title': '',
|
|
'display_mode': 'card',
|
|
'without_user': False,
|
|
'custom_schema': {},
|
|
'only_for_user': False,
|
|
'template_name': None,
|
|
'extra_css_class': '',
|
|
'carddef_reference': 'eservices:test-related-adulte:par-defaut',
|
|
'related_card_path': 'enfant/block_parents_parent',
|
|
'last_update_timestamp': '2022-08-08T19:53:02.097Z',
|
|
'restricted_to_unlogged': False,
|
|
'page': 14
|
|
}
|
|
}, {
|
|
'model': 'wcs.wcscardinfoscell',
|
|
'fields': {
|
|
'slug': '',
|
|
'limit': None,
|
|
'order': 3,
|
|
'groups': [],
|
|
'public': True,
|
|
'card_ids': '',
|
|
'condition': '',
|
|
'title_type': 'empty',
|
|
'placeholder': 'content',
|
|
'custom_title': 'Les parents !',
|
|
'display_mode': 'table',
|
|
'without_user': False,
|
|
'custom_schema': {},
|
|
'only_for_user': False,
|
|
'template_name': None,
|
|
'extra_css_class': '',
|
|
'carddef_reference': 'eservices:test-related-adulte:par-defaut',
|
|
'related_card_path': 'enfant/block_parents_parent',
|
|
'last_update_timestamp': '2022-08-11T13:07:35.757Z',
|
|
'restricted_to_unlogged': False,
|
|
'page': 14
|
|
}
|
|
}],
|
|
'fields': {
|
|
'slug': 'related-enfant',
|
|
'order': 6,
|
|
'title': 'Related enfant',
|
|
'groups': [],
|
|
'parent': ['search-related'],
|
|
'public': True,
|
|
'picture': '',
|
|
'snapshot': None,
|
|
'sub_slug': 'test-related-enfant_id',
|
|
'edit_role': None,
|
|
'description': '',
|
|
'redirect_url': '',
|
|
'template_name': 'standard',
|
|
'extra_variables': {},
|
|
'creation_timestamp': '2022-08-08T13:55:29.502Z',
|
|
'subpages_edit_role': None,
|
|
'placeholder_options': {},
|
|
'last_update_timestamp': '2022-08-11T13:57:43.369Z',
|
|
'exclude_from_navigation': True
|
|
},
|
|
'model': 'data.page',
|
|
'pk': 14
|
|
}
|
|
"""
|
|
page = Page.objects.create(title='xxx', slug='test_snapshots', template_name='standard')
|
|
PageSnapshot.take(page)
|
|
snapshot = page.pagesnapshot_set.first()
|
|
snapshot.serialization['cells'].append(
|
|
{
|
|
'model': 'wcs.wcscardinfoscell',
|
|
'fields': {
|
|
'slug': 'my-card',
|
|
'limit': 42,
|
|
'order': 1,
|
|
'groups': [],
|
|
'public': True,
|
|
'card_ids': '42,35',
|
|
'condition': 'my-condition',
|
|
'title_type': 'manual',
|
|
'placeholder': 'content',
|
|
'custom_title': 'my-title',
|
|
'display_mode': 'card',
|
|
'without_user': True,
|
|
'custom_schema': {},
|
|
'only_for_user': True,
|
|
'template_name': None,
|
|
'extra_css_class': '',
|
|
'carddef_reference': 'default:card_model_1',
|
|
'related_card_path': '',
|
|
'last_update_timestamp': '2022-08-11T13:57:43.362Z',
|
|
'restricted_to_unlogged': False,
|
|
'page': page.pk,
|
|
},
|
|
}
|
|
)
|
|
snapshot.serialization['cells'].append(
|
|
{
|
|
'model': 'wcs.wcscardscell',
|
|
'fields': {
|
|
'slug': 'my-other-card',
|
|
'limit': 35,
|
|
'order': 2,
|
|
'groups': [],
|
|
'public': True,
|
|
'condition': '',
|
|
'placeholder': 'content',
|
|
'custom_title': 'my-other-title',
|
|
'without_user': False,
|
|
'only_for_user': False,
|
|
'template_name': None,
|
|
'extra_css_class': '',
|
|
'carddef_reference': 'default:card_model_1',
|
|
'last_update_timestamp': '2022-08-12T07:19:18.541Z',
|
|
'restricted_to_unlogged': False,
|
|
'page': page.pk,
|
|
},
|
|
}
|
|
)
|
|
old_page = snapshot.get_page()
|
|
cell1 = old_page.get_cells()[0]
|
|
assert isinstance(cell1, WcsCardCell)
|
|
assert cell1.slug == 'my-card'
|
|
assert cell1.limit == 42
|
|
assert cell1.card_ids == '42,35'
|
|
assert cell1.title_type == 'manual'
|
|
assert cell1.custom_title == 'my-title'
|
|
assert cell1.display_mode == 'card'
|
|
assert cell1.without_user is True
|
|
assert cell1.custom_schema == {}
|
|
assert cell1.only_for_user is True
|
|
assert cell1.carddef_reference == 'default:card_model_1'
|
|
assert cell1.related_card_path == ''
|
|
cell2 = old_page.get_cells()[1]
|
|
assert isinstance(cell1, WcsCardCell)
|
|
assert cell2.slug == 'my-other-card'
|
|
assert cell2.limit == 35
|
|
assert cell2.card_ids == ''
|
|
assert cell2.title_type == 'manual'
|
|
assert cell2.custom_title == 'my-other-title'
|
|
assert cell2.display_mode == 'table'
|
|
assert cell2.without_user is False
|
|
assert cell2.custom_schema == {}
|
|
assert cell2.only_for_user is False
|
|
assert cell2.carddef_reference == 'default:card_model_1'
|
|
assert cell2.related_card_path == '__all__'
|
|
|
|
|
|
def get_output_of_command(command, *args, **kwargs):
|
|
old_stdout = sys.stdout
|
|
output = sys.stdout = StringIO()
|
|
call_command(command, format_json=True, *args, **kwargs)
|
|
sys.stdout = old_stdout
|
|
return output.getvalue()
|
|
|
|
|
|
def test_export_import_card_cell_with_page_link():
|
|
root_page = Page.objects.create(title='Root', slug='root', template_name='standard')
|
|
card_page = Page.objects.create(
|
|
title='Card',
|
|
slug='card',
|
|
template_name='standard',
|
|
sub_slug='card_model_1_id',
|
|
parent=root_page,
|
|
)
|
|
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
WcsCardCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
carddef_reference='default:card_model_1',
|
|
custom_schema={
|
|
'cells': [
|
|
{
|
|
'varname': '@link@',
|
|
'page': card_page.pk,
|
|
'template': 'Foo',
|
|
'display_mode': 'link',
|
|
},
|
|
]
|
|
},
|
|
)
|
|
|
|
site_export = get_output_of_command('export_site')
|
|
site_data = json.loads(site_export)
|
|
assert len(site_data['pages']) == 3
|
|
assert site_data['pages'][-1]['cells'][0]['fields']['custom_schema']['cells'][0]['page'] == 'root/card'
|
|
import_site(data={}, clean=True)
|
|
assert Page.objects.all().count() == 0
|
|
|
|
import_site(data=site_data, clean=True)
|
|
new_card_page = Page.objects.get(slug='card')
|
|
new_cell = WcsCardCell.objects.get()
|
|
assert new_cell.custom_schema['cells'][0]['page'] == new_card_page.pk
|
|
|
|
# unknown target page
|
|
new_cell.custom_schema['cells'][0]['page'] = 0
|
|
new_cell.save()
|
|
site_export = get_output_of_command('export_site')
|
|
site_data = json.loads(site_export)
|
|
assert site_data['pages'][-1]['cells'][0]['fields']['custom_schema']['cells'][0]['page'] == ''
|
|
|
|
site_data['pages'][-1]['cells'][0]['fields']['custom_schema']['cells'][0]['page'] = 'unknown'
|
|
import_site(data=site_data, clean=True)
|
|
new_card_page = Page.objects.get(slug='card')
|
|
new_cell = WcsCardCell.objects.get()
|
|
assert new_cell.custom_schema['cells'][0]['page'] == ''
|