168 lines
6.2 KiB
Python
168 lines
6.2 KiB
Python
import json
|
|
import time
|
|
from unittest import mock
|
|
|
|
from django.core.cache import cache
|
|
from django.test import override_settings
|
|
from django.test.client import RequestFactory
|
|
from django.utils import translation
|
|
from httmock import HTTMock, urlmatch
|
|
|
|
from hobo.context_processors import theme_base, user_urls
|
|
|
|
|
|
def test_theme_base(settings, rf):
|
|
settings.THEME_SKELETON_URL = 'http://combo.example.com/_skeleton_/'
|
|
seen_urls = []
|
|
TEMPLATE = 'Feeling lucky, punk?'
|
|
TEMPLATE_PAGE2 = 'Response for page 2'
|
|
|
|
@urlmatch(netloc=r'combo.example.com$')
|
|
def combo_mock(url, request):
|
|
seen_urls.append(url.geturl())
|
|
status_code = 200
|
|
content = TEMPLATE
|
|
if 'page2' in url.query:
|
|
content = TEMPLATE_PAGE2
|
|
elif 'page1' in url.query:
|
|
status_code = 500
|
|
content = 'No template sorry'
|
|
return {
|
|
'status_code': status_code,
|
|
'content': content,
|
|
'headers': {
|
|
'X-Combo-Skeleton-Pages': json.dumps(
|
|
{'1': 'http://testserver/foo', '2': 'http://testserver/page1/page2/'}
|
|
)
|
|
},
|
|
}
|
|
|
|
cache.clear()
|
|
|
|
def check(context, value):
|
|
assert context['theme_base']().source == value
|
|
|
|
with HTTMock(combo_mock), override_settings(INSTALLED_APPS=[]):
|
|
context = theme_base(rf.get('/'))
|
|
check(context, TEMPLATE)
|
|
assert seen_urls[0] == 'http://combo.example.com/_skeleton_/?source=http%3A%2F%2Ftestserver%2F'
|
|
for dummy in range(10):
|
|
# wait for the other requests, made from a thread, to happen
|
|
time.sleep(0.1)
|
|
if len(seen_urls) == 4:
|
|
break
|
|
assert len(seen_urls) == 4
|
|
# requested page + root + pages from X-Combo-Skeleton-Pages header
|
|
seen_urls = []
|
|
context = theme_base(rf.get('/'))
|
|
check(context, TEMPLATE)
|
|
assert len(seen_urls) == 0
|
|
seen_urls = []
|
|
context = theme_base(rf.get('/page1/page2/'))
|
|
check(context, TEMPLATE_PAGE2)
|
|
assert len(seen_urls) == 0
|
|
seen_urls = []
|
|
context = theme_base(rf.get('/page1/'))
|
|
check(context, TEMPLATE)
|
|
assert len(seen_urls) == 0
|
|
context = theme_base(rf.get('/page1/page2/'))
|
|
check(context, TEMPLATE_PAGE2)
|
|
assert len(seen_urls) == 0
|
|
|
|
|
|
def test_theme_base_language(settings, rf):
|
|
settings.THEME_SKELETON_URL = 'http://combo.example.com/_skeleton_/'
|
|
seen_urls = []
|
|
|
|
@urlmatch(netloc=r'combo.example.com$')
|
|
def combo_mock(url, request):
|
|
language = request.headers['Accept-Language']
|
|
seen_urls.append((language, url.geturl()))
|
|
status_code = 200
|
|
assert language in ('en', 'fr'), 'invalid language'
|
|
if language == 'en':
|
|
content = 'Skeleton for English'
|
|
elif language == 'fr':
|
|
content = 'Skeleton for French'
|
|
return {
|
|
'status_code': status_code,
|
|
'content': content,
|
|
'headers': {'X-Combo-Skeleton-Pages': json.dumps({'1': 'http://testserver/foo'})},
|
|
}
|
|
|
|
cache.clear()
|
|
|
|
with HTTMock(combo_mock), override_settings(
|
|
INSTALLED_APPS=[], LANGUAGES=[('en', 'English'), ('fr', 'French')]
|
|
):
|
|
context = theme_base(rf.get('/'))
|
|
assert context['theme_base']().source == 'Skeleton for English'
|
|
for dummy in range(10):
|
|
# wait for the other requests, made from a thread, to happen
|
|
time.sleep(0.1)
|
|
if len(seen_urls) == 5:
|
|
break
|
|
assert len(seen_urls) == 5
|
|
assert ('en', 'http://combo.example.com/_skeleton_/?source=http%3A%2F%2Ftestserver%2F') in seen_urls
|
|
assert ('fr', 'http://combo.example.com/_skeleton_/?source=http%3A%2F%2Ftestserver%2F') in seen_urls
|
|
assert (
|
|
'en',
|
|
'http://combo.example.com/_skeleton_/?source=http%3A%2F%2Ftestserver%2Ffoo',
|
|
) in seen_urls
|
|
assert (
|
|
'fr',
|
|
'http://combo.example.com/_skeleton_/?source=http%3A%2F%2Ftestserver%2Ffoo',
|
|
) in seen_urls
|
|
|
|
assert theme_base(rf.get('/'))['theme_base']().source == 'Skeleton for English'
|
|
|
|
with translation.override('fr'):
|
|
assert theme_base(rf.get('/'))['theme_base']().source == 'Skeleton for French'
|
|
|
|
|
|
class IdPRequestFactory(RequestFactory):
|
|
def _base_environ(self, **request):
|
|
environ = super()._base_environ(**request)
|
|
environ['SCRIPT_NAME'] = 'idp'
|
|
environ['wsgi.url_scheme'] = 'https'
|
|
return environ
|
|
|
|
|
|
def test_user_urls(settings, rf):
|
|
settings.TEMPLATE_VARS = {
|
|
'idp_registration_url': 'https://idp/register/',
|
|
'idp_account_url': 'https://idp/accounts/',
|
|
}
|
|
|
|
request = rf.get('/page/')
|
|
assert user_urls(request) == {
|
|
'login_url': '/login/?next=%2Fpage%2F',
|
|
'logout_url': '/logout/?next=%2F',
|
|
'registration_url': 'https://idp/register/?next=http%3A%2F%2Ftestserver%2Fpage%2F',
|
|
'account_url': 'https://idp/accounts/?next=http%3A%2F%2Ftestserver%2Fpage%2F',
|
|
}
|
|
|
|
request = IdPRequestFactory().get('/accounts/?next=http%3A%2F%2Ftestserver%2Fpage%2F')
|
|
assert user_urls(request)['account_url'] == 'https://idp/accounts/?next=http%3A%2F%2Ftestserver%2Fpage%2F'
|
|
|
|
with mock.patch('hobo.context_processors._authentic2_get_next_url', return_value='coin'):
|
|
# simulate the real get_next_url of authentic2
|
|
from django.conf import settings as real_settings
|
|
|
|
real_settings.PROJECT_NAME = 'authentic2-multitenant'
|
|
request = rf.get('/login/?next=coin&nonce=2')
|
|
assert user_urls(request) == {
|
|
'login_url': '#',
|
|
'logout_url': '/logout/?next=%2F',
|
|
'registration_url': '/register/?next=coin&nonce=2',
|
|
'account_url': 'https://idp/accounts/?next=http%3A%2F%2Ftestserver%2Flogin%2F%3Fnext%3Dcoin%26nonce%3D2',
|
|
}
|
|
|
|
request = rf.get('/register/?next=coin&nonce=2')
|
|
assert user_urls(request) == {
|
|
'login_url': '/login/?next=coin&nonce=2',
|
|
'logout_url': '/logout/?next=%2F',
|
|
'registration_url': '#',
|
|
'account_url': 'https://idp/accounts/?next=http%3A%2F%2Ftestserver%2Fregister%2F%3Fnext%3Dcoin%26nonce%3D2',
|
|
}
|