Projet

Général

Profil

0001-matomo-simulate-first-tracking-visit-32796.patch

Nicolas Roche, 07 mai 2019 10:06

Télécharger (11,8 ko)

Voir les différences:

Subject: [PATCH 1/4] matomo: simulate first tracking visit (#32796)

 hobo/matomo/utils.py       | 23 ++++++++++-
 tests/test_matomo_utils.py | 81 +++++++++++++++++++++++++++++++++-----
 tests/test_matomo_views.py | 59 ++++++++++++++-------------
 3 files changed, 126 insertions(+), 37 deletions(-)
hobo/matomo/utils.py
13 13
#
14 14
# You should have received a copy of the GNU Affero General Public License
15 15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16

  
17 16
import hashlib
18 17
import re
19 18
import requests
......
215 214
            raise MatomoException('get_javascript_tag fails')
216 215
        return tag.text
217 216

  
217
    def ping(self, id_site):
218
        """this function use a different matomo's webservice API"""
219
        url = "%s/matomo.php" % self.url_ws_base
220
        data = {'requests':['?idsite=%s&action_name=ping&rec=1' % id_site]}
221
        resp = requests.post(url, json=data)
222
        try:
223
            tree = resp.json()
224
        except ValueError:
225
            raise MatomoException(
226
                'internal error on ping (JSON expected): %s' % resp.content)
227
        if not isinstance(tree, dict):
228
            raise MatomoException(
229
                'internal error on ping (dict expected): %s' % resp.content)
230
        if 'status' not in tree:
231
            raise MatomoException(
232
                'internal error on ping (status expected): %s' % resp.content)
233
        if tree['status'] != 'success':
234
            raise MatomoError('ping fails: %s' % resp.content)
235
        return True
236

  
237

  
218 238
def upgrade_site(matomo, tenant_name, site_urls):
219 239
    try:
220 240
        # tenant name match because it is the basename of one of registered urls
......
293 313
    id_site = upgrade_site(matomo, tenant_name, site_urls)
294 314
    logme_url = upgrade_user(matomo, tenant_name, id_site)
295 315
    tracking_js = upgrade_javascript_tag(matomo, id_site)
316
    matomo.ping(id_site)
296 317

  
297 318
    # save matomo's variables
298 319
    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
-