##// END OF EJS Templates
user-sessions: fixed tests and translation mechanism for user sessions.
marcink -
r1366:a2429da9 default
parent child Browse files
Show More
@@ -1,100 +1,100 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
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 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 import logging
22 22
23 23 from pylons import tmpl_context as c
24 24 from pyramid.view import view_config
25 25 from pyramid.httpexceptions import HTTPFound
26 26
27 27 from rhodecode.translation import _
28 28
29 29 from rhodecode.admin.views.base import AdminSettingsView
30 30 from rhodecode.lib.auth import (
31 31 LoginRequired, HasPermissionAllDecorator, CSRFRequired)
32 32 from rhodecode.lib.utils2 import safe_int
33 33 from rhodecode.lib import system_info
34 34 from rhodecode.lib import user_sessions
35 35
36 36
37 37 from rhodecode.admin.navigation import navigation_list
38 38
39 39
40 40 log = logging.getLogger(__name__)
41 41
42 42
43 43 class AdminSessionSettingsView(AdminSettingsView):
44 44
45 45 @LoginRequired()
46 46 @HasPermissionAllDecorator('hg.admin')
47 47 @view_config(
48 48 route_name='admin_settings_sessions', request_method='GET',
49 49 renderer='rhodecode:templates/admin/settings/settings.mako')
50 50 def settings_sessions(self):
51 51 c.active = 'sessions'
52 52 c.navlist = navigation_list(self.request)
53 53
54 54 c.cleanup_older_days = 60
55 55 older_than_seconds = 60 * 60 * 24 * c.cleanup_older_days
56 56
57 57 config = system_info.rhodecode_config().get_value()['value']['config']
58 58 c.session_model = user_sessions.get_session_handler(
59 59 config.get('beaker.session.type', 'memory'))(config)
60 60
61 61 c.session_conf = c.session_model.config
62 62 c.session_count = c.session_model.get_count()
63 63 c.session_expired_count = c.session_model.get_expired_count(
64 64 older_than_seconds)
65 65
66 66 return {}
67 67
68 68 @LoginRequired()
69 69 @CSRFRequired()
70 70 @HasPermissionAllDecorator('hg.admin')
71 71 @view_config(
72 72 route_name='admin_settings_sessions_cleanup', request_method='POST')
73 73 def settings_sessions_cleanup(self):
74
74 _ = self.request.translate
75 75 expire_days = safe_int(self.request.params.get('expire_days'))
76 76
77 77 if expire_days is None:
78 78 expire_days = 60
79 79
80 80 older_than_seconds = 60 * 60 * 24 * expire_days
81 81
82 82 config = system_info.rhodecode_config().get_value()['value']['config']
83 83 session_model = user_sessions.get_session_handler(
84 84 config.get('beaker.session.type', 'memory'))(config)
85 85
86 86 try:
87 87 session_model.clean_sessions(
88 88 older_than_seconds=older_than_seconds)
89 89 self.request.session.flash(
90 90 _('Cleaned up old sessions'), queue='success')
91 91 except user_sessions.CleanupCommand as msg:
92 92 self.request.session.flash(msg.message, queue='warning')
93 93 except Exception as e:
94 94 log.exception('Failed session cleanup')
95 95 self.request.session.flash(
96 96 _('Failed to cleanup up old sessions'), queue='error')
97 97
98 98 redirect_to = self.request.resource_path(
99 99 self.context, route_name='admin_settings_sessions')
100 100 return HTTPFound(redirect_to)
@@ -1,665 +1,665 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2010-2017 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
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 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 import mock
22 22 import pytest
23 23
24 24 import rhodecode
25 25 from rhodecode.config.routing import ADMIN_PREFIX
26 26 from rhodecode.lib.utils2 import md5
27 27 from rhodecode.model.db import RhodeCodeUi
28 28 from rhodecode.model.meta import Session
29 29 from rhodecode.model.settings import SettingsModel, IssueTrackerSettingsModel
30 30 from rhodecode.tests import url, assert_session_flash
31 31 from rhodecode.tests.utils import AssertResponse
32 32
33 33
34 34 UPDATE_DATA_QUALNAME = (
35 35 'rhodecode.admin.views.system_info.AdminSystemInfoSettingsView.get_update_data')
36 36
37 37
38 38 @pytest.mark.usefixtures('autologin_user', 'app')
39 39 class TestAdminSettingsController(object):
40 40
41 41 @pytest.mark.parametrize('urlname', [
42 42 'admin_settings_vcs',
43 43 'admin_settings_mapping',
44 44 'admin_settings_global',
45 45 'admin_settings_visual',
46 46 'admin_settings_email',
47 47 'admin_settings_hooks',
48 48 'admin_settings_search',
49 49 ])
50 50 def test_simple_get(self, urlname, app):
51 51 app.get(url(urlname))
52 52
53 53 def test_create_custom_hook(self, csrf_token):
54 54 response = self.app.post(
55 55 url('admin_settings_hooks'),
56 56 params={
57 57 'new_hook_ui_key': 'test_hooks_1',
58 58 'new_hook_ui_value': 'cd /tmp',
59 59 'csrf_token': csrf_token})
60 60
61 61 response = response.follow()
62 62 response.mustcontain('test_hooks_1')
63 63 response.mustcontain('cd /tmp')
64 64
65 65 def test_create_custom_hook_delete(self, csrf_token):
66 66 response = self.app.post(
67 67 url('admin_settings_hooks'),
68 68 params={
69 69 'new_hook_ui_key': 'test_hooks_2',
70 70 'new_hook_ui_value': 'cd /tmp2',
71 71 'csrf_token': csrf_token})
72 72
73 73 response = response.follow()
74 74 response.mustcontain('test_hooks_2')
75 75 response.mustcontain('cd /tmp2')
76 76
77 77 hook_id = SettingsModel().get_ui_by_key('test_hooks_2').ui_id
78 78
79 79 # delete
80 80 self.app.post(
81 81 url('admin_settings_hooks'),
82 82 params={'hook_id': hook_id, 'csrf_token': csrf_token})
83 83 response = self.app.get(url('admin_settings_hooks'))
84 84 response.mustcontain(no=['test_hooks_2'])
85 85 response.mustcontain(no=['cd /tmp2'])
86 86
87 87
88 88 @pytest.mark.usefixtures('autologin_user', 'app')
89 89 class TestAdminSettingsGlobal(object):
90 90
91 91 def test_pre_post_code_code_active(self, csrf_token):
92 92 pre_code = 'rc-pre-code-187652122'
93 93 post_code = 'rc-postcode-98165231'
94 94
95 95 response = self.post_and_verify_settings({
96 96 'rhodecode_pre_code': pre_code,
97 97 'rhodecode_post_code': post_code,
98 98 'csrf_token': csrf_token,
99 99 })
100 100
101 101 response = response.follow()
102 102 response.mustcontain(pre_code, post_code)
103 103
104 104 def test_pre_post_code_code_inactive(self, csrf_token):
105 105 pre_code = 'rc-pre-code-187652122'
106 106 post_code = 'rc-postcode-98165231'
107 107 response = self.post_and_verify_settings({
108 108 'rhodecode_pre_code': '',
109 109 'rhodecode_post_code': '',
110 110 'csrf_token': csrf_token,
111 111 })
112 112
113 113 response = response.follow()
114 114 response.mustcontain(no=[pre_code, post_code])
115 115
116 116 def test_captcha_activate(self, csrf_token):
117 117 self.post_and_verify_settings({
118 118 'rhodecode_captcha_private_key': '1234567890',
119 119 'rhodecode_captcha_public_key': '1234567890',
120 120 'csrf_token': csrf_token,
121 121 })
122 122
123 123 response = self.app.get(ADMIN_PREFIX + '/register')
124 124 response.mustcontain('captcha')
125 125
126 126 def test_captcha_deactivate(self, csrf_token):
127 127 self.post_and_verify_settings({
128 128 'rhodecode_captcha_private_key': '',
129 129 'rhodecode_captcha_public_key': '1234567890',
130 130 'csrf_token': csrf_token,
131 131 })
132 132
133 133 response = self.app.get(ADMIN_PREFIX + '/register')
134 134 response.mustcontain(no=['captcha'])
135 135
136 136 def test_title_change(self, csrf_token):
137 137 old_title = 'RhodeCode'
138 138 new_title = old_title + '_changed'
139 139
140 140 for new_title in ['Changed', 'Ε»Γ³Ε‚wik', old_title]:
141 141 response = self.post_and_verify_settings({
142 142 'rhodecode_title': new_title,
143 143 'csrf_token': csrf_token,
144 144 })
145 145
146 146 response = response.follow()
147 147 response.mustcontain(
148 148 """<div class="branding">- %s</div>""" % new_title)
149 149
150 150 def post_and_verify_settings(self, settings):
151 151 old_title = 'RhodeCode'
152 152 old_realm = 'RhodeCode authentication'
153 153 params = {
154 154 'rhodecode_title': old_title,
155 155 'rhodecode_realm': old_realm,
156 156 'rhodecode_pre_code': '',
157 157 'rhodecode_post_code': '',
158 158 'rhodecode_captcha_private_key': '',
159 159 'rhodecode_captcha_public_key': '',
160 160 'rhodecode_create_personal_repo_group': False,
161 161 'rhodecode_personal_repo_group_pattern': '${username}',
162 162 }
163 163 params.update(settings)
164 164 response = self.app.post(url('admin_settings_global'), params=params)
165 165
166 166 assert_session_flash(response, 'Updated application settings')
167 167 app_settings = SettingsModel().get_all_settings()
168 168 del settings['csrf_token']
169 169 for key, value in settings.iteritems():
170 170 assert app_settings[key] == value.decode('utf-8')
171 171
172 172 return response
173 173
174 174
175 175 @pytest.mark.usefixtures('autologin_user', 'app')
176 176 class TestAdminSettingsVcs(object):
177 177
178 178 def test_contains_svn_default_patterns(self, app):
179 179 response = app.get(url('admin_settings_vcs'))
180 180 expected_patterns = [
181 181 '/trunk',
182 182 '/branches/*',
183 183 '/tags/*',
184 184 ]
185 185 for pattern in expected_patterns:
186 186 response.mustcontain(pattern)
187 187
188 188 def test_add_new_svn_branch_and_tag_pattern(
189 189 self, app, backend_svn, form_defaults, disable_sql_cache,
190 190 csrf_token):
191 191 form_defaults.update({
192 192 'new_svn_branch': '/exp/branches/*',
193 193 'new_svn_tag': '/important_tags/*',
194 194 'csrf_token': csrf_token,
195 195 })
196 196
197 197 response = app.post(
198 198 url('admin_settings_vcs'), params=form_defaults, status=302)
199 199 response = response.follow()
200 200
201 201 # Expect to find the new values on the page
202 202 response.mustcontain('/exp/branches/*')
203 203 response.mustcontain('/important_tags/*')
204 204
205 205 # Expect that those patterns are used to match branches and tags now
206 206 repo = backend_svn['svn-simple-layout'].scm_instance()
207 207 assert 'exp/branches/exp-sphinx-docs' in repo.branches
208 208 assert 'important_tags/v0.5' in repo.tags
209 209
210 210 def test_add_same_svn_value_twice_shows_an_error_message(
211 211 self, app, form_defaults, csrf_token, settings_util):
212 212 settings_util.create_rhodecode_ui('vcs_svn_branch', '/test')
213 213 settings_util.create_rhodecode_ui('vcs_svn_tag', '/test')
214 214
215 215 response = app.post(
216 216 url('admin_settings_vcs'),
217 217 params={
218 218 'paths_root_path': form_defaults['paths_root_path'],
219 219 'new_svn_branch': '/test',
220 220 'new_svn_tag': '/test',
221 221 'csrf_token': csrf_token,
222 222 },
223 223 status=200)
224 224
225 225 response.mustcontain("Pattern already exists")
226 226 response.mustcontain("Some form inputs contain invalid data.")
227 227
228 228 @pytest.mark.parametrize('section', [
229 229 'vcs_svn_branch',
230 230 'vcs_svn_tag',
231 231 ])
232 232 def test_delete_svn_patterns(
233 233 self, section, app, csrf_token, settings_util):
234 234 setting = settings_util.create_rhodecode_ui(
235 235 section, '/test_delete', cleanup=False)
236 236
237 237 app.post(
238 238 url('admin_settings_vcs'),
239 239 params={
240 240 '_method': 'delete',
241 241 'delete_svn_pattern': setting.ui_id,
242 242 'csrf_token': csrf_token},
243 243 headers={'X-REQUESTED-WITH': 'XMLHttpRequest'})
244 244
245 245 @pytest.mark.parametrize('section', [
246 246 'vcs_svn_branch',
247 247 'vcs_svn_tag',
248 248 ])
249 249 def test_delete_svn_patterns_raises_400_when_no_xhr(
250 250 self, section, app, csrf_token, settings_util):
251 251 setting = settings_util.create_rhodecode_ui(section, '/test_delete')
252 252
253 253 app.post(
254 254 url('admin_settings_vcs'),
255 255 params={
256 256 '_method': 'delete',
257 257 'delete_svn_pattern': setting.ui_id,
258 258 'csrf_token': csrf_token},
259 259 status=400)
260 260
261 261 def test_extensions_hgsubversion(self, app, form_defaults, csrf_token):
262 262 form_defaults.update({
263 263 'csrf_token': csrf_token,
264 264 'extensions_hgsubversion': 'True',
265 265 })
266 266 response = app.post(
267 267 url('admin_settings_vcs'),
268 268 params=form_defaults,
269 269 status=302)
270 270
271 271 response = response.follow()
272 272 extensions_input = (
273 273 '<input id="extensions_hgsubversion" '
274 274 'name="extensions_hgsubversion" type="checkbox" '
275 275 'value="True" checked="checked" />')
276 276 response.mustcontain(extensions_input)
277 277
278 278 def test_has_a_section_for_pull_request_settings(self, app):
279 279 response = app.get(url('admin_settings_vcs'))
280 280 response.mustcontain('Pull Request Settings')
281 281
282 282 def test_has_an_input_for_invalidation_of_inline_comments(
283 283 self, app):
284 284 response = app.get(url('admin_settings_vcs'))
285 285 assert_response = AssertResponse(response)
286 286 assert_response.one_element_exists(
287 287 '[name=rhodecode_use_outdated_comments]')
288 288
289 289 @pytest.mark.parametrize('new_value', [True, False])
290 290 def test_allows_to_change_invalidation_of_inline_comments(
291 291 self, app, form_defaults, csrf_token, new_value):
292 292 setting_key = 'use_outdated_comments'
293 293 setting = SettingsModel().create_or_update_setting(
294 294 setting_key, not new_value, 'bool')
295 295 Session().add(setting)
296 296 Session().commit()
297 297
298 298 form_defaults.update({
299 299 'csrf_token': csrf_token,
300 300 'rhodecode_use_outdated_comments': str(new_value),
301 301 })
302 302 response = app.post(
303 303 url('admin_settings_vcs'),
304 304 params=form_defaults,
305 305 status=302)
306 306 response = response.follow()
307 307 setting = SettingsModel().get_setting_by_name(setting_key)
308 308 assert setting.app_settings_value is new_value
309 309
310 310 def test_has_a_section_for_labs_settings_if_enabled(self, app):
311 311 with mock.patch.dict(
312 312 rhodecode.CONFIG, {'labs_settings_active': 'true'}):
313 313 response = self.app.get(url('admin_settings_vcs'))
314 314 response.mustcontain('Labs Settings')
315 315
316 316 def test_has_not_a_section_for_labs_settings_if_disables(self, app):
317 317 with mock.patch.dict(
318 318 rhodecode.CONFIG, {'labs_settings_active': 'false'}):
319 319 response = self.app.get(url('admin_settings_vcs'))
320 320 response.mustcontain(no='Labs Settings')
321 321
322 322 @pytest.mark.parametrize('new_value', [True, False])
323 323 def test_allows_to_change_hg_rebase_merge_strategy(
324 324 self, app, form_defaults, csrf_token, new_value):
325 325 setting_key = 'hg_use_rebase_for_merging'
326 326
327 327 form_defaults.update({
328 328 'csrf_token': csrf_token,
329 329 'rhodecode_' + setting_key: str(new_value),
330 330 })
331 331
332 332 with mock.patch.dict(
333 333 rhodecode.CONFIG, {'labs_settings_active': 'true'}):
334 334 app.post(
335 335 url('admin_settings_vcs'),
336 336 params=form_defaults,
337 337 status=302)
338 338
339 339 setting = SettingsModel().get_setting_by_name(setting_key)
340 340 assert setting.app_settings_value is new_value
341 341
342 342 @pytest.fixture
343 343 def disable_sql_cache(self, request):
344 344 patcher = mock.patch(
345 345 'rhodecode.lib.caching_query.FromCache.process_query')
346 346 request.addfinalizer(patcher.stop)
347 347 patcher.start()
348 348
349 349 @pytest.fixture
350 350 def form_defaults(self):
351 351 from rhodecode.controllers.admin.settings import SettingsController
352 352 controller = SettingsController()
353 353 return controller._form_defaults()
354 354
355 355 # TODO: johbo: What we really want is to checkpoint before a test run and
356 356 # reset the session afterwards.
357 357 @pytest.fixture(scope='class', autouse=True)
358 358 def cleanup_settings(self, request, pylonsapp):
359 359 ui_id = RhodeCodeUi.ui_id
360 360 original_ids = list(
361 361 r.ui_id for r in RhodeCodeUi.query().values(ui_id))
362 362
363 363 @request.addfinalizer
364 364 def cleanup():
365 365 RhodeCodeUi.query().filter(
366 366 ui_id.notin_(original_ids)).delete(False)
367 367
368 368
369 369 @pytest.mark.usefixtures('autologin_user', 'app')
370 370 class TestLabsSettings(object):
371 371 def test_get_settings_page_disabled(self):
372 372 with mock.patch.dict(rhodecode.CONFIG,
373 373 {'labs_settings_active': 'false'}):
374 374 response = self.app.get(url('admin_settings_labs'), status=302)
375 375
376 376 assert response.location.endswith(url('admin_settings'))
377 377
378 378 def test_get_settings_page_enabled(self):
379 379 from rhodecode.controllers.admin import settings
380 380 lab_settings = [
381 381 settings.LabSetting(
382 382 key='rhodecode_bool',
383 383 type='bool',
384 384 group='bool group',
385 385 label='bool label',
386 386 help='bool help'
387 387 ),
388 388 settings.LabSetting(
389 389 key='rhodecode_text',
390 390 type='unicode',
391 391 group='text group',
392 392 label='text label',
393 393 help='text help'
394 394 ),
395 395 ]
396 396 with mock.patch.dict(rhodecode.CONFIG,
397 397 {'labs_settings_active': 'true'}):
398 398 with mock.patch.object(settings, '_LAB_SETTINGS', lab_settings):
399 399 response = self.app.get(url('admin_settings_labs'))
400 400
401 401 assert '<label>bool group:</label>' in response
402 402 assert '<label for="rhodecode_bool">bool label</label>' in response
403 403 assert '<p class="help-block">bool help</p>' in response
404 404 assert 'name="rhodecode_bool" type="checkbox"' in response
405 405
406 406 assert '<label>text group:</label>' in response
407 407 assert '<label for="rhodecode_text">text label</label>' in response
408 408 assert '<p class="help-block">text help</p>' in response
409 409 assert 'name="rhodecode_text" size="60" type="text"' in response
410 410
411 411
412 412 @pytest.mark.usefixtures('app')
413 413 class TestOpenSourceLicenses(object):
414 414
415 415 def _get_url(self):
416 416 return ADMIN_PREFIX + '/settings/open_source'
417 417
418 418 def test_records_are_displayed(self, autologin_user):
419 419 sample_licenses = {
420 420 "python2.7-pytest-2.7.1": {
421 421 "UNKNOWN": None
422 422 },
423 423 "python2.7-Markdown-2.6.2": {
424 424 "BSD-3-Clause": "http://spdx.org/licenses/BSD-3-Clause"
425 425 }
426 426 }
427 427 read_licenses_patch = mock.patch(
428 428 'rhodecode.admin.views.open_source_licenses.read_opensource_licenses',
429 429 return_value=sample_licenses)
430 430 with read_licenses_patch:
431 431 response = self.app.get(self._get_url(), status=200)
432 432
433 433 assert_response = AssertResponse(response)
434 434 assert_response.element_contains(
435 435 '.panel-heading', 'Licenses of Third Party Packages')
436 436 for name in sample_licenses:
437 437 response.mustcontain(name)
438 438 for license in sample_licenses[name]:
439 439 assert_response.element_contains('.panel-body', license)
440 440
441 441 def test_records_can_be_read(self, autologin_user):
442 442 response = self.app.get(self._get_url(), status=200)
443 443 assert_response = AssertResponse(response)
444 444 assert_response.element_contains(
445 445 '.panel-heading', 'Licenses of Third Party Packages')
446 446
447 447 def test_forbidden_when_normal_user(self, autologin_regular_user):
448 448 self.app.get(self._get_url(), status=403)
449 449
450 450
451 451 @pytest.mark.usefixtures('app')
452 452 class TestUserSessions(object):
453 453
454 454 def _get_url(self, name='admin_settings_sessions'):
455 455 return {
456 456 'admin_settings_sessions': ADMIN_PREFIX + '/settings/sessions',
457 457 'admin_settings_sessions_cleanup': ADMIN_PREFIX + '/settings/sessions/cleanup'
458 458 }[name]
459 459
460 460 def test_forbidden_when_normal_user(self, autologin_regular_user):
461 461 self.app.get(self._get_url(), status=403)
462 462
463 463 def test_show_sessions_page(self, autologin_user):
464 464 response = self.app.get(self._get_url(), status=200)
465 465 response.mustcontain('file')
466 466
467 467 def test_cleanup_old_sessions(self, autologin_user, csrf_token):
468 468
469 469 post_data = {
470 470 'csrf_token': csrf_token,
471 471 'expire_days': '60'
472 472 }
473 473 response = self.app.post(
474 474 self._get_url('admin_settings_sessions_cleanup'), params=post_data,
475 475 status=302)
476 assert_session_flash(response, 'Please execute this command')
476 assert_session_flash(response, 'Cleaned up old sessions')
477 477
478 478
479 479 @pytest.mark.usefixtures('app')
480 480 class TestAdminSystemInfo(object):
481 481 def _get_url(self, name='admin_settings_system'):
482 482 return {
483 483 'admin_settings_system': ADMIN_PREFIX + '/settings/system',
484 484 'admin_settings_system_update': ADMIN_PREFIX + '/settings/system/updates',
485 485 }[name]
486 486
487 487 def test_forbidden_when_normal_user(self, autologin_regular_user):
488 488 self.app.get(self._get_url(), status=403)
489 489
490 490 def test_system_info_page(self, autologin_user):
491 491 response = self.app.get(self._get_url())
492 492 response.mustcontain('RhodeCode Community Edition, version {}'.format(
493 493 rhodecode.__version__))
494 494
495 495 def test_system_update_new_version(self, autologin_user):
496 496 update_data = {
497 497 'versions': [
498 498 {
499 499 'version': '100.3.1415926535',
500 500 'general': 'The latest version we are ever going to ship'
501 501 },
502 502 {
503 503 'version': '0.0.0',
504 504 'general': 'The first version we ever shipped'
505 505 }
506 506 ]
507 507 }
508 508 with mock.patch(UPDATE_DATA_QUALNAME, return_value=update_data):
509 509 response = self.app.get(self._get_url('admin_settings_system_update'))
510 510 response.mustcontain('A <b>new version</b> is available')
511 511
512 512 def test_system_update_nothing_new(self, autologin_user):
513 513 update_data = {
514 514 'versions': [
515 515 {
516 516 'version': '0.0.0',
517 517 'general': 'The first version we ever shipped'
518 518 }
519 519 ]
520 520 }
521 521 with mock.patch(UPDATE_DATA_QUALNAME, return_value=update_data):
522 522 response = self.app.get(self._get_url('admin_settings_system_update'))
523 523 response.mustcontain(
524 524 'You already have the <b>latest</b> stable version.')
525 525
526 526 def test_system_update_bad_response(self, autologin_user):
527 527 with mock.patch(UPDATE_DATA_QUALNAME, side_effect=ValueError('foo')):
528 528 response = self.app.get(self._get_url('admin_settings_system_update'))
529 529 response.mustcontain(
530 530 'Bad data sent from update server')
531 531
532 532
533 533 @pytest.mark.usefixtures("app")
534 534 class TestAdminSettingsIssueTracker(object):
535 535 RC_PREFIX = 'rhodecode_'
536 536 SHORT_PATTERN_KEY = 'issuetracker_pat_'
537 537 PATTERN_KEY = RC_PREFIX + SHORT_PATTERN_KEY
538 538
539 539 def test_issuetracker_index(self, autologin_user):
540 540 response = self.app.get(url('admin_settings_issuetracker'))
541 541 assert response.status_code == 200
542 542
543 543 def test_add_empty_issuetracker_pattern(
544 544 self, request, autologin_user, csrf_token):
545 545 post_url = url('admin_settings_issuetracker_save')
546 546 post_data = {
547 547 'csrf_token': csrf_token
548 548 }
549 549 self.app.post(post_url, post_data, status=302)
550 550
551 551 def test_add_issuetracker_pattern(
552 552 self, request, autologin_user, csrf_token):
553 553 pattern = 'issuetracker_pat'
554 554 another_pattern = pattern+'1'
555 555 post_url = url('admin_settings_issuetracker_save')
556 556 post_data = {
557 557 'new_pattern_pattern_0': pattern,
558 558 'new_pattern_url_0': 'url',
559 559 'new_pattern_prefix_0': 'prefix',
560 560 'new_pattern_description_0': 'description',
561 561 'new_pattern_pattern_1': another_pattern,
562 562 'new_pattern_url_1': 'url1',
563 563 'new_pattern_prefix_1': 'prefix1',
564 564 'new_pattern_description_1': 'description1',
565 565 'csrf_token': csrf_token
566 566 }
567 567 self.app.post(post_url, post_data, status=302)
568 568 settings = SettingsModel().get_all_settings()
569 569 self.uid = md5(pattern)
570 570 assert settings[self.PATTERN_KEY+self.uid] == pattern
571 571 self.another_uid = md5(another_pattern)
572 572 assert settings[self.PATTERN_KEY+self.another_uid] == another_pattern
573 573
574 574 @request.addfinalizer
575 575 def cleanup():
576 576 defaults = SettingsModel().get_all_settings()
577 577
578 578 entries = [name for name in defaults if (
579 579 (self.uid in name) or (self.another_uid) in name)]
580 580 start = len(self.RC_PREFIX)
581 581 for del_key in entries:
582 582 # TODO: anderson: get_by_name needs name without prefix
583 583 entry = SettingsModel().get_setting_by_name(del_key[start:])
584 584 Session().delete(entry)
585 585
586 586 Session().commit()
587 587
588 588 def test_edit_issuetracker_pattern(
589 589 self, autologin_user, backend, csrf_token, request):
590 590 old_pattern = 'issuetracker_pat'
591 591 old_uid = md5(old_pattern)
592 592 pattern = 'issuetracker_pat_new'
593 593 self.new_uid = md5(pattern)
594 594
595 595 SettingsModel().create_or_update_setting(
596 596 self.SHORT_PATTERN_KEY+old_uid, old_pattern, 'unicode')
597 597
598 598 post_url = url('admin_settings_issuetracker_save')
599 599 post_data = {
600 600 'new_pattern_pattern_0': pattern,
601 601 'new_pattern_url_0': 'url',
602 602 'new_pattern_prefix_0': 'prefix',
603 603 'new_pattern_description_0': 'description',
604 604 'uid': old_uid,
605 605 'csrf_token': csrf_token
606 606 }
607 607 self.app.post(post_url, post_data, status=302)
608 608 settings = SettingsModel().get_all_settings()
609 609 assert settings[self.PATTERN_KEY+self.new_uid] == pattern
610 610 assert self.PATTERN_KEY+old_uid not in settings
611 611
612 612 @request.addfinalizer
613 613 def cleanup():
614 614 IssueTrackerSettingsModel().delete_entries(self.new_uid)
615 615
616 616 def test_replace_issuetracker_pattern_description(
617 617 self, autologin_user, csrf_token, request, settings_util):
618 618 prefix = 'issuetracker'
619 619 pattern = 'issuetracker_pat'
620 620 self.uid = md5(pattern)
621 621 pattern_key = '_'.join([prefix, 'pat', self.uid])
622 622 rc_pattern_key = '_'.join(['rhodecode', pattern_key])
623 623 desc_key = '_'.join([prefix, 'desc', self.uid])
624 624 rc_desc_key = '_'.join(['rhodecode', desc_key])
625 625 new_description = 'new_description'
626 626
627 627 settings_util.create_rhodecode_setting(
628 628 pattern_key, pattern, 'unicode', cleanup=False)
629 629 settings_util.create_rhodecode_setting(
630 630 desc_key, 'old description', 'unicode', cleanup=False)
631 631
632 632 post_url = url('admin_settings_issuetracker_save')
633 633 post_data = {
634 634 'new_pattern_pattern_0': pattern,
635 635 'new_pattern_url_0': 'url',
636 636 'new_pattern_prefix_0': 'prefix',
637 637 'new_pattern_description_0': new_description,
638 638 'uid': self.uid,
639 639 'csrf_token': csrf_token
640 640 }
641 641 self.app.post(post_url, post_data, status=302)
642 642 settings = SettingsModel().get_all_settings()
643 643 assert settings[rc_pattern_key] == pattern
644 644 assert settings[rc_desc_key] == new_description
645 645
646 646 @request.addfinalizer
647 647 def cleanup():
648 648 IssueTrackerSettingsModel().delete_entries(self.uid)
649 649
650 650 def test_delete_issuetracker_pattern(
651 651 self, autologin_user, backend, csrf_token, settings_util):
652 652 pattern = 'issuetracker_pat'
653 653 uid = md5(pattern)
654 654 settings_util.create_rhodecode_setting(
655 655 self.SHORT_PATTERN_KEY+uid, pattern, 'unicode', cleanup=False)
656 656
657 657 post_url = url('admin_issuetracker_delete')
658 658 post_data = {
659 659 '_method': 'delete',
660 660 'uid': uid,
661 661 'csrf_token': csrf_token
662 662 }
663 663 self.app.post(post_url, post_data, status=302)
664 664 settings = SettingsModel().get_all_settings()
665 665 assert 'rhodecode_%s%s' % (self.SHORT_PATTERN_KEY, uid) not in settings
General Comments 0
You need to be logged in to leave comments. Login now