Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: sitescripts/reports/tests/test_updateReport.py

Issue 29993614: Issue 2267 - Unify form handling by reusing form_handler() (Closed) Base URL: https://hg.adblockplus.org/sitescripts/
Left Patch Set: Add mocker patches Created Feb. 5, 2019, 5 a.m.
Right Patch Set: Remove unnecessary checks Created Feb. 8, 2019, 1:32 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | sitescripts/reports/web/updateReport.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 # This file is part of the Adblock Plus web scripts, 1 # This file is part of the Adblock Plus web scripts,
2 # Copyright (C) 2017-present eyeo GmbH 2 # Copyright (C) 2017-present eyeo GmbH
3 # 3 #
4 # Adblock Plus is free software: you can redistribute it and/or modify 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 5 # it under the terms of the GNU General Public License version 3 as
6 # published by the Free Software Foundation. 6 # published by the Free Software Foundation.
7 # 7 #
8 # Adblock Plus is distributed in the hope that it will be useful, 8 # Adblock Plus is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details. 11 # GNU General Public License for more details.
12 # 12 #
13 # You should have received a copy of the GNU General Public License 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/>. 14 # along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
15 15
16 import sys 16 import sys
17 from urllib import urlencode 17 from urllib import urlencode
18 from urllib2 import urlopen, HTTPError 18 from urllib2 import urlopen, HTTPError
19 19
20 import pytest 20 import pytest
21 from wsgi_intercept import (urllib_intercept, add_wsgi_intercept, 21 from wsgi_intercept import (urllib_intercept, add_wsgi_intercept,
22 remove_wsgi_intercept) 22 remove_wsgi_intercept)
23 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.
24 sys.modules['MySQLdb'] = sys 26 sys.modules['MySQLdb'] = sys
Vasily Kuznetsov 2019/02/05 17:12:08 We should probably add a comment here explaining w
rhowell 2019/02/07 03:54:33 Done.
25 from sitescripts.reports.web.updateReport import handleRequest 27 from sitescripts.reports.web.updateReport import handleRequest
26 28
27 LOCAL_HOST = 'test.local' 29 LOCAL_HOST = 'test.local'
28 REMOTE_HOST = 'reports.adblockplus.org' 30 REMOTE_HOST = 'reports.adblockplus.org'
29 PORT = 80 31 PORT = 80
30 PLAINTEXT_GUID = '12345678-1234-1234-1234-123456789abc' 32 PLAINTEXT_GUID = '12345678-1234-1234-1234-123456789abc'
33 UR_PATH = 'sitescripts.reports.web.updateReport.'
31 34
32 35
33 def intercept_fn(environ, start_response): 36 def intercept_fn(environ, start_response):
34 assert environ['SERVER_NAME'] == REMOTE_HOST 37 assert environ['SERVER_NAME'] == REMOTE_HOST
35 assert PLAINTEXT_GUID in environ['PATH_INFO'] 38 assert PLAINTEXT_GUID in environ['PATH_INFO']
36 return 'Intercepted!' 39 return 'Intercepted!'
37 40
38 41
39 @pytest.fixture 42 @pytest.fixture
40 def response_for(): 43 def response_for():
41 """Register two intercepts, and return responses for them.""" 44 """Register two intercepts, and return responses for them."""
42 urllib_intercept.install_opener() 45 urllib_intercept.install_opener()
43 add_wsgi_intercept(LOCAL_HOST, PORT, lambda: handleRequest) 46 add_wsgi_intercept(LOCAL_HOST, PORT, lambda: handleRequest)
44 add_wsgi_intercept(REMOTE_HOST, 443, lambda: intercept_fn) 47 add_wsgi_intercept(REMOTE_HOST, 443, lambda: intercept_fn)
45 48
46 def response_for(data): 49 def response_for(data):
47 url = 'http://{}:{}'.format(LOCAL_HOST, PORT) 50 url = 'http://{}:{}'.format(LOCAL_HOST, PORT)
48 response = urlopen(url, urlencode(data)) 51 response = urlopen(url, urlencode(data))
49 return response.code, response.read() 52 return response.code, response.read()
50 53
51 yield response_for 54 yield response_for
52 remove_wsgi_intercept() 55 remove_wsgi_intercept()
53 56
54 57
55 @pytest.fixture 58 @pytest.fixture
56 def form_data(): 59 def form_data():
57 return { 60 return {
58 'email': 'john_doe@gmail.com', 61 'email': 'jane_doe@example.com',
59 'secret': '92b3e705f2abe74c20c1c5ea9abd9ba2', 62 'secret': '92b3e705f2abe74c20c1c5ea9abd9ba2',
60 'guid': PLAINTEXT_GUID, 63 'guid': PLAINTEXT_GUID,
61 'status': 'x' * 1025, 64 'status': 'x' * 1025,
62 'usefulness': 'test USEFULNESS', 65 'usefulness': 0,
63 'notify': 'test NOTIFY', 66 'notify': 'test NOTIFY',
64 'test_mode': True, 67 'message': 'test MESSAGE',
68 'subject': 'test SUBJECT',
69 'name': 'test NAME',
65 } 70 }
66 71
67 72
68 @pytest.mark.parametrize('field,message', [ 73 @pytest.mark.parametrize('field,message', [
69 (('guid', ''), 'Invalid or missing report GUID'), 74 (('guid', 'badGUID'), 'Invalid or missing report GUID'),
70 (('secret', ''), 'Wrong secret value'), 75 (('secret', 'badSECRET'), 'Wrong secret value'),
71 ]) 76 ])
72 def test_http_errs(field, message, response_for, form_data, mocker): 77 def test_http_errs(field, message, response_for, form_data, mocker):
73 mocker.patch('sitescripts.reports.web.updateReport.getReport', 78 mocker.patch(UR_PATH + 'getReport', new=lambda *args: {'usefulness': 1})
Vasily Kuznetsov 2019/02/05 17:12:08 This patch could be made into a fixture, since we
rhowell 2019/02/07 03:54:32 Each of the three calls to getReport return someth
Vasily Kuznetsov 2019/02/07 20:19:15 Yeah, you're right. Not worth it.
rhowell 2019/02/08 01:34:51 Acknowledged.
74 new=lambda *args: {'usefulness': 1})
75 key, value = field 79 key, value = field
76 form_data[key] = value 80 form_data[key] = value
77 with pytest.raises(HTTPError) as error: 81 with pytest.raises(HTTPError) as error:
78 response_for(form_data) 82 response_for(form_data)
79 83
80 assert message in error.value.read() 84 assert message in error.value.read()
81 85
82 86
83 def test_success(response_for, form_data, mocker): 87 def test_success(response_for, form_data, mocker):
84 # These methods are patched to avoid the need for a MySQL database 88 # These methods are patched to avoid the need for a MySQL database
85 mocker.patch('sitescripts.reports.web.updateReport.getReport', 89 mocker.patch(UR_PATH + 'getReport', new=lambda *args: {'usefulness': 1,
86 new=lambda *args: {'usefulness': 1, 'email': 'test@test.com'}) 90 'email': 'jane_doe@example.com'})
87 mocker.patch('sitescripts.reports.web.updateReport.saveReport', 91 sr_mock = mocker.patch(UR_PATH + 'saveReport')
Vasily Kuznetsov 2019/02/05 17:12:08 If you want a noop function, you actually don't ev
rhowell 2019/02/07 03:54:33 Ah, nice. Good idea.
88 new=lambda *args: None) 92 uuu_mock = mocker.patch(UR_PATH + 'updateUserUsefulness')
89 mocker.patch('sitescripts.reports.web.updateReport.updateUserUsefulness', 93 sun_mock = mocker.patch(UR_PATH + 'sendUpdateNotification')
90 new=lambda *args: None) 94
91 mocker.patch('sitescripts.reports.web.updateReport.sendUpdateNotification',
92 new=lambda *args: None)
93 assert response_for(form_data) == (200, '\nIntercepted!') 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']
94 112
95 113
96 def test_get_report_error(response_for, form_data, mocker): 114 def test_get_report_error(response_for, form_data, mocker):
97 mocker.patch('sitescripts.reports.web.updateReport.getReport', 115 mocker.patch(UR_PATH + 'getReport', new=lambda *args: None)
98 new=lambda *args: None)
rhowell 2019/02/07 03:54:33 For some reason, I get an error if I don't provide
Vasily Kuznetsov 2019/02/07 20:19:15 I tested it a bit and it seems that when we provid
rhowell 2019/02/08 01:34:51 Done.
99 with pytest.raises(HTTPError) as error: 116 with pytest.raises(HTTPError) as error:
100 response_for(form_data) 117 response_for(form_data)
101 118
102 assert 'Report does not exist' in error.value.read() 119 assert 'Report does not exist' in error.value.read()
LEFTRIGHT

Powered by Google App Engine
This is Rietveld