| OLD | NEW | 
| (Empty) |  | 
 |    1 # This file is part of the Adblock Plus web scripts, | 
 |    2 # Copyright (C) 2017-present eyeo GmbH | 
 |    3 # | 
 |    4 # Adblock Plus is free software: you can redistribute it and/or modify | 
 |    5 # it under the terms of the GNU General Public License version 3 as | 
 |    6 # published by the Free Software Foundation. | 
 |    7 # | 
 |    8 # Adblock Plus is distributed in the hope that it will be useful, | 
 |    9 # but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |   10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
 |   11 # GNU General Public License for more details. | 
 |   12 # | 
 |   13 # You should have received a copy of the GNU General Public License | 
 |   14 # along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 
 |   15  | 
 |   16 import sys | 
 |   17 from urllib import urlencode | 
 |   18 from urllib2 import urlopen, HTTPError | 
 |   19  | 
 |   20 import pytest | 
 |   21 from wsgi_intercept import (urllib_intercept, add_wsgi_intercept, | 
 |   22                             remove_wsgi_intercept) | 
 |   23  | 
 |   24 # We are mocking the functions that use MySQLdb, so it is not needed. This | 
 |   25 # is to prevent the tests from crashing when they try to import it. | 
 |   26 sys.modules['MySQLdb'] = sys | 
 |   27 from sitescripts.reports.web.updateReport import handleRequest | 
 |   28  | 
 |   29 LOCAL_HOST = 'test.local' | 
 |   30 REMOTE_HOST = 'reports.adblockplus.org' | 
 |   31 PORT = 80 | 
 |   32 PLAINTEXT_GUID = '12345678-1234-1234-1234-123456789abc' | 
 |   33 UR_PATH = 'sitescripts.reports.web.updateReport.' | 
 |   34  | 
 |   35  | 
 |   36 def intercept_fn(environ, start_response): | 
 |   37     assert environ['SERVER_NAME'] == REMOTE_HOST | 
 |   38     assert PLAINTEXT_GUID in environ['PATH_INFO'] | 
 |   39     return 'Intercepted!' | 
 |   40  | 
 |   41  | 
 |   42 @pytest.fixture | 
 |   43 def response_for(): | 
 |   44     """Register two intercepts, and return responses for them.""" | 
 |   45     urllib_intercept.install_opener() | 
 |   46     add_wsgi_intercept(LOCAL_HOST, PORT, lambda: handleRequest) | 
 |   47     add_wsgi_intercept(REMOTE_HOST, 443, lambda: intercept_fn) | 
 |   48  | 
 |   49     def response_for(data): | 
 |   50         url = 'http://{}:{}'.format(LOCAL_HOST, PORT) | 
 |   51         response = urlopen(url, urlencode(data)) | 
 |   52         return response.code, response.read() | 
 |   53  | 
 |   54     yield response_for | 
 |   55     remove_wsgi_intercept() | 
 |   56  | 
 |   57  | 
 |   58 @pytest.fixture | 
 |   59 def form_data(): | 
 |   60     return { | 
 |   61         'email': 'jane_doe@example.com', | 
 |   62         'secret': '92b3e705f2abe74c20c1c5ea9abd9ba2', | 
 |   63         'guid': PLAINTEXT_GUID, | 
 |   64         'status': 'x' * 1025, | 
 |   65         'usefulness': 0, | 
 |   66         'notify': 'test NOTIFY', | 
 |   67         'message': 'test MESSAGE', | 
 |   68         'subject': 'test SUBJECT', | 
 |   69         'name': 'test NAME', | 
 |   70     } | 
 |   71  | 
 |   72  | 
 |   73 @pytest.mark.parametrize('field,message', [ | 
 |   74     (('guid', 'badGUID'), 'Invalid or missing report GUID'), | 
 |   75     (('secret', 'badSECRET'), 'Wrong secret value'), | 
 |   76 ]) | 
 |   77 def test_http_errs(field, message, response_for, form_data, mocker): | 
 |   78     mocker.patch(UR_PATH + 'getReport', new=lambda *args: {'usefulness': 1}) | 
 |   79     key, value = field | 
 |   80     form_data[key] = value | 
 |   81     with pytest.raises(HTTPError) as error: | 
 |   82         response_for(form_data) | 
 |   83  | 
 |   84     assert message in error.value.read() | 
 |   85  | 
 |   86  | 
 |   87 def test_success(response_for, form_data, mocker): | 
 |   88     # These methods are patched to avoid the need for a MySQL database | 
 |   89     mocker.patch(UR_PATH + 'getReport', new=lambda *args: {'usefulness': 1, | 
 |   90                  'email': 'jane_doe@example.com'}) | 
 |   91     sr_mock = mocker.patch(UR_PATH + 'saveReport') | 
 |   92     uuu_mock = mocker.patch(UR_PATH + 'updateUserUsefulness') | 
 |   93     sun_mock = mocker.patch(UR_PATH + 'sendUpdateNotification') | 
 |   94  | 
 |   95     assert response_for(form_data) == (200, '\nIntercepted!') | 
 |   96  | 
 |   97     assert sr_mock.call_count == 1 | 
 |   98     for key in ['usefulness', 'email']: | 
 |   99         assert key in sr_mock.call_args[0][1] | 
 |  100         assert sr_mock.call_args[0][1][key] == str(form_data[key]) | 
 |  101  | 
 |  102     assert '0' in uuu_mock.call_args[0] and 1 in uuu_mock.call_args[0] | 
 |  103  | 
 |  104     for key in ['email', 'status']: | 
 |  105         assert key in sun_mock.call_args[0][0] | 
 |  106     assert sun_mock.call_args[0][0]['email'] == form_data['email'] | 
 |  107  | 
 |  108     # These should not be equal, because updateReport.py strips characters | 
 |  109     # over 1024, and form_data['status'] has 1025. | 
 |  110     assert str(sr_mock.call_args[0][1]['status']) != form_data['status'] | 
 |  111     assert str(sun_mock.call_args[0][0]['status']) != form_data['status'] | 
 |  112  | 
 |  113  | 
 |  114 def test_get_report_error(response_for, form_data, mocker): | 
 |  115     mocker.patch(UR_PATH + 'getReport', new=lambda *args: None) | 
 |  116     with pytest.raises(HTTPError) as error: | 
 |  117         response_for(form_data) | 
 |  118  | 
 |  119     assert 'Report does not exist' in error.value.read() | 
| OLD | NEW |