matomo: simulate first tracking visit (#32796)

This commit is contained in:
Nicolas Roche 2019-05-05 23:49:10 +02:00 committed by Nicolas ROCHE
parent a8670a2197
commit 3dcdf9552a
3 changed files with 126 additions and 36 deletions

View File

@ -215,6 +215,27 @@ class MatomoWS(object):
raise MatomoException('get_javascript_tag fails')
return tag.text
def ping(self, id_site):
"""this function use a different matomo's webservice API"""
url = "%s/matomo.php" % self.url_ws_base
data = {'requests': ['?idsite=%s&action_name=ping&rec=1' % id_site]}
resp = requests.post(url, json=data)
try:
tree = resp.json()
except ValueError:
raise MatomoException(
'internal error on ping (JSON expected): %s' % resp.content)
if not isinstance(tree, dict):
raise MatomoException(
'internal error on ping (dict expected): %s' % resp.content)
if 'status' not in tree:
raise MatomoException(
'internal error on ping (status expected): %s' % resp.content)
if tree['status'] != 'success':
raise MatomoError('ping fails: %s' % resp.content)
return True
def upgrade_site(matomo, tenant_name, site_urls):
try:
# tenant name match because it is the basename of one of registered urls
@ -293,6 +314,7 @@ def auto_configure_matomo():
id_site = upgrade_site(matomo, tenant_name, site_urls)
logme_url = upgrade_user(matomo, tenant_name, id_site)
tracking_js = upgrade_javascript_tag(matomo, id_site)
matomo.ping(id_site)
# save matomo's variables
logme_url_var = get_variable('matomo_logme_url')

View File

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
import json
import mock
import pytest
from requests import Response
@ -161,12 +162,23 @@ JAVASCRIPT_TAG_BAD_RESPONSE = """<?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._content = content
# response may be XML or JSON
if content[0] == '{':
response.json = mock.MagicMock(return_value = json.loads(content))
else:
response._content = content
response.status_code = 200
responses.append(response)
return responses
@ -498,6 +510,50 @@ def test_get_javascript_tag(mocked_post):
else:
assert False
@mock.patch('requests.post')
def test_ping(mocked_post):
"""webservice to simulate a first tracking call"""
with override_settings(MATOMO_SERVER=CONFIG):
matomo = MatomoWS()
response = Response()
# success
content = PING_SUCCESS
response.json = mock.MagicMock(return_value=json.loads(content))
mocked_post.return_value = response
matomo.ping('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.ping('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.ping('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.ping('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.ping('42')
@mock.patch('requests.post')
def test_upgrade_site(mocked_post):
"""function to test if the site is already regisered"""
@ -627,7 +683,7 @@ def test_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'
assert value2 == 'undefined'
@mock.patch('requests.post')
def test_upgrade_javascript_tag(mocked_post):
@ -658,7 +714,7 @@ def test_auto_configure_matomo(mocked_post):
with override_settings(MATOMO_SERVER=CONFIG):
contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS,
DEL_UNKNOWN_USER, MATOMO_SUCCESS,
JAVASCRIPT_TAG]
JAVASCRIPT_TAG, PING_SUCCESS]
mocked_post.side_effect = requests_post_mocked_replies(contents)
assert auto_configure_matomo() is True
logme_url_var = get_variable('matomo_logme_url')
@ -670,7 +726,7 @@ def test_auto_configure_matomo(mocked_post):
@mock.patch('requests.post')
def test_auto_configure_matomo_no_url(mocked_post):
# no Wc url so as to raise
# 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')
@ -696,11 +752,18 @@ def test_auto_configure_matomo_error(mocked_post):
DEL_UNKNOWN_USER, MATOMO_SUCCESS,
JAVASCRIPT_TAG_BAD_RESPONSE]
mocked_post.side_effect = requests_post_mocked_replies(contents)
try:
with pytest.raises(MatomoException) as exc:
auto_configure_matomo()
assert "get_javascript_tag fails" in str(exc)
tracking_js_var = get_variable('visits_tracking_js')
assert tracking_js_var.value == 'js_code'
with override_settings(MATOMO_SERVER=CONFIG):
contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS,
DEL_UNKNOWN_USER, MATOMO_SUCCESS,
JAVASCRIPT_TAG, PING_ERROR]
mocked_post.side_effect = requests_post_mocked_replies(contents)
with pytest.raises(MatomoError, match='ping fails'):
auto_configure_matomo()
except MatomoException as exc:
assert str(exc) == "get_javascript_tag fails"
else:
assert False
tracking_js_var = get_variable('visits_tracking_js')
assert tracking_js_var.value == 'js_code'

View File

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
import json
import mock
import pytest
import re
@ -62,6 +63,25 @@ JAVASCRIPT_TAG = """<?xml version="1.0" encoding="utf-8" ?>
</result>
"""
PING_SUCCESS = '{"status":"success","tracked":1,"invalid":0}'
PING_ERROR = 'somethings else'
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))
else:
response._content = content
response.status_code = 200
responses.append(response)
return responses
@pytest.fixture
def admin_user():
try:
@ -120,28 +140,6 @@ def test_enable_manual(admin_user):
assert resp3.body.find('<button class="submit-button">Save</button>') != -1
assert resp3.body.find('Good respect of user rights') != -1
def auto_conf_mocked_post(url, **kwargs):
contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS,
DEL_UNKNOWN_USER, MATOMO_SUCCESS,
JAVASCRIPT_TAG]
response = Response()
response._content = contents[auto_conf_mocked_post.cpt]
response.status_code = 200
auto_conf_mocked_post.cpt += 1
return response
def auto_conf_failure_mocked_post(url, **kwargs):
contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS,
DEL_UNKNOWN_USER, MATOMO_SUCCESS,
JAVASCRIPT_TAG_BAD_RESPONSE]
response = Response()
response._content = contents[auto_conf_mocked_post.cpt]
response.status_code = 200
auto_conf_mocked_post.cpt += 1
return response
def test_available_options(admin_user):
"""check available buttons (manual/automatic configurations)"""
with override_settings(MATOMO_SERVER=CONFIG):
@ -156,7 +154,7 @@ def test_available_options(admin_user):
assert str(resp).find('href="/matomo/enable-manual"') != -1
assert str(resp).find('href="/matomo/enable-auto"') == -1
@mock.patch('requests.post', side_effect=auto_conf_mocked_post)
@mock.patch('requests.post')
def test_enable_auto(mocked_post, admin_user):
"""succesfull automatic scenario"""
Combo.objects.create(base_url='https://combo.dev.publik.love',
@ -164,7 +162,11 @@ def test_enable_auto(mocked_post, admin_user):
Wcs.objects.create(base_url='https://wcs.dev.publik.love')
Fargo.objects.create(base_url='https://fargo.dev.publik.love')
auto_conf_mocked_post.cpt = 0
contents = [GET_NO_SITE_FROM_URL, ADD_SITE_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):
app = login(TestApp(application))
resp1 = app.get('/matomo/enable-auto', status=200)
@ -177,8 +179,7 @@ def test_enable_auto(mocked_post, admin_user):
# expect the CNIL compliance message is displayed
assert resp3.body.find('Excellent respect of user rights') != -1
@mock.patch('requests.post', side_effect=auto_conf_failure_mocked_post)
@mock.patch('requests.post')
def test_enable_auto_failure(mocked_post, admin_user):
"""error on automatic scenario"""
Combo.objects.create(base_url='https://combo.dev.publik.love',
@ -186,7 +187,11 @@ def test_enable_auto_failure(mocked_post, admin_user):
Wcs.objects.create(base_url='https://wcs.dev.publik.love')
Fargo.objects.create(base_url='https://fargo.dev.publik.love')
auto_conf_mocked_post.cpt = 0
contents = [GET_NO_SITE_FROM_URL, ADD_SITE_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):
app = login(TestApp(application))
resp1 = app.get('/matomo/enable-auto', status=200)