266 lines
9.0 KiB
Python
266 lines
9.0 KiB
Python
import json
|
|
import re
|
|
from unittest import mock
|
|
|
|
import pytest
|
|
from django.test import override_settings
|
|
from requests import Response
|
|
|
|
from hobo.environment.models import Combo, Fargo, Wcs
|
|
|
|
from .test_manager import login
|
|
|
|
pytestmark = pytest.mark.django_db
|
|
|
|
CONFIG = {'URL': 'https://matomo.test', 'TOKEN_AUTH': '1234', 'EMAIL_TEMPLATE': 'noreply+%s@entrouvert.test'}
|
|
|
|
GET_NO_SITE_FROM_URL = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<result />
|
|
"""
|
|
|
|
ADD_SITE_SUCCESS = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<result>42</result>
|
|
"""
|
|
|
|
ADD_SITE_ALIAS_URLS_SUCCESS = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<result>1</result>
|
|
"""
|
|
|
|
DEL_UNKNOWN_USER = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<result>
|
|
<error message="User 'hobo.dev.publik.love' doesn't exist." />
|
|
</result>
|
|
"""
|
|
|
|
MATOMO_SUCCESS = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<result>
|
|
<success message="ok" />
|
|
</result>
|
|
"""
|
|
|
|
JAVASCRIPT_TAG_BAD_RESPONSE = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<no_result_tag/>
|
|
"""
|
|
|
|
JAVASCRIPT_TAG = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<result><!-- Matomo -->
|
|
<script type="text/javascript">
|
|
var _paq = window._paq || [];
|
|
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
|
|
_paq.push(['trackPageView']);
|
|
_paq.push(['enableLinkTracking']);
|
|
(function() {
|
|
var u="//matomo-test.entrouvert.org/";
|
|
_paq.push(['setTrackerUrl', u+'piwik.php']);
|
|
_paq.push(['setSiteId', '7']);
|
|
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
|
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
|
|
})();
|
|
</script>
|
|
<!-- End Matomo Code -->
|
|
</result>
|
|
"""
|
|
|
|
PING_SUCCESS = '{"status":"success","tracked":1,"invalid":0}'
|
|
PING_ERROR = '{"status":"not success"}'
|
|
|
|
|
|
def requests_post_mocked_replies(contents):
|
|
"""buid an iterator for mock's side_effect parameter"""
|
|
responses = []
|
|
for content in contents:
|
|
response = Response()
|
|
|
|
# response may be XML or JSON
|
|
if content[0] == '{':
|
|
response.json = mock.MagicMock(return_value=json.loads(content))
|
|
response._content = content
|
|
|
|
response.status_code = 200
|
|
responses.append(response)
|
|
return responses
|
|
|
|
|
|
def test_unlogged_access(app):
|
|
# connect while not being logged in
|
|
resp = app.get('/visits-tracking/', status=302)
|
|
assert resp.location.endswith('/login/?next=/visits-tracking/')
|
|
|
|
|
|
def test_access(app, admin_user):
|
|
login(app)
|
|
assert app.get('/visits-tracking/', status=200)
|
|
|
|
|
|
def test_disable(app, admin_user):
|
|
login(app)
|
|
resp1 = app.get('/visits-tracking/disable', status=200)
|
|
resp2 = resp1.form.submit()
|
|
assert resp2.location.endswith('/visits-tracking/')
|
|
|
|
|
|
def test_enable_manual(app, admin_user):
|
|
"""scenario where user manually paste a javascript code"""
|
|
login(app)
|
|
|
|
# get matomo's validation page
|
|
resp = app.get('/visits-tracking/enable-manual', status=200)
|
|
assert re.search('<textarea.* name="tracking_js"', resp.text)
|
|
|
|
# validate and get matomo's home page
|
|
resp.form['tracking_js'] = '...js_code_1...'
|
|
resp = resp.form.submit().follow()
|
|
assert resp.text.find('Manual configuration.')
|
|
assert re.search('<textarea.* name="tracking_js"', resp.text)
|
|
assert resp.text.find('...js_code_1...</textarea>') != -1
|
|
assert resp.text.find('<button class="submit-button">Save</button>') != -1
|
|
|
|
# update JS code on matomo's home page
|
|
resp.form['tracking_js'] = '...js_code_2...'
|
|
resp = resp.form.submit().follow()
|
|
assert resp.text.find('Manual configuration.') != -1
|
|
assert re.search('<textarea.* name="tracking_js"', resp.text)
|
|
assert resp.text.find('...js_code_2...</textarea>') != -1
|
|
assert resp.text.find('<button class="submit-button">Save</button>') != -1
|
|
assert resp.text.find('Good respect of user rights') != -1
|
|
|
|
# check erroneous html tag
|
|
resp.form['tracking_js'] = '<script >'
|
|
resp = resp.form.submit()
|
|
assert (
|
|
'<ul class="errorlist"><li>This field should only contain the Javascript code. '
|
|
'You should remove the surrounding <script> markup.</li></ul>'
|
|
) in resp.text
|
|
|
|
# check against a more realistic tracking js input. it should succeed.
|
|
resp.form[
|
|
'tracking_js'
|
|
] = '''<!-- Matomo -->
|
|
<script type="text/javascript">
|
|
var _paq = window._paq = window._paq || [];
|
|
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
|
|
_paq.push(['trackPageView']);
|
|
_paq.push(['enableLinkTracking']);
|
|
(function() {
|
|
var u="https://.../";
|
|
_paq.push(['setTrackerUrl', u+'matomo.php']);
|
|
_paq.push(['setSiteId', '112']);
|
|
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
|
g.type='text/javascript'; g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
|
|
})();
|
|
</script>
|
|
<!-- End Matomo Code -->'''
|
|
resp = resp.form.submit().follow()
|
|
assert resp.text.find('Manual configuration.') != -1
|
|
assert re.search('<textarea.* name="tracking_js"', resp.text)
|
|
assert resp.text.find('enableLinkTracking') != -1
|
|
assert resp.text.find('<button class="submit-button">Save</button>') != -1
|
|
assert resp.text.find('Good respect of user rights') != -1
|
|
|
|
|
|
def test_available_options(app, admin_user):
|
|
"""check available buttons (manual/automatic configurations)"""
|
|
login(app)
|
|
|
|
with override_settings(MATOMO_SERVER=CONFIG):
|
|
resp = app.get('/visits-tracking/', status=200)
|
|
assert str(resp).find('href="/visits-tracking/enable-manual"') != -1
|
|
assert str(resp).find('href="/visits-tracking/enable-auto"') != -1
|
|
|
|
# without configuration: no automatic configuration available
|
|
resp = app.get('/visits-tracking/', status=200)
|
|
assert str(resp).find('href="/visits-tracking/enable-manual"') != -1
|
|
assert str(resp).find('href="/visits-tracking/enable-auto"') == -1
|
|
|
|
|
|
@mock.patch('requests.post')
|
|
def test_enable_auto(mocked_post, app, admin_user):
|
|
"""succesfull automatic scenario"""
|
|
Combo.objects.create(base_url='https://combo.dev.publik.love', template_name='portal-user')
|
|
Wcs.objects.create(base_url='https://wcs.dev.publik.love')
|
|
Fargo.objects.create(base_url='https://fargo.dev.publik.love')
|
|
login(app)
|
|
|
|
contents = [
|
|
GET_NO_SITE_FROM_URL,
|
|
ADD_SITE_SUCCESS,
|
|
ADD_SITE_ALIAS_URLS_SUCCESS,
|
|
DEL_UNKNOWN_USER,
|
|
MATOMO_SUCCESS,
|
|
JAVASCRIPT_TAG,
|
|
PING_SUCCESS,
|
|
]
|
|
|
|
mocked_post.side_effect = requests_post_mocked_replies(contents)
|
|
with override_settings(MATOMO_SERVER=CONFIG):
|
|
resp1 = app.get('/visits-tracking/enable-auto', status=200)
|
|
resp2 = resp1.form.submit()
|
|
|
|
# call utils.py::auto_configure_matomo()
|
|
resp3 = resp2.follow()
|
|
|
|
# expect the CNIL compliance message is displayed
|
|
assert resp3.text.find('Excellent respect of user rights') != -1
|
|
|
|
|
|
@mock.patch('requests.post')
|
|
def test_enable_auto_warning(mocked_post, app, admin_user):
|
|
"""succesfull automatic scenario having final ping failure"""
|
|
Combo.objects.create(base_url='https://combo.dev.publik.love', template_name='portal-user')
|
|
Wcs.objects.create(base_url='https://wcs.dev.publik.love')
|
|
Fargo.objects.create(base_url='https://fargo.dev.publik.love')
|
|
login(app)
|
|
|
|
contents = [
|
|
GET_NO_SITE_FROM_URL,
|
|
ADD_SITE_SUCCESS,
|
|
ADD_SITE_ALIAS_URLS_SUCCESS,
|
|
DEL_UNKNOWN_USER,
|
|
MATOMO_SUCCESS,
|
|
JAVASCRIPT_TAG,
|
|
PING_ERROR,
|
|
]
|
|
|
|
mocked_post.side_effect = requests_post_mocked_replies(contents)
|
|
with override_settings(MATOMO_SERVER=CONFIG):
|
|
resp1 = app.get('/visits-tracking/enable-auto', status=200)
|
|
resp2 = resp1.form.submit()
|
|
|
|
# call utils.py::auto_configure_matomo()
|
|
resp3 = resp2.follow()
|
|
|
|
# expect 'ping fails' warning
|
|
assert resp3.text.find('class="warning">ping: ping fails') != -1
|
|
|
|
# expect the CNIL compliance message is displayed
|
|
assert resp3.text.find('Excellent respect of user rights') != -1
|
|
|
|
|
|
@mock.patch('requests.post')
|
|
def test_enable_auto_error(mocked_post, app, admin_user):
|
|
"""error on automatic scenario"""
|
|
Combo.objects.create(base_url='https://combo.dev.publik.love', template_name='portal-user')
|
|
Wcs.objects.create(base_url='https://wcs.dev.publik.love')
|
|
Fargo.objects.create(base_url='https://fargo.dev.publik.love')
|
|
login(app)
|
|
|
|
contents = [
|
|
GET_NO_SITE_FROM_URL,
|
|
ADD_SITE_SUCCESS,
|
|
ADD_SITE_ALIAS_URLS_SUCCESS,
|
|
DEL_UNKNOWN_USER,
|
|
MATOMO_SUCCESS,
|
|
JAVASCRIPT_TAG_BAD_RESPONSE,
|
|
]
|
|
|
|
mocked_post.side_effect = requests_post_mocked_replies(contents)
|
|
with override_settings(MATOMO_SERVER=CONFIG):
|
|
resp1 = app.get('/visits-tracking/enable-auto', status=200)
|
|
resp2 = resp1.form.submit()
|
|
|
|
# call utils.py::auto_configure_matomo()
|
|
resp3 = resp2.follow()
|
|
|
|
# expect a Django error message is displayed
|
|
assert resp3.text.find('class="error">matomo: get_javascript_tag fails') != -1
|