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