##// END OF EJS Templates
repositories: rewrote whole admin section to pyramid....
marcink -
r2014:b776c5e0 default
parent child
Show More
@@ -0,0 +1,180
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 #
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
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
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/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
21 import logging
22 import formencode
23
24 from pyramid.httpexceptions import HTTPFound, HTTPForbidden
25 from pyramid.view import view_config
26 from pyramid.renderers import render
27 from pyramid.response import Response
28
29 from rhodecode.apps._base import BaseAppView, DataGridAppView
30
31 from rhodecode.lib.ext_json import json
32 from rhodecode.lib.auth import (
33 LoginRequired, CSRFRequired, NotAnonymous,
34 HasPermissionAny, HasRepoGroupPermissionAny)
35 from rhodecode.lib import helpers as h
36 from rhodecode.lib.utils import repo_name_slug
37 from rhodecode.lib.utils2 import safe_int, safe_unicode
38 from rhodecode.model.forms import RepoForm
39 from rhodecode.model.repo import RepoModel
40 from rhodecode.model.scm import RepoList, RepoGroupList, ScmModel
41 from rhodecode.model.settings import SettingsModel
42 from rhodecode.model.db import Repository, RepoGroup
43
44 log = logging.getLogger(__name__)
45
46
47 class AdminReposView(BaseAppView, DataGridAppView):
48
49 def load_default_context(self):
50 c = self._get_local_tmpl_context()
51 self._register_global_c(c)
52 return c
53
54 def _load_form_data(self, c):
55 acl_groups = RepoGroupList(RepoGroup.query().all(),
56 perm_set=['group.write', 'group.admin'])
57 c.repo_groups = RepoGroup.groups_choices(groups=acl_groups)
58 c.repo_groups_choices = map(lambda k: safe_unicode(k[0]), c.repo_groups)
59 c.landing_revs_choices, c.landing_revs = \
60 ScmModel().get_repo_landing_revs()
61 c.personal_repo_group = self._rhodecode_user.personal_repo_group
62
63 @LoginRequired()
64 @NotAnonymous()
65 @view_config(
66 route_name='repos', request_method='GET',
67 renderer='rhodecode:templates/admin/repos/repos.mako')
68 def repository_list(self):
69 c = self.load_default_context()
70
71 repo_list = Repository.get_all_repos()
72 c.repo_list = RepoList(repo_list, perm_set=['repository.admin'])
73 repos_data = RepoModel().get_repos_as_dict(
74 repo_list=c.repo_list, admin=True, super_user_actions=True)
75 # json used to render the grid
76 c.data = json.dumps(repos_data)
77
78 return self._get_template_context(c)
79
80 @LoginRequired()
81 @NotAnonymous()
82 # perms check inside
83 @view_config(
84 route_name='repo_new', request_method='GET',
85 renderer='rhodecode:templates/admin/repos/repo_add.mako')
86 def repository_new(self):
87 c = self.load_default_context()
88
89 new_repo = self.request.GET.get('repo', '')
90 parent_group = safe_int(self.request.GET.get('parent_group'))
91 _gr = RepoGroup.get(parent_group)
92
93 if not HasPermissionAny('hg.admin', 'hg.create.repository')():
94 # you're not super admin nor have global create permissions,
95 # but maybe you have at least write permission to a parent group ?
96
97 gr_name = _gr.group_name if _gr else None
98 # create repositories with write permission on group is set to true
99 create_on_write = HasPermissionAny('hg.create.write_on_repogroup.true')()
100 group_admin = HasRepoGroupPermissionAny('group.admin')(group_name=gr_name)
101 group_write = HasRepoGroupPermissionAny('group.write')(group_name=gr_name)
102 if not (group_admin or (group_write and create_on_write)):
103 raise HTTPForbidden()
104
105 self._load_form_data(c)
106 c.new_repo = repo_name_slug(new_repo)
107
108 # apply the defaults from defaults page
109 defaults = SettingsModel().get_default_repo_settings(strip_prefix=True)
110 # set checkbox to autochecked
111 defaults['repo_copy_permissions'] = True
112
113 parent_group_choice = '-1'
114 if not self._rhodecode_user.is_admin and self._rhodecode_user.personal_repo_group:
115 parent_group_choice = self._rhodecode_user.personal_repo_group
116
117 if parent_group and _gr:
118 if parent_group in [x[0] for x in c.repo_groups]:
119 parent_group_choice = safe_unicode(parent_group)
120
121 defaults.update({'repo_group': parent_group_choice})
122
123 data = render('rhodecode:templates/admin/repos/repo_add.mako',
124 self._get_template_context(c), self.request)
125 html = formencode.htmlfill.render(
126 data,
127 defaults=defaults,
128 encoding="UTF-8",
129 force_defaults=False
130 )
131 return Response(html)
132
133 @LoginRequired()
134 @NotAnonymous()
135 @CSRFRequired()
136 # perms check inside
137 @view_config(
138 route_name='repo_create', request_method='POST',
139 renderer='rhodecode:templates/admin/repos/repos.mako')
140 def repository_create(self):
141 c = self.load_default_context()
142
143 form_result = {}
144 task_id = None
145 self._load_form_data(c)
146
147 try:
148 # CanWriteToGroup validators checks permissions of this POST
149 form_result = RepoForm(repo_groups=c.repo_groups_choices,
150 landing_revs=c.landing_revs_choices)()\
151 .to_python(dict(self.request.POST))
152
153 # create is done sometimes async on celery, db transaction
154 # management is handled there.
155 task = RepoModel().create(form_result, self._rhodecode_user.user_id)
156 from celery.result import BaseAsyncResult
157 if isinstance(task, BaseAsyncResult):
158 task_id = task.task_id
159 except formencode.Invalid as errors:
160 data = render('rhodecode:templates/admin/repos/repo_add.mako',
161 self._get_template_context(c), self.request)
162 html = formencode.htmlfill.render(
163 data,
164 defaults=errors.value,
165 errors=errors.error_dict or {},
166 prefix_error=False,
167 encoding="UTF-8",
168 force_defaults=False
169 )
170 return Response(html)
171
172 except Exception as e:
173 msg = self._log_creation_exception(e, form_result.get('repo_name'))
174 h.flash(msg, category='error')
175 raise HTTPFound(h.route_path('home'))
176
177 raise HTTPFound(
178 h.route_path('repo_creating',
179 repo_name=form_result['repo_name_full'],
180 _query=dict(task_id=task_id)))
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
This diff has been collapsed as it changes many lines, (685 lines changed) Show them Hide them
@@ -0,0 +1,685
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2010-2017 RhodeCode GmbH
4 #
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
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
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/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
21 import mock
22 import pytest
23
24 from rhodecode.lib import auth
25 from rhodecode.lib.utils2 import str2bool
26 from rhodecode.model.db import (
27 Repository, UserRepoToPerm, User)
28 from rhodecode.model.meta import Session
29 from rhodecode.model.settings import SettingsModel, VcsSettingsModel
30 from rhodecode.model.user import UserModel
31 from rhodecode.tests import (
32 login_user_session, logout_user_session,
33 TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
34 from rhodecode.tests.fixture import Fixture
35 from rhodecode.tests.utils import AssertResponse
36
37 fixture = Fixture()
38
39
40 def route_path(name, params=None, **kwargs):
41 import urllib
42
43 base_url = {
44 'repo_summary': '/{repo_name}',
45 'repo_creating_check': '/{repo_name}/repo_creating_check',
46 'edit_repo': '/{repo_name}/settings',
47 'edit_repo_vcs': '/{repo_name}/settings/vcs',
48 'edit_repo_vcs_update': '/{repo_name}/settings/vcs/update',
49 'edit_repo_vcs_svn_pattern_delete': '/{repo_name}/settings/vcs/svn_pattern/delete'
50 }[name].format(**kwargs)
51
52 if params:
53 base_url = '{}?{}'.format(base_url, urllib.urlencode(params))
54 return base_url
55
56
57 @pytest.mark.usefixtures("app")
58 class TestVcsSettings(object):
59 FORM_DATA = {
60 'inherit_global_settings': False,
61 'hooks_changegroup_repo_size': False,
62 'hooks_changegroup_push_logger': False,
63 'hooks_outgoing_pull_logger': False,
64 'extensions_largefiles': False,
65 'extensions_evolve': False,
66 'phases_publish': 'False',
67 'rhodecode_pr_merge_enabled': False,
68 'rhodecode_use_outdated_comments': False,
69 'new_svn_branch': '',
70 'new_svn_tag': ''
71 }
72
73 @pytest.mark.skip_backends('svn')
74 def test_global_settings_initial_values(self, autologin_user, backend):
75 repo_name = backend.repo_name
76 response = self.app.get(route_path('edit_repo_vcs', repo_name=repo_name))
77
78 expected_settings = (
79 'rhodecode_use_outdated_comments', 'rhodecode_pr_merge_enabled',
80 'hooks_changegroup_repo_size', 'hooks_changegroup_push_logger',
81 'hooks_outgoing_pull_logger'
82 )
83 for setting in expected_settings:
84 self.assert_repo_value_equals_global_value(response, setting)
85
86 def test_show_settings_requires_repo_admin_permission(
87 self, backend, user_util, settings_util):
88 repo = backend.create_repo()
89 repo_name = repo.repo_name
90 user = UserModel().get_by_username(TEST_USER_REGULAR_LOGIN)
91 user_util.grant_user_permission_to_repo(repo, user, 'repository.admin')
92 login_user_session(
93 self.app, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
94 self.app.get(route_path('edit_repo_vcs', repo_name=repo_name), status=200)
95
96 def test_inherit_global_settings_flag_is_true_by_default(
97 self, autologin_user, backend):
98 repo_name = backend.repo_name
99 response = self.app.get(route_path('edit_repo_vcs', repo_name=repo_name))
100
101 assert_response = AssertResponse(response)
102 element = assert_response.get_element('#inherit_global_settings')
103 assert element.checked
104
105 @pytest.mark.parametrize('checked_value', [True, False])
106 def test_inherit_global_settings_value(
107 self, autologin_user, backend, checked_value, settings_util):
108 repo = backend.create_repo()
109 repo_name = repo.repo_name
110 settings_util.create_repo_rhodecode_setting(
111 repo, 'inherit_vcs_settings', checked_value, 'bool')
112 response = self.app.get(route_path('edit_repo_vcs', repo_name=repo_name))
113
114 assert_response = AssertResponse(response)
115 element = assert_response.get_element('#inherit_global_settings')
116 assert element.checked == checked_value
117
118 @pytest.mark.skip_backends('svn')
119 def test_hooks_settings_are_created(
120 self, autologin_user, backend, csrf_token):
121 repo_name = backend.repo_name
122 data = self.FORM_DATA.copy()
123 data['csrf_token'] = csrf_token
124 self.app.post(
125 route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302)
126 settings = SettingsModel(repo=repo_name)
127 try:
128 for section, key in VcsSettingsModel.HOOKS_SETTINGS:
129 ui = settings.get_ui_by_section_and_key(section, key)
130 assert ui.ui_active is False
131 finally:
132 self._cleanup_repo_settings(settings)
133
134 def test_hooks_settings_are_not_created_for_svn(
135 self, autologin_user, backend_svn, csrf_token):
136 repo_name = backend_svn.repo_name
137 data = self.FORM_DATA.copy()
138 data['csrf_token'] = csrf_token
139 self.app.post(
140 route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302)
141 settings = SettingsModel(repo=repo_name)
142 try:
143 for section, key in VcsSettingsModel.HOOKS_SETTINGS:
144 ui = settings.get_ui_by_section_and_key(section, key)
145 assert ui is None
146 finally:
147 self._cleanup_repo_settings(settings)
148
149 @pytest.mark.skip_backends('svn')
150 def test_hooks_settings_are_updated(
151 self, autologin_user, backend, csrf_token):
152 repo_name = backend.repo_name
153 settings = SettingsModel(repo=repo_name)
154 for section, key in VcsSettingsModel.HOOKS_SETTINGS:
155 settings.create_ui_section_value(section, '', key=key, active=True)
156
157 data = self.FORM_DATA.copy()
158 data['csrf_token'] = csrf_token
159 self.app.post(
160 route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302)
161 try:
162 for section, key in VcsSettingsModel.HOOKS_SETTINGS:
163 ui = settings.get_ui_by_section_and_key(section, key)
164 assert ui.ui_active is False
165 finally:
166 self._cleanup_repo_settings(settings)
167
168 def test_hooks_settings_are_not_updated_for_svn(
169 self, autologin_user, backend_svn, csrf_token):
170 repo_name = backend_svn.repo_name
171 settings = SettingsModel(repo=repo_name)
172 for section, key in VcsSettingsModel.HOOKS_SETTINGS:
173 settings.create_ui_section_value(section, '', key=key, active=True)
174
175 data = self.FORM_DATA.copy()
176 data['csrf_token'] = csrf_token
177 self.app.post(
178 route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302)
179 try:
180 for section, key in VcsSettingsModel.HOOKS_SETTINGS:
181 ui = settings.get_ui_by_section_and_key(section, key)
182 assert ui.ui_active is True
183 finally:
184 self._cleanup_repo_settings(settings)
185
186 @pytest.mark.skip_backends('svn')
187 def test_pr_settings_are_created(
188 self, autologin_user, backend, csrf_token):
189 repo_name = backend.repo_name
190 data = self.FORM_DATA.copy()
191 data['csrf_token'] = csrf_token
192 self.app.post(
193 route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302)
194 settings = SettingsModel(repo=repo_name)
195 try:
196 for name in VcsSettingsModel.GENERAL_SETTINGS:
197 setting = settings.get_setting_by_name(name)
198 assert setting.app_settings_value is False
199 finally:
200 self._cleanup_repo_settings(settings)
201
202 def test_pr_settings_are_not_created_for_svn(
203 self, autologin_user, backend_svn, csrf_token):
204 repo_name = backend_svn.repo_name
205 data = self.FORM_DATA.copy()
206 data['csrf_token'] = csrf_token
207 self.app.post(
208 route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302)
209 settings = SettingsModel(repo=repo_name)
210 try:
211 for name in VcsSettingsModel.GENERAL_SETTINGS:
212 setting = settings.get_setting_by_name(name)
213 assert setting is None
214 finally:
215 self._cleanup_repo_settings(settings)
216
217 def test_pr_settings_creation_requires_repo_admin_permission(
218 self, backend, user_util, settings_util, csrf_token):
219 repo = backend.create_repo()
220 repo_name = repo.repo_name
221
222 logout_user_session(self.app, csrf_token)
223 session = login_user_session(
224 self.app, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
225 new_csrf_token = auth.get_csrf_token(session)
226
227 user = UserModel().get_by_username(TEST_USER_REGULAR_LOGIN)
228 repo = Repository.get_by_repo_name(repo_name)
229 user_util.grant_user_permission_to_repo(repo, user, 'repository.admin')
230 data = self.FORM_DATA.copy()
231 data['csrf_token'] = new_csrf_token
232 settings = SettingsModel(repo=repo_name)
233
234 try:
235 self.app.post(
236 route_path('edit_repo_vcs_update', repo_name=repo_name), data,
237 status=302)
238 finally:
239 self._cleanup_repo_settings(settings)
240
241 @pytest.mark.skip_backends('svn')
242 def test_pr_settings_are_updated(
243 self, autologin_user, backend, csrf_token):
244 repo_name = backend.repo_name
245 settings = SettingsModel(repo=repo_name)
246 for name in VcsSettingsModel.GENERAL_SETTINGS:
247 settings.create_or_update_setting(name, True, 'bool')
248
249 data = self.FORM_DATA.copy()
250 data['csrf_token'] = csrf_token
251 self.app.post(
252 route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302)
253 try:
254 for name in VcsSettingsModel.GENERAL_SETTINGS:
255 setting = settings.get_setting_by_name(name)
256 assert setting.app_settings_value is False
257 finally:
258 self._cleanup_repo_settings(settings)
259
260 def test_pr_settings_are_not_updated_for_svn(
261 self, autologin_user, backend_svn, csrf_token):
262 repo_name = backend_svn.repo_name
263 settings = SettingsModel(repo=repo_name)
264 for name in VcsSettingsModel.GENERAL_SETTINGS:
265 settings.create_or_update_setting(name, True, 'bool')
266
267 data = self.FORM_DATA.copy()
268 data['csrf_token'] = csrf_token
269 self.app.post(
270 route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302)
271 try:
272 for name in VcsSettingsModel.GENERAL_SETTINGS:
273 setting = settings.get_setting_by_name(name)
274 assert setting.app_settings_value is True
275 finally:
276 self._cleanup_repo_settings(settings)
277
278 def test_svn_settings_are_created(
279 self, autologin_user, backend_svn, csrf_token, settings_util):
280 repo_name = backend_svn.repo_name
281 data = self.FORM_DATA.copy()
282 data['new_svn_tag'] = 'svn-tag'
283 data['new_svn_branch'] = 'svn-branch'
284 data['csrf_token'] = csrf_token
285
286 # Create few global settings to make sure that uniqueness validators
287 # are not triggered
288 settings_util.create_rhodecode_ui(
289 VcsSettingsModel.SVN_BRANCH_SECTION, 'svn-branch')
290 settings_util.create_rhodecode_ui(
291 VcsSettingsModel.SVN_TAG_SECTION, 'svn-tag')
292
293 self.app.post(
294 route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302)
295 settings = SettingsModel(repo=repo_name)
296 try:
297 svn_branches = settings.get_ui_by_section(
298 VcsSettingsModel.SVN_BRANCH_SECTION)
299 svn_branch_names = [b.ui_value for b in svn_branches]
300 svn_tags = settings.get_ui_by_section(
301 VcsSettingsModel.SVN_TAG_SECTION)
302 svn_tag_names = [b.ui_value for b in svn_tags]
303 assert 'svn-branch' in svn_branch_names
304 assert 'svn-tag' in svn_tag_names
305 finally:
306 self._cleanup_repo_settings(settings)
307
308 def test_svn_settings_are_unique(
309 self, autologin_user, backend_svn, csrf_token, settings_util):
310 repo = backend_svn.repo
311 repo_name = repo.repo_name
312 data = self.FORM_DATA.copy()
313 data['new_svn_tag'] = 'test_tag'
314 data['new_svn_branch'] = 'test_branch'
315 data['csrf_token'] = csrf_token
316 settings_util.create_repo_rhodecode_ui(
317 repo, VcsSettingsModel.SVN_BRANCH_SECTION, 'test_branch')
318 settings_util.create_repo_rhodecode_ui(
319 repo, VcsSettingsModel.SVN_TAG_SECTION, 'test_tag')
320
321 response = self.app.post(
322 route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=200)
323 response.mustcontain('Pattern already exists')
324
325 def test_svn_settings_with_empty_values_are_not_created(
326 self, autologin_user, backend_svn, csrf_token):
327 repo_name = backend_svn.repo_name
328 data = self.FORM_DATA.copy()
329 data['csrf_token'] = csrf_token
330 self.app.post(
331 route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302)
332 settings = SettingsModel(repo=repo_name)
333 try:
334 svn_branches = settings.get_ui_by_section(
335 VcsSettingsModel.SVN_BRANCH_SECTION)
336 svn_tags = settings.get_ui_by_section(
337 VcsSettingsModel.SVN_TAG_SECTION)
338 assert len(svn_branches) == 0
339 assert len(svn_tags) == 0
340 finally:
341 self._cleanup_repo_settings(settings)
342
343 def test_svn_settings_are_shown_for_svn_repository(
344 self, autologin_user, backend_svn, csrf_token):
345 repo_name = backend_svn.repo_name
346 response = self.app.get(
347 route_path('edit_repo_vcs', repo_name=repo_name), status=200)
348 response.mustcontain('Subversion Settings')
349
350 @pytest.mark.skip_backends('svn')
351 def test_svn_settings_are_not_created_for_not_svn_repository(
352 self, autologin_user, backend, csrf_token):
353 repo_name = backend.repo_name
354 data = self.FORM_DATA.copy()
355 data['csrf_token'] = csrf_token
356 self.app.post(
357 route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302)
358 settings = SettingsModel(repo=repo_name)
359 try:
360 svn_branches = settings.get_ui_by_section(
361 VcsSettingsModel.SVN_BRANCH_SECTION)
362 svn_tags = settings.get_ui_by_section(
363 VcsSettingsModel.SVN_TAG_SECTION)
364 assert len(svn_branches) == 0
365 assert len(svn_tags) == 0
366 finally:
367 self._cleanup_repo_settings(settings)
368
369 @pytest.mark.skip_backends('svn')
370 def test_svn_settings_are_shown_only_for_svn_repository(
371 self, autologin_user, backend, csrf_token):
372 repo_name = backend.repo_name
373 response = self.app.get(
374 route_path('edit_repo_vcs', repo_name=repo_name), status=200)
375 response.mustcontain(no='Subversion Settings')
376
377 def test_hg_settings_are_created(
378 self, autologin_user, backend_hg, csrf_token):
379 repo_name = backend_hg.repo_name
380 data = self.FORM_DATA.copy()
381 data['new_svn_tag'] = 'svn-tag'
382 data['new_svn_branch'] = 'svn-branch'
383 data['csrf_token'] = csrf_token
384 self.app.post(
385 route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302)
386 settings = SettingsModel(repo=repo_name)
387 try:
388 largefiles_ui = settings.get_ui_by_section_and_key(
389 'extensions', 'largefiles')
390 assert largefiles_ui.ui_active is False
391 phases_ui = settings.get_ui_by_section_and_key(
392 'phases', 'publish')
393 assert str2bool(phases_ui.ui_value) is False
394 finally:
395 self._cleanup_repo_settings(settings)
396
397 def test_hg_settings_are_updated(
398 self, autologin_user, backend_hg, csrf_token):
399 repo_name = backend_hg.repo_name
400 settings = SettingsModel(repo=repo_name)
401 settings.create_ui_section_value(
402 'extensions', '', key='largefiles', active=True)
403 settings.create_ui_section_value(
404 'phases', '1', key='publish', active=True)
405
406 data = self.FORM_DATA.copy()
407 data['csrf_token'] = csrf_token
408 self.app.post(
409 route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302)
410 try:
411 largefiles_ui = settings.get_ui_by_section_and_key(
412 'extensions', 'largefiles')
413 assert largefiles_ui.ui_active is False
414 phases_ui = settings.get_ui_by_section_and_key(
415 'phases', 'publish')
416 assert str2bool(phases_ui.ui_value) is False
417 finally:
418 self._cleanup_repo_settings(settings)
419
420 def test_hg_settings_are_shown_for_hg_repository(
421 self, autologin_user, backend_hg, csrf_token):
422 repo_name = backend_hg.repo_name
423 response = self.app.get(
424 route_path('edit_repo_vcs', repo_name=repo_name), status=200)
425 response.mustcontain('Mercurial Settings')
426
427 @pytest.mark.skip_backends('hg')
428 def test_hg_settings_are_created_only_for_hg_repository(
429 self, autologin_user, backend, csrf_token):
430 repo_name = backend.repo_name
431 data = self.FORM_DATA.copy()
432 data['csrf_token'] = csrf_token
433 self.app.post(
434 route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302)
435 settings = SettingsModel(repo=repo_name)
436 try:
437 largefiles_ui = settings.get_ui_by_section_and_key(
438 'extensions', 'largefiles')
439 assert largefiles_ui is None
440 phases_ui = settings.get_ui_by_section_and_key(
441 'phases', 'publish')
442 assert phases_ui is None
443 finally:
444 self._cleanup_repo_settings(settings)
445
446 @pytest.mark.skip_backends('hg')
447 def test_hg_settings_are_shown_only_for_hg_repository(
448 self, autologin_user, backend, csrf_token):
449 repo_name = backend.repo_name
450 response = self.app.get(
451 route_path('edit_repo_vcs', repo_name=repo_name), status=200)
452 response.mustcontain(no='Mercurial Settings')
453
454 @pytest.mark.skip_backends('hg')
455 def test_hg_settings_are_updated_only_for_hg_repository(
456 self, autologin_user, backend, csrf_token):
457 repo_name = backend.repo_name
458 settings = SettingsModel(repo=repo_name)
459 settings.create_ui_section_value(
460 'extensions', '', key='largefiles', active=True)
461 settings.create_ui_section_value(
462 'phases', '1', key='publish', active=True)
463
464 data = self.FORM_DATA.copy()
465 data['csrf_token'] = csrf_token
466 self.app.post(
467 route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302)
468 try:
469 largefiles_ui = settings.get_ui_by_section_and_key(
470 'extensions', 'largefiles')
471 assert largefiles_ui.ui_active is True
472 phases_ui = settings.get_ui_by_section_and_key(
473 'phases', 'publish')
474 assert phases_ui.ui_value == '1'
475 finally:
476 self._cleanup_repo_settings(settings)
477
478 def test_per_repo_svn_settings_are_displayed(
479 self, autologin_user, backend_svn, settings_util):
480 repo = backend_svn.create_repo()
481 repo_name = repo.repo_name
482 branches = [
483 settings_util.create_repo_rhodecode_ui(
484 repo, VcsSettingsModel.SVN_BRANCH_SECTION,
485 'branch_{}'.format(i))
486 for i in range(10)]
487 tags = [
488 settings_util.create_repo_rhodecode_ui(
489 repo, VcsSettingsModel.SVN_TAG_SECTION, 'tag_{}'.format(i))
490 for i in range(10)]
491
492 response = self.app.get(
493 route_path('edit_repo_vcs', repo_name=repo_name), status=200)
494 assert_response = AssertResponse(response)
495 for branch in branches:
496 css_selector = '[name=branch_value_{}]'.format(branch.ui_id)
497 element = assert_response.get_element(css_selector)
498 assert element.value == branch.ui_value
499 for tag in tags:
500 css_selector = '[name=tag_ui_value_new_{}]'.format(tag.ui_id)
501 element = assert_response.get_element(css_selector)
502 assert element.value == tag.ui_value
503
504 def test_per_repo_hg_and_pr_settings_are_not_displayed_for_svn(
505 self, autologin_user, backend_svn, settings_util):
506 repo = backend_svn.create_repo()
507 repo_name = repo.repo_name
508 response = self.app.get(
509 route_path('edit_repo_vcs', repo_name=repo_name), status=200)
510 response.mustcontain(no='<label>Hooks:</label>')
511 response.mustcontain(no='<label>Pull Request Settings:</label>')
512
513 def test_inherit_global_settings_value_is_saved(
514 self, autologin_user, backend, csrf_token):
515 repo_name = backend.repo_name
516 data = self.FORM_DATA.copy()
517 data['csrf_token'] = csrf_token
518 data['inherit_global_settings'] = True
519 self.app.post(
520 route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302)
521
522 settings = SettingsModel(repo=repo_name)
523 vcs_settings = VcsSettingsModel(repo=repo_name)
524 try:
525 assert vcs_settings.inherit_global_settings is True
526 finally:
527 self._cleanup_repo_settings(settings)
528
529 def test_repo_cache_is_invalidated_when_settings_are_updated(
530 self, autologin_user, backend, csrf_token):
531 repo_name = backend.repo_name
532 data = self.FORM_DATA.copy()
533 data['csrf_token'] = csrf_token
534 data['inherit_global_settings'] = True
535 settings = SettingsModel(repo=repo_name)
536
537 invalidation_patcher = mock.patch(
538 'rhodecode.model.scm.ScmModel.mark_for_invalidation')
539 with invalidation_patcher as invalidation_mock:
540 self.app.post(
541 route_path('edit_repo_vcs_update', repo_name=repo_name), data,
542 status=302)
543 try:
544 invalidation_mock.assert_called_once_with(repo_name, delete=True)
545 finally:
546 self._cleanup_repo_settings(settings)
547
548 def test_other_settings_not_saved_inherit_global_settings_is_true(
549 self, autologin_user, backend, csrf_token):
550 repo_name = backend.repo_name
551 data = self.FORM_DATA.copy()
552 data['csrf_token'] = csrf_token
553 data['inherit_global_settings'] = True
554 self.app.post(
555 route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302)
556
557 settings = SettingsModel(repo=repo_name)