combo/tests/test_wcs_templatetags.py

334 lines
13 KiB
Python

# -*- coding: utf-8 -*-
import copy
import json
import mock
import pytest
from django.template import Context, Template
from django.test.client import RequestFactory
from requests.exceptions import ConnectionError
from requests.models import Response
from combo.apps.wcs.context_processors import Cards
@pytest.fixture
def context():
ctx = Context(
{
'cards': Cards(),
'request': RequestFactory().get('/'),
}
)
ctx['request'].user = None
return ctx
class MockAnonymousUser(object):
is_authenticated = False
is_anonymous = True
class MockUser(object):
email = 'foo@example.net'
is_authenticated = True
is_anonymous = False
def get_name_id(self):
return None
class MockUserWithNameId(object):
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 mocked_requests_send(request, **kwargs):
data = [{'id': 1, 'fields': {'foo': 'bar'}}, {'id': 2, 'fields': {'foo': 'baz'}}] # fake result
return MockedRequestResponse(content=json.dumps({'data': data}))
def test_context(context):
assert 'cards' in context
@mock.patch('combo.apps.wcs.models.requests.send', side_effect=mocked_requests_send)
def test_objects(mock_send, settings, context, nocache):
# lazy filters
t = Template('{% load wcs %}{{ cards|objects:"foo" }}')
assert t.render(context).startswith(
'<combo.apps.wcs.context_processors.LazyCardDefObjectsManager object at'
)
assert mock_send.call_args_list == [] # lazy
t = Template('{% load wcs %}{{ cards|objects:"default:foo" }}')
assert t.render(context).startswith(
'<combo.apps.wcs.context_processors.LazyCardDefObjectsManager object at'
)
assert mock_send.call_args_list == [] # lazy
# test filters evaluation
t = Template('{% load wcs %}{% for card in cards|objects:"foo" %}{{ card.id }} {% endfor %}')
assert t.render(context) == "1 2 "
assert mock_send.call_args_list[0][0][0].url.startswith(
'http://127.0.0.1:8999/api/cards/foo/list?'
) # primary service
t = Template('{% load wcs %}{{ cards|objects:"default:foo"|list }}')
t.render(context)
assert mock_send.call_args_list[0][0][0].url.startswith('http://127.0.0.1:8999/api/cards/foo/list?')
mock_send.reset_mock()
t = Template('{% load wcs %}{{ cards|objects:"other:foo"|list }}')
t.render(context)
assert mock_send.call_args_list[0][0][0].url.startswith('http://127.0.0.2:8999/api/cards/foo/list?')
mock_send.reset_mock()
t = Template('{% load wcs %}{{ cards|objects:"unknown:foo"|list }}')
t.render(context)
assert mock_send.call_args_list == [] # unknown, not evaluated
# test card_id with variable
context['foobar'] = 'some-slug'
mock_send.reset_mock()
t = Template('{% load wcs %}{{ cards|objects:foobar|list }}')
t.render(context)
assert mock_send.call_args_list[0][0][0].url.startswith('http://127.0.0.1:8999/api/cards/some-slug/list?')
# test with no secondary param
KNOWN_SERVICES = copy.deepcopy(settings.KNOWN_SERVICES)
KNOWN_SERVICES['wcs'] = {'default': {'url': 'http://127.0.0.3:8999/'}}
settings.KNOWN_SERVICES = KNOWN_SERVICES
mock_send.reset_mock()
t = Template('{% load wcs %}{{ cards|objects:"bar"|list }}')
t.render(context)
assert mock_send.call_args_list[0][0][0].url.startswith('http://127.0.0.3:8999/api/cards/bar/list?')
@mock.patch('combo.apps.wcs.models.requests.send', side_effect=mocked_requests_send)
def test_with_custom_view(mock_send, context, nocache):
t = Template('{% load wcs %}{{ cards|objects:"foo"|with_custom_view:"foobar"|list }}')
t.render(context)
assert mock_send.call_args_list[0][0][0].url.startswith(
'http://127.0.0.1:8999/api/cards/foo/list/foobar?'
) # primary service
t = Template('{% load wcs %}{{ cards|objects:"default:foo"|with_custom_view:"foobar"|list }}')
t.render(context)
assert mock_send.call_args_list[0][0][0].url.startswith(
'http://127.0.0.1:8999/api/cards/foo/list/foobar?'
)
mock_send.reset_mock()
t = Template('{% load wcs %}{{ cards|objects:"other:foo"|with_custom_view:"foobar"|list }}')
t.render(context)
assert mock_send.call_args_list[0][0][0].url.startswith(
'http://127.0.0.2:8999/api/cards/foo/list/foobar?'
)
mock_send.reset_mock()
t = Template('{% load wcs %}{{ cards|objects:"unknown:foo"|with_custom_view:"foobar"|list }}')
t.render(context)
assert mock_send.call_args_list == [] # unknown, not evaluated
@mock.patch('combo.apps.wcs.models.requests.send', side_effect=mocked_requests_send)
def test_full(mock_send, context, nocache):
t = Template('{% load wcs %}{{ cards|objects:"foo"|list }}')
t.render(context)
assert 'full=on&' not in mock_send.call_args_list[0][0][0].url
mock_send.reset_mock()
t = Template('{% load wcs %}{{ cards|objects:"foo"|get_full|list }}')
t.render(context)
assert 'full=on&' in mock_send.call_args_list[0][0][0].url
@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send)
def test_errors(mock_send, context, nocache):
t = Template('{% load wcs %}{{ cards|objects:"foo"|list }}')
with mock.patch('combo.apps.wcs.utils.requests.get') as requests_get:
mock_resp = Response()
mock_resp.status_code = 500
requests_get.return_value = mock_resp
assert t.render(context) == "[]"
with mock.patch('combo.apps.wcs.utils.requests.get') as requests_get:
requests_get.side_effect = ConnectionError()
requests_get.return_value = mock_resp
assert t.render(context) == "[]"
with mock.patch('combo.apps.wcs.utils.requests.get') as requests_get:
mock_resp = Response()
mock_resp.status_code = 404
requests_get.return_value = mock_resp
assert t.render(context) == "[]"
mock_send.side_effect = lambda *a, **k: MockedRequestResponse(content=json.dumps({'err': 1}))
assert t.render(context) == "[]"
mock_send.side_effect = lambda *a, **k: MockedRequestResponse(content=json.dumps({}))
assert t.render(context) == "[]"
mock_send.side_effect = lambda *a, **k: MockedRequestResponse(content=json.dumps({'data': None}))
assert t.render(context) == "[]"
@mock.patch('combo.apps.wcs.models.requests.send', side_effect=mocked_requests_send)
def test_access_control(mock_send, context, nocache):
# no user in context
t = Template('{% load wcs %}{{ cards|objects:"foo"|list }}')
t.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_send.reset_mock()
t = Template('{% load wcs %}{{ cards|objects:"foo"|access_control:request.user|list }}')
t.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
# current user in anonymous
context['request'].user = MockAnonymousUser()
mock_send.reset_mock()
t = Template('{% load wcs %}{{ cards|objects:"foo"|list }}')
t.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_send.reset_mock()
t = Template('{% load wcs %}{{ cards|objects:"foo"|access_control:request.user|list }}')
t.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
# current user with uuid
context['request'].user = MockUserWithNameId()
mock_send.reset_mock()
t = Template('{% load wcs %}{{ cards|objects:"foo"|list }}')
t.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_send.reset_mock()
t = Template('{% load wcs %}{{ cards|objects:"foo"|access_control:request.user|list }}')
t.render(context)
assert 'NameID=xyz&' in mock_send.call_args_list[0][0][0].url
assert 'email' not in mock_send.call_args_list[0][0][0].url
# current user without uuid
context['request'].user = MockUser()
mock_send.reset_mock()
t = Template('{% load wcs %}{{ cards|objects:"foo"|list }}')
t.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_send.reset_mock()
t = Template('{% load wcs %}{{ cards|objects:"foo"|access_control:request.user|list }}')
t.render(context)
assert 'NameID' not in mock_send.call_args_list[0][0][0].url
assert 'email=foo%40example.net&' in mock_send.call_args_list[0][0][0].url
@mock.patch('combo.apps.wcs.models.requests.send', side_effect=mocked_requests_send)
def test_count(mock_send, context, nocache):
t = Template('{% load wcs %}{{ cards|objects:"foo"|count }}')
assert t.render(context) == "2"
@mock.patch('combo.apps.wcs.models.requests.send', side_effect=mocked_requests_send)
def test_filter(mock_send, context, nocache):
t = Template('{% load wcs %}{{ cards|objects:"foo"|filter_by:"foo"|filter_value:"bar"|list }}')
t.render(context)
assert 'filter-foo=bar&' in mock_send.call_args_list[0][0][0].url
mock_send.reset_mock()
t = Template(
'{% load wcs %}{{ cards|objects:"foo"|filter_by:"foo"|filter_value:"bar"|filter_by:"foo2"|filter_value:"bar2"|list }}'
)
t.render(context)
assert 'filter-foo=bar&' in mock_send.call_args_list[0][0][0].url
assert 'filter-foo2=bar2&' in mock_send.call_args_list[0][0][0].url
# check boolean
mock_send.reset_mock()
t = Template('{% load wcs %}{{ cards|objects:"foo"|filter_by:"foo"|filter_value:True|list }}')
t.render(context)
assert 'filter-foo=true&' in mock_send.call_args_list[0][0][0].url
mock_send.reset_mock()
t = Template('{% load wcs %}{{ cards|objects:"foo"|filter_by:"foo"|filter_value:False|list }}')
t.render(context)
assert 'filter-foo=false&' in mock_send.call_args_list[0][0][0].url
# check None
mock_send.reset_mock()
t = Template('{% load wcs %}{{ cards|objects:"foo"|filter_by:"foo"|filter_value:None|list }}')
t.render(context)
assert 'filter-foo=&' in mock_send.call_args_list[0][0][0].url
@mock.patch('combo.apps.wcs.models.requests.send', side_effect=mocked_requests_send)
def test_filter_by_user(mock_send, context, nocache):
t = Template('{% load wcs %}{{ cards|objects:"foo"|filter_by_user:request.user|list }}')
t.render(context)
assert 'filter-user-uuid' not in mock_send.call_args_list[0][0][0].url
context['request'].user = MockAnonymousUser()
mock_send.reset_mock()
t.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()
t.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()
t.render(context)
assert 'filter-user-uuid=xyz&' in mock_send.call_args_list[0][0][0].url
@mock.patch('combo.apps.wcs.models.requests.send', side_effect=mocked_requests_send)
def test_filter_by_status(mock_send, context, nocache):
t = Template('{% load wcs %}{{ cards|objects:"foo"|list }}')
t.render(context)
assert 'filter=&' not in mock_send.call_args_list[0][0][0].url
mock_send.reset_mock()
t = Template('{% load wcs %}{{ cards|objects:"foo"|filter_by_status:None|list }}')
t.render(context)
assert 'filter=&' not in mock_send.call_args_list[0][0][0].url
mock_send.reset_mock()
t = Template('{% load wcs %}{{ cards|objects:"foo"|filter_by_status:""|list }}')
t.render(context)
assert 'filter=&' not in mock_send.call_args_list[0][0][0].url
mock_send.reset_mock()
t = Template('{% load wcs %}{{ cards|objects:"foo"|filter_by_status:"foobar"|list }}')
t.render(context)
assert 'filter=foobar&' in mock_send.call_args_list[0][0][0].url
@mock.patch('combo.apps.wcs.models.requests.send', side_effect=mocked_requests_send)
def test_getlist(mock_send, context, nocache):
t = Template('{% load wcs %}{% for v in cards|objects:"foo"|getlist:"id" %}{{ v }},{% endfor %}')
t.render(context)
assert t.render(context) == "1,2,"
t = Template('{% load wcs %}{% for v in cards|objects:"foo"|getlist:"fields" %}{{ v }},{% endfor %}')
t.render(context)
assert t.render(context) == "{'foo': 'bar'},{'foo': 'baz'},"
t = Template(
'{% load wcs %}{% for v in cards|objects:"foo"|getlist:"fields"|getlist:"foo" %}{{ v }},{% endfor %}'
)
t.render(context)
assert t.render(context) == "bar,baz,"
t = Template(
'{% load wcs %}{% for v in cards|objects:"foo"|getlist:"fields"|getlist:"unknown" %}{{ v }},{% endfor %}'
)
t.render(context)
assert t.render(context) == "None,None,"