combo/tests/test_cells.py

367 lines
13 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
cell.url = 'http://test2'
requests_get.return_value = mock.Mock(content=json.dumps(data), status_code=404)
context = cell.get_cell_extra_context({})
assert context['json'] is None
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 == ''
# 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 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 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['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]',
'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'
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'