4745 lines
182 KiB
Python
4745 lines
182 KiB
Python
import copy
|
|
import json
|
|
import re
|
|
import urllib.parse
|
|
from importlib import import_module
|
|
from unittest import mock
|
|
|
|
import pytest
|
|
from django.apps import apps
|
|
from django.conf import settings
|
|
from django.contrib.auth.models import AnonymousUser
|
|
from django.core.cache import cache
|
|
from django.db import connection
|
|
from django.test.client import RequestFactory
|
|
from django.test.utils import CaptureQueriesContext
|
|
from django.urls import reverse
|
|
from pyquery import PyQuery
|
|
from requests.exceptions import ConnectionError
|
|
from requests.models import Response
|
|
|
|
from combo.apps.search.engines import engines
|
|
from combo.apps.search.models import SearchCell
|
|
from combo.apps.search.utils import index_site, search_site
|
|
from combo.apps.wcs.models import (
|
|
BackofficeSubmissionCell,
|
|
CategoriesCell,
|
|
TrackingCodeInputCell,
|
|
WcsCardInfosCell,
|
|
WcsCardsCell,
|
|
WcsCareFormsCell,
|
|
WcsCategoryCell,
|
|
WcsCurrentDraftsCell,
|
|
WcsCurrentFormsCell,
|
|
WcsFormCell,
|
|
WcsFormsOfCategoryCell,
|
|
)
|
|
from combo.data.library import get_cell_classes
|
|
from combo.data.models import CellBase, LinkCell, LinkListCell, Page, ValidityInfo
|
|
from combo.utils import NothingInCacheException
|
|
|
|
from .test_manager import login
|
|
from .utils import manager_submit_cell
|
|
|
|
pytestmark = pytest.mark.django_db
|
|
|
|
|
|
WCS_FORMDEFS_DATA = [
|
|
{'slug': 'a-private-form', 'title': 'a private form', 'url': '/a-private-form/'},
|
|
{'slug': 'a-second-form-title', 'title': 'a second form title', 'url': '/a-second-form-title/'},
|
|
{'slug': 'form-title', 'title': 'form title', 'url': '/form-title/', 'keywords': ['foo', 'bar']},
|
|
{'slug': 'third-form-title', 'title': 'Third form title', 'url': '/third-form-title/'},
|
|
]
|
|
|
|
WCS_CATEGORIES_DATA = [
|
|
{'slug': 'test-%s' % i, 'title': 'Test %s' % i, 'url': '/test-%s/' % i} for i in [3, 9]
|
|
]
|
|
|
|
WCS_CATEGORIES_FORMDEFS_DATA = [
|
|
{
|
|
'slug': 'form-title',
|
|
'title': 'form title',
|
|
'url': '/form-title/',
|
|
'keywords': ['foo', 'bar'],
|
|
'count': 42,
|
|
},
|
|
{
|
|
'slug': 'a-second-form-title',
|
|
'title': 'a second form title',
|
|
'url': '/a-second-form-title/',
|
|
'count': 35,
|
|
},
|
|
]
|
|
|
|
WCS_USER_FORMS_DATA = [
|
|
{
|
|
'name': 'name',
|
|
'title': 'Title',
|
|
'url': '/form/1/',
|
|
'form_receipt_datetime': '2015-01-01T00:00:00',
|
|
'readable': True,
|
|
'category_slug': 'test-9',
|
|
},
|
|
{'name': 'name', 'url': '/form/2/', 'form_receipt_datetime': '2015-01-01T00:00:00', 'readable': True},
|
|
{'name': 'name', 'title': 'Title', 'url': '/form/3/', 'form_receipt_datetime': '2015-01-01T00:00:00'},
|
|
]
|
|
|
|
WCS_FORMS_DATA = [
|
|
{
|
|
'form_receipt_datetime': '2019-10-17T16:46:03',
|
|
'form_url': '/foobar/1',
|
|
'form_url_backoffice': '/backoffice/management/foobar/1/',
|
|
},
|
|
{
|
|
'form_receipt_datetime': '2019-10-17T16:46:04',
|
|
'form_url': '/foobar/2',
|
|
'form_url_backoffice': '/backoffice/management/foobar/2/',
|
|
},
|
|
]
|
|
|
|
WCS_USER_DRAFTS_DATA = [
|
|
{
|
|
'name': 'name',
|
|
'title': 'Title',
|
|
'url': '/form/1/',
|
|
'form_receipt_datetime': '2015-01-01T00:00:00',
|
|
'category_slug': 'test-9',
|
|
},
|
|
{'name': 'name', 'url': '/form/2/', 'form_receipt_datetime': '2015-01-01T00:00:00'},
|
|
{'name': 'name', 'title': 'Title', 'url': '/form/3/', 'form_receipt_datetime': '2015-01-01T00:00:00'},
|
|
{
|
|
'name': 'name',
|
|
'title': 'Title',
|
|
'url': '/form/4/',
|
|
'form_receipt_datetime': '2015-01-01T00:00:00',
|
|
'form_status_is_endpoint': True,
|
|
'category_slug': 'test-9',
|
|
},
|
|
]
|
|
|
|
WCS_CARDDEFS_DATA = [
|
|
{'title': 'Card Model 1', 'slug': 'card_model_1', 'custom_views': [{'id': 'foo', 'text': 'bar'}]},
|
|
{'title': 'Card Model 2', 'slug': 'card_model_2'},
|
|
{'title': 'Card Model 3', 'slug': 'card_model_3'},
|
|
{'title': 'Card A', 'slug': 'card_a'},
|
|
{'title': 'Card B', 'slug': 'card_b', 'custom_views': [{'id': 'a-custom-view', 'text': 'foo bar'}]},
|
|
{'title': 'Card C', 'slug': 'card_c'},
|
|
{'title': 'Card D', 'slug': 'card_d'},
|
|
{'title': 'Card E', 'slug': 'card_e'},
|
|
]
|
|
|
|
WCS_CARDS_DATA = {
|
|
'card_model_1': [
|
|
{
|
|
'id': 11,
|
|
'display_id': '10-11',
|
|
'display_name': 'Card Model 1 - n°10-11',
|
|
'digest': 'a a a',
|
|
'text': 'aa',
|
|
'url': '/backoffice/data/card_model_1/11/',
|
|
'fields': {
|
|
'fielda': '<i>a</i>',
|
|
'fieldb': True,
|
|
'fieldc': '2020-09-28',
|
|
'fieldd': {'filename': 'file.pdf', 'url': 'http://127.0.0.1:8999/download?f=42'},
|
|
'fielde': "lorem<strong>ipsum\n\nhello'world",
|
|
'fieldf': 'lorem<strong>ipsum\n\nhello world',
|
|
'fieldg': 'test@localhost',
|
|
'fieldh': 'https://www.example.net/',
|
|
'related': 'Foo Bar',
|
|
'related_raw': 42,
|
|
'related_structured': {'id': 42, 'text': 'blah'},
|
|
},
|
|
},
|
|
{
|
|
'id': 12,
|
|
'display_id': '10-12',
|
|
'display_name': 'Card Model 1 - n°10-12',
|
|
'digest': 'b b b',
|
|
'text': 'bb',
|
|
'url': '/backoffice/data/card_model_1/12/',
|
|
},
|
|
{
|
|
'id': 13,
|
|
'display_id': '10-13',
|
|
'display_name': 'Card Model 1 - n°10-13',
|
|
'digest': 'c c c',
|
|
'text': 'cc',
|
|
'url': '/backoffice/data/card_model_1/13/',
|
|
},
|
|
],
|
|
'card_a': [
|
|
{
|
|
'id': 1,
|
|
'fields': {
|
|
'cardb_raw': 1,
|
|
'cardsb_raw': [2, 3],
|
|
'blockb_raw': [{'cardb_raw': 4}, {'cardb_raw': 5}],
|
|
'cardc_raw': 6,
|
|
'cardz_raw': 42,
|
|
},
|
|
},
|
|
{
|
|
'id': 2,
|
|
'fields': {
|
|
'cardb_raw': 1,
|
|
'cardsb_raw': [2, 3],
|
|
'blockb_raw': [{'cardb_raw': 4}, {'cardb_raw': 5}],
|
|
'cardc_raw': 61, # unknown card_c
|
|
},
|
|
},
|
|
{
|
|
'id': 3,
|
|
'fields': {
|
|
# some missing fields
|
|
'blockb_raw': [{}],
|
|
},
|
|
},
|
|
{
|
|
'id': 4,
|
|
'fields': {
|
|
# some empty fields
|
|
'cardb_raw': None,
|
|
'cardsb_raw': None,
|
|
'blockb_raw': [{'cardb_raw': None}],
|
|
'cardc_raw': 7,
|
|
},
|
|
},
|
|
],
|
|
'card_b': [{'id': i, 'fields': []} for i in range(1, 12) if i != 6],
|
|
'card_c': [
|
|
{
|
|
'id': 6,
|
|
'fields': {
|
|
'cardb_raw': 7,
|
|
'cardsb_raw': [8, 9],
|
|
'blockb_raw': [{'cardb_raw': 10}, {'cardb_raw': 11}],
|
|
},
|
|
},
|
|
{
|
|
'id': 7,
|
|
'fields': {},
|
|
},
|
|
],
|
|
'card_f': [
|
|
{'id': 41, 'fields': {'cardh_raw': 42}},
|
|
],
|
|
'card_g': [
|
|
{'id': 43, 'fields': {'cardh_raw': 44}},
|
|
],
|
|
'card_h': [
|
|
{'id': 42, 'fields': {}},
|
|
{'id': 44, 'fields': {}},
|
|
],
|
|
}
|
|
|
|
WCS_CARDS_CUSTOM_VIEW_DATA = [
|
|
{
|
|
'id': 11,
|
|
'display_id': '10-11',
|
|
'display_name': 'Card Model 1 - n°10-11',
|
|
'digest': 'a a a',
|
|
'text': 'aa',
|
|
'url': '/backoffice/data/card_model_1/11/',
|
|
},
|
|
{
|
|
'id': 12,
|
|
'display_id': '10-12',
|
|
'display_name': 'Card Model 1 - n°10-12',
|
|
'digest': 'b b b',
|
|
'text': 'bb',
|
|
'url': '/backoffice/data/card_model_1/12/',
|
|
},
|
|
]
|
|
|
|
WCS_CARDDEF_SCHEMAS = {
|
|
'card_model_1': {
|
|
'name': 'Card Model 1',
|
|
'fields': [
|
|
{'label': 'Field A', 'varname': 'fielda', 'type': 'string'},
|
|
{'label': 'Field B', 'varname': 'fieldb', 'type': 'bool'},
|
|
{'label': 'Field C', 'varname': 'fieldc', 'type': 'date'},
|
|
{'label': 'Field D', 'varname': 'fieldd', 'type': 'file'},
|
|
{'label': 'Field E', 'varname': 'fielde', 'type': 'text'},
|
|
{'label': 'Field F', 'varname': 'fieldf', 'type': 'text', 'pre': True},
|
|
{'label': 'Field G', 'varname': 'fieldg', 'type': 'email'},
|
|
{'label': 'Field H', 'varname': 'fieldh', 'type': 'string'},
|
|
{'label': 'Empty', 'varname': 'empty', 'type': 'string'},
|
|
{'label': 'Related', 'varname': 'related', 'type': 'item'},
|
|
{'label': 'Page', 'type': 'page'},
|
|
{'label': 'Comment', 'type': 'comment'},
|
|
{'label': 'Title', 'type': 'title'},
|
|
{'label': 'Subtitle', 'type': 'subtitle'},
|
|
{'label': 'Empty', 'varname': None, 'type': 'string'},
|
|
],
|
|
},
|
|
'card_a': {
|
|
'name': 'Card A',
|
|
'fields': [
|
|
{'label': 'Card B', 'varname': 'cardb', 'type': 'item'},
|
|
{'label': 'Cards B', 'varname': 'cardsb', 'type': 'items'},
|
|
{'label': 'Block B', 'varname': 'blockb', 'type': 'block:b'},
|
|
{'label': 'Card C', 'varname': 'cardc', 'type': 'item'},
|
|
],
|
|
'relations': [
|
|
{'obj': 'carddef:card_b', 'varname': 'cardb', 'type': 'item', 'reverse': False},
|
|
{'obj': 'carddef:card_b', 'varname': 'cardsb', 'type': 'items', 'reverse': False},
|
|
{'obj': 'carddef:card_b', 'varname': 'blockb_cardb', 'type': 'item', 'reverse': False},
|
|
{'obj': 'carddef:card_c', 'varname': 'cardc', 'type': 'item', 'reverse': False},
|
|
{
|
|
'obj': 'carddef:card_z', # unknown card model
|
|
'varname': 'cardz',
|
|
'type': 'item',
|
|
'reverse': False,
|
|
},
|
|
],
|
|
},
|
|
'card_b': {
|
|
'name': 'Card B',
|
|
'fields': [],
|
|
'relations': [
|
|
{'obj': 'carddef:card_a', 'varname': 'cardb', 'type': 'item', 'reverse': True},
|
|
{'obj': 'carddef:card_a', 'varname': 'cardsb', 'type': 'items', 'reverse': True},
|
|
{'obj': 'carddef:card_a', 'varname': 'blockb_cardb', 'type': 'item', 'reverse': True},
|
|
{'obj': 'carddef:card_c', 'varname': 'cardb', 'type': 'item', 'reverse': True},
|
|
{'obj': 'carddef:card_c', 'varname': 'cardsb', 'type': 'items', 'reverse': True},
|
|
{'obj': 'carddef:card_c', 'varname': 'blockb_cardb', 'type': 'item', 'reverse': True},
|
|
],
|
|
},
|
|
'card_c': {
|
|
'name': 'Card C',
|
|
'fields': [
|
|
{'label': 'Card B', 'varname': 'cardb', 'type': 'item'},
|
|
{'label': 'Cards B', 'varname': 'cardsb', 'type': 'items'},
|
|
{'label': 'Block B', 'varname': 'blockb', 'type': 'block:b'},
|
|
],
|
|
'relations': [
|
|
{'obj': 'carddef:card_b', 'varname': 'cardb', 'type': 'item', 'reverse': False},
|
|
{'obj': 'carddef:card_b', 'varname': 'cardsb', 'type': 'items', 'reverse': False},
|
|
{'obj': 'carddef:card_b', 'varname': 'blockb_cardb', 'type': 'item', 'reverse': False},
|
|
{'obj': 'carddef:card_a', 'varname': 'cardc', 'type': 'item', 'reverse': True},
|
|
],
|
|
},
|
|
'card_d': {
|
|
'name': 'Card D',
|
|
'fields': [
|
|
{'label': 'Card D', 'varname': 'cardd-foo', 'type': 'item'},
|
|
{'label': 'Card E', 'varname': 'carde-foo', 'type': 'item'},
|
|
],
|
|
'relations': [
|
|
{'obj': 'carddef:card_d', 'varname': 'cardd-foo', 'type': 'item', 'reverse': False},
|
|
{'obj': 'carddef:card_d', 'varname': 'cardd-foo', 'type': 'item', 'reverse': True},
|
|
{'obj': 'carddef:card_e', 'varname': 'carde-foo', 'type': 'item', 'reverse': False},
|
|
],
|
|
},
|
|
'card_e': {
|
|
'name': 'Card E',
|
|
'fields': [
|
|
{'label': 'Card D', 'varname': 'cardd-bar', 'type': 'item'},
|
|
],
|
|
'relations': [
|
|
{'obj': 'carddef:card_d', 'varname': 'cardd-bar', 'type': 'item', 'reverse': False},
|
|
{'obj': 'carddef:card_d', 'varname': 'carde-foo', 'type': 'item', 'reverse': True},
|
|
],
|
|
},
|
|
'card_f': {
|
|
'name': 'Card F',
|
|
'fields': [
|
|
{'label': 'Card H', 'varname': 'cardh', 'type': 'item'},
|
|
],
|
|
'relations': [
|
|
{'obj': 'carddef:card_h', 'varname': 'cardh', 'type': 'item', 'reverse': False},
|
|
],
|
|
},
|
|
'card_g': {
|
|
'name': 'Card G',
|
|
'fields': [
|
|
{'label': 'Card H', 'varname': 'cardh', 'type': 'item'},
|
|
],
|
|
'relations': [
|
|
{'obj': 'carddef:card_h', 'varname': 'cardh', 'type': 'item', 'reverse': False},
|
|
],
|
|
},
|
|
'card_h': {
|
|
'name': 'Card H',
|
|
'fields': [],
|
|
'relations': [
|
|
{'obj': 'carddef:card_f', 'varname': 'cardh', 'type': 'item', 'reverse': True},
|
|
{'obj': 'carddef:card_g', 'varname': 'cardh', 'type': 'item', 'reverse': True},
|
|
],
|
|
},
|
|
}
|
|
|
|
|
|
class MockUser:
|
|
email = 'foo@example.net'
|
|
is_authenticated = True
|
|
is_anonymous = False
|
|
|
|
def get_name_id(self):
|
|
return None
|
|
|
|
|
|
class MockUserWithNameId:
|
|
email = 'foo@example.net'
|
|
is_authenticated = True
|
|
is_anonymous = False
|
|
|
|
def get_name_id(self):
|
|
return 'xyz'
|
|
|
|
|
|
class MockedRequestResponse(mock.Mock):
|
|
status_code = 200
|
|
|
|
def json(self):
|
|
return json.loads(self.content)
|
|
|
|
|
|
def get_data_from_url(url):
|
|
if '/api/formdefs/' in url:
|
|
return WCS_FORMDEFS_DATA
|
|
if '/api/categories/' in url:
|
|
if '/formdefs/' in url:
|
|
return WCS_CATEGORIES_FORMDEFS_DATA
|
|
return WCS_CATEGORIES_DATA
|
|
if '/api/user/forms' in url:
|
|
return WCS_USER_FORMS_DATA
|
|
if '/api/forms' in url:
|
|
return WCS_FORMS_DATA
|
|
if '/api/user/drafts' in url:
|
|
return WCS_USER_DRAFTS_DATA
|
|
if '/api/cards/@list' in url:
|
|
return WCS_CARDDEFS_DATA
|
|
m_schema = re.match(r'/api/cards/([a-z0-9_]+)/@schema', url)
|
|
if m_schema:
|
|
return WCS_CARDDEF_SCHEMAS.get(m_schema.group(1)) or {}
|
|
m_card = re.match(r'/api/cards/([a-z0-9_]+)/(\d+)/', url)
|
|
if m_card:
|
|
try:
|
|
return [d for d in WCS_CARDS_DATA[m_card.group(1)] if d['id'] == int(m_card.group(2))][0]
|
|
except IndexError:
|
|
return {}
|
|
m_card = re.match(r'/api/cards/([a-z0-9_]+)/([a-z0-9_]+)/(\d+)/', url) # model/custom-view/id
|
|
if m_card:
|
|
try:
|
|
return [d for d in WCS_CARDS_DATA[m_card.group(1)] if d['id'] == int(m_card.group(3))][0]
|
|
except IndexError:
|
|
return {}
|
|
if 'api/cards/card_model_1/list/foo' in url:
|
|
return WCS_CARDS_CUSTOM_VIEW_DATA
|
|
m_list = re.match(r'/api/cards/([a-z0-9_]+)/list', url)
|
|
if m_list:
|
|
return WCS_CARDS_DATA.get(m_list.group(1)) or []
|
|
return []
|
|
|
|
|
|
def mocked_requests_send(request, **kwargs):
|
|
request_url = urllib.parse.urlparse(request.url)
|
|
data = copy.deepcopy(get_data_from_url(request_url.path))
|
|
|
|
if not isinstance(data, list):
|
|
return MockedRequestResponse(content=json.dumps(data))
|
|
|
|
for elem in data:
|
|
for key in ['url', 'form_url', 'form_url_backoffice']:
|
|
if key not in elem:
|
|
continue
|
|
elem_url = elem[key]
|
|
elem[key] = '{scheme}://{netloc}{url}'.format(
|
|
scheme=request_url.scheme, netloc=request_url.netloc, url=elem_url
|
|
)
|
|
|
|
return MockedRequestResponse(content=json.dumps({'data': data}))
|
|
|
|
|
|
@pytest.fixture
|
|
def context():
|
|
ctx = {'request': RequestFactory().get('/')}
|
|
ctx['request'].user = None
|
|
session_engine = import_module(settings.SESSION_ENGINE)
|
|
ctx['request'].session = session_engine.SessionStore()
|
|
return ctx
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_form_cell_setup(mock_send):
|
|
cell = WcsFormCell()
|
|
form_class = cell.get_default_form_class()
|
|
form = form_class()
|
|
assert form.fields['formdef_reference'].widget.choices == [
|
|
('default:a-private-form', 'test : a private form'),
|
|
('default:a-second-form-title', 'test : a second form title'),
|
|
('default:form-title', 'test : form title'),
|
|
('default:third-form-title', 'test : Third form title'),
|
|
('other:a-private-form', 'test2 : a private form'),
|
|
('other:a-second-form-title', 'test2 : a second form title'),
|
|
('other:form-title', 'test2 : form title'),
|
|
('other:third-form-title', 'test2 : Third form title'),
|
|
]
|
|
assert 'extra_css_class' not in form.fields
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_form_cell_save_cache(mock_send):
|
|
page = Page(title='xxx', slug='test_form_cell_save_cache', template_name='standard')
|
|
page.save()
|
|
cell = WcsFormCell(page=page, placeholder='content', order=0)
|
|
assert cell.get_additional_label() is None
|
|
cell.formdef_reference = 'default:form-title'
|
|
cell.save()
|
|
assert cell.cached_title == 'form title'
|
|
assert cell.get_additional_label() == 'form title'
|
|
# make sure cached attributes are removed from serialized pages
|
|
assert 'cached_' not in json.dumps(page.get_serialized_page())
|
|
|
|
# check content provided to search engine
|
|
assert cell.render_for_search() == ''
|
|
assert cell.get_external_links_data() == [
|
|
{'title': 'form title', 'url': 'http://127.0.0.1:8999/form-title/', 'text': 'foo bar'}
|
|
]
|
|
|
|
# artificially change title
|
|
WcsFormCell.objects.filter(id=cell.id).update(cached_title='XXX')
|
|
assert WcsFormCell.objects.get(id=cell.id).cached_title == 'XXX'
|
|
# run update db cache
|
|
appconfig = apps.get_app_config('wcs')
|
|
appconfig.update_db_cache()
|
|
assert WcsFormCell.objects.get(id=cell.id).cached_title == 'form title'
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_form_cell_validity(mock_send):
|
|
page = Page.objects.create(title='xxx', slug='test_form_cell_save_cache', template_name='standard')
|
|
cell = WcsFormCell.objects.create(page=page, placeholder='content', order=0)
|
|
validity_info = ValidityInfo.objects.latest('pk')
|
|
assert validity_info.invalid_reason_code == 'wcs_form_not_defined'
|
|
assert validity_info.invalid_since is not None
|
|
|
|
cell.formdef_reference = 'default:form-title'
|
|
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 formdefs, 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
|
|
|
|
cell.formdef_reference = 'default:foobar'
|
|
cell.save()
|
|
validity_info = ValidityInfo.objects.latest('pk')
|
|
assert validity_info.invalid_reason_code == 'wcs_form_not_found'
|
|
assert validity_info.invalid_since is not None
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_form_cell_load(mock_send):
|
|
page = Page(title='xxx', slug='test_form_cell_save_cache', template_name='standard')
|
|
page.save()
|
|
cell = WcsFormCell(page=page, placeholder='content', order=0)
|
|
cell.formdef_reference = 'default:form-title'
|
|
cell.save()
|
|
site_export = [page.get_serialized_page()]
|
|
cell.delete()
|
|
assert not Page.objects.get(id=page.id).get_cells()
|
|
Page.load_serialized_pages(site_export)
|
|
page = Page.objects.get(slug='test_form_cell_save_cache')
|
|
cells = page.get_cells()
|
|
assert len(cells) == 1
|
|
cell = cells[0]
|
|
assert cell.cached_title == 'form title'
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_category_cell_save_cache(mock_send):
|
|
page = Page(title='xxx', slug='test_category_cell_save_cache', template_name='standard')
|
|
page.save()
|
|
cell = WcsCategoryCell(page=page, placeholder='content', order=0)
|
|
assert cell.get_additional_label() is None
|
|
cell.category_reference = 'default:test-3'
|
|
cell.save()
|
|
assert cell.cached_title == 'Test 3'
|
|
assert cell.get_additional_label() == 'Test 3'
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_category_cell_validity(mock_send):
|
|
page = Page.objects.create(title='xxx', slug='test_category_cell_save_cache', template_name='standard')
|
|
cell = WcsCategoryCell.objects.create(page=page, placeholder='content', order=0)
|
|
validity_info = ValidityInfo.objects.latest('pk')
|
|
assert validity_info.invalid_reason_code == 'wcs_category_not_defined'
|
|
assert validity_info.invalid_since is not None
|
|
|
|
cell.category_reference = 'default:test-3'
|
|
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 categories, 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
|
|
|
|
cell.category_reference = 'default:foobar'
|
|
cell.save()
|
|
validity_info = ValidityInfo.objects.latest('pk')
|
|
assert validity_info.invalid_reason_code == 'wcs_category_not_found'
|
|
assert validity_info.invalid_since is not None
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_manager_categories_cell(mock_send, settings, app, admin_user):
|
|
page = Page.objects.create(title='xxx', slug='test', template_name='standard')
|
|
CategoriesCell.objects.create(page=page, placeholder='content', order=0)
|
|
|
|
app = login(app)
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
assert resp.pyquery('[data-tab-slug="general"] select[name$="wcs_site"]')
|
|
|
|
default = settings.KNOWN_SERVICES['wcs']['default']
|
|
settings.KNOWN_SERVICES = {'wcs': {'default': default}}
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
assert not resp.pyquery('[data-tab-slug="general"]')
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_categories_cell_check_validity(mock_send):
|
|
page = Page.objects.create(title='xxx', slug='test', template_name='standard')
|
|
cell = CategoriesCell.objects.create(page=page, placeholder='content', order=0)
|
|
|
|
# invalid wcs_site
|
|
cell.wcs_site = 'invalid'
|
|
cell.save()
|
|
cell.check_validity()
|
|
validity_info = ValidityInfo.objects.latest('pk')
|
|
assert validity_info.invalid_reason_code == 'wcs_site_not_found'
|
|
assert validity_info.invalid_since is not None
|
|
|
|
# valid wcs_site
|
|
cell.wcs_site = 'default'
|
|
cell.save()
|
|
cell.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_form_cell_render(mock_send):
|
|
page = Page(title='xxx', slug='test_form_cell_render', template_name='standard')
|
|
page.save()
|
|
cell = WcsFormCell(page=page, placeholder='content', order=0)
|
|
cell.formdef_reference = 'default:form-title'
|
|
cell.save()
|
|
result = cell.render({'request': RequestFactory().get('/')})
|
|
assert 'http://127.0.0.1:8999/form-title/tryauth' in result
|
|
assert 'form title' in result
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_current_forms_cell_setup(mock_send):
|
|
cell = WcsCurrentFormsCell()
|
|
form_class = cell.get_default_form_class()
|
|
form = form_class()
|
|
assert form.fields['wcs_site'].widget.choices == [
|
|
('', 'All'),
|
|
('default', 'test'),
|
|
('other', 'test2'),
|
|
]
|
|
assert 'current_forms' in form.fields
|
|
assert cell.get_additional_label() == 'All Sites - Current Forms'
|
|
cell.wcs_site = 'default'
|
|
assert cell.get_additional_label() == 'test - Current Forms'
|
|
cell.wcs_site = None
|
|
|
|
cell.current_forms = True
|
|
cell.done_forms = True
|
|
assert cell.get_additional_label() == 'All Sites - All Forms'
|
|
|
|
cell.current_forms = False
|
|
cell.done_forms = True
|
|
assert cell.get_additional_label() == 'All Sites - Done Forms'
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_current_forms_cell_render(mock_send, context):
|
|
page = Page(title='xxx', slug='test_current_forms_cell_render', template_name='standard')
|
|
page.save()
|
|
cell = WcsCurrentFormsCell(page=page, placeholder='content', order=0)
|
|
cell.save()
|
|
|
|
context['request'].user = MockUser()
|
|
|
|
# query should fail as nothing is cached
|
|
cache.clear()
|
|
with pytest.raises(NothingInCacheException):
|
|
result = cell.render(context)
|
|
|
|
context['synchronous'] = True # to get fresh content
|
|
|
|
result = cell.render(context)
|
|
assert 'http://127.0.0.1:8999/form/1/' in result
|
|
assert 'http://127.0.0.1:8999/form/2/' not in result # no title
|
|
assert 'http://127.0.0.1:8999/form/3/' not in result # not readable
|
|
assert 'http://127.0.0.2:8999/form/1/' in result
|
|
assert 'http://127.0.0.2:8999/form/2/' not in result
|
|
assert 'http://127.0.0.2:8999/form/3/' not in result
|
|
|
|
# limit to categories
|
|
cell.categories = {'data': ['default:test-3', 'other:test-6']}
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
cell.get_cell_extra_context(context)
|
|
assert len(requests_get.call_args_list) == 2
|
|
assert (
|
|
requests_get.call_args_list[0][0][0]
|
|
== '/api/user/forms/?status=open&limit=100&sort=desc&category_slugs=test-3'
|
|
)
|
|
assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://127.0.0.1:8999/'
|
|
assert (
|
|
requests_get.call_args_list[1][0][0]
|
|
== '/api/user/forms/?status=open&limit=100&sort=desc&category_slugs=test-6'
|
|
)
|
|
assert requests_get.call_args_list[1][1]['remote_service']['url'] == 'http://127.0.0.2:8999/'
|
|
|
|
# check include drafts
|
|
cell.categories = None
|
|
cell.include_drafts = False
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
cell.get_cell_extra_context(context)
|
|
assert len(requests_get.call_args_list) == 2
|
|
assert requests_get.call_args_list[0][0][0] == '/api/user/forms/?status=open&limit=100&sort=desc'
|
|
assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://127.0.0.1:8999/'
|
|
assert requests_get.call_args_list[1][0][0] == '/api/user/forms/?status=open&limit=100&sort=desc'
|
|
assert requests_get.call_args_list[1][1]['remote_service']['url'] == 'http://127.0.0.2:8999/'
|
|
|
|
cell.include_drafts = True
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
cell.get_cell_extra_context(context)
|
|
assert len(requests_get.call_args_list) == 2
|
|
assert (
|
|
requests_get.call_args_list[0][0][0]
|
|
== '/api/user/forms/?status=open&include-drafts=on&limit=100&sort=desc'
|
|
)
|
|
assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://127.0.0.1:8999/'
|
|
assert (
|
|
requests_get.call_args_list[1][0][0]
|
|
== '/api/user/forms/?status=open&include-drafts=on&limit=100&sort=desc'
|
|
)
|
|
assert requests_get.call_args_list[1][1]['remote_service']['url'] == 'http://127.0.0.2:8999/'
|
|
|
|
cell.categories = {'data': ['default:test-3']}
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
cell.get_cell_extra_context(context)
|
|
assert len(requests_get.call_args_list) == 1
|
|
assert (
|
|
requests_get.call_args_list[0][0][0]
|
|
== '/api/user/forms/?status=open&include-drafts=on&limit=100&sort=desc&category_slugs=test-3'
|
|
)
|
|
assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://127.0.0.1:8999/'
|
|
|
|
cell.categories = {'data': []}
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
cell.get_cell_extra_context(context)
|
|
assert len(requests_get.call_args_list) == 2
|
|
|
|
# current_forms only
|
|
cell.include_drafts = False
|
|
cell.current_forms = True
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
cell.get_cell_extra_context(context)
|
|
assert len(requests_get.call_args_list) == 2
|
|
assert requests_get.call_args_list[0][0][0] == '/api/user/forms/?status=open&limit=100&sort=desc'
|
|
assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://127.0.0.1:8999/'
|
|
assert requests_get.call_args_list[1][0][0] == '/api/user/forms/?status=open&limit=100&sort=desc'
|
|
assert requests_get.call_args_list[1][1]['remote_service']['url'] == 'http://127.0.0.2:8999/'
|
|
|
|
# all forms
|
|
cell.done_forms = True
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
cell.get_cell_extra_context(context)
|
|
assert len(requests_get.call_args_list) == 2
|
|
assert requests_get.call_args_list[0][0][0] == '/api/user/forms/?status=all&limit=100&sort=desc'
|
|
assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://127.0.0.1:8999/'
|
|
assert requests_get.call_args_list[1][0][0] == '/api/user/forms/?status=all&limit=100&sort=desc'
|
|
assert requests_get.call_args_list[1][1]['remote_service']['url'] == 'http://127.0.0.2:8999/'
|
|
|
|
# done forms only
|
|
cell.current_forms = False
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
cell.get_cell_extra_context(context)
|
|
assert len(requests_get.call_args_list) == 2
|
|
assert requests_get.call_args_list[0][0][0] == '/api/user/forms/?status=done&limit=100&sort=desc'
|
|
assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://127.0.0.1:8999/'
|
|
assert requests_get.call_args_list[1][0][0] == '/api/user/forms/?status=done&limit=100&sort=desc'
|
|
assert requests_get.call_args_list[1][1]['remote_service']['url'] == 'http://127.0.0.2:8999/'
|
|
|
|
# include forms user can see
|
|
cell.include_forms_user_can_access = True
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
cell.render(context)
|
|
assert (
|
|
requests_get.call_args_list[0][0][0]
|
|
== '/api/user/forms/?status=done&include-accessible=on&limit=100&sort=desc'
|
|
)
|
|
|
|
# check empty messages and title
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
cell.current_forms = True
|
|
cell.done_forms = False
|
|
cell.include_drafts = False
|
|
result = cell.render(context)
|
|
assert '<h2>Current Forms</h2>' in result
|
|
assert 'There are no current forms.' in result
|
|
cell.custom_title = 'Foo bar'
|
|
result = cell.render(context)
|
|
assert '<h2>Foo bar</h2>' in result
|
|
cell.custom_title = ''
|
|
cell.done_forms = True
|
|
result = cell.render(context)
|
|
assert '<h2>All Forms</h2>' in result
|
|
assert 'There are no forms.' in result
|
|
cell.custom_title = 'Foo bar'
|
|
result = cell.render(context)
|
|
assert '<h2>Foo bar</h2>' in result
|
|
cell.custom_title = ''
|
|
cell.current_forms = False
|
|
result = cell.render(context)
|
|
assert '<h2>Done Forms</h2>' in result
|
|
assert 'There are no done forms' in result
|
|
cell.custom_title = 'Foo bar'
|
|
result = cell.render(context)
|
|
assert '<h2>Foo bar</h2>' in result
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_current_forms_cell_validity(mock_send, context):
|
|
page = Page.objects.create(title='xxx', slug='test_current_forms_cell_render', template_name='standard')
|
|
cell = WcsCurrentFormsCell.objects.create(page=page, placeholder='content', order=0)
|
|
context['request'].user = MockUser()
|
|
context['synchronous'] = True # to get fresh content
|
|
|
|
cell.get_data(context)
|
|
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.get_data(context)
|
|
assert ValidityInfo.objects.exists() is False
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
requests_get.side_effect = ConnectionError()
|
|
cell.get_data(context)
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
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.get_data(context)
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_current_forms_cell_check_validity(mock_send, context):
|
|
page = Page.objects.create(title='xxx', slug='test_current_forms_cell_render', template_name='standard')
|
|
cell = WcsCurrentFormsCell.objects.create(page=page, placeholder='content', order=0)
|
|
|
|
# no category
|
|
cell.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
# valid categories
|
|
cell.categories = {'data': ['default:test-3', 'default:test-9']}
|
|
cell.save()
|
|
cell.check_validity()
|
|
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.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
requests_get.side_effect = ConnectionError()
|
|
cell.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
# can not retrieve categories, 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.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
# invalid category
|
|
cell.categories = {'data': ['default:foobar', 'default:test-9']}
|
|
cell.save()
|
|
cell.check_validity()
|
|
validity_info = ValidityInfo.objects.latest('pk')
|
|
assert validity_info.invalid_reason_code == 'wcs_category_not_found'
|
|
assert validity_info.invalid_since is not None
|
|
|
|
# invalid wcs_site
|
|
cell.categories = {'data': ['default:test-3', 'default:test-9']}
|
|
cell.wcs_site = 'invalid'
|
|
cell.save()
|
|
cell.check_validity()
|
|
validity_info = ValidityInfo.objects.latest('pk')
|
|
assert validity_info.invalid_reason_code == 'wcs_site_not_found'
|
|
assert validity_info.invalid_since is not None
|
|
|
|
# valid wcs_site
|
|
cell.wcs_site = 'default'
|
|
cell.save()
|
|
cell.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_current_forms_cell_render_single_site(mock_send, context):
|
|
page = Page(title='xxx', slug='test_current_forms_cell_render', template_name='standard')
|
|
page.save()
|
|
cell = WcsCurrentFormsCell(page=page, placeholder='content', order=0)
|
|
cell.wcs_site = 'default'
|
|
cell.save()
|
|
|
|
context['request'].user = MockUser()
|
|
|
|
# query should fail as nothing is cached
|
|
cache.clear()
|
|
with pytest.raises(NothingInCacheException):
|
|
result = cell.render(context)
|
|
|
|
context['synchronous'] = True # to get fresh content
|
|
|
|
result = cell.render(context)
|
|
assert 'http://127.0.0.1:8999/form/1/' in result
|
|
assert 'http://127.0.0.2:8999/form/1/' not in result
|
|
|
|
|
|
def test_current_forms_name_id(context):
|
|
page = Page(title='xxx', slug='test_current_forms_cell_render', template_name='standard')
|
|
page.save()
|
|
cell = WcsCurrentFormsCell(page=page, placeholder='content', order=0)
|
|
cell.wcs_site = 'default'
|
|
cell.save()
|
|
|
|
context['synchronous'] = True # to get fresh content
|
|
|
|
# anonymous user
|
|
context['request'].user = AnonymousUser()
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
cell.render(context)
|
|
assert requests_get.call_args_list[0][0][0] == '/api/user/forms/?status=open&limit=100&sort=desc'
|
|
|
|
# user with name_id
|
|
context['request'].user = MockUserWithNameId()
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
cell.render(context)
|
|
assert requests_get.call_args_list[0][0][0] == '/api/users/xyz/forms?status=open&limit=100&sort=desc'
|
|
|
|
|
|
def test_care_forms_cell_setup():
|
|
cell = WcsCareFormsCell()
|
|
form_class = cell.get_default_form_class()
|
|
form = form_class()
|
|
assert form.fields['wcs_site'].widget.choices == [
|
|
('', 'All'),
|
|
('default', 'test'),
|
|
('other', 'test2'),
|
|
]
|
|
assert cell.get_additional_label() == 'All Sites'
|
|
cell.wcs_site = 'default'
|
|
assert cell.get_additional_label() == 'test'
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_manager_care_forms_cell(mock_send, app, admin_user):
|
|
page = Page(title='One', slug='one', template_name='standard')
|
|
page.save()
|
|
app = login(app)
|
|
resp = app.get('/manage/pages/%s/' % page.id)
|
|
resp = app.get(
|
|
resp.html.find('option', **{'data-add-url': re.compile('wcscareformscell')})['data-add-url']
|
|
)
|
|
|
|
cells = Page.objects.get(id=page.id).get_cells()
|
|
assert len(cells) == 1
|
|
assert isinstance(cells[0], WcsCareFormsCell)
|
|
|
|
resp = app.get('/manage/pages/%s/' % page.id)
|
|
assert not resp.pyquery('[data-tab-slug="general"] input[name$="custom_title"]')
|
|
assert resp.pyquery('[data-tab-slug="appearance"] input[name$="custom_title"]')
|
|
assert (
|
|
resp.pyquery.find('div.cell [data-tab-slug="advanced"] input[name$="cache_duration"]').val() == '120'
|
|
)
|
|
resp.forms[0]['c%s-cache_duration' % cells[0].get_reference()] = '10'
|
|
manager_submit_cell(resp.forms[0])
|
|
cells[0].refresh_from_db()
|
|
assert cells[0].cache_duration == 10
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_care_forms_cell_render(mock_send, context):
|
|
page = Page(title='xxx', slug='test_care_forms_cell_render', template_name='standard')
|
|
page.save()
|
|
cell = WcsCareFormsCell(page=page, placeholder='content', order=0)
|
|
cell.save()
|
|
|
|
context['request'].user = MockUser()
|
|
|
|
# query should fail as nothing is cached
|
|
cache.clear()
|
|
with pytest.raises(NothingInCacheException):
|
|
result = cell.render(context)
|
|
|
|
context['synchronous'] = True # to get fresh content
|
|
|
|
with mock.patch('combo.apps.wcs.models.is_portal_agent') as is_portal_agent:
|
|
is_portal_agent.return_value = True
|
|
result = cell.render(context)
|
|
|
|
assert 'Forms to process - test' in result
|
|
assert 'http://127.0.0.1:8999/backoffice/management/foobar/1' in result
|
|
assert 'http://127.0.0.1:8999/backoffice/management/foobar/2' in result
|
|
assert '"http://127.0.0.1:8999/backoffice/management/listing"' in result
|
|
assert 'Forms to process - test2' in result
|
|
assert 'http://127.0.0.2:8999/backoffice/management/foobar/1' in result
|
|
assert 'http://127.0.0.2:8999/backoffice/management/foobar/2' in result
|
|
assert '"http://127.0.0.2:8999/backoffice/management/listing"' in result
|
|
|
|
cell.custom_title = 'Foo Bar'
|
|
with mock.patch('combo.apps.wcs.models.is_portal_agent') as is_portal_agent:
|
|
is_portal_agent.return_value = False
|
|
result = cell.render(context)
|
|
|
|
assert 'Forms to process - test' not in result
|
|
assert 'Foo Bar' in result
|
|
assert 'http://127.0.0.1:8999/foobar/1' in result
|
|
assert 'http://127.0.0.1:8999/foobar/2' in result
|
|
assert 'Forms to process - test2' not in result
|
|
assert 'Foo Bar' in result
|
|
assert 'http://127.0.0.2:8999/foobar/1' in result
|
|
assert 'http://127.0.0.2:8999/foobar/2' in result
|
|
assert '/listing' not in result
|
|
|
|
data = cell.get_data(context)
|
|
assert 'default' in data
|
|
assert 'other' in data
|
|
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
cell.render(context)
|
|
assert requests_get.call_args_list[0][0][0] == '/api/forms/?limit=10'
|
|
assert requests_get.call_args_list[1][0][0] == '/api/forms/?limit=10'
|
|
|
|
# limit to a list of categories
|
|
cell.categories = {'data': ['default:test-3', 'other:test-4']}
|
|
|
|
with mock.patch('combo.apps.wcs.models.is_portal_agent') as is_portal_agent:
|
|
is_portal_agent.return_value = True
|
|
result = cell.render(context)
|
|
assert '"http://127.0.0.1:8999/backoffice/management/listing?category_slugs=test-3"' in result
|
|
assert '"http://127.0.0.2:8999/backoffice/management/listing?category_slugs=test-4"' in result
|
|
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
cell.render(context)
|
|
assert len(requests_get.call_args_list) == 2
|
|
assert requests_get.call_args_list[0][0][0] == '/api/forms/?limit=10&category_slugs=test-3'
|
|
assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://127.0.0.1:8999/'
|
|
assert requests_get.call_args_list[1][0][0] == '/api/forms/?limit=10&category_slugs=test-4'
|
|
assert requests_get.call_args_list[1][1]['remote_service']['url'] == 'http://127.0.0.2:8999/'
|
|
|
|
# limit to a single category
|
|
cell.categories = {'data': ['default:test-3']}
|
|
|
|
with mock.patch('combo.apps.wcs.models.is_portal_agent') as is_portal_agent:
|
|
is_portal_agent.return_value = True
|
|
result = cell.render(context)
|
|
assert '"http://127.0.0.1:8999/backoffice/management/listing?category_slugs=test-3"' in result
|
|
assert '"http://127.0.0.2:8999/backoffice/management/listing' not in result
|
|
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
cell.render(context)
|
|
assert len(requests_get.call_args_list) == 1
|
|
assert requests_get.call_args_list[0][0][0] == '/api/forms/?limit=10&category_slugs=test-3'
|
|
assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://127.0.0.1:8999/'
|
|
|
|
# no category selected: call all sites
|
|
cell.categories = {'data': []}
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
cell.render(context)
|
|
assert len(requests_get.call_args_list) == 2
|
|
|
|
|
|
def test_care_forms_cell_validity(context):
|
|
page = Page.objects.create(title='xxx', slug='test_care_forms_cell_render', template_name='standard')
|
|
cell = WcsCareFormsCell.objects.create(page=page, placeholder='content', order=0)
|
|
context['synchronous'] = True # to get fresh content
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
cell.get_data(context)
|
|
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.get_data(context)
|
|
assert ValidityInfo.objects.exists() is False
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
requests_get.side_effect = ConnectionError()
|
|
cell.get_data(context)
|
|
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_json = mock.Mock(status_code=500)
|
|
requests_get.return_value = mock_json
|
|
cell.get_data(context)
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=404)
|
|
requests_get.return_value = mock_json
|
|
cell.get_data(context)
|
|
validity_info = ValidityInfo.objects.latest('pk')
|
|
assert validity_info.invalid_reason_code == 'wcs_data_failure'
|
|
assert validity_info.invalid_since is not None
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_care_forms_cell_check_validity(mock_send, context):
|
|
page = Page.objects.create(title='xxx', slug='test_care_forms_cell_render', template_name='standard')
|
|
cell = WcsCareFormsCell.objects.create(page=page, placeholder='content', order=0)
|
|
|
|
# no category
|
|
cell.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
# valid categories
|
|
cell.categories = {'data': ['default:test-3', 'default:test-9']}
|
|
cell.save()
|
|
cell.check_validity()
|
|
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.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
requests_get.side_effect = ConnectionError()
|
|
cell.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
# can not retrieve categories, 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.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
# invalid category
|
|
cell.categories = {'data': ['default:foobar', 'default:test-9']}
|
|
cell.save()
|
|
cell.check_validity()
|
|
validity_info = ValidityInfo.objects.latest('pk')
|
|
assert validity_info.invalid_reason_code == 'wcs_category_not_found'
|
|
assert validity_info.invalid_since is not None
|
|
|
|
# invalid wcs_site
|
|
cell.categories = {'data': ['default:test-3', 'default:test-9']}
|
|
cell.wcs_site = 'invalid'
|
|
cell.save()
|
|
cell.check_validity()
|
|
validity_info = ValidityInfo.objects.latest('pk')
|
|
assert validity_info.invalid_reason_code == 'wcs_site_not_found'
|
|
assert validity_info.invalid_since is not None
|
|
|
|
# valid wcs_site
|
|
cell.wcs_site = 'default'
|
|
cell.save()
|
|
cell.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_care_forms_cell_render_single_site(mock_send, context):
|
|
page = Page(title='xxx', slug='test_care_forms_cell_render', template_name='standard')
|
|
page.save()
|
|
cell = WcsCareFormsCell(page=page, placeholder='content', order=0)
|
|
cell.wcs_site = 'default'
|
|
cell.save()
|
|
|
|
context['request'].user = MockUser()
|
|
|
|
# query should fail as nothing is cached
|
|
cache.clear()
|
|
with pytest.raises(NothingInCacheException):
|
|
result = cell.render(context)
|
|
|
|
context['synchronous'] = True # to get fresh content
|
|
|
|
with mock.patch('combo.apps.wcs.models.is_portal_agent') as is_portal_agent:
|
|
is_portal_agent.return_value = True
|
|
result = cell.render(context)
|
|
assert '"http://127.0.0.1:8999/backoffice/management/listing"' in result
|
|
assert '"http://127.0.0.2:8999/backoffice/management/listing"' not in result
|
|
|
|
data = cell.get_data(context)
|
|
assert 'default' in data
|
|
assert 'other' not in data
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_forms_of_category_cell_setup(mock_send):
|
|
cell = WcsFormsOfCategoryCell()
|
|
form_class = cell.get_default_form_class()
|
|
form = form_class()
|
|
assert form.fields['category_reference'].widget.choices == [
|
|
('default:test-3', 'test : Test 3'),
|
|
('default:test-9', 'test : Test 9'),
|
|
('other:test-3', 'test2 : Test 3'),
|
|
('other:test-9', 'test2 : Test 9'),
|
|
]
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_forms_of_category_cell_render(mock_send, context):
|
|
page = Page(title='xxx', slug='test_forms_of_category_cell_render', template_name='standard')
|
|
page.save()
|
|
cell = WcsFormsOfCategoryCell(page=page, placeholder='content', order=0)
|
|
cell.category_reference = 'default:test-9'
|
|
cell.ordering = 'alpha'
|
|
cell.save()
|
|
context['synchronous'] = True # to get fresh content
|
|
result = cell.render(context)
|
|
assert 'form title' in result and 'a second form title' in result
|
|
assert result.index('form title') > result.index('a second form title')
|
|
assert 'http://127.0.0.1:8999/form-title/tryauth' in result
|
|
assert 'http://127.0.0.1:8999/a-second-form-title/tryauth' in result
|
|
assert 'keyword-foo' in result
|
|
assert 'keyword-bar' in result
|
|
|
|
cell.ordering = 'popularity'
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert 'form title' in result and 'a second form title' in result
|
|
assert result.index('form title') < result.index('a second form title')
|
|
|
|
cell.ordering = 'manual'
|
|
cell.save()
|
|
result = cell.render(context)
|
|
# by default all forms should be present, in alphabetical order
|
|
assert result.index('form title') > result.index('a second form title')
|
|
|
|
# set a manual order
|
|
cell.manual_order = {'data': ['default:test-9:a-second-form-title', 'default:test-9:form-title']}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert result.index('form title') > result.index('a second form title')
|
|
|
|
# make sure all forms are displayed even if the manual order only specify
|
|
# some.
|
|
cell.manual_order = {'data': ['default:test-9:a-second-form-title']}
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert result.index('form title') > result.index('a second form title')
|
|
assert 'form title' in result and 'a second form title' in result
|
|
|
|
# check content provided to search engine
|
|
assert cell.render_for_search() == ''
|
|
assert len(list(cell.get_external_links_data())) == 2
|
|
|
|
# existing category, but empty
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
result = cell.render(context)
|
|
assert '<h2>' not in result
|
|
context['combo_display_even_empty_categories'] = True
|
|
assert len(requests_get.call_args_list) == 1
|
|
assert requests_get.call_args_list[0][0][0] == '/api/categories/test-9/formdefs/'
|
|
assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://127.0.0.1:8999/'
|
|
|
|
result = cell.render(context)
|
|
assert '<h2>' in result
|
|
context.pop('combo_display_even_empty_categories')
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_forms_of_category_cancelurl(mock_send, app):
|
|
page = Page(title='xxx', slug='test_forms_of_category_cell_render', template_name='standard')
|
|
page.save()
|
|
cell = WcsFormsOfCategoryCell(page=page, placeholder='content', order=0)
|
|
cell.category_reference = 'default:test-9'
|
|
cell.ordering = 'alpha'
|
|
cell.save()
|
|
resp = app.get(page.get_online_url())
|
|
ajax_cell_url = PyQuery(resp.text).find('[data-ajax-cell-url]').attr('data-ajax-cell-url')
|
|
extra_ctx = PyQuery(resp.text).find('[data-ajax-cell-url]').attr('data-extra-context')
|
|
cell_resp = app.get(ajax_cell_url + '?ctx=' + extra_ctx)
|
|
assert (
|
|
PyQuery(cell_resp.text).find('a').attr('href')
|
|
== 'http://127.0.0.1:8999/a-second-form-title/tryauth?cancelurl=http://testserver/test_forms_of_category_cell_render/'
|
|
)
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_forms_of_category_cell_validity(mock_send, context):
|
|
page = Page.objects.create(
|
|
title='xxx', slug='test_forms_of_category_cell_render', template_name='standard'
|
|
)
|
|
cell = WcsFormsOfCategoryCell.objects.create(page=page, placeholder='content', order=0)
|
|
validity_info = ValidityInfo.objects.latest('pk')
|
|
assert validity_info.invalid_reason_code == 'wcs_category_not_defined'
|
|
assert validity_info.invalid_since is not None
|
|
cell.category_reference = 'default:test-9'
|
|
cell.save()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=404)
|
|
requests_get.return_value = mock_json
|
|
cell.render(context)
|
|
validity_info = ValidityInfo.objects.latest('pk')
|
|
assert validity_info.invalid_reason_code == 'wcs_data_failure'
|
|
assert validity_info.invalid_since is not None
|
|
cell.mark_as_valid()
|
|
|
|
# can not retrieve data, don't set cell as invalid
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=500)
|
|
requests_get.return_value = mock_json
|
|
cell.render(context)
|
|
assert ValidityInfo.objects.exists() is False
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
requests_get.side_effect = ConnectionError()
|
|
cell.render(context)
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
# can not retrieve categories, 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
|
|
|
|
cell.category_reference = 'default:foobar'
|
|
cell.save()
|
|
validity_info = ValidityInfo.objects.latest('pk')
|
|
assert validity_info.invalid_reason_code == 'wcs_category_not_found'
|
|
assert validity_info.invalid_since is not None
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_forms_of_category_cell_check_validity(mock_send, context):
|
|
page = Page.objects.create(
|
|
title='xxx', slug='test_forms_of_category_cell_render', template_name='standard'
|
|
)
|
|
cell = WcsFormsOfCategoryCell.objects.create(page=page, placeholder='content', order=0)
|
|
|
|
# valid category
|
|
cell.category_reference = 'default:test-9'
|
|
cell.save()
|
|
cell.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
# valid category but empty
|
|
cell.category_reference = 'default:test-1'
|
|
cell.save()
|
|
cell.check_validity()
|
|
validity_info = ValidityInfo.objects.latest('pk')
|
|
assert validity_info.invalid_reason_code == 'wcs_category_not_found'
|
|
assert validity_info.invalid_since is not None
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_no_tryauth_for_bot(mock_send):
|
|
page = Page(title='xxx', slug='test_form_cell_render', template_name='standard')
|
|
page.save()
|
|
request = RequestFactory().get('/')
|
|
request.META[
|
|
'HTTP_USER_AGENT'
|
|
] = 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'
|
|
context = {'request': request}
|
|
|
|
cell = WcsFormCell(page=page, placeholder='content', order=0)
|
|
cell.formdef_reference = 'default:form-title'
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert 'http://127.0.0.1:8999/form-title/' in result
|
|
assert 'form title' in result
|
|
# no tryout, no cancelurl
|
|
assert 'tryauth' not in result
|
|
assert 'cancelurl' not in result
|
|
|
|
cell = WcsFormsOfCategoryCell(page=page, placeholder='content', order=0)
|
|
cell.category_reference = 'default:test-9'
|
|
cell.ordering = 'alpha'
|
|
cell.save()
|
|
context['synchronous'] = True # to get fresh content
|
|
result = cell.render(context)
|
|
assert 'form title' in result and 'a second form title' in result
|
|
assert result.index('form title') > result.index('a second form title')
|
|
assert 'http://127.0.0.1:8999/form-title/' in result
|
|
assert 'http://127.0.0.1:8999/a-second-form-title/' in result
|
|
assert 'keyword-foo' in result
|
|
assert 'keyword-bar' in result
|
|
# no tryout, no cancelurl
|
|
assert 'tryauth' not in result
|
|
assert 'cancelurl' not in result
|
|
|
|
|
|
def test_current_drafts_cell_render_unlogged(context):
|
|
page = Page(title='xxx', slug='test_current_drafts_cell_render', template_name='standard')
|
|
page.save()
|
|
cell = WcsCurrentDraftsCell(page=page, placeholder='content', order=0)
|
|
cell.save()
|
|
context['synchronous'] = True # to get fresh content
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
result = cell.render(context)
|
|
assert requests_get.call_args_list[0][0][0] == '/api/user/drafts'
|
|
assert 'http://127.0.0.1:8999/third-form-title' not in result # no form
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_current_drafts_cell_render_logged_in(mock_send, context):
|
|
page = Page(title='xxx', slug='test_current_drafts_cell_render', template_name='standard')
|
|
page.save()
|
|
cell = WcsCurrentDraftsCell(page=page, placeholder='content', order=0)
|
|
cell.save()
|
|
context['synchronous'] = True # to get fresh content
|
|
|
|
context['request'].user = MockUser()
|
|
|
|
# default is to get current forms from all wcs sites
|
|
result = cell.render(context)
|
|
assert 'http://127.0.0.1:8999/form/1/' in result
|
|
assert 'http://127.0.0.1:8999/form/2/' not in result # no title
|
|
assert 'http://127.0.0.1:8999/form/3/' in result
|
|
assert 'http://127.0.0.1:8999/form/4/' not in result # done
|
|
assert 'http://127.0.0.2:8999/form/1/' in result
|
|
assert 'http://127.0.0.2:8999/form/2/' not in result
|
|
assert 'http://127.0.0.2:8999/form/3/' in result
|
|
assert 'http://127.0.0.2:8999/form/4/' not in result
|
|
|
|
# check flat list
|
|
extra_context = cell.get_cell_extra_context(context)
|
|
assert len(extra_context['drafts']) == 8
|
|
assert len([x for x in extra_context['drafts'] if x['site_slug'] == 'default']) == 4
|
|
assert len([x for x in extra_context['drafts'] if x['site_slug'] == 'other']) == 4
|
|
|
|
# limit to categories
|
|
cell.categories = {'data': ['default:test-3', 'other:test-6']}
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
cell.get_cell_extra_context(context)
|
|
assert len(requests_get.call_args_list) == 2
|
|
assert requests_get.call_args_list[0][0][0] == '/api/user/drafts?category_slugs=test-3'
|
|
assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://127.0.0.1:8999/'
|
|
assert requests_get.call_args_list[1][0][0] == '/api/user/drafts?category_slugs=test-6'
|
|
assert requests_get.call_args_list[1][1]['remote_service']['url'] == 'http://127.0.0.2:8999/'
|
|
|
|
cell.categories = {'data': ['default:test-3']}
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
cell.get_cell_extra_context(context)
|
|
assert len(requests_get.call_args_list) == 1
|
|
assert requests_get.call_args_list[0][0][0] == '/api/user/drafts?category_slugs=test-3'
|
|
assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://127.0.0.1:8999/'
|
|
|
|
cell.categories = {'data': []}
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
cell.get_cell_extra_context(context)
|
|
assert len(requests_get.call_args_list) == 2
|
|
|
|
# check empty message
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
result = cell.render(context)
|
|
assert 'There are no current drafts.' in result
|
|
|
|
context['request'].user = MockUserWithNameId()
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
cell.render(context)
|
|
assert requests_get.call_args_list[0][0][0] == '/api/users/xyz/drafts'
|
|
|
|
# anonymous user
|
|
context['request'].user = AnonymousUser()
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
cell.render(context)
|
|
assert requests_get.call_args_list[0][0][0] == '/api/user/drafts'
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_current_drafts_cell_check_validity(mock_send, context):
|
|
page = Page.objects.create(title='xxx', slug='test_current_forms_cell_render', template_name='standard')
|
|
cell = WcsCurrentDraftsCell.objects.create(page=page, placeholder='content', order=0)
|
|
|
|
# no category
|
|
cell.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
# valid categories
|
|
cell.categories = {'data': ['default:test-3', 'default:test-9']}
|
|
cell.save()
|
|
cell.check_validity()
|
|
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.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
requests_get.side_effect = ConnectionError()
|
|
cell.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
# can not retrieve categories, 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.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
# invalid category
|
|
cell.categories = {'data': ['default:foobar', 'default:test-9']}
|
|
cell.save()
|
|
cell.check_validity()
|
|
validity_info = ValidityInfo.objects.latest('pk')
|
|
assert validity_info.invalid_reason_code == 'wcs_category_not_found'
|
|
assert validity_info.invalid_since is not None
|
|
|
|
# invalid wcs_site
|
|
cell.categories = {'data': ['default:test-3', 'default:test-9']}
|
|
cell.wcs_site = 'invalid'
|
|
cell.save()
|
|
cell.check_validity()
|
|
validity_info = ValidityInfo.objects.latest('pk')
|
|
assert validity_info.invalid_reason_code == 'wcs_site_not_found'
|
|
assert validity_info.invalid_since is not None
|
|
|
|
# valid wcs_site
|
|
cell.wcs_site = 'default'
|
|
cell.save()
|
|
cell.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_manager_forms_of_category_cell(mock_send, app, admin_user):
|
|
page = Page(title='One', slug='one', template_name='standard')
|
|
page.save()
|
|
app = login(app)
|
|
resp = app.get('/manage/pages/%s/' % page.id)
|
|
resp = app.get(
|
|
resp.html.find('option', **{'data-add-url': re.compile('wcsformsofcategorycell')})['data-add-url']
|
|
)
|
|
|
|
cells = Page.objects.get(id=page.id).get_cells()
|
|
assert len(cells) == 1
|
|
assert isinstance(cells[0], WcsFormsOfCategoryCell)
|
|
|
|
resp = app.get('/manage/pages/%s/' % page.id)
|
|
assert ('data-cell-reference="%s"' % cells[0].get_reference()) in resp.text
|
|
resp.forms[0]['c%s-ordering' % cells[0].get_reference()].value = 'manual'
|
|
manager_submit_cell(resp.forms[0])
|
|
cells[0].refresh_from_db()
|
|
resp.forms[0]['c%s-manual_order' % cells[0].get_reference()].select_multiple(
|
|
['default::a-second-form-title', 'default::third-form-title']
|
|
)
|
|
manager_submit_cell(resp.forms[0])
|
|
cells[0].refresh_from_db()
|
|
assert cells[0].manual_order == {'data': ['default::a-second-form-title', 'default::third-form-title']}
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_manager_current_forms(mock_send, settings, app, admin_user):
|
|
page = Page(title='One', slug='one', template_name='standard')
|
|
page.save()
|
|
app = login(app)
|
|
resp = app.get('/manage/pages/%s/' % page.id)
|
|
resp = app.get(
|
|
resp.html.find('option', **{'data-add-url': re.compile('wcscurrentformscell')})['data-add-url']
|
|
)
|
|
|
|
cells = Page.objects.get(id=page.id).get_cells()
|
|
assert len(cells) == 1
|
|
assert isinstance(cells[0], WcsCurrentFormsCell)
|
|
|
|
resp = app.get('/manage/pages/%s/' % page.id)
|
|
assert ('data-cell-reference="%s"' % cells[0].get_reference()) in resp.text
|
|
assert len(resp.form['c%s-categories' % cells[0].get_reference()].options) == 4
|
|
resp.form['c%s-categories' % cells[0].get_reference()].value = ['default:test-3', 'default:test-9']
|
|
manager_submit_cell(resp.form)
|
|
assert resp.form['c%s-categories' % cells[0].get_reference()].value == [
|
|
'default:test-3',
|
|
'default:test-9',
|
|
]
|
|
resp.form['c%s-current_forms' % cells[0].get_reference()] = False
|
|
resp.form['c%s-done_forms' % cells[0].get_reference()] = False
|
|
resp = resp.form.submit()
|
|
assert 'Please choose at least one option among the following: Current Forms, Done Forms' in resp
|
|
resp = app.get('/manage/pages/%s/' % page.id)
|
|
resp.form['c%s-done_forms' % cells[0].get_reference()] = True
|
|
manager_submit_cell(resp.form)
|
|
|
|
# check wcs_site field is a select box
|
|
assert resp.form['c%s-wcs_site' % cells[0].get_reference()].tag == 'select'
|
|
|
|
default = settings.KNOWN_SERVICES['wcs']['default']
|
|
settings.KNOWN_SERVICES = {'wcs': {'default': default}}
|
|
resp = app.get('/manage/pages/%s/' % page.id)
|
|
assert resp.form['c%s-wcs_site' % cells[0].get_reference()].attrs['type'] == 'hidden'
|
|
|
|
|
|
def test_manager_current_forms_tabs(app, admin_user):
|
|
page = Page(title='One', slug='one', template_name='standard')
|
|
page.save()
|
|
cell = WcsCurrentFormsCell.objects.create(page=page, placeholder='content', order=1)
|
|
cell.save()
|
|
app = login(app)
|
|
resp = app.get('/manage/pages/%s/' % page.id)
|
|
|
|
assert not resp.pyquery('[data-tab-slug="general"] input[name$="custom_title"]')
|
|
assert resp.pyquery('[data-tab-slug="appearance"] input[name$="custom_title"]')
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_manager_cards_cell(mock_send, app, admin_user):
|
|
page = Page.objects.create(title='xxx', slug='test_cards_cell_save_cache', template_name='standard')
|
|
cell = WcsCardsCell.objects.create(page=page, placeholder='content', order=0)
|
|
app = login(app)
|
|
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
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
|
|
|
|
|
|
def test_manager_cards_cell_tabs(app, admin_user):
|
|
page = Page.objects.create(title='xxx', slug='test_cards_cell_save_cache', template_name='standard')
|
|
cell = WcsCardsCell.objects.create(page=page, placeholder='content', order=0)
|
|
login(app)
|
|
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
|
|
assert not resp.pyquery('[data-tab-slug="general"] input[name$="custom_title"]')
|
|
assert not resp.pyquery('#tab-%s-general.pk-tabs--button-marker' % cell.get_reference())
|
|
assert resp.pyquery('[data-tab-slug="appearance"] input[name$="custom_title"]')
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_cards_cell_setup(mock_send):
|
|
cell = WcsCardsCell()
|
|
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'),
|
|
]
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_cards_cell_save_cache(mock_send):
|
|
page = Page.objects.create(title='xxx', slug='test_cards_cell_save_cache', template_name='standard')
|
|
cell = WcsCardsCell(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.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())
|
|
|
|
cell.carddef_reference = 'default:card_model_1:foo'
|
|
cell.save()
|
|
assert cell.cached_title == 'Card Model 1 - bar'
|
|
assert cell.get_additional_label() == 'Card Model 1 - bar'
|
|
|
|
# check content provided to search engine
|
|
assert cell.render_for_search() == ''
|
|
|
|
# artificially change title
|
|
WcsCardsCell.objects.filter(pk=cell.pk).update(cached_title='XXX')
|
|
assert WcsCardsCell.objects.get(pk=cell.pk).cached_title == 'XXX'
|
|
# run update db cache
|
|
appconfig = apps.get_app_config('wcs')
|
|
appconfig.update_db_cache()
|
|
assert WcsCardsCell.objects.get(pk=cell.pk).cached_title == 'Card Model 1 - bar'
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_cards_cell_validity(mock_send):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardsCell.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
|
|
|
|
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
|
|
|
|
cell.carddef_reference = 'default:card_model_1:foo'
|
|
cell.save()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
cell.carddef_reference = 'default:card_model_1:bar'
|
|
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_cards_cell_load(mock_send):
|
|
page = Page.objects.create(title='xxx', slug='test_cards', template_name='standard')
|
|
cell = WcsCardsCell(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'
|
|
|
|
cell.carddef_reference = 'default:card_model_1:foo'
|
|
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 - bar'
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_cards_cell_render(mock_send, context):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardsCell(page=page, placeholder='content', order=0)
|
|
cell.carddef_reference = 'default:card_model_1'
|
|
cell.save()
|
|
|
|
# query should fail as nothing is cached
|
|
cache.clear()
|
|
with pytest.raises(NothingInCacheException):
|
|
result = cell.render(context)
|
|
|
|
context['synchronous'] = True # to get fresh content
|
|
context['cell'] = cell
|
|
|
|
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 - bar</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:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
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'
|
|
assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://127.0.0.1:8999/'
|
|
|
|
cell.custom_title = 'Foo bar'
|
|
cell.save()
|
|
result = cell.render(context)
|
|
assert '<h2>Card Model 1 - bar</h2>' not in result
|
|
assert '<h2>Foo bar</h2>' in result
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_cards_cell_only_for_user(mock_send, context):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardsCell(page=page, placeholder='content', order=0)
|
|
cell.carddef_reference = 'default:card_model_1'
|
|
cell.only_for_user = False
|
|
cell.save()
|
|
|
|
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
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_cards_cell_render_user(mock_send, context, nocache):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardsCell(page=page, placeholder='content', order=0)
|
|
cell.carddef_reference = 'default:card_model_1'
|
|
cell.save()
|
|
|
|
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 = AnonymousUser()
|
|
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_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 = WcsCardInfosCell(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'),
|
|
]
|
|
assert 'customize_display' not in form.fields
|
|
assert 'custom_schema' not in form.fields
|
|
|
|
cell.save()
|
|
assert 'customize_display' not in form.fields
|
|
assert 'custom_schema' not in form.fields
|
|
|
|
cell.carddef_reference = 'default:card_model_1'
|
|
cell.save()
|
|
form = form_class(instance=cell)
|
|
assert 'customize_display' in form.fields
|
|
assert 'custom_schema' in form.fields
|
|
assert 'customize_display' not in form.initial
|
|
assert form.initial['custom_schema'] == {}
|
|
|
|
cell.carddef_reference = 'default:card_model_1:foo'
|
|
cell.save()
|
|
form = form_class(instance=cell)
|
|
assert 'customize_display' in form.fields
|
|
assert 'custom_schema' in form.fields
|
|
assert 'customize_display' not in form.initial
|
|
assert form.initial['custom_schema'] == {}
|
|
|
|
cell.carddef_reference = 'default:card_model_1'
|
|
cell.save()
|
|
|
|
cell.custom_schema = {'cells': [{'varname': 'foo', 'display_mode': 'value'}]}
|
|
cell.save()
|
|
form = form_class(instance=cell)
|
|
assert 'customize_display' in form.fields
|
|
assert 'custom_schema' in form.fields
|
|
assert form.initial['customize_display'] is True
|
|
assert form.initial['custom_schema'] == {
|
|
'cells': [
|
|
{'varname': 'foo', 'field_content': 'value', 'display_mode': 'text', 'empty_value': '@empty@'}
|
|
]
|
|
}
|
|
|
|
WcsCardInfosCell.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 Information Cell'][0].get(
|
|
'data-add-url'
|
|
)
|
|
resp = app.get(cell_add_url).follow()
|
|
cell = WcsCardInfosCell.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.customize_display = True
|
|
cell.custom_schema = {
|
|
'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 == {}
|
|
|
|
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-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.']}
|
|
|
|
|
|
def test_card_cell_custom_schema_migration():
|
|
cell = WcsCardInfosCell()
|
|
|
|
cell.custom_schema = {
|
|
'cells': [{'varname': 'some-field', 'display_mode': 'label', 'cell_size': 'foobar'}]
|
|
}
|
|
assert cell.get_custom_schema() == {
|
|
'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() == {
|
|
'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() == {
|
|
'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() == {
|
|
'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() == {
|
|
'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() == {
|
|
'cells': [{'varname': '@custom@', 'template': 'foobar', 'display_mode': 'text'}]
|
|
}
|
|
cell.custom_schema = {'cells': [{'varname': '@custom@', 'template': 'foobar', 'display_mode': 'title'}]}
|
|
assert cell.get_custom_schema() == {
|
|
'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 = WcsCardInfosCell(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
|
|
WcsCardInfosCell.objects.filter(pk=cell.pk).update(cached_title='XXX', cached_json={})
|
|
assert WcsCardInfosCell.objects.get(pk=cell.pk).cached_title == 'XXX'
|
|
assert WcsCardInfosCell.objects.get(pk=cell.pk).cached_json == {}
|
|
# run update db cache
|
|
appconfig = apps.get_app_config('wcs')
|
|
appconfig.update_db_cache()
|
|
assert WcsCardInfosCell.objects.get(pk=cell.pk).cached_title == 'Card Model 1'
|
|
assert WcsCardInfosCell.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 = WcsCardInfosCell.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 = WcsCardInfosCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
carddef_reference='default:card_a',
|
|
card_ids='1',
|
|
)
|
|
cell2 = WcsCardInfosCell.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 = WcsCardInfosCell.objects.create(page=page, placeholder='content', order=0)
|
|
|
|
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 == [
|
|
('--', True, 'Identifier from page URL'),
|
|
('', False, 'Other Card Identifiers'),
|
|
]
|
|
|
|
# add a second cell, related to the first card model
|
|
cell2 = WcsCardInfosCell.objects.create(
|
|
page=page, placeholder='content', order=1, carddef_reference='default:card_b'
|
|
)
|
|
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 == [
|
|
('--', True, 'Identifier from page URL'),
|
|
('', False, 'Other Card Identifiers'),
|
|
]
|
|
# no cell with id and slug
|
|
assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
|
|
('--', True, 'Identifier from page URL'),
|
|
('', False, 'Other Card Identifiers'),
|
|
]
|
|
|
|
# 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 == [
|
|
('--', True, 'Identifier from page URL'),
|
|
('', False, 'Other Card Identifiers'),
|
|
]
|
|
# multiple relations to follow
|
|
assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
|
|
('--', True, 'Identifier from page URL'),
|
|
('', False, 'Other Card Identifiers'),
|
|
('sluga/cardb', False, 'sluga/cardb'),
|
|
('sluga/cardsb', False, 'sluga/cardsb'),
|
|
('sluga/blockb_cardb', False, 'sluga/blockb_cardb'),
|
|
('sluga/cardc/cardb', False, 'sluga/cardc/cardb'),
|
|
('sluga/cardc/cardsb', False, 'sluga/cardc/cardsb'),
|
|
('sluga/cardc/blockb_cardb', False, 'sluga/cardc/blockb_cardb'),
|
|
]
|
|
|
|
# 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 == [
|
|
('--', False, 'Identifier from page URL'),
|
|
('', True, 'Other Card Identifiers'),
|
|
]
|
|
# can not user cell with multiple ids as reference
|
|
assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
|
|
('--', True, 'Identifier from page URL'),
|
|
('', False, 'Other Card Identifiers'),
|
|
]
|
|
|
|
# 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 == [
|
|
('--', True, 'Identifier from page URL'),
|
|
('', False, 'Other Card Identifiers'),
|
|
('slugb/reverse:cardb', False, 'slugb/cardb (reverse)'),
|
|
('slugb/reverse:cardsb', False, 'slugb/cardsb (reverse)'),
|
|
('slugb/reverse:blockb_cardb', False, 'slugb/blockb_cardb (reverse)'),
|
|
]
|
|
# still multiple relations to follow
|
|
assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
|
|
('--', True, 'Identifier from page URL'),
|
|
('', False, 'Other Card Identifiers'),
|
|
('sluga/cardb', False, 'sluga/cardb'),
|
|
('sluga/cardsb', False, 'sluga/cardsb'),
|
|
('sluga/blockb_cardb', False, 'sluga/blockb_cardb'),
|
|
('sluga/cardc/cardb', False, 'sluga/cardc/cardb'),
|
|
('sluga/cardc/cardsb', False, 'sluga/cardc/cardsb'),
|
|
('sluga/cardc/blockb_cardb', False, 'sluga/cardc/blockb_cardb'),
|
|
]
|
|
|
|
# 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 == [
|
|
('--', True, 'Identifier from page URL'),
|
|
('', False, 'Other Card Identifiers'),
|
|
]
|
|
# still multiple relations to follow
|
|
assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
|
|
('--', False, 'Identifier from page URL'),
|
|
('', False, 'Other Card Identifiers'),
|
|
('sluga/cardb', True, 'sluga/cardb'),
|
|
('sluga/cardsb', False, 'sluga/cardsb'),
|
|
('sluga/blockb_cardb', False, 'sluga/blockb_cardb'),
|
|
('sluga/cardc/cardb', False, 'sluga/cardc/cardb'),
|
|
('sluga/cardc/cardsb', False, 'sluga/cardc/cardsb'),
|
|
('sluga/cardc/blockb_cardb', False, 'sluga/cardc/blockb_cardb'),
|
|
]
|
|
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 == [
|
|
('--', True, 'Identifier from page URL'),
|
|
('', False, 'Other Card Identifiers'),
|
|
('slugd/cardd-foo/carde-foo', False, 'slugd/cardd-foo/carde-foo'),
|
|
('slugd/carde-foo', False, 'slugd/carde-foo'),
|
|
]
|
|
assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
|
|
('--', True, 'Identifier from page URL'),
|
|
('', False, 'Other Card Identifiers'),
|
|
('sluge/cardd-bar', False, 'sluge/cardd-bar'),
|
|
('sluge/reverse:carde-foo', False, 'sluge/carde-foo (reverse)'),
|
|
]
|
|
|
|
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 == [
|
|
('--', True, 'Identifier from page URL'),
|
|
('', False, 'Other Card Identifiers'),
|
|
('slugd-bis/cardd-foo', False, 'slugd-bis/cardd-foo'),
|
|
('slugd-bis/reverse:cardd-foo', False, 'slugd-bis/cardd-foo (reverse)'),
|
|
('slugd-bis/carde-foo/cardd-bar', False, 'slugd-bis/carde-foo/cardd-bar'),
|
|
('slugd-bis/carde-foo/reverse:carde-foo', False, 'slugd-bis/carde-foo/carde-foo (reverse)'),
|
|
]
|
|
assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
|
|
('--', True, 'Identifier from page URL'),
|
|
('', False, 'Other Card Identifiers'),
|
|
('slugd/cardd-foo', False, 'slugd/cardd-foo'),
|
|
('slugd/reverse:cardd-foo', False, 'slugd/cardd-foo (reverse)'),
|
|
('slugd/carde-foo/cardd-bar', False, 'slugd/carde-foo/cardd-bar'),
|
|
('slugd/carde-foo/reverse:carde-foo', False, 'slugd/carde-foo/carde-foo (reverse)'),
|
|
]
|
|
|
|
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 == [
|
|
('--', True, 'Identifier from page URL'),
|
|
('', False, 'Other Card Identifiers'),
|
|
('sluge-bis/cardd-bar/carde-foo', False, 'sluge-bis/cardd-bar/carde-foo'),
|
|
]
|
|
assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
|
|
('--', True, 'Identifier from page URL'),
|
|
('', False, 'Other Card Identifiers'),
|
|
('sluge/cardd-bar/carde-foo', False, 'sluge/cardd-bar/carde-foo'),
|
|
]
|
|
|
|
|
|
def test_manager_card_cell_tabs(app, admin_user):
|
|
page = Page.objects.create(title='xxx', slug='test_cards', template_name='standard', sub_slug='foobar')
|
|
cell = WcsCardInfosCell.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('#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"]')
|
|
|
|
|
|
@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 = WcsCardInfosCell(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_render(mock_send, context, app):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardInfosCell(page=page, placeholder='content', order=0)
|
|
cell.title_type = 'manual'
|
|
cell.custom_title = 'Foo bar {{ card.fields.title }}'
|
|
cell.save()
|
|
|
|
# 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_render_text_field(mock_send, context):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardInfosCell(page=page, placeholder='content', order=0)
|
|
cell.carddef_reference = 'default:card_model_1'
|
|
cell.save()
|
|
|
|
context['card_model_1_id'] = 11
|
|
request = RequestFactory().get('/')
|
|
cell.modify_global_context(context, request)
|
|
cell.repeat_index = 0
|
|
context['synchronous'] = True # to get fresh content
|
|
|
|
result = cell.render(context)
|
|
|
|
# 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_render_email_field(mock_send, context):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardInfosCell(page=page, placeholder='content', order=0)
|
|
cell.carddef_reference = 'default:card_model_1'
|
|
cell.save()
|
|
|
|
context['card_model_1_id'] = 11
|
|
request = RequestFactory().get('/')
|
|
cell.modify_global_context(context, request)
|
|
cell.repeat_index = 0
|
|
context['synchronous'] = True # to get fresh content
|
|
|
|
result = cell.render(context)
|
|
|
|
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_render_string_with_url_field(mock_send, context):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardInfosCell(page=page, placeholder='content', order=0)
|
|
cell.carddef_reference = 'default:card_model_1'
|
|
cell.custom_title = 'Foo bar {{ card.fields.title }}'
|
|
cell.save()
|
|
|
|
context['card_model_1_id'] = 11
|
|
request = RequestFactory().get('/')
|
|
cell.modify_global_context(context, request)
|
|
cell.repeat_index = 0
|
|
context['synchronous'] = True # to get fresh content
|
|
|
|
result = cell.render(context)
|
|
|
|
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_render_custom_schema_card_field(mock_send, context):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardInfosCell.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': '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/'
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_render_custom_schema_card_empty_field(mock_send, context):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardInfosCell.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_render_custom_schema_custom_entry(mock_send, context, app):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardInfosCell.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',
|
|
},
|
|
]
|
|
},
|
|
)
|
|
|
|
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_render_custom_schema_link_entry(mock_send, context, app):
|
|
page = Page.objects.create(title='xxx', template_name='standard')
|
|
cell = WcsCardInfosCell.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',
|
|
},
|
|
]
|
|
},
|
|
)
|
|
|
|
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
|
|
)
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_card_cell_render_identifier(mock_send, nocache, app):
|
|
page = Page.objects.create(
|
|
title='xxx', slug='foo', template_name='standard', sub_slug='(?P<card_model_1_id>[a-z0-9]+)'
|
|
)
|
|
cell = WcsCardInfosCell.objects.create(
|
|
page=page, placeholder='content', order=0, carddef_reference='default:card_model_1'
|
|
)
|
|
|
|
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/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
|
|
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/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']) == 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/list' in mock_send.call_args_list[2][0][0].url
|
|
assert '&filter-internal-id=13&' in mock_send.call_args_list[2][0][0].url
|
|
|
|
def test_card_ids():
|
|
mock_send.reset_mock()
|
|
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_render_identifier_from_related(mock_send, nocache, app):
|
|
page = Page.objects.create(title='xxx', slug='foo', template_name='standard')
|
|
cell = WcsCardInfosCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
slug='sluga',
|
|
carddef_reference='default:card_a',
|
|
card_ids='1',
|
|
)
|
|
cell2 = WcsCardInfosCell.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 = WcsCardInfosCell.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 WcsCardInfosCell
|
|
cell3 = WcsCardsCell.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/list', '&filter-internal-id=1&'), # check user access
|
|
('/api/cards/card_b/list', '&filter-internal-id=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/list', '&filter-internal-id=7&'), # check user access
|
|
('/api/cards/card_b/list', '&filter-internal-id=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/list', '&filter-internal-id=7&'), # check user access
|
|
('/api/cards/card_b/list', '&filter-internal-id=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/list/a-custom-view', '&filter-internal-id=7&'), # check user access
|
|
('/api/cards/card_b/list/a-custom-view', '&filter-internal-id=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/list', '&filter-internal-id=41&'), # check user access
|
|
('/api/cards/card_f/list', '&filter-internal-id=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/list', '&filter-internal-id=43&'), # check user access
|
|
('/api/cards/card_g/list', '&filter-internal-id=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 = WcsCardInfosCell(page=page, placeholder='content', order=0)
|
|
cell.carddef_reference = carddef_reference
|
|
cell.only_for_user = False
|
|
cell.save()
|
|
|
|
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 = WcsCardInfosCell(page=page, placeholder='content', order=0)
|
|
cell.carddef_reference = carddef_reference
|
|
cell.save()
|
|
|
|
context['card_model_1_id'] = 11
|
|
request = RequestFactory().get('/')
|
|
cell.modify_global_context(context, request)
|
|
cell.repeat_index = 0
|
|
context['synchronous'] = True # to get fresh content
|
|
|
|
assert context['request'].user is None
|
|
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
|
|
|
|
|
|
def test_tracking_code_cell(app, nocache):
|
|
page = Page(title='One', slug='index', template_name='standard')
|
|
page.save()
|
|
cell = TrackingCodeInputCell(page=page, placeholder='content', order=0)
|
|
cell.save()
|
|
|
|
resp = app.get('/')
|
|
resp.form['code'] = 'FOOBAR'
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
resp = resp.form.submit()
|
|
assert len(requests_get.call_args_list) == 2
|
|
assert requests_get.call_args_list[0][0][0] == '/api/code/FOOBAR'
|
|
assert requests_get.call_args_list[1][0][0] == '/api/code/FOOBAR'
|
|
remote_service_urls = [c[1]['remote_service']['url'] for c in requests_get.call_args_list]
|
|
assert set(remote_service_urls) == {'http://127.0.0.1:8999/', 'http://127.0.0.2:8999/'}
|
|
assert resp.status_code == 302
|
|
resp = resp.follow()
|
|
assert '<li class="error">The tracking code could not been found.</li>' in resp.text
|
|
|
|
resp = app.get('/')
|
|
resp.form['code'] = 'FOO?BAR?bad<code>'
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
resp = resp.form.submit()
|
|
assert requests_get.call_args_list[0][0][0] == '/api/code/FOO%3FBAR%3FBAD%3CCODE%3E'
|
|
assert resp.status_code == 302
|
|
resp = resp.follow()
|
|
assert '<li class="error">The tracking code could not been found.</li>' in resp.text
|
|
|
|
resp = app.get('/')
|
|
resp.form['code'] = 'CNPHNTFB'
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
requests_get.return_value = MockedRequestResponse(
|
|
content=json.dumps({'err': 0, 'load_url': 'http://127.0.0.2:8999/code/CNPHNTFB/load'})
|
|
)
|
|
resp = resp.form.submit()
|
|
assert resp.status_code == 302
|
|
assert resp.location == 'http://127.0.0.2:8999/code/CNPHNTFB/load'
|
|
|
|
# space/case
|
|
resp = app.get('/')
|
|
resp.form['code'] = ' cnphntfb'
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
requests_get.side_effect = [
|
|
mock.Mock(status_code=200),
|
|
MockedRequestResponse(
|
|
content=json.dumps({'err': 0, 'load_url': 'http://127.0.0.2:8999/code/CNPHNTFB/load'})
|
|
),
|
|
]
|
|
resp = resp.form.submit()
|
|
assert requests_get.call_args_list[0][0][0] == '/api/code/CNPHNTFB'
|
|
assert requests_get.call_args_list[1][0][0] == '/api/code/CNPHNTFB'
|
|
assert resp.status_code == 302
|
|
assert resp.location == 'http://127.0.0.2:8999/code/CNPHNTFB/load'
|
|
|
|
# lock cell to a single site
|
|
cell.wcs_site = 'default'
|
|
cell.save()
|
|
resp = app.get('/')
|
|
resp.form['code'] = 'CNPHNTFB'
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
resp = resp.form.submit()
|
|
assert len(requests_get.call_args_list) == 1
|
|
assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://127.0.0.1:8999/'
|
|
resp = resp.follow()
|
|
assert '<li class="error">The tracking code could not been found.</li>' in resp.text
|
|
|
|
# unknown wcs_site
|
|
cell.wcs_site = 'unknown'
|
|
cell.save()
|
|
resp = app.get('/')
|
|
resp.form['code'] = 'CNPHNTFB'
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
resp = resp.form.submit()
|
|
assert len(requests_get.call_args_list) == 0
|
|
resp = resp.follow()
|
|
assert '<li class="error">The tracking code could not been found.</li>' in resp.text
|
|
|
|
# simulate cell being displayed on a different site
|
|
resp = app.get('/')
|
|
resp.form['url'] = 'http://example.org/'
|
|
resp.form['code'] = 'CNPHNTFB'
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
resp = resp.form.submit()
|
|
assert resp.location == 'http://example.org/?unknown-tracking-code'
|
|
|
|
resp = app.get('/')
|
|
resp.form['url'] = 'http://example.org/?foo=bar'
|
|
resp.form['code'] = 'CNPHNTFB'
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
resp = resp.form.submit()
|
|
assert resp.location == 'http://example.org/?foo=bar&unknown-tracking-code'
|
|
|
|
# redirect to an unknown site
|
|
resp = app.get('/')
|
|
resp.form['url'] = 'http://example.net/'
|
|
resp.form['code'] = 'CNPHNTFB'
|
|
resp = resp.form.submit(status=400)
|
|
|
|
# error handling
|
|
resp = app.get('/')
|
|
resp.form['cell'] = '9999'
|
|
resp.form['code'] = 'CNPHNTFB'
|
|
resp = resp.form.submit(status=400)
|
|
|
|
resp = app.get('/')
|
|
resp.form['cell'] = 'xxxx'
|
|
resp.form['code'] = 'CNPHNTFB'
|
|
resp = resp.form.submit(status=400)
|
|
|
|
resp = app.post(reverse('wcs-tracking-code'), params={'cell': cell.id}, status=400)
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_tracking_code_cell_check_validity(mock_send):
|
|
page = Page.objects.create(title='xxx', slug='test', template_name='standard')
|
|
cell = TrackingCodeInputCell.objects.create(page=page, placeholder='content', order=0)
|
|
|
|
# invalid wcs_site
|
|
cell.wcs_site = 'invalid'
|
|
cell.save()
|
|
cell.check_validity()
|
|
validity_info = ValidityInfo.objects.latest('pk')
|
|
assert validity_info.invalid_reason_code == 'wcs_site_not_found'
|
|
assert validity_info.invalid_since is not None
|
|
|
|
# valid wcs_site
|
|
cell.wcs_site = 'default'
|
|
cell.save()
|
|
cell.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_cell_assets(mock_send, settings, app, admin_user):
|
|
page = Page.objects.create(title='xxx', slug='test_cell_assets', template_name='standard')
|
|
cell1 = WcsFormCell.objects.create(
|
|
page=page, placeholder='content', order=0, formdef_reference='default:form-title'
|
|
)
|
|
|
|
cell2 = WcsFormsOfCategoryCell.objects.create(
|
|
page=page, placeholder='content', order=0, category_reference='default:test-9', ordering='alpha'
|
|
)
|
|
|
|
app = login(app)
|
|
settings.WCS_CATEGORY_ASSET_SLOTS = {}
|
|
settings.WCS_FORM_ASSET_SLOTS = {}
|
|
settings.COMBO_CELL_ASSET_SLOTS = {}
|
|
resp = app.get('/manage/assets/')
|
|
assert 'have any asset yet.' in resp.text
|
|
|
|
# Old settings have priority
|
|
settings.WCS_CATEGORY_ASSET_SLOTS = {'logo': {'prefix': 'Logo'}}
|
|
settings.WCS_FORM_ASSET_SLOTS = {'picture': {'prefix': 'Picture'}}
|
|
settings.COMBO_CELL_ASSET_SLOTS = {
|
|
'wcs_wcsformcell': {'picture': {'prefix': 'Picture blabla', 'suffix': 'test'}},
|
|
'wcs_wcsformsofcategorycell': {'logo': {'prefix': 'Logo blabla', 'suffix': 'test'}},
|
|
}
|
|
resp = app.get('/manage/assets/')
|
|
assert 'Logo — %s' % cell2.get_label_for_asset() in resp.text
|
|
assert 'Logo blabla — %s' % cell2.get_label_for_asset() not in resp.text
|
|
assert 'Picture — %s' % cell1.get_label_for_asset() in resp.text
|
|
assert 'Picture blabla — %s' % cell1.get_label_for_asset() not in resp.text
|
|
# New settings
|
|
settings.WCS_CATEGORY_ASSET_SLOTS = {}
|
|
settings.WCS_FORM_ASSET_SLOTS = {}
|
|
settings.COMBO_CELL_ASSET_SLOTS = {
|
|
'wcs_wcsformcell': {'picture': {'prefix': 'Picture'}},
|
|
'wcs_wcsformsofcategorycell': {'logo': {'prefix': 'Logo'}},
|
|
}
|
|
resp = app.get('/manage/assets/')
|
|
assert 'Logo — %s' % cell2.get_label_for_asset() in resp.text
|
|
assert 'Picture — %s' % cell1.get_label_for_asset() in resp.text
|
|
|
|
# test suffix
|
|
settings.COMBO_CELL_ASSET_SLOTS = {
|
|
'wcs_wcsformcell': {'picture': {'prefix': 'Picture', 'suffix': 'test'}},
|
|
'wcs_wcsformsofcategorycell': {'logo': {'prefix': 'Logo', 'suffix': 'test'}},
|
|
}
|
|
resp = app.get('/manage/assets/')
|
|
assert 'Logo — %s (test)' % cell2.get_label_for_asset() in resp.text
|
|
assert 'Picture — %s (test)' % cell1.get_label_for_asset() in resp.text
|
|
|
|
|
|
def test_tracking_code_search(settings, app, nocache):
|
|
settings.TEMPLATE_VARS['is_portal_agent'] = True
|
|
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
result = app.get('/api/search/tracking-code/').json
|
|
assert len(result.get('data')) == 0
|
|
assert result.get('err') == 0
|
|
assert requests_get.called is False # no code
|
|
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
assert len(app.get('/api/search/tracking-code/?q=123').json.get('data')) == 0
|
|
assert requests_get.called is False # no letters
|
|
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
assert len(app.get('/api/search/tracking-code/?q=BBCCDFF').json.get('data')) == 0
|
|
assert requests_get.called is False # too short
|
|
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
assert len(app.get('/api/search/tracking-code/?q=BBCCDDFF').json.get('data')) == 0
|
|
assert len(requests_get.call_args_list) == 2
|
|
assert requests_get.call_args_list[0][0][0] == '/api/code/BBCCDDFF'
|
|
assert requests_get.call_args_list[1][0][0] == '/api/code/BBCCDDFF'
|
|
remote_service_urls = [c[1]['remote_service']['url'] for c in requests_get.call_args_list]
|
|
assert set(remote_service_urls) == {'http://127.0.0.1:8999/', 'http://127.0.0.2:8999/'}
|
|
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
requests_get.return_value = MockedRequestResponse(
|
|
content=json.dumps({'err': 0, 'load_url': 'http://127.0.0.2:8999/code/CNPHNTFB/load'})
|
|
)
|
|
assert len(app.get('/api/search/tracking-code/?q=CNPHNTFB').json.get('data')) == 1
|
|
assert requests_get.call_args_list[0][0][0] == '/api/code/CNPHNTFB'
|
|
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
assert len(app.get('/api/search/tracking-code/?q=BBCCDDFFG').json.get('data')) == 0
|
|
assert requests_get.called is False # too long
|
|
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
requests_get.side_effect = [
|
|
mock.Mock(status_code=200),
|
|
MockedRequestResponse(
|
|
content=json.dumps({'err': 0, 'load_url': 'http://127.0.0.2:8999/code/CNPHNTFB/load'})
|
|
),
|
|
]
|
|
assert len(app.get('/api/search/tracking-code/?q= cnphntfb').json.get('data')) == 1
|
|
assert requests_get.call_args_list[0][0][0] == '/api/code/CNPHNTFB'
|
|
|
|
|
|
def test_tracking_code_search_rate_limit(settings, app):
|
|
settings.TEMPLATE_VARS['is_portal_agent'] = True
|
|
settings.WCS_TRACKING_CODE_RATE_LIMIT = '0/s'
|
|
assert app.get('/api/search/tracking-code/?q=BBCCDDFF').json.get('err') == 1
|
|
|
|
page = Page(title='One', slug='index', template_name='standard')
|
|
page.save()
|
|
cell = TrackingCodeInputCell(page=page, placeholder='content', order=0)
|
|
cell.save()
|
|
|
|
resp = app.get('/')
|
|
resp.form['code'] = 'FOOBAR'
|
|
resp = resp.form.submit()
|
|
assert resp.status_code == 302
|
|
resp = resp.follow()
|
|
assert '<li class="error">Looking up tracking code is currently rate limited.</li>' in resp.text
|
|
|
|
resp = app.get('/')
|
|
resp.form['code'] = 'FOOBAR'
|
|
resp.form['url'] = 'http://example.org/'
|
|
resp = resp.form.submit(status=403)
|
|
|
|
|
|
def test_wcs_search_engines(app):
|
|
settings.TEMPLATE_VARS['is_portal_agent'] = True
|
|
search_engines = engines.get_engines()
|
|
assert 'tracking-code' in search_engines
|
|
assert len([x for x in search_engines if x.startswith('formdata:')]) == 2
|
|
settings.TEMPLATE_VARS['is_portal_agent'] = False
|
|
search_engines = engines.get_engines()
|
|
assert 'tracking-code' not in search_engines
|
|
assert len([x for x in search_engines if x.startswith('formdata:')]) == 0
|
|
|
|
|
|
def test_backoffice_submission_cell_render(context):
|
|
page = Page(title='xxx', slug='test_backoffice_submission_cell_render', template_name='standard')
|
|
page.save()
|
|
cell = BackofficeSubmissionCell.objects.create(page=page, placeholder='content', order=0)
|
|
|
|
context['synchronous'] = True # to get fresh content
|
|
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
mock_json = mock.Mock(status_code=200)
|
|
requests_get.return_value = mock_json
|
|
result = cell.render(context)
|
|
assert requests_get.call_args_list[0][0][0] == '/api/formdefs/?backoffice-submission=on'
|
|
assert context['all_formdefs'] == {}
|
|
assert 'h2' not in result
|
|
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
requests_get.return_value = MockedRequestResponse(
|
|
content=json.dumps(
|
|
{
|
|
'data': [
|
|
{
|
|
'backoffice_submission_url': '/backoffice/submission/a-private-form/',
|
|
'title': 'Foo',
|
|
}
|
|
]
|
|
}
|
|
)
|
|
)
|
|
result = cell.render(context)
|
|
assert '/backoffice/submission/a-private-form/' in result
|
|
assert list(context['all_formdefs'].keys()) == ['default', 'other']
|
|
assert 'h2' in result
|
|
|
|
# limit to categories
|
|
requests_get.reset_mock()
|
|
cell.categories = {'data': ['default:test-3', 'other:test-6']}
|
|
|
|
result = cell.render(context)
|
|
assert len(requests_get.call_args_list) == 2
|
|
assert (
|
|
requests_get.call_args_list[0][0][0]
|
|
== '/api/formdefs/?backoffice-submission=on&category_slugs=test-3'
|
|
)
|
|
assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://127.0.0.1:8999/'
|
|
assert (
|
|
requests_get.call_args_list[1][0][0]
|
|
== '/api/formdefs/?backoffice-submission=on&category_slugs=test-6'
|
|
)
|
|
assert requests_get.call_args_list[1][1]['remote_service']['url'] == 'http://127.0.0.2:8999/'
|
|
|
|
requests_get.reset_mock()
|
|
cell.categories = {'data': ['default:test-3']}
|
|
result = cell.render(context)
|
|
assert len(requests_get.call_args_list) == 1
|
|
assert (
|
|
requests_get.call_args_list[0][0][0]
|
|
== '/api/formdefs/?backoffice-submission=on&category_slugs=test-3'
|
|
)
|
|
assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://127.0.0.1:8999/'
|
|
|
|
requests_get.reset_mock()
|
|
cell.categories = {'data': []}
|
|
result = cell.render(context)
|
|
assert len(requests_get.call_args_list) == 2
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_backoffice_submission_cell_check_validity(mock_send, context):
|
|
page = Page.objects.create(title='xxx', slug='test_current_forms_cell_render', template_name='standard')
|
|
cell = BackofficeSubmissionCell.objects.create(page=page, placeholder='content', order=0)
|
|
|
|
# no category
|
|
cell.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
# valid categories
|
|
cell.categories = {'data': ['default:test-3', 'default:test-9']}
|
|
cell.save()
|
|
cell.check_validity()
|
|
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.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
with mock.patch('combo.apps.wcs.models.requests.get') as requests_get:
|
|
requests_get.side_effect = ConnectionError()
|
|
cell.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
# can not retrieve categories, 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.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
# invalid category
|
|
cell.categories = {'data': ['default:foobar', 'default:test-9']}
|
|
cell.save()
|
|
cell.check_validity()
|
|
validity_info = ValidityInfo.objects.latest('pk')
|
|
assert validity_info.invalid_reason_code == 'wcs_category_not_found'
|
|
assert validity_info.invalid_since is not None
|
|
|
|
# invalid wcs_site
|
|
cell.categories = {'data': ['default:test-3', 'default:test-9']}
|
|
cell.wcs_site = 'invalid'
|
|
cell.save()
|
|
cell.check_validity()
|
|
validity_info = ValidityInfo.objects.latest('pk')
|
|
assert validity_info.invalid_reason_code == 'wcs_site_not_found'
|
|
assert validity_info.invalid_since is not None
|
|
|
|
# valid wcs_site
|
|
cell.wcs_site = 'default'
|
|
cell.save()
|
|
cell.check_validity()
|
|
assert ValidityInfo.objects.exists() is False
|
|
|
|
|
|
def test_manager_link_list_cell_duplicate():
|
|
page = Page.objects.create(title='xxx', slug='new', template_name='standard')
|
|
cell = LinkListCell.objects.create(order=0, page=page)
|
|
item = WcsFormCell.objects.create(
|
|
page=page,
|
|
placeholder=cell.link_placeholder,
|
|
cached_title='A title',
|
|
cached_url='http://example.com',
|
|
cached_json={'foo': 'bar'},
|
|
order=1,
|
|
)
|
|
|
|
new_cell = cell.duplicate()
|
|
assert WcsFormCell.objects.count() == 2
|
|
assert len(new_cell.get_items()) == 1
|
|
new_item = new_cell.get_items()[0]
|
|
assert new_item.page == page
|
|
assert new_item.placeholder == new_cell.link_placeholder
|
|
assert new_item.pk != item.pk
|
|
assert new_item.cached_title == item.cached_title
|
|
assert new_item.cached_url == item.cached_url
|
|
assert new_item.cached_json == item.cached_json
|
|
|
|
|
|
@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 = WcsCardInfosCell.objects.create(
|
|
page=page,
|
|
placeholder='content',
|
|
order=0,
|
|
carddef_reference='default:card_model_1',
|
|
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
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_link_list_cell_condition(mock_send, nocache, app):
|
|
page = Page.objects.create(title='xxx', slug='foo', template_name='standard')
|
|
cell = LinkListCell.objects.create(order=0, placeholder='content', page=page)
|
|
link_cell = LinkCell.objects.create(
|
|
page=page,
|
|
placeholder=cell.link_placeholder,
|
|
title='Example Site',
|
|
url='http://example.net/',
|
|
order=0,
|
|
)
|
|
|
|
link_cell.condition = 'cards|objects:"card_model_1"|getlist:"id"|list'
|
|
link_cell.save()
|
|
resp = app.get(page.get_online_url())
|
|
assert len(resp.context['cells']) == 1
|
|
assert 'Example Site' in resp
|
|
|
|
link_cell.condition = 'cards|objects:"card_model_1"|getlist:"id"|get:42'
|
|
link_cell.save()
|
|
resp = app.get(page.get_online_url())
|
|
assert len(resp.context['cells']) == 1
|
|
assert 'Example Site' not in resp
|
|
|
|
page.extra_variables = {'var1': '{{ cards|objects:"card_model_1"|getlist:"id"|list }}'}
|
|
page.save()
|
|
link_cell.condition = 'var1'
|
|
link_cell.save()
|
|
resp = app.get(page.get_online_url())
|
|
assert len(resp.context['cells']) == 1
|
|
assert 'Example Site' in resp
|
|
|
|
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['cells']) == 1
|
|
assert 'Example Site' not in resp
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_manager_add_edit_delete_list_link_item(mock_send, app, admin_user):
|
|
page = Page.objects.create(title='One', slug='one', template_name='standard')
|
|
cell = LinkListCell.objects.create(order=0, placeholder='content', page=page)
|
|
app = login(app)
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
|
|
resp = resp.click(href='.*/add-link/form-link$')
|
|
resp.forms[0]['formdef_reference'] = 'default:form-title'
|
|
resp.forms[0]['extra_css_class'] = 'foobar'
|
|
resp = resp.forms[0].submit()
|
|
assert resp.status_int == 302
|
|
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.pk, cell.get_reference()))
|
|
assert WcsFormCell.objects.count() == 1
|
|
item = WcsFormCell.objects.get()
|
|
assert item.formdef_reference == 'default:form-title'
|
|
assert item.page == page
|
|
assert item.placeholder == cell.link_placeholder
|
|
assert item.extra_css_class == 'foobar'
|
|
|
|
resp = resp.follow()
|
|
resp = resp.click(href='.*/link/%s/$' % item.get_reference())
|
|
resp.forms[0]['formdef_reference'] = 'default:a-private-form'
|
|
resp = resp.forms[0].submit()
|
|
assert resp.status_int == 302
|
|
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.pk, cell.get_reference()))
|
|
assert WcsFormCell.objects.count() == 1
|
|
item.refresh_from_db()
|
|
assert item.formdef_reference == 'default:a-private-form'
|
|
|
|
resp = resp.follow()
|
|
resp = resp.click(href='.*/link/%s/delete' % item.get_reference())
|
|
resp = resp.forms[0].submit()
|
|
assert resp.status_int == 302
|
|
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.pk, cell.get_reference()))
|
|
assert WcsFormCell.objects.count() == 0
|
|
|
|
|
|
def test_manager_link_list_tabs(app, admin_user):
|
|
page = Page.objects.create(title='One', slug='one', template_name='standard')
|
|
cell = LinkListCell.objects.create(order=0, placeholder='content', page=page)
|
|
app = login(app)
|
|
resp = app.get('/manage/pages/%s/' % page.pk)
|
|
|
|
assert not resp.pyquery('[data-tab-slug="general"] input[name$="title"]')
|
|
assert not resp.pyquery('#tab-%s-general.pk-tabs--button-marker' % cell.get_reference())
|
|
assert resp.pyquery('[data-tab-slug="appearance"] input[name$="title"]')
|
|
|
|
LinkCell.objects.create(
|
|
page=page,
|
|
placeholder=cell.link_placeholder,
|
|
title='Example Site',
|
|
url='http://example.net/',
|
|
link_page=page,
|
|
order=1,
|
|
)
|
|
resp = app.get('/manage/pages/%s/' % page.id)
|
|
assert resp.pyquery('#tab-%s-general.pk-tabs--button-marker' % cell.get_reference())
|
|
|
|
|
|
def test_import_export_pages_with_links():
|
|
page = Page(title='bar', slug='bar', order=1)
|
|
page.save()
|
|
|
|
cell = LinkListCell.objects.create(order=0, placeholder='content', page=page)
|
|
item = WcsFormCell.objects.create(
|
|
page=page,
|
|
placeholder=cell.link_placeholder,
|
|
cached_title='A title',
|
|
cached_url='http://example.com',
|
|
cached_json={'foo': 'bar'},
|
|
order=0,
|
|
)
|
|
|
|
site_export = [x.get_serialized_page() for x in Page.objects.all()]
|
|
|
|
Page.load_serialized_pages(site_export)
|
|
|
|
new_page = Page.objects.get()
|
|
new_cells = CellBase.get_cells(page_id=new_page.id, placeholder='content')
|
|
assert len(new_cells[0].get_items()) == 1
|
|
new_item = new_cells[0].get_items()[0]
|
|
assert isinstance(new_item, WcsFormCell)
|
|
assert new_item.cached_title == item.cached_title
|
|
assert new_item.cached_url == item.cached_url
|
|
assert new_item.cached_json == item.cached_json
|
|
|
|
|
|
def test_list_of_links_with_form_render(app):
|
|
page = Page(title='xxx', slug='test_list_of_links_with_form_render', template_name='standard')
|
|
page.save()
|
|
|
|
cell = LinkListCell.objects.create(order=0, placeholder='content', page=page)
|
|
link = WcsFormCell.objects.create(
|
|
page=page,
|
|
placeholder=cell.link_placeholder,
|
|
cached_title='A title',
|
|
cached_url='http://example.com/',
|
|
order=0,
|
|
extra_css_class='foobar',
|
|
)
|
|
|
|
resp = app.get('/test_list_of_links_with_form_render/')
|
|
assert PyQuery(resp.text).find('.links-list a').text() == 'A title'
|
|
assert PyQuery(resp.text).find('.links-list li').attr('class') == ' foobar'
|
|
assert (
|
|
PyQuery(resp.text).find('.links-list a').attr('href')
|
|
== 'http://example.com/tryauth?cancelurl=http%3A//testserver/test_list_of_links_with_form_render/'
|
|
)
|
|
|
|
link.cached_json = {'keywords': ['bar']}
|
|
link.save()
|
|
resp = app.get('/test_list_of_links_with_form_render/')
|
|
assert PyQuery(resp.text).find('.links-list li').attr('class') == 'keyword-bar foobar'
|
|
|
|
link.extra_css_class = ''
|
|
link.save()
|
|
resp = app.get('/test_list_of_links_with_form_render/')
|
|
assert PyQuery(resp.text).find('.links-list li').attr('class') == 'keyword-bar'
|
|
|
|
|
|
def test_view_page_with_wcs_cells_num_queries(app, admin_user):
|
|
page = Page.objects.create(title='bar', slug='index', order=1)
|
|
for i in range(0, 15):
|
|
WcsCurrentDraftsCell.objects.create(page=page, placeholder='content', order=i)
|
|
for i in range(15, 50):
|
|
WcsCurrentFormsCell.objects.create(page=page, placeholder='content', order=i)
|
|
app = login(app)
|
|
app.get('/') # load once to populate caches
|
|
with CaptureQueriesContext(connection) as ctx:
|
|
app.get('/')
|
|
assert len(ctx.captured_queries) == 62
|
|
|
|
|
|
def test_hourly():
|
|
appconfig = apps.get_app_config('wcs')
|
|
page = Page.objects.create(title='xxx', slug='test_current_forms_cell_render', template_name='standard')
|
|
cell_classes = [c for c in appconfig.get_models() if c in get_cell_classes()]
|
|
for klass in cell_classes:
|
|
klass.objects.create(page=page, placeholder='content', order=0)
|
|
for klass in cell_classes:
|
|
if klass in [
|
|
WcsCareFormsCell,
|
|
WcsCurrentFormsCell,
|
|
WcsCurrentDraftsCell,
|
|
WcsFormsOfCategoryCell,
|
|
WcsCardInfosCell,
|
|
BackofficeSubmissionCell,
|
|
CategoriesCell,
|
|
TrackingCodeInputCell,
|
|
]:
|
|
with mock.patch('combo.apps.wcs.models.%s.check_validity' % klass.__name__) as check_validity:
|
|
appconfig.hourly()
|
|
assert check_validity.call_args_list == [mock.call()]
|
|
else:
|
|
assert hasattr(klass, 'check_validity') is False
|
|
|
|
|
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
|
def test_search_external_forms_links(mock_send, context):
|
|
page = Page(title='xxx', slug='test_forms_of_category_cell_search', template_name='standard')
|
|
page.save()
|
|
|
|
cell = SearchCell(page=page, _search_services={'data': ['_text']}, order=0)
|
|
cell.save()
|
|
|
|
index_site()
|
|
request = RequestFactory().get('/')
|
|
request.user = AnonymousUser()
|
|
hits = search_site(request, 'form')
|
|
assert len(hits) == 0
|
|
|
|
cell = WcsFormsOfCategoryCell(page=page, placeholder='content', order=1)
|
|
cell.category_reference = 'default:test-9'
|
|
cell.ordering = 'alpha'
|
|
cell.save()
|
|
context['synchronous'] = True # to get fresh content
|
|
result = cell.render(context)
|
|
assert 'form title' in result and 'a second form title' in result
|
|
assert 'http://127.0.0.1:8999/form-title/tryauth' in result
|
|
assert 'http://127.0.0.1:8999/a-second-form-title/tryauth' in result
|
|
|
|
index_site()
|
|
request = RequestFactory().get('/')
|
|
request.user = AnonymousUser()
|
|
hits = search_site(request, 'form')
|
|
assert len(hits) == 2
|
|
|
|
|
|
@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 = WcsCardInfosCell(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)
|