0004-matomo-do-not-abort-if-simulated-first-tracking-visi.patch
hobo/matomo/utils.py | ||
---|---|---|
217 | 217 |
raise MatomoException('get_javascript_tag fails') |
218 | 218 |
return tag.text |
219 | 219 | |
220 |
def ping(self, id_site):
|
|
220 |
def create_fake_first_tracking_visit(self, id_site):
|
|
221 | 221 |
"""this function use a different matomo's webservice API""" |
222 | 222 |
url = "%s/matomo.php" % self.url_ws_base |
223 | 223 |
data = {'requests': ['?idsite=%s&action_name=ping&rec=1' % id_site]} |
... | ... | |
307 | 307 |
return 'warning' |
308 | 308 |
return 'success' |
309 | 309 | |
310 |
def auto_configure_matomo(): |
|
310 |
def auto_configure_matomo(matomo):
|
|
311 | 311 |
"""main function""" |
312 | 312 |
tenant_name, site_urls = get_tenant_name_and_public_urls() |
313 | 313 |
if tenant_name is None: |
314 | 314 |
raise MatomoException("no portal-user's url available") |
315 | 315 | |
316 | 316 |
# update matomo account |
317 |
matomo = MatomoWS() |
|
318 | 317 |
id_site = upgrade_site(matomo, tenant_name, site_urls) |
319 | 318 |
logme_url = upgrade_user(matomo, tenant_name, id_site) |
320 | 319 |
tracking_js = upgrade_javascript_tag(matomo, id_site) |
321 |
matomo.ping(id_site) |
|
322 | 320 | |
323 | 321 |
# save matomo's variables |
324 | 322 |
logme_url_var = get_variable('matomo_logme_url') |
325 | 323 |
logme_url_var.value = logme_url |
326 | 324 |
logme_url_var.save() |
327 | 325 |
put_tracking_js(tracking_js) |
328 |
return True |
|
326 |
return id_site |
hobo/matomo/views.py | ||
---|---|---|
92 | 92 |
success_url = reverse_lazy('matomo-home') |
93 | 93 | |
94 | 94 |
def form_valid(self, form): |
95 |
matomo = MatomoWS() |
|
95 | 96 |
try: |
96 |
auto_configure_matomo()
|
|
97 |
id_site = auto_configure_matomo(matomo)
|
|
97 | 98 |
except MatomoException as exc: |
98 |
messages.error(self.request, str(exc)) |
|
99 |
messages.error(self.request, 'matomo: '+str(exc)) |
|
100 |
else: |
|
101 |
try: |
|
102 |
matomo.create_fake_first_tracking_visit(id_site) |
|
103 |
except MatomoException as exc: |
|
104 |
messages.warning(self.request, 'ping: '+str(exc)) |
|
99 | 105 |
return super(EnableAutoView, self).form_valid(form) |
100 | 106 | |
101 | 107 |
enable_auto = EnableAutoView.as_view() |
tests/test_matomo_utils.py | ||
---|---|---|
175 | 175 | |
176 | 176 |
# response may be XML or JSON |
177 | 177 |
if content[0] == '{': |
178 |
response.json = mock.MagicMock(return_value = json.loads(content)) |
|
179 |
else: |
|
180 |
response._content = content |
|
178 |
response.json = mock.MagicMock(return_value=json.loads(content)) |
|
179 |
response._content = content |
|
181 | 180 | |
182 | 181 |
response.status_code = 200 |
183 | 182 |
responses.append(response) |
... | ... | |
462 | 461 |
javascript_tag = matomo.get_javascript_tag('42') |
463 | 462 | |
464 | 463 |
@mock.patch('requests.post') |
465 |
def test_ping(mocked_post):
|
|
466 |
"""webservice to simulate a first tracking call"""
|
|
464 |
def test_create_fake_first_tracking_visit(mocked_post):
|
|
465 |
"""webservice to create a fake first tracking call"""
|
|
467 | 466 |
with override_settings(MATOMO_SERVER=CONFIG): |
468 | 467 |
matomo = MatomoWS() |
469 | 468 |
response = Response() |
... | ... | |
473 | 472 |
content = PING_SUCCESS |
474 | 473 |
response.json = mock.MagicMock(return_value=json.loads(content)) |
475 | 474 |
mocked_post.return_value = response |
476 |
matomo.ping('42')
|
|
475 |
matomo.create_fake_first_tracking_visit('42')
|
|
477 | 476 |
assert True |
478 | 477 | |
479 | 478 |
# error |
... | ... | |
481 | 480 |
response.json = mock.MagicMock(return_value=json.loads(content)) |
482 | 481 |
mocked_post.return_value = response |
483 | 482 |
with pytest.raises(MatomoError, match='ping fails'): |
484 |
matomo.ping('42')
|
|
483 |
matomo.create_fake_first_tracking_visit('42')
|
|
485 | 484 | |
486 | 485 |
# failure (no status) |
487 | 486 |
content = PING_NOSTATUS_ERROR |
... | ... | |
489 | 488 |
mocked_post.return_value = response |
490 | 489 |
with pytest.raises(MatomoException, |
491 | 490 |
match='internal error on ping \(status expected\)'): |
492 |
matomo.ping('42')
|
|
491 |
matomo.create_fake_first_tracking_visit('42')
|
|
493 | 492 | |
494 | 493 |
# failure (no dict) |
495 | 494 |
content = PING_NODICT_ERROR |
... | ... | |
497 | 496 |
mocked_post.return_value = response |
498 | 497 |
with pytest.raises(MatomoException, |
499 | 498 |
match='internal error on ping \(dict expected\)'): |
500 |
matomo.ping('42')
|
|
499 |
matomo.create_fake_first_tracking_visit('42')
|
|
501 | 500 | |
502 | 501 |
# failure (no JSON) |
503 | 502 |
response.json = mock.MagicMock(side_effect=ValueError('not a JSON')) |
504 | 503 |
mocked_post.return_value = response |
505 | 504 |
with pytest.raises(MatomoException, |
506 | 505 |
match='internal error on ping \(JSON expected\)'): |
507 |
matomo.ping('42')
|
|
506 |
matomo.create_fake_first_tracking_visit('42')
|
|
508 | 507 | |
509 | 508 |
# failure (status 500) |
510 | 509 |
mocked_post.return_value.status_code = 500 |
511 | 510 |
with pytest.raises(MatomoException, match='unexpected status code: 500'): |
512 |
matomo.ping('42')
|
|
511 |
matomo.create_fake_first_tracking_visit('42')
|
|
513 | 512 | |
514 | 513 |
@mock.patch('requests.post') |
515 | 514 |
def test_upgrade_site(mocked_post): |
... | ... | |
662 | 661 |
DEL_UNKNOWN_USER, MATOMO_SUCCESS, |
663 | 662 |
JAVASCRIPT_TAG, PING_SUCCESS] |
664 | 663 |
mocked_post.side_effect = requests_post_mocked_replies(contents) |
665 |
assert auto_configure_matomo() is True |
|
664 |
matomo = MatomoWS() |
|
665 |
assert auto_configure_matomo(matomo) == '42' |
|
666 | 666 |
logme_url_var = get_variable('matomo_logme_url') |
667 | 667 |
assert logme_url_var.value != '' |
668 | 668 |
tracking_js_var = get_variable('visits_tracking_js') |
... | ... | |
677 | 677 | |
678 | 678 |
with override_settings(MATOMO_SERVER=CONFIG): |
679 | 679 |
with pytest.raises(MatomoException, match="no portal-user's url available"): |
680 |
auto_configure_matomo() |
|
680 |
matomo = MatomoWS() |
|
681 |
auto_configure_matomo(matomo) |
|
681 | 682 | |
682 | 683 |
@mock.patch('requests.post') |
683 | 684 |
def test_auto_configure_matomo_error(mocked_post): |
... | ... | |
694 | 695 |
JAVASCRIPT_TAG_BAD_RESPONSE] |
695 | 696 |
mocked_post.side_effect = requests_post_mocked_replies(contents) |
696 | 697 |
with pytest.raises(MatomoException, match="get_javascript_tag fails"): |
697 |
auto_configure_matomo() |
|
698 |
tracking_js_var = get_variable('visits_tracking_js') |
|
699 |
assert tracking_js_var.value == 'js_code' |
|
700 | ||
701 |
with override_settings(MATOMO_SERVER=CONFIG): |
|
702 |
contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS, |
|
703 |
DEL_UNKNOWN_USER, MATOMO_SUCCESS, |
|
704 |
JAVASCRIPT_TAG, PING_ERROR] |
|
705 |
mocked_post.side_effect = requests_post_mocked_replies(contents) |
|
706 |
with pytest.raises(MatomoError, match='ping fails'): |
|
707 |
auto_configure_matomo() |
|
698 |
matomo = MatomoWS() |
|
699 |
auto_configure_matomo(matomo) |
|
708 | 700 |
tracking_js_var = get_variable('visits_tracking_js') |
709 | 701 |
assert tracking_js_var.value == 'js_code' |
tests/test_matomo_views.py | ||
---|---|---|
64 | 64 |
""" |
65 | 65 | |
66 | 66 |
PING_SUCCESS = '{"status":"success","tracked":1,"invalid":0}' |
67 |
PING_ERROR = 'somethings else'
|
|
67 |
PING_ERROR = '{"status":"not success"}'
|
|
68 | 68 | |
69 | 69 |
def requests_post_mocked_replies(contents): |
70 | 70 |
"""buid an iterator for mock's side_effect parameter""" |
... | ... | |
74 | 74 | |
75 | 75 |
# response may be XML or JSON |
76 | 76 |
if content[0] == '{': |
77 |
response.json = mock.MagicMock(return_value = json.loads(content)) |
|
78 |
else: |
|
79 |
response._content = content |
|
77 |
response.json = mock.MagicMock(return_value=json.loads(content)) |
|
78 |
response._content = content |
|
80 | 79 | |
81 | 80 |
response.status_code = 200 |
82 | 81 |
responses.append(response) |
... | ... | |
174 | 173 | |
175 | 174 |
# call utils.py::auto_configure_matomo() |
176 | 175 |
resp3 = resp2.follow() |
177 |
print resp3.body |
|
178 | 176 | |
179 | 177 |
# expect the CNIL compliance message is displayed |
180 | 178 |
assert resp3.body.find('Excellent respect of user rights') != -1 |
181 | 179 | |
182 | 180 |
@mock.patch('requests.post') |
183 |
def test_enable_auto_failure(mocked_post, admin_user): |
|
181 |
def test_enable_auto_warning(mocked_post, admin_user): |
|
182 |
"""succesfull automatic scenario having final ping failure""" |
|
183 |
Combo.objects.create(base_url='https://combo.dev.publik.love', |
|
184 |
template_name='portal-user') |
|
185 |
Wcs.objects.create(base_url='https://wcs.dev.publik.love') |
|
186 |
Fargo.objects.create(base_url='https://fargo.dev.publik.love') |
|
187 | ||
188 |
contents = [GET_NO_SITE_FROM_URL, ADD_SITE_SUCCESS, |
|
189 |
DEL_UNKNOWN_USER, MATOMO_SUCCESS, |
|
190 |
JAVASCRIPT_TAG, PING_ERROR] |
|
191 | ||
192 |
mocked_post.side_effect = requests_post_mocked_replies(contents) |
|
193 |
with override_settings(MATOMO_SERVER=CONFIG): |
|
194 |
app = login(TestApp(application)) |
|
195 |
resp1 = app.get('/matomo/enable-auto', status=200) |
|
196 |
resp2 = resp1.form.submit() |
|
197 | ||
198 |
# call utils.py::auto_configure_matomo() |
|
199 |
resp3 = resp2.follow() |
|
200 | ||
201 |
# expect 'ping fails' warning |
|
202 |
assert resp3.body.find('class="warning">ping: ping fails') != -1 |
|
203 | ||
204 |
# expect the CNIL compliance message is displayed |
|
205 |
assert resp3.body.find('Excellent respect of user rights') != -1 |
|
206 | ||
207 |
@mock.patch('requests.post') |
|
208 |
def test_enable_auto_error(mocked_post, admin_user): |
|
184 | 209 |
"""error on automatic scenario""" |
185 | 210 |
Combo.objects.create(base_url='https://combo.dev.publik.love', |
186 | 211 |
template_name='portal-user') |
... | ... | |
201 | 226 |
resp3 = resp2.follow() |
202 | 227 | |
203 | 228 |
# expect a Django error message is displayed |
204 |
assert resp3.body.find('class="error">get_javascript_tag fails') != -1 |
|
229 |
assert resp3.body.find('class="error">matomo: get_javascript_tag fails') != -1 |
|
205 |
- |