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

Side by Side Diff: sitescripts/formmail/test/test_formmail2.py

Issue 29374647: Issue 4814 - Adds csv log to formmail2 (Closed) Base URL: https://hg.adblockplus.org/sitescripts
Patch Set: Created March 18, 2017, 4:13 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
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) 2006-2016 Eyeo GmbH 2 # Copyright (C) 2006-2016 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 from urllib import urlencode 16 from urllib import urlencode
16 from urllib2 import urlopen, HTTPError 17 from urllib2 import urlopen, HTTPError
18 from csv import DictReader
17 19
18 import pytest 20 import pytest
19 from wsgi_intercept import (urllib_intercept, add_wsgi_intercept, 21 from wsgi_intercept import (urllib_intercept, add_wsgi_intercept,
20 remove_wsgi_intercept) 22 remove_wsgi_intercept)
21 23
22 from sitescripts.formmail.web import formmail2 24 from sitescripts.formmail.web import formmail2
23 25
26 HOST = 'test.local'
27 LOG_PORT = 80
28 NO_LOG_PORT = 81
24 29
25 @pytest.fixture() 30
26 def form_config(): 31 @pytest.fixture
32 def log_path(tmpdir):
33 return str(tmpdir.join('test.csv_log'))
34
35
36 @pytest.fixture
37 def log_form_config():
27 return formmail2.conf_parse(formmail2.get_config_items())['test'] 38 return formmail2.conf_parse(formmail2.get_config_items())['test']
28 39
29 40
30 @pytest.fixture() 41 @pytest.fixture
31 def form_handler(form_config): 42 def form_config():
32 return formmail2.make_handler('test', form_config)[1] 43 config = formmail2.conf_parse(formmail2.get_config_items())['test']
44 del config['csv_log']
45 return config
46
47
48 @pytest.fixture
49 def form_handler(log_path, form_config, log_form_config):
50 """ Create two handlers, one that logs and another that doesn't """
51 log_form_config['csv_log'].value = log_path
52 return (formmail2.make_handler('test', log_form_config)[1],
53 formmail2.make_handler('test', form_config)[1])
33 54
34 55
35 # We make this a fixture instead of a constant so we can modify it in each 56 # We make this a fixture instead of a constant so we can modify it in each
36 # test as needed without affecting other tests. 57 # test as needed without affecting other tests.
37 @pytest.fixture 58 @pytest.fixture
38 def form_data(): 59 def form_data():
39 return { 60 return {
40 'email': 'john_doe@gmail.com', 61 'email': 'john_doe@gmail.com',
41 'mandatory': 'john_doe@gmail.com', 62 'mandatory': 'john_doe@gmail.com',
42 'non_mandatory_message': 'Once upon a time\nthere lived a king.', 63 'non_mandatory_message': 'Once upon a time\nthere lived a king.',
43 'non_mandatory_email': 'test@test.com' 64 'non_mandatory_email': 'test@test.com'
Vasily Kuznetsov 2017/03/21 14:00:34 I usually put the comma at the end of last item in
Jon Sonesen 2017/03/22 14:28:20 Done.
44 } 65 }
45 66
46 67
47 @pytest.fixture() 68 @pytest.fixture
48 def response_for(form_handler): 69 def response_for(form_handler):
49 host, port = 'test.local', 80 70 """ Registers two intercepts, returns responses for them based on bool """
50 urllib_intercept.install_opener() 71 urllib_intercept.install_opener()
51 add_wsgi_intercept(host, port, lambda: form_handler) 72 add_wsgi_intercept(HOST, LOG_PORT, lambda: form_handler[0])
52 url = 'http://{}:{}'.format(host, port) 73 add_wsgi_intercept(HOST, NO_LOG_PORT, lambda: form_handler[1])
53 74
54 def response_for(data): 75 def response_for(data, log=False):
76 url = 'http://{}:{}'.format(HOST, NO_LOG_PORT)
77 if log:
Vasily Kuznetsov 2017/03/21 14:00:34 I think this would be more readable as: if log:
Jon Sonesen 2017/03/22 14:28:20 Done.
78 url = 'http://{}:{}'.format(HOST, LOG_PORT)
55 if data is None: 79 if data is None:
56 response = urlopen(url) 80 response = urlopen(url)
57 else: 81 else:
58 response = urlopen(url, urlencode(data)) 82 response = urlopen(url, urlencode(data))
59 return response.code, response.read() 83 return response.code, response.read()
60 84
61 yield response_for 85 yield response_for
62 remove_wsgi_intercept() 86 remove_wsgi_intercept()
63 87
64 88
65 def test_form_handler_email_errors(form_config): 89 def test_form_handler_email_errors(form_config):
66 tmp_config = form_config 90 tmp_config = form_config
Vasily Kuznetsov 2017/03/21 14:00:34 What is the purpose of this assignment? Why don't
Jon Sonesen 2017/03/22 14:28:20 whoops. Done
67 del tmp_config['url'].value 91 del tmp_config['url'].value
68 with pytest.raises(Exception) as error: 92 with pytest.raises(Exception) as error:
69 formmail2.make_handler('test', tmp_config)[1] 93 formmail2.make_handler('test', tmp_config)[1]
70 assert error.value.message == 'No URL configured for form handler: test' 94 assert error.value.message == 'No URL configured for form handler: test'
71 95
72 96
73 def test_form_handler_field_errors(form_config): 97 def test_form_handler_field_errors(form_config):
74 tmp_config = form_config 98 tmp_config = form_config
75 tmp_config['fields'] = {} 99 tmp_config['fields'] = {}
76 with pytest.raises(Exception) as error: 100 with pytest.raises(Exception) as error:
(...skipping 23 matching lines...) Expand all
100 formmail2.make_handler('test', tmp_config)[1] 124 formmail2.make_handler('test', tmp_config)[1]
101 assert error.value.message == ('No template configured for form handler' 125 assert error.value.message == ('No template configured for form handler'
102 ': test') 126 ': test')
103 127
104 128
105 def test_config_parse(form_config): 129 def test_config_parse(form_config):
106 assert form_config['url'].value == 'test/apply/submit' 130 assert form_config['url'].value == 'test/apply/submit'
107 assert form_config['fields']['email'].value == 'mandatory, email' 131 assert form_config['fields']['email'].value == 'mandatory, email'
108 132
109 133
134 def test_sendmail_fail(log_path, response_for, form_data, mocker):
135 sm_mock = mocker.patch('sitescripts.formmail.web.formmail2.sendMail')
136 sm_mock.side_effect = Exception('Sendmail Fail')
137 with pytest.raises(HTTPError) as error:
138 response_for(form_data, log=True)
139 assert error.typename == 'HTTPError'
140
141 with open(log_path) as log_file:
142 row = DictReader(log_file).next()
143 assert 'time' in row
144
145
146 @pytest.mark.parametrize('log, res',
147 [(True, (200, '')), (False, (200, ''))])
148 def test_utf8_success(log, res, log_path, response_for, form_data, mocker):
149 """ DictWriter does not accpet utf-8, call log handler """
Vasily Kuznetsov 2017/03/21 14:00:34 typo in "accpet".
Jon Sonesen 2017/03/22 14:28:19 Done.
150 form_data['non_mandatory_message'] = '\xc3\xb6'
151 sm_mock = mocker.patch('sitescripts.formmail.web.formmail2.sendMail')
152 assert response_for(form_data, log) == res
153 assert sm_mock.call_count == 1
154 params = sm_mock.call_args[0][1]['fields']
155 assert set(params.keys()) == set(form_data.keys())
156 for key, value in form_data.items():
157 assert params[key] == value.decode('utf8')
158
159
110 def test_success(response_for, form_data, mocker): 160 def test_success(response_for, form_data, mocker):
111 sm_mock = mocker.patch('sitescripts.formmail.web.formmail2.sendMail') 161 sm_mock = mocker.patch('sitescripts.formmail.web.formmail2.sendMail')
Vasily Kuznetsov 2017/03/21 14:00:34 This and some following lines seem to be duplicate
Jon Sonesen 2017/03/22 14:28:20 The thing is that some of the test's have differen
112 assert response_for(form_data) == (200, '') 162 assert response_for(form_data) == (200, '')
113 assert sm_mock.call_count == 1 163 assert sm_mock.call_count == 1
114 params = sm_mock.call_args[0][1]['fields'] 164 params = sm_mock.call_args[0][1]['fields']
115 assert set(params.keys()) == set(form_data.keys()) 165 assert set(params.keys()) == set(form_data.keys())
116 for key, value in form_data.items(): 166 for key, value in form_data.items():
117 assert params[key] == value 167 assert params[key] == value
118 168
119 169
170 def test_log_success(log_path, response_for, form_data, mocker):
171 sm_mock = mocker.patch('sitescripts.formmail.web.formmail2.sendMail')
172 assert response_for(form_data, log=True) == (200, '')
173 assert sm_mock.call_count == 1
174 params = sm_mock.call_args[0][1]['fields']
175 assert set(params.keys()) == set(form_data.keys())
176 for key, value in form_data.items():
177 assert params[key] == value
178 with open(log_path) as log_file:
179 row = DictReader(log_file).next()
180 assert 'time' in row
181
182
183 def test_log_append_success(log_path, response_for, form_data, mocker):
184 sm_mock = mocker.patch('sitescripts.formmail.web.formmail2.sendMail')
185 assert response_for(form_data, log=True) == (200, '')
186 form_data['non_mandatory_message'] = ''
187 assert response_for(form_data, log=True) == (200, '')
188 assert sm_mock.call_count == 2
189 params = sm_mock.call_args[0][1]['fields']
190 assert set(params.keys()) == set(form_data.keys())
191 for key, value in form_data.items():
192 assert params[key] == value
193 with open(log_path) as log_file:
194 reader = DictReader(log_file)
195 row = reader.next()
196 assert row != reader.next()
197
198
120 def test_non_mandatory_no_msg(response_for, form_data, mocker): 199 def test_non_mandatory_no_msg(response_for, form_data, mocker):
121 mocker.patch('sitescripts.formmail.web.formmail2.sendMail') 200 mocker.patch('sitescripts.formmail.web.formmail2.sendMail')
122 form_data['non_mandatory'] = '' 201 form_data['non_mandatory_message'] = ''
123 assert response_for(form_data) == (200, '') 202 assert response_for(form_data) == (200, '')
124 203
125 204
126 def test_invalid_email_cstm_msg(response_for, form_data, mocker, form_config): 205 def test_invalid_email_cstm_msg(response_for, form_data, mocker, form_config):
127 mocker.patch('sitescripts.formmail.web.formmail2.sendMail') 206 mocker.patch('sitescripts.formmail.web.formmail2.sendMail')
128 form_data['email'] = 'bademail' 207 form_data['email'] = 'bademail'
129 with pytest.raises(HTTPError) as error: 208 with pytest.raises(HTTPError) as error:
130 response_for(form_data) 209 response_for(form_data)
131 assert error.value.read() == 'You failed the email validation' 210 assert error.value.read() == 'You failed the email validation'
132 211
133 212
134 def test_valid_nan_mandatory_email(response_for, form_data, mocker): 213 def test_valid_nan_mandatory_email(response_for, form_data, mocker):
Vasily Kuznetsov 2017/03/21 14:00:34 ...non_mandatory...? :)
Jon Sonesen 2017/03/22 14:28:20 Done.
135 mocker.patch('sitescripts.formmail.web.formmail2.sendMail') 214 mocker.patch('sitescripts.formmail.web.formmail2.sendMail')
136 form_data['non_mandatory_email'] = 'asfaf' 215 form_data['non_mandatory_email'] = 'asfaf'
137 with pytest.raises(HTTPError) as error: 216 with pytest.raises(HTTPError) as error:
138 response_for(form_data) 217 response_for(form_data)
139 assert error.value.read() == 'Invalid email' 218 assert error.value.read() == 'Invalid email'
140 219
141 del form_data['non_mandatory_email'] 220 del form_data['non_mandatory_email']
142 assert response_for(form_data) == (200, '') 221 assert response_for(form_data) == (200, '')
143 222
144 223
145 def test_mandatory_fail_dflt_msg(response_for, form_data, mocker): 224 def test_mandatory_fail_dflt_msg(response_for, form_data, mocker):
146 mocker.patch('sitescripts.formmail.web.formmail2.sendMail') 225 mocker.patch('sitescripts.formmail.web.formmail2.sendMail')
147 del form_data['mandatory'] 226 del form_data['mandatory']
148 with pytest.raises(HTTPError) as error: 227 with pytest.raises(HTTPError) as error:
149 response_for(form_data) 228 response_for(form_data)
150 assert error.value.read() == 'No mandatory entered' 229 assert error.value.read() == 'No mandatory entered'
230
231
232 def test_field_err(form_config, form_data, log_path):
233 """ Submits a form that does not have the dame fields as previous submission s
Vasily Kuznetsov 2017/03/21 14:00:35 typo in "dame"?
Jon Sonesen 2017/03/22 14:28:20 Done.
234
Vasily Kuznetsov 2017/03/21 14:00:34 Here you're continuing the same sentence in the li
Jon Sonesen 2017/03/22 14:28:20 Done.
235 that have the same form name, asserts that proper message is returned and
236 the row was properly written
237 """
238 formmail2.log_formdata(form_data, log_path)
239 del(form_config['fields']['email'])
240 del(form_data['email'])
241 try:
242 formmail2.log_formdata(form_data, log_path)
243 except Exception as e:
244 assert e.message == ('Field names have changed, error log '
245 'written to {}_error').format(log_path)
246
247 with open(log_path+'_error') as error_log:
248 assert DictReader(error_log).next() == form_data
249
250
251 def test_append_field_err(form_config, form_data, log_path):
252 """ Submits two identical forms that do not match the previous fields
253
254 found in the log file, triggering two rows to be added to the error
255 log and asserting the proper message is returned and that the rows
256 were written as expected
257 """
258 formmail2.log_formdata(form_data, log_path)
259 del(form_config['fields']['email'])
260 del(form_data['email'])
261 try:
262 formmail2.log_formdata(form_data, log_path)
263 except Exception:
264 pass
265 try:
266 formmail2.log_formdata(form_data, log_path)
267 except Exception as e:
268 assert e.message == ('Field names have changed, error log'
269 ' appended to {}_error').format(log_path)
270
271 with open(log_path+'_error') as error_log:
272 reader = DictReader(error_log)
273 # two identical rows should be in the error log
274 assert reader.next() == form_data
275 assert reader.next() == form_data
OLDNEW

Powered by Google App Engine
This is Rietveld