0001-matomo-simulate-first-tracking-visit-32796.patch
hobo/matomo/utils.py | ||
---|---|---|
215 | 215 |
raise MatomoException('get_javascript_tag fails') |
216 | 216 |
return tag.text |
217 | 217 | |
218 |
def ping(self, id_site): |
|
219 |
"""this function use a different matomo's webservice API""" |
|
220 |
url = "%s/matomo.php" % self.url_ws_base |
|
221 |
data = {'requests': ['?idsite=%s&action_name=ping&rec=1' % id_site]} |
|
222 |
resp = requests.post(url, json=data) |
|
223 |
try: |
|
224 |
tree = resp.json() |
|
225 |
except ValueError: |
|
226 |
raise MatomoException( |
|
227 |
'internal error on ping (JSON expected): %s' % resp.content) |
|
228 |
if not isinstance(tree, dict): |
|
229 |
raise MatomoException( |
|
230 |
'internal error on ping (dict expected): %s' % resp.content) |
|
231 |
if 'status' not in tree: |
|
232 |
raise MatomoException( |
|
233 |
'internal error on ping (status expected): %s' % resp.content) |
|
234 |
if tree['status'] != 'success': |
|
235 |
raise MatomoError('ping fails: %s' % resp.content) |
|
236 |
return True |
|
237 | ||
238 | ||
218 | 239 |
def upgrade_site(matomo, tenant_name, site_urls): |
219 | 240 |
try: |
220 | 241 |
# tenant name match because it is the basename of one of registered urls |
... | ... | |
293 | 314 |
id_site = upgrade_site(matomo, tenant_name, site_urls) |
294 | 315 |
logme_url = upgrade_user(matomo, tenant_name, id_site) |
295 | 316 |
tracking_js = upgrade_javascript_tag(matomo, id_site) |
317 |
matomo.ping(id_site) |
|
296 | 318 | |
297 | 319 |
# save matomo's variables |
298 | 320 |
logme_url_var = get_variable('matomo_logme_url') |
tests/test_matomo_utils.py | ||
---|---|---|
1 | 1 |
# -*- coding: utf-8 -*- |
2 | 2 | |
3 |
import json |
|
3 | 4 |
import mock |
4 | 5 |
import pytest |
5 | 6 |
from requests import Response |
... | ... | |
161 | 162 |
<no_result_tag/> |
162 | 163 |
""" |
163 | 164 | |
165 |
PING_SUCCESS = '{"status":"success","tracked":1,"invalid":0}' |
|
166 |
PING_ERROR = '{"status":"not success"}' |
|
167 |
PING_NOSTATUS_ERROR = '{}' |
|
168 |
PING_NODICT_ERROR = '"json but not a dict"' |
|
169 | ||
164 | 170 |
def requests_post_mocked_replies(contents): |
165 | 171 |
"""buid an iterator for mock's side_effect parameter""" |
166 | 172 |
responses = [] |
167 | 173 |
for content in contents: |
168 | 174 |
response = Response() |
169 |
response._content = content |
|
175 | ||
176 |
# response may be XML or JSON |
|
177 |
if content[0] == '{': |
|
178 |
response.json = mock.MagicMock(return_value = json.loads(content)) |
|
179 |
else: |
|
180 |
response._content = content |
|
181 | ||
170 | 182 |
response.status_code = 200 |
171 | 183 |
responses.append(response) |
172 | 184 |
return responses |
... | ... | |
498 | 510 |
else: |
499 | 511 |
assert False |
500 | 512 | |
513 |
@mock.patch('requests.post') |
|
514 |
def test_ping(mocked_post): |
|
515 |
"""webservice to simulate a first tracking call""" |
|
516 |
with override_settings(MATOMO_SERVER=CONFIG): |
|
517 |
matomo = MatomoWS() |
|
518 |
response = Response() |
|
519 | ||
520 |
# success |
|
521 |
content = PING_SUCCESS |
|
522 |
response.json = mock.MagicMock(return_value=json.loads(content)) |
|
523 |
mocked_post.return_value = response |
|
524 |
matomo.ping('42') |
|
525 |
assert True |
|
526 | ||
527 |
# error |
|
528 |
content = PING_ERROR |
|
529 |
response.json = mock.MagicMock(return_value=json.loads(content)) |
|
530 |
mocked_post.return_value = response |
|
531 |
with pytest.raises(MatomoError, match='ping fails'): |
|
532 |
matomo.ping('42') |
|
533 | ||
534 |
# failure (no status) |
|
535 |
content = PING_NOSTATUS_ERROR |
|
536 |
response.json = mock.MagicMock(return_value=json.loads(content)) |
|
537 |
mocked_post.return_value = response |
|
538 |
with pytest.raises(MatomoException, |
|
539 |
match='internal error on ping \(status expected\)'): |
|
540 |
matomo.ping('42') |
|
541 | ||
542 |
# failure (no dict) |
|
543 |
content = PING_NODICT_ERROR |
|
544 |
response.json = mock.MagicMock(return_value=content) |
|
545 |
mocked_post.return_value = response |
|
546 |
with pytest.raises(MatomoException, |
|
547 |
match='internal error on ping \(dict expected\)'): |
|
548 |
matomo.ping('42') |
|
549 | ||
550 |
# failure (no JSON) |
|
551 |
response.json = mock.MagicMock(side_effect=ValueError('not a JSON')) |
|
552 |
mocked_post.return_value = response |
|
553 |
with pytest.raises(MatomoException, |
|
554 |
match='internal error on ping \(JSON expected\)'): |
|
555 |
matomo.ping('42') |
|
556 | ||
501 | 557 |
@mock.patch('requests.post') |
502 | 558 |
def test_upgrade_site(mocked_post): |
503 | 559 |
"""function to test if the site is already regisered""" |
... | ... | |
627 | 683 |
value1 = get_variable_value('cnil_compliant_visits_tracking_js', 'undefined') |
628 | 684 |
value2 = get_variable_value('visits_tracking_js', 'undefined') |
629 | 685 |
assert value1 == 'undefined' |
630 |
assert value2 == 'undefined'
|
|
686 |
assert value2 == 'undefined' |
|
631 | 687 | |
632 | 688 |
@mock.patch('requests.post') |
633 | 689 |
def test_upgrade_javascript_tag(mocked_post): |
... | ... | |
658 | 714 |
with override_settings(MATOMO_SERVER=CONFIG): |
659 | 715 |
contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS, |
660 | 716 |
DEL_UNKNOWN_USER, MATOMO_SUCCESS, |
661 |
JAVASCRIPT_TAG] |
|
717 |
JAVASCRIPT_TAG, PING_SUCCESS]
|
|
662 | 718 |
mocked_post.side_effect = requests_post_mocked_replies(contents) |
663 | 719 |
assert auto_configure_matomo() is True |
664 | 720 |
logme_url_var = get_variable('matomo_logme_url') |
... | ... | |
670 | 726 | |
671 | 727 |
@mock.patch('requests.post') |
672 | 728 |
def test_auto_configure_matomo_no_url(mocked_post): |
673 |
# no Wc url so as to raise
|
|
729 |
# no Combo url so as to raise
|
|
674 | 730 |
Wcs.objects.create(base_url='https://wcs.dev.publik.love') |
675 | 731 |
Fargo.objects.create(base_url='https://fargo.dev.publik.love') |
676 | 732 | |
... | ... | |
696 | 752 |
DEL_UNKNOWN_USER, MATOMO_SUCCESS, |
697 | 753 |
JAVASCRIPT_TAG_BAD_RESPONSE] |
698 | 754 |
mocked_post.side_effect = requests_post_mocked_replies(contents) |
699 |
try: |
|
755 |
with pytest.raises(MatomoException) as exc: |
|
756 |
auto_configure_matomo() |
|
757 |
assert "get_javascript_tag fails" in str(exc) |
|
758 |
tracking_js_var = get_variable('visits_tracking_js') |
|
759 |
assert tracking_js_var.value == 'js_code' |
|
760 | ||
761 |
with override_settings(MATOMO_SERVER=CONFIG): |
|
762 |
contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS, |
|
763 |
DEL_UNKNOWN_USER, MATOMO_SUCCESS, |
|
764 |
JAVASCRIPT_TAG, PING_ERROR] |
|
765 |
mocked_post.side_effect = requests_post_mocked_replies(contents) |
|
766 |
with pytest.raises(MatomoError, match='ping fails'): |
|
700 | 767 |
auto_configure_matomo() |
701 |
except MatomoException as exc: |
|
702 |
assert str(exc) == "get_javascript_tag fails" |
|
703 |
else: |
|
704 |
assert False |
|
705 | 768 |
tracking_js_var = get_variable('visits_tracking_js') |
706 | 769 |
assert tracking_js_var.value == 'js_code' |
tests/test_matomo_views.py | ||
---|---|---|
1 | 1 |
# -*- coding: utf-8 -*- |
2 | 2 | |
3 |
import json |
|
3 | 4 |
import mock |
4 | 5 |
import pytest |
5 | 6 |
import re |
... | ... | |
62 | 63 |
</result> |
63 | 64 |
""" |
64 | 65 | |
66 |
PING_SUCCESS = '{"status":"success","tracked":1,"invalid":0}' |
|
67 |
PING_ERROR = 'somethings else' |
|
68 | ||
69 |
def requests_post_mocked_replies(contents): |
|
70 |
"""buid an iterator for mock's side_effect parameter""" |
|
71 |
responses = [] |
|
72 |
for content in contents: |
|
73 |
response = Response() |
|
74 | ||
75 |
# response may be XML or JSON |
|
76 |
if content[0] == '{': |
|
77 |
response.json = mock.MagicMock(return_value = json.loads(content)) |
|
78 |
else: |
|
79 |
response._content = content |
|
80 | ||
81 |
response.status_code = 200 |
|
82 |
responses.append(response) |
|
83 |
return responses |
|
84 | ||
65 | 85 |
@pytest.fixture |
66 | 86 |
def admin_user(): |
67 | 87 |
try: |
... | ... | |
120 | 140 |
assert resp3.body.find('<button class="submit-button">Save</button>') != -1 |
121 | 141 |
assert resp3.body.find('Good respect of user rights') != -1 |
122 | 142 | |
123 |
def auto_conf_mocked_post(url, **kwargs): |
|
124 |
contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS, |
|
125 |
DEL_UNKNOWN_USER, MATOMO_SUCCESS, |
|
126 |
JAVASCRIPT_TAG] |
|
127 |
response = Response() |
|
128 |
response._content = contents[auto_conf_mocked_post.cpt] |
|
129 |
response.status_code = 200 |
|
130 | ||
131 |
auto_conf_mocked_post.cpt += 1 |
|
132 |
return response |
|
133 | ||
134 |
def auto_conf_failure_mocked_post(url, **kwargs): |
|
135 |
contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS, |
|
136 |
DEL_UNKNOWN_USER, MATOMO_SUCCESS, |
|
137 |
JAVASCRIPT_TAG_BAD_RESPONSE] |
|
138 |
response = Response() |
|
139 |
response._content = contents[auto_conf_mocked_post.cpt] |
|
140 |
response.status_code = 200 |
|
141 | ||
142 |
auto_conf_mocked_post.cpt += 1 |
|
143 |
return response |
|
144 | ||
145 | 143 |
def test_available_options(admin_user): |
146 | 144 |
"""check available buttons (manual/automatic configurations)""" |
147 | 145 |
with override_settings(MATOMO_SERVER=CONFIG): |
... | ... | |
156 | 154 |
assert str(resp).find('href="/matomo/enable-manual"') != -1 |
157 | 155 |
assert str(resp).find('href="/matomo/enable-auto"') == -1 |
158 | 156 | |
159 |
@mock.patch('requests.post', side_effect=auto_conf_mocked_post)
|
|
157 |
@mock.patch('requests.post') |
|
160 | 158 |
def test_enable_auto(mocked_post, admin_user): |
161 | 159 |
"""succesfull automatic scenario""" |
162 | 160 |
Combo.objects.create(base_url='https://combo.dev.publik.love', |
... | ... | |
164 | 162 |
Wcs.objects.create(base_url='https://wcs.dev.publik.love') |
165 | 163 |
Fargo.objects.create(base_url='https://fargo.dev.publik.love') |
166 | 164 | |
167 |
auto_conf_mocked_post.cpt = 0 |
|
165 |
contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS, |
|
166 |
DEL_UNKNOWN_USER, MATOMO_SUCCESS, |
|
167 |
JAVASCRIPT_TAG, PING_SUCCESS] |
|
168 | ||
169 |
mocked_post.side_effect = requests_post_mocked_replies(contents) |
|
168 | 170 |
with override_settings(MATOMO_SERVER=CONFIG): |
169 | 171 |
app = login(TestApp(application)) |
170 | 172 |
resp1 = app.get('/matomo/enable-auto', status=200) |
... | ... | |
177 | 179 |
# expect the CNIL compliance message is displayed |
178 | 180 |
assert resp3.body.find('Excellent respect of user rights') != -1 |
179 | 181 | |
180 | ||
181 |
@mock.patch('requests.post', side_effect=auto_conf_failure_mocked_post) |
|
182 |
@mock.patch('requests.post') |
|
182 | 183 |
def test_enable_auto_failure(mocked_post, admin_user): |
183 | 184 |
"""error on automatic scenario""" |
184 | 185 |
Combo.objects.create(base_url='https://combo.dev.publik.love', |
... | ... | |
186 | 187 |
Wcs.objects.create(base_url='https://wcs.dev.publik.love') |
187 | 188 |
Fargo.objects.create(base_url='https://fargo.dev.publik.love') |
188 | 189 | |
189 |
auto_conf_mocked_post.cpt = 0 |
|
190 |
contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS, |
|
191 |
DEL_UNKNOWN_USER, MATOMO_SUCCESS, |
|
192 |
JAVASCRIPT_TAG_BAD_RESPONSE] |
|
193 | ||
194 |
mocked_post.side_effect = requests_post_mocked_replies(contents) |
|
190 | 195 |
with override_settings(MATOMO_SERVER=CONFIG): |
191 | 196 |
app = login(TestApp(application)) |
192 | 197 |
resp1 = app.get('/matomo/enable-auto', status=200) |
193 |
- |