469 lines
18 KiB
Python
469 lines
18 KiB
Python
import json
|
|
import mock
|
|
import os
|
|
import pytest
|
|
import requests
|
|
|
|
from combo.data.models import Page, CellBase, TextCell, LinkCell, JsonCellBase, JsonCell, ConfigJsonCell
|
|
from django.forms.widgets import Media
|
|
from django.template import Context
|
|
from django.test import override_settings
|
|
from django.test.client import RequestFactory
|
|
from django.contrib.auth.models import User
|
|
from django.core.urlresolvers import reverse
|
|
|
|
from combo.utils import NothingInCacheException
|
|
|
|
pytestmark = pytest.mark.django_db
|
|
|
|
|
|
def test_cell_reference():
|
|
page = Page()
|
|
page.save()
|
|
|
|
cell = TextCell()
|
|
cell.page = page
|
|
cell.text = 'foobar'
|
|
cell.order = 0
|
|
cell.save()
|
|
|
|
assert CellBase.get_cell(cell.get_reference()) == cell
|
|
|
|
|
|
def test_media():
|
|
class TextCelleWithMedia(TextCell):
|
|
class Media:
|
|
js = ['coincoin.js']
|
|
|
|
class Meta:
|
|
# to prevent error in Models metaclass as the current module is not
|
|
# in a registered applicatoin
|
|
app_label = 'data'
|
|
abstract = True
|
|
cells = [TextCelleWithMedia() for i in range(3)]
|
|
assert unicode(sum((cell.media for cell in cells), Media())) == u'<script type="text/javascript" src="/static/coincoin.js"></script>'
|
|
|
|
|
|
def test_additional_label():
|
|
page = Page()
|
|
page.save()
|
|
|
|
cell = TextCell()
|
|
cell.page = page
|
|
cell.text = '<p>foobar</p>'
|
|
cell.order = 0
|
|
cell.save()
|
|
|
|
assert cell.get_additional_label() == 'foobar'
|
|
|
|
cell = TextCell()
|
|
cell.page = page
|
|
cell.text = '<p>%s</p>' % 'foo'*30
|
|
cell.order = 0
|
|
cell.save()
|
|
|
|
assert len(cell.get_additional_label()) < 100
|
|
assert '...' in cell.get_additional_label()
|
|
|
|
def test_link_cell():
|
|
page = Page(title='example page', slug='example-page')
|
|
page.save()
|
|
|
|
cell = LinkCell()
|
|
cell.page = page
|
|
cell.title = 'Example Site'
|
|
cell.url = 'http://example.net/'
|
|
cell.order = 0
|
|
cell.save()
|
|
|
|
assert cell.get_additional_label() == 'Example Site'
|
|
|
|
from django.template import Context
|
|
ctx = Context()
|
|
assert cell.render(ctx).strip() == '<a href="http://example.net/">Example Site</a>'
|
|
|
|
cell.title = ''
|
|
cell.save()
|
|
assert cell.render(ctx).strip() == '<a href="http://example.net/">http://example.net/</a>'
|
|
|
|
cell.link_page = page
|
|
cell.save()
|
|
assert cell.render(ctx).strip() == '<a href="/example-page/">example page</a>'
|
|
|
|
cell.title = 'altertitle'
|
|
cell.save()
|
|
assert cell.render(ctx).strip() == '<a href="/example-page/">altertitle</a>'
|
|
|
|
cell.anchor = 'anchor'
|
|
cell.save()
|
|
assert cell.render(ctx).strip() == '<a href="/example-page/#anchor">altertitle</a>'
|
|
|
|
cell.link_page = None
|
|
cell.save()
|
|
assert cell.render(ctx).strip() == '<a href="http://example.net/#anchor">altertitle</a>'
|
|
|
|
|
|
def test_variant_templates():
|
|
page = Page(title='example page', slug='example-page')
|
|
page.save()
|
|
|
|
cell = TextCell()
|
|
cell.page = page
|
|
cell.text = '<p>foobar</p>'
|
|
cell.order = 0
|
|
cell.save()
|
|
|
|
from django.template import Context
|
|
ctx = Context()
|
|
assert cell.render(ctx).strip() == '<p>foobar</p>'
|
|
|
|
with override_settings(TEMPLATE_DIRS=['%s/templates-1' % os.path.abspath(os.path.dirname(__file__))]):
|
|
assert cell.render(ctx).strip() == '<p>foobar</p>'
|
|
cell.slug = 'foobar'
|
|
cell.save()
|
|
assert cell.render(ctx).strip() == '<div class="XXX"><p>foobar</p></div>'
|
|
|
|
assert cell.render(ctx).strip() == '<p>foobar</p>'
|
|
|
|
def mocked_request(*args, **kwargs):
|
|
pass
|
|
|
|
def test_json_cell():
|
|
page = Page(title='example page', slug='example-page')
|
|
page.save()
|
|
|
|
cell = JsonCell()
|
|
cell.page = page
|
|
cell.title = 'Example Site'
|
|
cell.order = 0
|
|
cell.save()
|
|
|
|
cell._json_content = None
|
|
assert cell.template_name == 'combo/json-error-cell.html'
|
|
|
|
cell._json_content = {}
|
|
assert cell.template_name == 'combo/json-cell.html'
|
|
|
|
cell._json_content = {'data': []}
|
|
assert cell.template_name == 'combo/json-cell.html'
|
|
|
|
cell._json_content = {'data': [{'url': 'xxx', 'text': 'xxx'}]}
|
|
assert cell.template_name == 'combo/json-list-cell.html'
|
|
|
|
cell._json_content = {'data': [{'foo': 'xxx', 'bar': 'xxx'}]}
|
|
assert cell.template_name == 'combo/json-cell.html'
|
|
|
|
with mock.patch('combo.utils.requests.get') as requests_get:
|
|
data = {'data': [{'url': 'xxx', 'text': 'xxx'}]}
|
|
requests_get.return_value = mock.Mock(content=json.dumps(data), status_code=200)
|
|
context = cell.get_cell_extra_context({})
|
|
assert context['json'] == data
|
|
assert context['json_url'] == ''
|
|
assert context['json_status'] == 200
|
|
assert 'json_error' not in context
|
|
|
|
requests_get.return_value = mock.Mock(status_code=204) # 204 : No Content
|
|
context = cell.get_cell_extra_context({})
|
|
assert context['json'] is None
|
|
assert context['json_url'] == ''
|
|
assert context['json_status'] == 204
|
|
assert 'json_error' not in context
|
|
|
|
cell.url = 'http://test2'
|
|
requests_get.return_value = mock.Mock(content='not found', status_code=404,
|
|
headers={})
|
|
context = cell.get_cell_extra_context({})
|
|
assert context['json'] is None
|
|
assert context['json_url'] == 'http://test2'
|
|
assert context['json_status'] == 404
|
|
assert 'json_error' not in context
|
|
|
|
requests_get.return_value = mock.Mock(content=json.dumps(data), status_code=404,
|
|
headers={'content-type': 'application/json'})
|
|
context = cell.get_cell_extra_context({})
|
|
assert context['json'] is None
|
|
assert context['json_url'] == 'http://test2'
|
|
assert context['json_status'] == 404
|
|
assert context['json_error'] == data
|
|
|
|
with pytest.raises(NothingInCacheException):
|
|
cell.url = 'http://test3'
|
|
cell.render({})
|
|
|
|
with mock.patch('combo.utils.requests.get') as requests_get:
|
|
data = {'data': [{'url': 'http://a.b', 'text': 'xxx'}]}
|
|
requests_get.return_value = mock.Mock(content=json.dumps(data), status_code=200)
|
|
cell.url = 'http://test4'
|
|
result = cell.render(Context({'synchronous': True}))
|
|
assert 'http://a.b' in result
|
|
assert requests_get.call_count == 1
|
|
|
|
cell.template_string = '{{json.data.0.text}}'
|
|
result = cell.render(Context({'synchronous': True}))
|
|
assert result == 'xxx'
|
|
|
|
with mock.patch('combo.utils.requests.get') as requests_get:
|
|
requests_get.return_value = mock.Mock(content='garbage', status_code=200)
|
|
cell.url = 'http://test5'
|
|
result = cell.render(Context({'synchronous': True}))
|
|
assert result == ''
|
|
|
|
context = cell.get_cell_extra_context({})
|
|
assert context['json'] is None
|
|
assert context['json_url'] == 'http://test5'
|
|
assert context['json_status'] == 200
|
|
assert context['json_error'] == 'invalid_json'
|
|
|
|
# URL is a template, using [variables]
|
|
cell.cache_duration = 10
|
|
data = {'data': [{'url': 'xxx', 'text': 'xxx'}]}
|
|
cell.url = 'http://testuser?[foobar]'
|
|
with mock.patch('combo.utils.requests.get') as requests_get:
|
|
requests_get.return_value = mock.Mock(content=json.dumps(data), status_code=200)
|
|
context = cell.get_cell_extra_context(Context({'foobar': 'barfoo'}))
|
|
assert context['json'] == data
|
|
assert context['json_url'] == 'http://testuser?barfoo'
|
|
assert context['json_status'] == 200
|
|
assert requests_get.call_args[0][0] == 'http://testuser?barfoo'
|
|
assert requests_get.call_args[1]['cache_duration'] == 10
|
|
assert requests_get.call_count == 1
|
|
with mock.patch('combo.utils.requests.get') as requests_get:
|
|
context = cell.get_cell_extra_context(Context({}))
|
|
# can't get URL, 'foobar' variable is missing
|
|
assert context['json'] == None
|
|
assert requests_get.call_count == 0
|
|
request = RequestFactory().get('/')
|
|
request.user = User(username='foo', email='foo@example.net')
|
|
cell.url = 'http://testuser?email=[user_email]'
|
|
with mock.patch('combo.utils.requests.get') as requests_get:
|
|
requests_get.return_value = mock.Mock(content=json.dumps(data), status_code=200)
|
|
context = cell.get_cell_extra_context(Context({'request': request}))
|
|
assert context['json'] == data
|
|
assert context['json_url'] == 'http://testuser?email=foo%40example.net'
|
|
assert requests_get.call_count == 1
|
|
assert requests_get.call_args[0][0] == 'http://testuser?email=foo%40example.net'
|
|
assert requests_get.call_args[1]['cache_duration'] == 10
|
|
|
|
def test_json_cell_with_varnames(app):
|
|
page = Page(title='example page', slug='index')
|
|
page.save()
|
|
|
|
cell = JsonCell()
|
|
cell.page = page
|
|
cell.title = 'Example Site'
|
|
cell.order = 0
|
|
cell.varnames_str = 'var1, var2, '
|
|
cell.url = 'http://foo?varone=[var1]&vartwo=[var2]'
|
|
cell.template_string = '/var1={{var1}}/var2={{var2}}/'
|
|
cell.save()
|
|
|
|
assert cell.varnames == ['var1', 'var2']
|
|
|
|
with mock.patch('combo.utils.requests.get') as requests_get:
|
|
data = {'data': []}
|
|
requests_get.return_value = mock.Mock(content=json.dumps(data), status_code=200)
|
|
url = reverse('combo-public-ajax-page-cell',
|
|
kwargs={'page_pk': page.id, 'cell_reference': cell.get_reference()})
|
|
resp = app.get(url + '?var1=foo&var2=bar') # request query string is here
|
|
assert requests_get.call_count == 1
|
|
assert requests_get.call_args[0][0] == 'http://foo?varone=foo&vartwo=bar'
|
|
assert '/var1=foo/' in resp.body
|
|
assert '/var2=bar/' in resp.body
|
|
|
|
def test_config_json_cell():
|
|
page = Page(title='example page', slug='example-page')
|
|
page.save()
|
|
|
|
request = RequestFactory().get('/')
|
|
|
|
with override_settings(JSON_CELL_TYPES={'foobar': {'name': 'Foobar', 'url': 'http://test/'}}):
|
|
cell = ConfigJsonCell()
|
|
cell.key = 'foobar'
|
|
cell.parameters = {'blah': 'plop'}
|
|
assert cell.get_label() == 'Foobar'
|
|
assert cell.url == 'http://test/'
|
|
assert cell.template_name == 'combo/json/foobar.html'
|
|
|
|
with mock.patch('combo.utils.requests.get') as requests_get:
|
|
requests_get.return_value = mock.Mock(content=json.dumps({'hello': 'world'}), status_code=200)
|
|
context = cell.get_cell_extra_context(Context({'request': request}))
|
|
assert context['json'] == {'hello': 'world'}
|
|
assert context['json_url'] == 'http://test/'
|
|
assert context['json_status'] == 200
|
|
assert context['parameters'] == {'blah': 'plop'}
|
|
assert context['blah'] == 'plop'
|
|
|
|
with override_settings(JSON_CELL_TYPES={'foobar': {
|
|
'name': 'Foobar', 'url': 'http://test/', 'cache_duration': 10}}):
|
|
cell = ConfigJsonCell()
|
|
cell.key = 'foobar'
|
|
cell.parameters = {'blah': 'plop'}
|
|
assert cell.get_label() == 'Foobar'
|
|
assert cell.url == 'http://test/'
|
|
assert cell.template_name == 'combo/json/foobar.html'
|
|
assert cell.cache_duration == 10
|
|
|
|
def test_config_json_cell_with_varnames(app):
|
|
page = Page(title='example page', slug='index')
|
|
page.save()
|
|
|
|
with override_settings(JSON_CELL_TYPES={
|
|
'test-config-json-cell': {
|
|
'name': 'Foobar',
|
|
'url': 'http://foo?varone=[var1]&vartwo=[var2]',
|
|
'varnames': ['var1', 'var2']
|
|
}},
|
|
TEMPLATE_DIRS=['%s/templates-1' % os.path.abspath(os.path.dirname(__file__))]):
|
|
cell = ConfigJsonCell()
|
|
cell.key = 'test-config-json-cell'
|
|
cell.page = page
|
|
cell.title = 'Example Site'
|
|
cell.order = 0
|
|
cell.save()
|
|
assert cell.varnames == ['var1', 'var2']
|
|
|
|
with mock.patch('combo.utils.requests.get') as requests_get:
|
|
data = {'data': []}
|
|
requests_get.return_value = mock.Mock(content=json.dumps(data), status_code=200)
|
|
url = reverse('combo-public-ajax-page-cell',
|
|
kwargs={'page_pk': page.id, 'cell_reference': cell.get_reference()})
|
|
resp = app.get(url + '?var1=foo&var2=bar') # request query string is here
|
|
assert requests_get.call_count == 1
|
|
assert requests_get.call_args[0][0] == 'http://foo?varone=foo&vartwo=bar'
|
|
assert '/var1=foo/' in resp.body
|
|
assert '/var2=bar/' in resp.body
|
|
|
|
def test_config_json_cell_with_param_in_url(app):
|
|
page = Page(title='example page', slug='index')
|
|
page.save()
|
|
|
|
with override_settings(JSON_CELL_TYPES={
|
|
'test-config-json-cell': {
|
|
'name': 'Foobar',
|
|
'url': 'http://foo?var=[identifier]',
|
|
'log_errors': False,
|
|
'form': [
|
|
{
|
|
"varname": "identifier",
|
|
"type": "string",
|
|
"label": "Identifier"
|
|
}
|
|
]
|
|
}},
|
|
TEMPLATE_DIRS=['%s/templates-1' % os.path.abspath(os.path.dirname(__file__))]):
|
|
cell = ConfigJsonCell()
|
|
cell.key = 'test-config-json-cell'
|
|
cell.parameters = {'identifier': 'plop'}
|
|
cell.page = page
|
|
cell.title = 'Example Site'
|
|
cell.order = 0
|
|
cell.save()
|
|
|
|
with mock.patch('combo.utils.requests.get') as requests_get:
|
|
data = {'data': []}
|
|
requests_get.return_value = mock.Mock(content=json.dumps(data), status_code=200)
|
|
url = reverse('combo-public-ajax-page-cell',
|
|
kwargs={'page_pk': page.id, 'cell_reference': cell.get_reference()})
|
|
resp = app.get(url)
|
|
assert requests_get.call_count == 1
|
|
assert requests_get.call_args[0][0] == 'http://foo?var=plop'
|
|
assert requests_get.call_args[-1]['log_errors'] == False
|
|
|
|
def test_json_force_async():
|
|
cell = JsonCellBase()
|
|
cell.url = 'http://example.net/test-force-async'
|
|
cell.template_string = '{{json.hello}}'
|
|
cell.force_async = True
|
|
with mock.patch('combo.utils.RequestsSession.request') as requests_get:
|
|
requests_get.return_value = mock.Mock(content=json.dumps({'hello': 'world'}), status_code=200)
|
|
with pytest.raises(NothingInCacheException):
|
|
cell.render(Context({}))
|
|
assert cell.render(Context({'synchronous': True})) == 'world'
|
|
# check force async is effective
|
|
with pytest.raises(NothingInCacheException):
|
|
cell.render(Context({}))
|
|
# disable force_async
|
|
cell.force_async = False
|
|
assert cell.render(Context({})) == 'world'
|
|
|
|
cell = JsonCellBase()
|
|
cell.url = 'http://example.net/test-force-async-2'
|
|
cell.template_string = '{{json.hello}}'
|
|
cell.force_async = False
|
|
with mock.patch('combo.utils.RequestsSession.request') as requests_get:
|
|
requests_get.return_value = mock.Mock(content=json.dumps({'hello': 'world2'}), status_code=200)
|
|
# raise if nothing in cache
|
|
with pytest.raises(NothingInCacheException):
|
|
cell.render(Context({}))
|
|
# force stuff in cache
|
|
assert cell.render(Context({'synchronous': True})) == 'world2'
|
|
# rerun with stuff in cache
|
|
assert cell.render(Context({})) == 'world2'
|
|
|
|
def test_config_json_cell_additional_url(app):
|
|
page = Page(title='example page', slug='index')
|
|
page.save()
|
|
|
|
with override_settings(JSON_CELL_TYPES={
|
|
'test-config-json-cell-2': {
|
|
'name': 'Foobar',
|
|
'url': 'http://foo',
|
|
'additional-data': [
|
|
{'key': 'plop', 'url': 'http://bar', 'log_errors': False},
|
|
]
|
|
}},
|
|
TEMPLATE_DIRS=['%s/templates-1' % os.path.abspath(os.path.dirname(__file__))]):
|
|
cell = ConfigJsonCell()
|
|
cell.key = 'test-config-json-cell-2'
|
|
cell.page = page
|
|
cell.title = 'Example Site'
|
|
cell.order = 0
|
|
cell.save()
|
|
|
|
with mock.patch('combo.utils.requests.get') as requests_get:
|
|
data = {'data': 'toto'}
|
|
requests_get.return_value = mock.Mock(content=json.dumps(data), status_code=200)
|
|
url = reverse('combo-public-ajax-page-cell',
|
|
kwargs={'page_pk': page.id, 'cell_reference': cell.get_reference()})
|
|
resp = app.get(url)
|
|
assert resp.body.strip() == '/var1=toto/var2=toto/'
|
|
assert len(requests_get.mock_calls) == 2
|
|
assert requests_get.mock_calls[0][1][0] == 'http://foo'
|
|
assert requests_get.mock_calls[0][-1]['log_errors'] == True
|
|
assert requests_get.mock_calls[1][1][0] == 'http://bar'
|
|
assert requests_get.mock_calls[1][-1]['log_errors'] == False
|
|
|
|
with mock.patch('combo.utils.requests.get') as requests_get:
|
|
data = {'data': 'toto'}
|
|
requests_get.return_value = mock.Mock(content=json.dumps(data), status_code=404,
|
|
headers={'content-type': 'application/json'})
|
|
url = reverse('combo-public-ajax-page-cell',
|
|
kwargs={'page_pk': page.id, 'cell_reference': cell.get_reference()})
|
|
resp = app.get(url)
|
|
assert resp.body.strip() == '/var1=/var2=/'
|
|
assert len(requests_get.mock_calls) == 2
|
|
assert requests_get.mock_calls[0][1][0] == 'http://foo'
|
|
assert requests_get.mock_calls[1][1][0] == 'http://bar'
|
|
context = cell.get_cell_extra_context({})
|
|
assert context['json'] == None
|
|
assert context['json_url'] == 'http://foo'
|
|
assert context['json_status'] == 404
|
|
assert context['json_error'] == data
|
|
assert context['plop'] == None
|
|
assert context['plop_url'] == 'http://bar'
|
|
assert context['plop_status'] == 404
|
|
assert context['plop_error'] == data
|
|
|
|
with mock.patch('combo.utils.requests.get') as requests_get:
|
|
data = {'data': 'toto'}
|
|
requests_get.return_value = mock.Mock(content=json.dumps(data), status_code=200)
|
|
context = cell.get_cell_extra_context({})
|
|
assert context['json'] == data
|
|
assert context['json_url'] == 'http://foo'
|
|
assert context['json_status'] == 200
|
|
assert 'json_error' not in context
|
|
assert context['plop'] == data
|
|
assert context['plop_url'] == 'http://bar'
|
|
assert context['plop_status'] == 200
|
|
assert 'plop_error' not in context
|