890 lines
32 KiB
Python
890 lines
32 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
import json
|
|
|
|
import mock
|
|
import pytest
|
|
from django.test import override_settings
|
|
from django.utils.encoding import force_text
|
|
from requests import Response
|
|
|
|
from hobo.environment.models import Combo, Fargo, Hobo, Variable, Wcs
|
|
from hobo.matomo.utils import (
|
|
MatomoError,
|
|
MatomoException,
|
|
MatomoWS,
|
|
auto_configure_matomo,
|
|
compute_cnil_acknowledgment_level,
|
|
get_tenant_name_and_public_urls,
|
|
get_tracking_js,
|
|
get_variable,
|
|
get_variable_value,
|
|
put_tracking_js,
|
|
upgrade_javascript_tag,
|
|
upgrade_site,
|
|
upgrade_user,
|
|
)
|
|
|
|
pytestmark = pytest.mark.django_db
|
|
|
|
CONFIG = {
|
|
'URL': 'https://matomo.test',
|
|
'TOKEN_AUTH': '1234',
|
|
'EMAIL_TEMPLATE': 'noreply+%(user_login)s@entrouvert.test',
|
|
}
|
|
|
|
MATOMO_SUCCESS = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<result>
|
|
<success message="ok" />
|
|
</result>
|
|
"""
|
|
|
|
MATOMO_ERROR = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<result>
|
|
<error message="here is the error message" />
|
|
</result>
|
|
"""
|
|
|
|
MATOMO_BAD_RESPONSE_1 = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<result>
|
|
<success message="KO" />
|
|
</result>
|
|
"""
|
|
|
|
MATOMO_BAD_RESPONSE_2 = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<result>
|
|
<success>no message attribute</success>
|
|
<not_success>no success tag</not_success>
|
|
</result>
|
|
"""
|
|
|
|
GET_SITE_42_FROM_URL = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<result>
|
|
<row>
|
|
<idsite>42</idsite>
|
|
<moretags>...</moretags>
|
|
</row>
|
|
</result>
|
|
"""
|
|
|
|
GET_NO_SITE_FROM_URL = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<result />
|
|
"""
|
|
|
|
GET_SITE_BAD_QUERY = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<result>
|
|
<error message="Please specify a value for 'url'." />
|
|
</result>
|
|
"""
|
|
|
|
GET_SITE_BAD_RESPONSE = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<result>
|
|
<row>
|
|
<not_idsite>there is no idsite tag</not_idsite>
|
|
<moretags>...</moretags>
|
|
</row>
|
|
</result>
|
|
"""
|
|
|
|
ADD_SITE_SUCCESS = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<result>42</result>
|
|
"""
|
|
|
|
ADD_SITE_ERROR = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<result>
|
|
<error message="Please specify a value for 'siteName'." />
|
|
</result>
|
|
"""
|
|
|
|
ADD_SITE_BAD_RESPONSE = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<not_result>no result tag</not_result>
|
|
"""
|
|
|
|
ADD_SITE_ALIAS_URLS_SUCCESS = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<result>1</result>
|
|
"""
|
|
|
|
ADD_SITE_ALIAS_URLS_ERROR = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<result>
|
|
<error message="Please specify a value for 'idSite'." />
|
|
</result>
|
|
"""
|
|
|
|
USER_ALREADY_THERE = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<result>
|
|
<error message="Username 'hobo.dev.publik.love' already exists." />
|
|
</result>"""
|
|
|
|
MAIL_ALREADY_THERE = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<result>
|
|
<error message="User with email 'hobo.dev.publik.love@testor.org' already exists." />
|
|
</result>"""
|
|
|
|
BAD_CREDENTIAL = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<result>
|
|
<error message="You can\'t access this resource as it requires a \'superuser\' access." />
|
|
</result>"""
|
|
|
|
DEL_UNKNOWN_USER = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<result>
|
|
<error message="User 'hobo.dev.publik.love' doesn't exist." />
|
|
</result>
|
|
"""
|
|
|
|
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>
|
|
"""
|
|
|
|
ENHANCED_JAVASCRIPT_TAG = """// Matomo
|
|
var _paq = window._paq || [];
|
|
|
|
// disallow cookie's time extension
|
|
_paq.push([function() {
|
|
var self = this;
|
|
function getOriginalVisitorCookieTimeout() {
|
|
var now = new Date(),
|
|
nowTs = Math.round(now.getTime() / 1000),
|
|
visitorInfo = self.getVisitorInfo();
|
|
var createTs = parseInt(visitorInfo[2]);
|
|
var cookieTimeout = 33696000; // 13 months in seconds
|
|
var originalTimeout = createTs + cookieTimeout - nowTs;
|
|
return originalTimeout;
|
|
}
|
|
this.setVisitorCookieTimeout( getOriginalVisitorCookieTimeout() );
|
|
}]);
|
|
|
|
/* 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);
|
|
})();
|
|
// End Matomo Code
|
|
"""
|
|
|
|
JAVASCRIPT_TAG_BAD_RESPONSE = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<no_result_tag/>
|
|
"""
|
|
|
|
PING_SUCCESS = '{"status":"success","tracked":1,"invalid":0}'
|
|
PING_ERROR = '{"status":"not success"}'
|
|
PING_NOSTATUS_ERROR = '{}'
|
|
PING_NODICT_ERROR = '"json but not a dict"'
|
|
|
|
|
|
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_get_variable():
|
|
"""hobo variables from"""
|
|
|
|
# create the variable with '' value if not there
|
|
id_site_var = get_variable('name1')
|
|
assert id_site_var.value == ''
|
|
|
|
# retrieve the variable if already there
|
|
Variable.objects.create(name='name2', value='42')
|
|
id_site_var = get_variable('name2')
|
|
assert id_site_var.value == '42'
|
|
|
|
|
|
def test_get_variable_value():
|
|
"""hobo variables from DB"""
|
|
|
|
# variable not there: return default value
|
|
assert get_variable_value('name1') == ''
|
|
assert get_variable_value('name2', default='42') == '42'
|
|
|
|
# variable already there
|
|
get_variable('name3', '42')
|
|
assert get_variable_value('name3') == '42'
|
|
|
|
|
|
def test_get_tenant_name_and_public_urls():
|
|
Combo.objects.create(base_url='https://combo.dev.publik.love', template_name='...portal-user...')
|
|
Combo.objects.create(base_url='https://agent-combo.dev.publik.love', template_name='...portal-agent...')
|
|
Combo.objects.create(base_url='https://no-template-combo.dev.publik.love')
|
|
Wcs.objects.create(base_url='https://wcs.dev.publik.love')
|
|
Fargo.objects.create(base_url='https://fargo.dev.publik.love')
|
|
Hobo.objects.create(base_url='https://hobo.dev.publik.love')
|
|
tenant_name, site_urls = get_tenant_name_and_public_urls()
|
|
assert tenant_name == 'combo.dev.publik.love'
|
|
assert site_urls == [
|
|
'https://combo.dev.publik.love/',
|
|
'https://wcs.dev.publik.love/',
|
|
'https://fargo.dev.publik.love/',
|
|
]
|
|
|
|
|
|
def test_get_tenant_name_and_public_urls_on_primary():
|
|
Hobo.objects.create(base_url='https://hobo.ville1.love', slug='hobo-ville1')
|
|
Hobo.objects.create(base_url='https://hobo.ville2.love', slug='hobo-ville2')
|
|
Combo.objects.create(
|
|
base_url='https://combo.agglo.love', template_name='...portal-user...', slug='portal'
|
|
)
|
|
Combo.objects.create(
|
|
base_url='https://combo.ville1.love',
|
|
template_name='...portal-user...',
|
|
slug='_hobo-ville1_portal',
|
|
secondary=True,
|
|
)
|
|
Combo.objects.create(
|
|
base_url='https://combo.ville2.love',
|
|
template_name='...portal-user...',
|
|
slug='_hobo-ville2_portal',
|
|
secondary=True,
|
|
)
|
|
Combo.objects.create(
|
|
base_url='https://agent-combo.agglo.love', template_name='...portal-agent...', slug='portal-agent'
|
|
)
|
|
Combo.objects.create(
|
|
base_url='https://agent-combo.ville1.love',
|
|
template_name='...portal-agent...',
|
|
slug='_hobo-ville1_portal-agent',
|
|
secondary=True,
|
|
)
|
|
Combo.objects.create(
|
|
base_url='https://agent-combo.ville2.love',
|
|
template_name='...portal-agent...',
|
|
slug='_hobo-ville2_portal-agent',
|
|
secondary=True,
|
|
)
|
|
Wcs.objects.create(base_url='https://wcs.agglo.love', slug='eservices')
|
|
Wcs.objects.create(base_url='https://wcs.ville1.love', slug='_hobo-ville1_eservices', secondary=True)
|
|
Wcs.objects.create(base_url='https://wcs.ville2.love', slug='_hobo-ville2_eservices', secondary=True)
|
|
Fargo.objects.create(base_url='https://fargo.agglo.love', slug='porte-doc')
|
|
Fargo.objects.create(base_url='https://fargo.ville1.love', slug='_hobo-ville1_porte-doc', secondary=True)
|
|
Fargo.objects.create(base_url='https://fargo.ville2.love', slug='_hobo-ville2_porte-doc', secondary=True)
|
|
|
|
tenant_name, site_urls = get_tenant_name_and_public_urls()
|
|
assert tenant_name == 'combo.agglo.love'
|
|
assert site_urls == ['https://combo.agglo.love/', 'https://wcs.agglo.love/', 'https://fargo.agglo.love/']
|
|
|
|
|
|
def test_get_tenant_name_and_public_urls_on_secondary():
|
|
Hobo.objects.create(base_url='https://hobo.agglo.love', slug='_interco_hobo')
|
|
Hobo.objects.create(base_url='https://hobo.ville1.love', slug='_interco_hobo-ville1')
|
|
Hobo.objects.create(base_url='https://hobo.ville2.love', slug='_interco_hobo-ville2')
|
|
Combo.objects.create(
|
|
base_url='https://combo.agglo.love',
|
|
template_name='...portal-user...',
|
|
slug='_interco_portal',
|
|
secondary=True,
|
|
)
|
|
Combo.objects.create(
|
|
base_url='https://combo.ville2.love', template_name='...portal-user...', slug='portal'
|
|
)
|
|
Combo.objects.create(
|
|
base_url='https://agent-combo.agglo.love',
|
|
template_name='...portal-agent...',
|
|
slug='_interco_portal-agent',
|
|
secondary=True,
|
|
)
|
|
Combo.objects.create(
|
|
base_url='https://agent-combo.ville2.love', template_name='...portal-agent...', slug='portal-agent'
|
|
)
|
|
Wcs.objects.create(base_url='https://wcs.agglo.love', slug='_interco_eservices', secondary=True)
|
|
Wcs.objects.create(base_url='https://wcs.ville2.love', slug='eservices')
|
|
Fargo.objects.create(base_url='https://fargo.agglo.love', slug='_interco_porte-doc', secondary=True)
|
|
Fargo.objects.create(base_url='https://fargo.ville2.love', slug='porte-doc')
|
|
|
|
tenant_name, site_urls = get_tenant_name_and_public_urls()
|
|
assert tenant_name == 'combo.ville2.love'
|
|
assert site_urls == [
|
|
'https://combo.ville2.love/',
|
|
'https://wcs.ville2.love/',
|
|
'https://fargo.ville2.love/',
|
|
]
|
|
|
|
|
|
def test_matomo_constructor():
|
|
"""build the matomo webservice object"""
|
|
with override_settings(MATOMO_SERVER=CONFIG):
|
|
matomo = MatomoWS()
|
|
assert matomo.url_ws_base == 'https://matomo.test'
|
|
assert matomo.token_auth == '1234'
|
|
|
|
with override_settings(MATOMO_SERVER={}):
|
|
with pytest.raises(MatomoException, match="no settings for matomo: 'URL'"):
|
|
matomo = MatomoWS()
|
|
|
|
|
|
def test_parse_response():
|
|
"""parser used by all matomo webservice calls"""
|
|
with override_settings(MATOMO_SERVER=CONFIG):
|
|
matomo = MatomoWS()
|
|
|
|
# no error (expected format)
|
|
content = b"""<?xml version="1.0" encoding="utf-8" ?><ok/>"""
|
|
tree = matomo.parse_response(content)
|
|
assert tree.tag == 'ok'
|
|
|
|
# error (not XML format)
|
|
content = """this is not XML"""
|
|
with pytest.raises(MatomoException, match="XMLSyntaxError: Start tag expected"):
|
|
tree = matomo.parse_response(content)
|
|
|
|
|
|
def test_parse_error_message():
|
|
"""error handler used by all matomo webservice calls"""
|
|
with override_settings(MATOMO_SERVER=CONFIG):
|
|
matomo = MatomoWS()
|
|
|
|
# no error (expected format)
|
|
content = b"""<?xml version="1.0" encoding="utf-8" ?><ok/>"""
|
|
tree = matomo.parse_response(content)
|
|
matomo.raise_on_error(tree)
|
|
assert tree.tag == 'ok'
|
|
|
|
# error (expected format)
|
|
content = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<result>
|
|
<error message="here is the error message" />
|
|
</result>
|
|
"""
|
|
tree = matomo.parse_response(content)
|
|
with pytest.raises(MatomoError, match='here is the error message'):
|
|
matomo.raise_on_error(tree)
|
|
|
|
# error (unexpected format)
|
|
content = b"""<?xml version="1.0" encoding="utf-8" ?>
|
|
<result>
|
|
<error>no 'message' attribute here</error>
|
|
</result>
|
|
"""
|
|
tree = matomo.parse_response(content)
|
|
with pytest.raises(MatomoException, match='internal error'):
|
|
matomo.raise_on_error(tree)
|
|
|
|
|
|
def test_assert_success():
|
|
"""webservice to add new user"""
|
|
with override_settings(MATOMO_SERVER=CONFIG):
|
|
matomo = MatomoWS()
|
|
|
|
# success
|
|
tree = matomo.parse_response(MATOMO_SUCCESS)
|
|
matomo.raise_on_error(tree)
|
|
assert matomo.assert_success(tree, 'me') is True
|
|
|
|
# error (KO instead of ok)
|
|
tree = matomo.parse_response(MATOMO_BAD_RESPONSE_1)
|
|
matomo.raise_on_error(tree)
|
|
with pytest.raises(MatomoException, match='me fails'):
|
|
matomo.assert_success(tree, 'me')
|
|
|
|
# error (no message attribute)
|
|
tree = matomo.parse_response(MATOMO_BAD_RESPONSE_2)
|
|
matomo.raise_on_error(tree)
|
|
with pytest.raises(MatomoException, match='me fails'):
|
|
matomo.assert_success(tree, 'me')
|
|
|
|
|
|
@mock.patch('requests.post')
|
|
def test_call(mocked_post):
|
|
"""test status_code"""
|
|
with override_settings(MATOMO_SERVER=CONFIG):
|
|
matomo = MatomoWS()
|
|
|
|
# success (status 200)
|
|
content = MATOMO_SUCCESS
|
|
mocked_post.return_value.status_code = 200
|
|
mocked_post.return_value.content = content
|
|
matomo.call({})
|
|
|
|
# failure (status 500)
|
|
mocked_post.return_value.status_code = 500
|
|
with pytest.raises(MatomoException, match='unexpected status code: 500'):
|
|
matomo.call({})
|
|
|
|
|
|
@mock.patch('requests.post')
|
|
def test_get_site_from_site_url(mocked_post):
|
|
"""webservice to test if the site is already registered"""
|
|
mocked_post.return_value.status_code = 200
|
|
with override_settings(MATOMO_SERVER=CONFIG):
|
|
matomo = MatomoWS()
|
|
|
|
# site already here
|
|
content = GET_SITE_42_FROM_URL
|
|
mocked_post.return_value.content = content
|
|
assert matomo.get_site_id_from_site_url('combo.dev.publik.love') == '42'
|
|
|
|
# no such url
|
|
content = GET_NO_SITE_FROM_URL
|
|
mocked_post.return_value.content = content
|
|
with pytest.raises(MatomoError, match='url not found'):
|
|
matomo.get_site_id_from_site_url('combo.dev.publik.love')
|
|
|
|
# error on empty id
|
|
content = GET_SITE_BAD_QUERY
|
|
mocked_post.return_value.content = content
|
|
with pytest.raises(MatomoError, match="Please specify a value for 'url'."):
|
|
matomo.get_site_id_from_site_url('combo.dev.publik.love')
|
|
|
|
# bad response (error on success response)
|
|
content = GET_SITE_BAD_RESPONSE
|
|
mocked_post.return_value.content = content
|
|
with pytest.raises(MatomoException, match='get_site_id_from_site_url fails'):
|
|
matomo.get_site_id_from_site_url('combo.dev.publik.love')
|
|
|
|
|
|
@mock.patch('requests.post')
|
|
def test_add_site(mocked_post):
|
|
"""webservice to add a new site"""
|
|
mocked_post.return_value.status_code = 200
|
|
with override_settings(MATOMO_SERVER=CONFIG):
|
|
matomo = MatomoWS()
|
|
|
|
# success
|
|
content = ADD_SITE_SUCCESS
|
|
mocked_post.return_value.content = content
|
|
site_id = matomo.add_site("hobo.dev.publik.love")
|
|
assert site_id == '42'
|
|
|
|
# error
|
|
content = ADD_SITE_ERROR
|
|
mocked_post.return_value.content = content
|
|
with pytest.raises(MatomoError, match="Please specify a value for 'siteName'."):
|
|
site_id = matomo.add_site("hobo.dev.publik.love")
|
|
|
|
# strange message
|
|
content = ADD_SITE_BAD_RESPONSE
|
|
mocked_post.return_value.content = content
|
|
with pytest.raises(MatomoException, match='add_site fails'):
|
|
site_id = matomo.add_site("hobo.dev.publik.love")
|
|
|
|
|
|
@mock.patch('requests.post')
|
|
def test_add_site_alias_url(mocked_post):
|
|
"""webservice to add a new site"""
|
|
mocked_post.return_value.status_code = 200
|
|
urls = ['https://combo.dev.publik.love', 'https://wcs.dev.publik.love']
|
|
with override_settings(MATOMO_SERVER=CONFIG):
|
|
matomo = MatomoWS()
|
|
|
|
# success
|
|
content = ADD_SITE_ALIAS_URLS_SUCCESS
|
|
mocked_post.return_value.content = content
|
|
site_id = matomo.add_site_alias_urls('42', urls)
|
|
assert site_id == '1'
|
|
|
|
# error
|
|
content = ADD_SITE_ALIAS_URLS_ERROR
|
|
mocked_post.return_value.content = content
|
|
with pytest.raises(MatomoError, match="Please specify a value for 'idSite'."):
|
|
site_id = matomo.add_site_alias_urls(None, urls)
|
|
|
|
# strange message
|
|
content = ADD_SITE_BAD_RESPONSE
|
|
mocked_post.return_value.content = content
|
|
with pytest.raises(MatomoException, match='add_site_alias_urls fails'):
|
|
site_id = matomo.add_site_alias_urls('42', urls)
|
|
|
|
|
|
@mock.patch('requests.post')
|
|
def test_add_user(mocked_post):
|
|
"""webservice to add new user"""
|
|
mocked_post.return_value.status_code = 200
|
|
with override_settings(MATOMO_SERVER=CONFIG):
|
|
matomo = MatomoWS()
|
|
|
|
# success
|
|
content = MATOMO_SUCCESS
|
|
mocked_post.return_value.content = content
|
|
matomo.add_user('hobo.dev.publik.love', 'xxx', '42')
|
|
assert True
|
|
|
|
# error (user already here)
|
|
content = USER_ALREADY_THERE
|
|
mocked_post.return_value.content = content
|
|
with pytest.raises(MatomoError, match="Username 'hobo.dev.publik.love' already"):
|
|
matomo.add_user('hobo.dev.publik.love', 'xxx', '42')
|
|
|
|
# error (mail already registered)
|
|
content = MAIL_ALREADY_THERE
|
|
mocked_post.return_value.content = content
|
|
with pytest.raises(MatomoError, match="email 'hobo.dev.publik.love@testor.org'"):
|
|
matomo.add_user('hobo.dev.publik.love', 'xxx', '42')
|
|
|
|
# error (bad credentials)
|
|
content = BAD_CREDENTIAL
|
|
mocked_post.return_value.content = content
|
|
with pytest.raises(MatomoError, match="You can\'t access this resource"):
|
|
matomo.add_user('hobo.dev.publik.love', 'xxx', '42')
|
|
|
|
# bad success message (wrong attribute value)
|
|
content = MATOMO_BAD_RESPONSE_1
|
|
mocked_post.return_value.content = content
|
|
with pytest.raises(MatomoException, match='add_user fails'):
|
|
matomo.add_user('hobo.dev.publik.love', 'xxx', '42')
|
|
|
|
# bad success message (no message attribute)
|
|
content = MATOMO_BAD_RESPONSE_2
|
|
mocked_post.return_value.content = content
|
|
with pytest.raises(MatomoException, match='add_user fails'):
|
|
matomo.add_user('hobo.dev.publik.love', 'xxx', '42')
|
|
|
|
|
|
@mock.patch('requests.post')
|
|
def test_del_user(mocked_post):
|
|
"""webservice to del an existing user"""
|
|
mocked_post.return_value.status_code = 200
|
|
with override_settings(MATOMO_SERVER=CONFIG):
|
|
matomo = MatomoWS()
|
|
|
|
# success
|
|
content = MATOMO_SUCCESS
|
|
mocked_post.return_value.content = content
|
|
matomo.del_user('hobo.dev.publik.love')
|
|
assert True
|
|
|
|
# error (unknown user)
|
|
content = DEL_UNKNOWN_USER
|
|
mocked_post.return_value.content = content
|
|
with pytest.raises(MatomoError, match="User 'hobo.dev.publik.love' doesn't exist."):
|
|
matomo.del_user('hobo.dev.publik.love')
|
|
|
|
|
|
@mock.patch('requests.post')
|
|
def test_get_javascript_tag(mocked_post):
|
|
"""webservice to get matomo JS tag"""
|
|
mocked_post.return_value.status_code = 200
|
|
with override_settings(MATOMO_SERVER=CONFIG):
|
|
matomo = MatomoWS()
|
|
|
|
# success
|
|
content = JAVASCRIPT_TAG
|
|
mocked_post.return_value.content = content
|
|
javascript_tag = matomo.get_javascript_tag('42')
|
|
assert javascript_tag.find('(function() {') != -1
|
|
|
|
# error (bad credentials)
|
|
content = BAD_CREDENTIAL
|
|
mocked_post.return_value.content = content
|
|
with pytest.raises(MatomoError, match="You can't access this resource"):
|
|
javascript_tag = matomo.get_javascript_tag('42')
|
|
|
|
# bad response (no result tag)
|
|
content = JAVASCRIPT_TAG_BAD_RESPONSE
|
|
mocked_post.return_value.content = content
|
|
with pytest.raises(MatomoException, match='get_javascript_tag fails'):
|
|
javascript_tag = matomo.get_javascript_tag('42')
|
|
|
|
|
|
@mock.patch('requests.post')
|
|
def test_create_fake_first_tracking_visit(mocked_post):
|
|
"""webservice to create a fake first tracking call"""
|
|
with override_settings(MATOMO_SERVER=CONFIG):
|
|
matomo = MatomoWS()
|
|
response = Response()
|
|
response.status_code = 200
|
|
|
|
# success
|
|
content = PING_SUCCESS
|
|
response.json = mock.MagicMock(return_value=json.loads(content))
|
|
mocked_post.return_value = response
|
|
matomo.create_fake_first_tracking_visit('42')
|
|
assert True
|
|
|
|
# error
|
|
content = PING_ERROR
|
|
response.json = mock.MagicMock(return_value=json.loads(content))
|
|
mocked_post.return_value = response
|
|
with pytest.raises(MatomoError, match='ping fails'):
|
|
matomo.create_fake_first_tracking_visit('42')
|
|
|
|
# failure (no status)
|
|
content = PING_NOSTATUS_ERROR
|
|
response.json = mock.MagicMock(return_value=json.loads(content))
|
|
mocked_post.return_value = response
|
|
with pytest.raises(MatomoException, match='internal error on ping \(status expected\)'):
|
|
matomo.create_fake_first_tracking_visit('42')
|
|
|
|
# failure (no dict)
|
|
content = PING_NODICT_ERROR
|
|
response.json = mock.MagicMock(return_value=content)
|
|
mocked_post.return_value = response
|
|
with pytest.raises(MatomoException, match='internal error on ping \(dict expected\)'):
|
|
matomo.create_fake_first_tracking_visit('42')
|
|
|
|
# failure (no JSON)
|
|
response.json = mock.MagicMock(side_effect=ValueError('not a JSON'))
|
|
mocked_post.return_value = response
|
|
with pytest.raises(MatomoException, match='internal error on ping \(JSON expected\)'):
|
|
matomo.create_fake_first_tracking_visit('42')
|
|
|
|
# failure (status 500)
|
|
mocked_post.return_value.status_code = 500
|
|
with pytest.raises(MatomoException, match='unexpected status code: 500'):
|
|
matomo.create_fake_first_tracking_visit('42')
|
|
|
|
|
|
@mock.patch('requests.post')
|
|
def test_upgrade_site(mocked_post):
|
|
"""function to test if the site is already regisered"""
|
|
urls = ['https://combo.dev.publik.love', 'https://wcs.dev.publik.love']
|
|
with override_settings(MATOMO_SERVER=CONFIG):
|
|
matomo = MatomoWS()
|
|
|
|
# site not already here
|
|
contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS, ADD_SITE_ALIAS_URLS_SUCCESS]
|
|
mocked_post.side_effect = requests_post_mocked_replies(contents)
|
|
site_id = upgrade_site(matomo, "hobo.dev.publik.love", urls)
|
|
assert site_id == '42'
|
|
|
|
# site already here
|
|
contents = [GET_SITE_42_FROM_URL, ADD_SITE_ALIAS_URLS_SUCCESS]
|
|
mocked_post.side_effect = requests_post_mocked_replies(contents)
|
|
site_id = upgrade_site(matomo, "hobo.dev.publik.love", urls)
|
|
assert site_id == '42'
|
|
|
|
# error while updating urls
|
|
contents = [GET_SITE_42_FROM_URL, ADD_SITE_ALIAS_URLS_ERROR]
|
|
mocked_post.side_effect = requests_post_mocked_replies(contents)
|
|
with pytest.raises(MatomoException):
|
|
upgrade_site(matomo, "hobo.dev.publik.love", urls)
|
|
|
|
# error while adding new site
|
|
contents = [GET_NO_SITE_FROM_URL, MATOMO_ERROR]
|
|
mocked_post.side_effect = requests_post_mocked_replies(contents)
|
|
with pytest.raises(MatomoException):
|
|
upgrade_site(matomo, "hobo.dev.publik.love", urls)
|
|
|
|
# error while looking for site already there
|
|
contents = [MATOMO_ERROR]
|
|
mocked_post.side_effect = requests_post_mocked_replies(contents)
|
|
with pytest.raises(MatomoException, match='here is the error message'):
|
|
upgrade_site(matomo, "hobo.dev.publik.love", urls)
|
|
|
|
|
|
@mock.patch('requests.post')
|
|
def test_upgrade_user(mocked_post):
|
|
"""function to assert we have a user"""
|
|
with override_settings(MATOMO_SERVER=CONFIG):
|
|
matomo = MatomoWS()
|
|
|
|
# success (add a new user)
|
|
contents = [DEL_UNKNOWN_USER, MATOMO_SUCCESS]
|
|
mocked_post.side_effect = requests_post_mocked_replies(contents)
|
|
logme_url = upgrade_user(matomo, 'hobo.dev.publik.love', '42')
|
|
assert logme_url.find('action=logme&login=hobo.dev.publik.love') != -1
|
|
|
|
# success (user already here)
|
|
contents = [MATOMO_SUCCESS, MATOMO_SUCCESS]
|
|
mocked_post.side_effect = requests_post_mocked_replies(contents)
|
|
logme_url = upgrade_user(matomo, 'hobo.dev.publik.love', '42')
|
|
assert logme_url.find('action=logme&login=hobo.dev.publik.love') != -1
|
|
|
|
# recover on error (del user fails)
|
|
contents = [MATOMO_ERROR, MATOMO_SUCCESS]
|
|
mocked_post.side_effect = requests_post_mocked_replies(contents)
|
|
logme_url = upgrade_user(matomo, 'hobo.dev.publik.love', '42')
|
|
assert logme_url.find('action=logme&login=hobo.dev.publik.love') != -1
|
|
|
|
# error (add user fails)
|
|
contents = [MATOMO_SUCCESS, MATOMO_ERROR]
|
|
mocked_post.side_effect = requests_post_mocked_replies(contents)
|
|
with pytest.raises(MatomoError):
|
|
upgrade_user(matomo, 'hobo.dev.publik.love', '42')
|
|
|
|
|
|
def test_compute_cnil_acknowledgment_level():
|
|
"""function use to inspect javascript content"""
|
|
warning_content = force_text(JAVASCRIPT_TAG)
|
|
|
|
# can't find cookie's life time extension prevention
|
|
assert compute_cnil_acknowledgment_level(warning_content) == 'good'
|
|
|
|
# ok
|
|
success_content = warning_content + '\npaq.push(...) ...getOriginalVisitorCookieTimeout...'
|
|
assert compute_cnil_acknowledgment_level(success_content) == 'excellent'
|
|
|
|
# google reference found into javascript
|
|
error_content = success_content + '\n...google...'
|
|
assert compute_cnil_acknowledgment_level(error_content) == 'bad'
|
|
|
|
|
|
def test_get_tracking_js():
|
|
"""read previous tracking JS from hobo variables"""
|
|
var1 = get_variable('cnil_compliant_visits_tracking_js', 'content1')
|
|
assert get_tracking_js() == 'content1'
|
|
|
|
var1.delete()
|
|
var1 = get_variable('cnil_compliant_visits_tracking_js', '')
|
|
var2 = get_variable('visits_tracking_js', 'content2')
|
|
assert get_tracking_js() == 'content2'
|
|
|
|
var1.delete()
|
|
var2.delete()
|
|
get_variable('cnil_compliant_visits_tracking_js', 'content1')
|
|
get_variable('visits_tracking_js', 'content2')
|
|
assert get_tracking_js() == "content1content2"
|
|
|
|
|
|
def test_put_tracking_js():
|
|
"""write tracking js into hobo variables:
|
|
- visits_tracking_js: a banner will be displayed (javascript may be not removed)
|
|
- cnil_compliant_visits_tracking_js: javascript is dislayed normally
|
|
"""
|
|
# JS is stored into 'cnil_compliant_visits_tracking_js'
|
|
put_tracking_js('/* no gafa => no banner */')
|
|
value1 = get_variable_value('cnil_compliant_visits_tracking_js', 'undefined')
|
|
value2 = get_variable_value('visits_tracking_js', 'undefined')
|
|
assert value1 == '/* no gafa => no banner */'
|
|
assert value2 == 'undefined'
|
|
|
|
# JS is stord into 'visits_tracking_js'
|
|
put_tracking_js('/* google => banner */')
|
|
value1 = get_variable_value('cnil_compliant_visits_tracking_js', 'undefined')
|
|
value2 = get_variable_value('visits_tracking_js', 'undefined')
|
|
assert value1 == 'undefined'
|
|
assert value2 == '/* google => banner */'
|
|
|
|
# test we remove variables when no more used
|
|
put_tracking_js('')
|
|
value1 = get_variable_value('cnil_compliant_visits_tracking_js', 'undefined')
|
|
value2 = get_variable_value('visits_tracking_js', 'undefined')
|
|
assert value1 == 'undefined'
|
|
assert value2 == 'undefined'
|
|
|
|
|
|
@mock.patch('requests.post')
|
|
def test_upgrade_javascript_tag(mocked_post):
|
|
"""function to get matomo JS tag"""
|
|
mocked_post.return_value.status_code = 200
|
|
with override_settings(MATOMO_SERVER=CONFIG):
|
|
matomo = MatomoWS()
|
|
|
|
# success
|
|
content = JAVASCRIPT_TAG
|
|
mocked_post.return_value.content = content
|
|
javascript_tag = upgrade_javascript_tag(matomo, '42')
|
|
assert javascript_tag.find('(function() {') != -1
|
|
assert javascript_tag.find('<script') == -1
|
|
assert javascript_tag.find('script>') == -1
|
|
assert javascript_tag == ENHANCED_JAVASCRIPT_TAG
|
|
assert compute_cnil_acknowledgment_level(javascript_tag) == 'excellent'
|
|
|
|
|
|
@mock.patch('requests.post')
|
|
def test_auto_configure_matomo(mocked_post):
|
|
tracking_js_var = get_variable('visits_tracking_js', 'js_code')
|
|
logme_url_var = get_variable('matomo_logme_url', '')
|
|
|
|
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')
|
|
|
|
with override_settings(MATOMO_SERVER=CONFIG):
|
|
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)
|
|
matomo = MatomoWS()
|
|
assert auto_configure_matomo(matomo) == '42'
|
|
logme_url_var = get_variable('matomo_logme_url')
|
|
assert logme_url_var.value != ''
|
|
tracking_js_var = get_variable('visits_tracking_js')
|
|
assert tracking_js_var.value == ''
|
|
tracking_js2_var = get_variable('cnil_compliant_visits_tracking_js')
|
|
assert tracking_js2_var.value != ''
|
|
|
|
|
|
def test_auto_configure_matomo_no_url():
|
|
# no Combo url so as to raise
|
|
Wcs.objects.create(base_url='https://wcs.dev.publik.love')
|
|
Fargo.objects.create(base_url='https://fargo.dev.publik.love')
|
|
|
|
with override_settings(MATOMO_SERVER=CONFIG):
|
|
with pytest.raises(MatomoException, match="no portal-user's url available"):
|
|
matomo = MatomoWS()
|
|
auto_configure_matomo(matomo)
|
|
|
|
|
|
@mock.patch('requests.post')
|
|
def test_auto_configure_matomo_error(mocked_post):
|
|
tracking_js_var = get_variable('visits_tracking_js', 'js_code')
|
|
|
|
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')
|
|
|
|
with override_settings(MATOMO_SERVER=CONFIG):
|
|
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 pytest.raises(MatomoException, match="get_javascript_tag fails"):
|
|
matomo = MatomoWS()
|
|
auto_configure_matomo(matomo)
|
|
tracking_js_var = get_variable('visits_tracking_js')
|
|
assert tracking_js_var.value == 'js_code'
|
|
|
|
|
|
def test_legacy_email_template_substitution():
|
|
with override_settings(
|
|
MATOMO_SERVER={
|
|
'URL': 'https://matomo.test',
|
|
'TOKEN_AUTH': '1234',
|
|
'EMAIL_TEMPLATE': 'noreply+%s@example.net',
|
|
}
|
|
):
|
|
matomo = MatomoWS()
|
|
assert matomo.email_template == 'noreply+%(user_login)s@example.net'
|
|
|
|
|
|
def test_email_template_no_substitution():
|
|
with override_settings(
|
|
MATOMO_SERVER={
|
|
'URL': 'https://matomo.test',
|
|
'TOKEN_AUTH': '1234',
|
|
'EMAIL_TEMPLATE': 'noreply@example.net',
|
|
}
|
|
):
|
|
matomo = MatomoWS()
|
|
assert matomo.email_template == 'noreply@example.net'
|