Show More
@@ -242,7 +242,7 b' def RepoForm(edit=False, old_data=None, ' | |||
|
242 | 242 | allow_extra_fields = True |
|
243 | 243 | filter_extra_fields = False |
|
244 | 244 | repo_name = All(v.UnicodeString(strip=True, min=1, not_empty=True), |
|
245 | v.SlugifyName()) | |
|
245 | v.SlugifyName(), v.CannotHaveGitSuffix()) | |
|
246 | 246 | repo_group = All(v.CanWriteGroup(old_data), |
|
247 | 247 | v.OneOf(repo_groups, hideList=True)) |
|
248 | 248 | repo_type = v.OneOf(supported_backends, required=False, |
@@ -191,7 +191,12 b' def deferred_unique_name_validator(node,' | |||
|
191 | 191 | |
|
192 | 192 | @colander.deferred |
|
193 | 193 | def deferred_repo_name_validator(node, kw): |
|
194 | return validators.valid_name_validator | |
|
194 | def no_git_suffix_validator(node, value): | |
|
195 | if value.endswith('.git'): | |
|
196 | msg = _('Repository name cannot end with .git') | |
|
197 | raise colander.Invalid(node, msg) | |
|
198 | return colander.All( | |
|
199 | no_git_suffix_validator, validators.valid_name_validator) | |
|
195 | 200 | |
|
196 | 201 | |
|
197 | 202 | class GroupType(colander.Mapping): |
@@ -574,6 +574,26 b' def SlugifyName():' | |||
|
574 | 574 | return _validator |
|
575 | 575 | |
|
576 | 576 | |
|
577 | def CannotHaveGitSuffix(): | |
|
578 | class _validator(formencode.validators.FancyValidator): | |
|
579 | messages = { | |
|
580 | 'has_git_suffix': | |
|
581 | _(u'Repository name cannot end with .git'), | |
|
582 | } | |
|
583 | ||
|
584 | def _to_python(self, value, state): | |
|
585 | return value | |
|
586 | ||
|
587 | def validate_python(self, value, state): | |
|
588 | if value and value.endswith('.git'): | |
|
589 | msg = M( | |
|
590 | self, 'has_git_suffix', state) | |
|
591 | raise formencode.Invalid( | |
|
592 | msg, value, state, error_dict={'repo_name': msg}) | |
|
593 | ||
|
594 | return _validator | |
|
595 | ||
|
596 | ||
|
577 | 597 | def ValidCloneUri(): |
|
578 | 598 | class InvalidCloneUrl(Exception): |
|
579 | 599 | allowed_prefixes = () |
@@ -24,7 +24,7 b' import mock' | |||
|
24 | 24 | import pytest |
|
25 | 25 | |
|
26 | 26 | from rhodecode.lib import auth |
|
27 | from rhodecode.lib.utils2 import safe_str, str2bool | |
|
27 | from rhodecode.lib.utils2 import safe_str, str2bool, safe_unicode | |
|
28 | 28 | from rhodecode.lib.vcs.exceptions import RepositoryRequirementError |
|
29 | 29 | from rhodecode.model.db import Repository, RepoGroup, UserRepoToPerm, User,\ |
|
30 | 30 | Permission |
@@ -44,7 +44,7 b' fixture = Fixture()' | |||
|
44 | 44 | |
|
45 | 45 | |
|
46 | 46 | @pytest.mark.usefixtures("app") |
|
47 | class TestAdminRepos: | |
|
47 | class TestAdminRepos(object): | |
|
48 | 48 | |
|
49 | 49 | def test_index(self): |
|
50 | 50 | self.app.get(url('repos')) |
@@ -63,13 +63,14 b' class TestAdminRepos:' | |||
|
63 | 63 | assert_response.element_contains('#repo_type', 'svn') |
|
64 | 64 | assert_response.element_contains('#repo_type', 'hg') |
|
65 | 65 | |
|
66 |
@pytest.mark.parametrize("suffix", |
|
|
66 | @pytest.mark.parametrize("suffix", | |
|
67 | [u'', u'xxa'], ids=['', 'non-ascii']) | |
|
67 | 68 | def test_create(self, autologin_user, backend, suffix, csrf_token): |
|
68 | 69 | repo_name_unicode = backend.new_repo_name(suffix=suffix) |
|
69 | 70 | repo_name = repo_name_unicode.encode('utf8') |
|
70 | 71 | description_unicode = u'description for newly created repo' + suffix |
|
71 | 72 | description = description_unicode.encode('utf8') |
|
72 | self.app.post( | |
|
73 | response = self.app.post( | |
|
73 | 74 | url('repos'), |
|
74 | 75 | fixture._get_repo_create_params( |
|
75 | 76 | repo_private=False, |
@@ -77,8 +78,7 b' class TestAdminRepos:' | |||
|
77 | 78 | repo_type=backend.alias, |
|
78 | 79 | repo_description=description, |
|
79 | 80 | csrf_token=csrf_token), |
|
80 | status=302 | |
|
81 | ) | |
|
81 | status=302) | |
|
82 | 82 | |
|
83 | 83 | self.assert_repository_is_created_correctly( |
|
84 | 84 | repo_name, description, backend) |
@@ -368,6 +368,20 b' class TestAdminRepos:' | |||
|
368 | 368 | csrf_token=csrf_token)) |
|
369 | 369 | response.mustcontain('invalid clone url') |
|
370 | 370 | |
|
371 | def test_create_with_git_suffix( | |
|
372 | self, autologin_user, backend, csrf_token): | |
|
373 | repo_name = backend.new_repo_name() + ".git" | |
|
374 | description = 'description for newly created repo' | |
|
375 | response = self.app.post( | |
|
376 | url('repos'), | |
|
377 | fixture._get_repo_create_params( | |
|
378 | repo_private=False, | |
|
379 | repo_name=repo_name, | |
|
380 | repo_type=backend.alias, | |
|
381 | repo_description=description, | |
|
382 | csrf_token=csrf_token)) | |
|
383 | response.mustcontain('Repository name cannot end with .git') | |
|
384 | ||
|
371 | 385 | @pytest.mark.parametrize("suffix", [u'', u'ąęł'], ids=['', 'non-ascii']) |
|
372 | 386 | def test_delete(self, autologin_user, backend, suffix, csrf_token): |
|
373 | 387 | repo = backend.create_repo(name_suffix=suffix) |
@@ -596,15 +610,15 b' class TestAdminRepos:' | |||
|
596 | 610 | |
|
597 | 611 | def assert_repository_is_created_correctly( |
|
598 | 612 | self, repo_name, description, backend): |
|
599 |
repo_name_utf8 = repo_name |
|
|
613 | repo_name_utf8 = safe_str(repo_name) | |
|
600 | 614 | |
|
601 | 615 | # run the check page that triggers the flash message |
|
602 | 616 | response = self.app.get(url('repo_check_home', repo_name=repo_name)) |
|
603 | 617 | assert response.json == {u'result': True} |
|
604 | assert_session_flash( | |
|
605 | response, | |
|
606 | u'Created repository <a href="/%s">%s</a>' | |
|
607 | % (urllib.quote(repo_name_utf8), repo_name)) | |
|
618 | ||
|
619 | flash_msg = u'Created repository <a href="/{}">{}</a>'.format( | |
|
620 | urllib.quote(repo_name_utf8), repo_name) | |
|
621 | assert_session_flash(response, flash_msg) | |
|
608 | 622 | |
|
609 | 623 | # test if the repo was created in the database |
|
610 | 624 | new_repo = RepoModel().get_by_repo_name(repo_name) |
General Comments 0
You need to be logged in to leave comments.
Login now