Show More
@@ -0,0 +1,33 b'' | |||
|
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 | from rhodecode.apps._base import add_route_with_slash | |
|
21 | ||
|
22 | ||
|
23 | def includeme(config): | |
|
24 | ||
|
25 | # Summary | |
|
26 | add_route_with_slash( | |
|
27 | config, | |
|
28 | name='repo_group_home', | |
|
29 | pattern='/{repo_group_name:.*?[^/]}', repo_group_route=True) | |
|
30 | ||
|
31 | # Scan module for configuration decorators. | |
|
32 | config.scan() | |
|
33 |
@@ -28,7 +28,7 b' from rhodecode.api.tests.utils import (' | |||
|
28 | 28 | |
|
29 | 29 | @pytest.mark.usefixtures("testuser_api", "app") |
|
30 | 30 | class TestApiGetGist(object): |
|
31 | def test_api_get_gist(self, gist_util): | |
|
31 | def test_api_get_gist(self, gist_util, http_host_stub): | |
|
32 | 32 | gist = gist_util.create_gist() |
|
33 | 33 | gist_id = gist.gist_access_id |
|
34 | 34 | gist_created_on = gist.created_on |
@@ -45,14 +45,14 b' class TestApiGetGist(object):' | |||
|
45 | 45 | 'expires': -1.0, |
|
46 | 46 | 'gist_id': int(gist_id), |
|
47 | 47 | 'type': 'public', |
|
48 |
'url': 'http:// |
|
|
48 | 'url': 'http://%s/_admin/gists/%s' % (http_host_stub, gist_id,), | |
|
49 | 49 | 'acl_level': Gist.ACL_LEVEL_PUBLIC, |
|
50 | 50 | 'content': None, |
|
51 | 51 | } |
|
52 | 52 | |
|
53 | 53 | assert_ok(id_, expected, given=response.body) |
|
54 | 54 | |
|
55 | def test_api_get_gist_with_content(self, gist_util): | |
|
55 | def test_api_get_gist_with_content(self, gist_util, http_host_stub): | |
|
56 | 56 | mapping = { |
|
57 | 57 | u'filename1.txt': {'content': u'hello world'}, |
|
58 | 58 | u'filename1Δ .txt': {'content': u'hello worldΔ'} |
@@ -73,7 +73,7 b' class TestApiGetGist(object):' | |||
|
73 | 73 | 'expires': -1.0, |
|
74 | 74 | 'gist_id': int(gist_id), |
|
75 | 75 | 'type': 'public', |
|
76 |
'url': 'http:// |
|
|
76 | 'url': 'http://%s/_admin/gists/%s' % (http_host_stub, gist_id,), | |
|
77 | 77 | 'acl_level': Gist.ACL_LEVEL_PUBLIC, |
|
78 | 78 | 'content': { |
|
79 | 79 | u'filename1.txt': u'hello world', |
@@ -19,13 +19,13 b'' | |||
|
19 | 19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
20 | 20 | |
|
21 | 21 | |
|
22 | import mock | |
|
23 | 22 | import pytest |
|
24 | 23 | import urlobject |
|
25 | 24 | from pylons import url |
|
26 | 25 | |
|
27 | 26 | from rhodecode.api.tests.utils import ( |
|
28 | 27 | build_data, api_call, assert_error, assert_ok) |
|
28 | from rhodecode.lib.utils2 import safe_unicode | |
|
29 | 29 | |
|
30 | 30 | pytestmark = pytest.mark.backends("git", "hg") |
|
31 | 31 | |
@@ -33,7 +33,7 b' pytestmark = pytest.mark.backends("git",' | |||
|
33 | 33 | @pytest.mark.usefixtures("testuser_api", "app") |
|
34 | 34 | class TestGetPullRequest(object): |
|
35 | 35 | |
|
36 | def test_api_get_pull_request(self, pr_util): | |
|
36 | def test_api_get_pull_request(self, pr_util, http_host_stub, http_host_only_stub): | |
|
37 | 37 | from rhodecode.model.pull_request import PullRequestModel |
|
38 | 38 | pull_request = pr_util.create_pull_request(mergeable=True) |
|
39 | 39 | id_, params = build_data( |
@@ -50,16 +50,16 b' class TestGetPullRequest(object):' | |||
|
50 | 50 | 'pullrequest_show', |
|
51 | 51 | repo_name=pull_request.target_repo.repo_name, |
|
52 | 52 | pull_request_id=pull_request.pull_request_id, qualified=True)) |
|
53 | pr_url = unicode( | |
|
54 | url_obj.with_netloc('test.example.com:80')) | |
|
55 | source_url = unicode( | |
|
56 | pull_request.source_repo.clone_url() | |
|
57 | .with_netloc('test.example.com:80')) | |
|
58 | target_url = unicode( | |
|
59 | pull_request.target_repo.clone_url() | |
|
60 | .with_netloc('test.example.com:80')) | |
|
61 | shadow_url = unicode( | |
|
53 | ||
|
54 | pr_url = safe_unicode( | |
|
55 | url_obj.with_netloc(http_host_stub)) | |
|
56 | source_url = safe_unicode( | |
|
57 | pull_request.source_repo.clone_url().with_netloc(http_host_only_stub)) | |
|
58 | target_url = safe_unicode( | |
|
59 | pull_request.target_repo.clone_url().with_netloc(http_host_only_stub)) | |
|
60 | shadow_url = safe_unicode( | |
|
62 | 61 | PullRequestModel().get_shadow_clone_url(pull_request)) |
|
62 | ||
|
63 | 63 | expected = { |
|
64 | 64 | 'pull_request_id': pull_request.pull_request_id, |
|
65 | 65 | 'url': pr_url, |
@@ -26,7 +26,7 b' from rhodecode.tests import TEST_USER_AD' | |||
|
26 | 26 | from rhodecode.api.tests.utils import ( |
|
27 | 27 | build_data, api_call, assert_error, assert_ok, crash, jsonify) |
|
28 | 28 | from rhodecode.tests.fixture import Fixture |
|
29 | ||
|
29 | from rhodecode.tests.plugin import http_host_stub, http_host_only_stub | |
|
30 | 30 | |
|
31 | 31 | fixture = Fixture() |
|
32 | 32 | |
@@ -71,14 +71,15 b' class TestApiUpdateRepo(object):' | |||
|
71 | 71 | ({'repo_name': 'new_repo_name'}, |
|
72 | 72 | { |
|
73 | 73 | 'repo_name': 'new_repo_name', |
|
74 |
'url': 'http:// |
|
|
74 | 'url': 'http://{}/new_repo_name'.format(http_host_only_stub()) | |
|
75 | 75 | }), |
|
76 | 76 | |
|
77 | 77 | ({'repo_name': 'test_group_for_update/{}'.format(UPDATE_REPO_NAME), |
|
78 | 78 | '_group': 'test_group_for_update'}, |
|
79 | 79 | { |
|
80 | 80 | 'repo_name': 'test_group_for_update/{}'.format(UPDATE_REPO_NAME), |
|
81 |
'url': 'http:// |
|
|
81 | 'url': 'http://{}/test_group_for_update/{}'.format( | |
|
82 | http_host_only_stub(), UPDATE_REPO_NAME) | |
|
82 | 83 | }), |
|
83 | 84 | ]) |
|
84 | 85 | def test_api_update_repo(self, updates, expected, backend): |
@@ -0,0 +1,19 b'' | |||
|
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/ |
@@ -29,6 +29,7 b' from rhodecode.lib.utils2 import StrictA' | |||
|
29 | 29 | from rhodecode.lib.vcs.exceptions import RepositoryRequirementError |
|
30 | 30 | from rhodecode.lib.ext_json import json |
|
31 | 31 | from rhodecode.model import repo |
|
32 | from rhodecode.model import repo_group | |
|
32 | 33 | from rhodecode.model.db import User |
|
33 | 34 | from rhodecode.model.scm import ScmModel |
|
34 | 35 | |
@@ -39,6 +40,12 b" ADMIN_PREFIX = '/_admin'" | |||
|
39 | 40 | STATIC_FILE_PREFIX = '/_static' |
|
40 | 41 | |
|
41 | 42 | |
|
43 | def add_route_with_slash(config,name, pattern, **kw): | |
|
44 | config.add_route(name, pattern, **kw) | |
|
45 | if not pattern.endswith('/'): | |
|
46 | config.add_route(name + '_slash', pattern + '/', **kw) | |
|
47 | ||
|
48 | ||
|
42 | 49 | def get_format_ref_id(repo): |
|
43 | 50 | """Returns a `repo` specific reference formatter function""" |
|
44 | 51 | if h.is_svn(repo): |
@@ -253,8 +260,7 b' class RepoRoutePredicate(object):' | |||
|
253 | 260 | repo_name = info['match']['repo_name'] |
|
254 | 261 | repo_model = repo.RepoModel() |
|
255 | 262 | by_name_match = repo_model.get_by_repo_name(repo_name, cache=True) |
|
256 | # if we match quickly from database, short circuit the operation, | |
|
257 | # and validate repo based on the type. | |
|
263 | ||
|
258 | 264 | if by_name_match: |
|
259 | 265 | # register this as request object we can re-use later |
|
260 | 266 | request.db_repo = by_name_match |
@@ -300,9 +306,33 b' class RepoTypeRoutePredicate(object):' | |||
|
300 | 306 | return False |
|
301 | 307 | |
|
302 | 308 | |
|
309 | class RepoGroupRoutePredicate(object): | |
|
310 | def __init__(self, val, config): | |
|
311 | self.val = val | |
|
312 | ||
|
313 | def text(self): | |
|
314 | return 'repo_group_route = %s' % self.val | |
|
315 | ||
|
316 | phash = text | |
|
317 | ||
|
318 | def __call__(self, info, request): | |
|
319 | repo_group_name = info['match']['repo_group_name'] | |
|
320 | repo_group_model = repo_group.RepoGroupModel() | |
|
321 | by_name_match = repo_group_model.get_by_group_name( | |
|
322 | repo_group_name, cache=True) | |
|
323 | ||
|
324 | if by_name_match: | |
|
325 | # register this as request object we can re-use later | |
|
326 | request.db_repo_group = by_name_match | |
|
327 | return True | |
|
328 | ||
|
329 | return False | |
|
330 | ||
|
303 | 331 | |
|
304 | 332 | def includeme(config): |
|
305 | 333 | config.add_route_predicate( |
|
306 | 334 | 'repo_route', RepoRoutePredicate) |
|
307 | 335 | config.add_route_predicate( |
|
308 | 'repo_accepted_types', RepoTypeRoutePredicate) No newline at end of file | |
|
336 | 'repo_accepted_types', RepoTypeRoutePredicate) | |
|
337 | config.add_route_predicate( | |
|
338 | 'repo_group_route', RepoGroupRoutePredicate) |
@@ -28,18 +28,25 b' from rhodecode.model.meta import Session' | |||
|
28 | 28 | from rhodecode.model.repo import RepoModel |
|
29 | 29 | from rhodecode.model.repo_group import RepoGroupModel |
|
30 | 30 | from rhodecode.model.settings import SettingsModel |
|
31 |
from rhodecode.tests import TestController |
|
|
31 | from rhodecode.tests import TestController | |
|
32 | 32 | from rhodecode.tests.fixture import Fixture |
|
33 | 33 | |
|
34 | 34 | |
|
35 | 35 | fixture = Fixture() |
|
36 | 36 | |
|
37 | 37 | |
|
38 | def route_path(name, **kwargs): | |
|
39 | return { | |
|
40 | 'home': '/', | |
|
41 | 'repo_group_home': '/{repo_group_name}' | |
|
42 | }[name].format(**kwargs) | |
|
43 | ||
|
44 | ||
|
38 | 45 | class TestHomeController(TestController): |
|
39 | 46 | |
|
40 | 47 | def test_index(self): |
|
41 | 48 | self.log_user() |
|
42 |
response = self.app.get( |
|
|
49 | response = self.app.get(route_path('home')) | |
|
43 | 50 | # if global permission is set |
|
44 | 51 | response.mustcontain('Add Repository') |
|
45 | 52 | |
@@ -49,7 +56,7 b' class TestHomeController(TestController)' | |||
|
49 | 56 | |
|
50 | 57 | def test_index_contains_statics_with_ver(self): |
|
51 | 58 | self.log_user() |
|
52 |
response = self.app.get( |
|
|
59 | response = self.app.get(route_path('home')) | |
|
53 | 60 | |
|
54 | 61 | rhodecode_version_hash = c.rhodecode_version_hash |
|
55 | 62 | response.mustcontain('style.css?ver={0}'.format(rhodecode_version_hash)) |
@@ -57,7 +64,7 b' class TestHomeController(TestController)' | |||
|
57 | 64 | |
|
58 | 65 | def test_index_contains_backend_specific_details(self, backend): |
|
59 | 66 | self.log_user() |
|
60 |
response = self.app.get( |
|
|
67 | response = self.app.get(route_path('home')) | |
|
61 | 68 | tip = backend.repo.get_commit().raw_id |
|
62 | 69 | |
|
63 | 70 | # html in javascript variable: |
@@ -69,17 +76,16 b' class TestHomeController(TestController)' | |||
|
69 | 76 | |
|
70 | 77 | def test_index_with_anonymous_access_disabled(self): |
|
71 | 78 | with fixture.anon_access(False): |
|
72 |
response = self.app.get( |
|
|
73 | status=302) | |
|
79 | response = self.app.get(route_path('home'), status=302) | |
|
74 | 80 | assert 'login' in response.location |
|
75 | 81 | |
|
76 | 82 | def test_index_page_on_groups(self, autologin_user, repo_group): |
|
77 |
response = self.app.get( |
|
|
83 | response = self.app.get(route_path('repo_group_home', repo_group_name='gr1')) | |
|
78 | 84 | response.mustcontain("gr1/repo_in_group") |
|
79 | 85 | |
|
80 | 86 | def test_index_page_on_group_with_trailing_slash( |
|
81 | 87 | self, autologin_user, repo_group): |
|
82 |
response = self.app.get( |
|
|
88 | response = self.app.get(route_path('repo_group_home', repo_group_name='gr1') + '/') | |
|
83 | 89 | response.mustcontain("gr1/repo_in_group") |
|
84 | 90 | |
|
85 | 91 | @pytest.fixture(scope='class') |
@@ -93,15 +99,17 b' class TestHomeController(TestController)' | |||
|
93 | 99 | RepoGroupModel().delete(repo_group='gr1', force_delete=True) |
|
94 | 100 | Session().commit() |
|
95 | 101 | |
|
96 | def test_index_with_name_with_tags(self, autologin_user): | |
|
97 |
user = |
|
|
102 | def test_index_with_name_with_tags(self, user_util, autologin_user): | |
|
103 | user = user_util.create_user() | |
|
104 | username = user.username | |
|
98 | 105 | user.name = '<img src="/image1" onload="alert(\'Hello, World!\');">' |
|
99 | 106 | user.lastname = ( |
|
100 | 107 | '<img src="/image2" onload="alert(\'Hello, World!\');">') |
|
101 | 108 | Session().add(user) |
|
102 | 109 | Session().commit() |
|
110 | user_util.create_repo(owner=username) | |
|
103 | 111 | |
|
104 |
response = self.app.get( |
|
|
112 | response = self.app.get(route_path('home')) | |
|
105 | 113 | response.mustcontain( |
|
106 | 114 | '<img src="/image1" onload="' |
|
107 | 115 | 'alert('Hello, World!');">') |
@@ -122,7 +130,7 b' class TestHomeController(TestController)' | |||
|
122 | 130 | Session().commit() |
|
123 | 131 | SettingsModel().invalidate_settings_cache() |
|
124 | 132 | |
|
125 |
response = self.app.get( |
|
|
133 | response = self.app.get(route_path('home')) | |
|
126 | 134 | if state is True: |
|
127 | 135 | response.mustcontain(version_string) |
|
128 | 136 | if state is False: |
@@ -25,12 +25,15 b' from pyramid.view import view_config' | |||
|
25 | 25 | |
|
26 | 26 | from rhodecode.apps._base import BaseAppView |
|
27 | 27 | from rhodecode.lib import helpers as h |
|
28 | from rhodecode.lib.auth import LoginRequired, NotAnonymous | |
|
28 | from rhodecode.lib.auth import LoginRequired, NotAnonymous, \ | |
|
29 | HasRepoGroupPermissionAnyDecorator | |
|
29 | 30 | from rhodecode.lib.index import searcher_from_config |
|
30 | 31 | from rhodecode.lib.utils2 import safe_unicode, str2bool |
|
32 | from rhodecode.lib.ext_json import json | |
|
31 | 33 | from rhodecode.model.db import func, Repository, RepoGroup |
|
32 | 34 | from rhodecode.model.repo import RepoModel |
|
33 |
from rhodecode.model. |
|
|
35 | from rhodecode.model.repo_group import RepoGroupModel | |
|
36 | from rhodecode.model.scm import ScmModel, RepoGroupList, RepoList | |
|
34 | 37 | from rhodecode.model.user import UserModel |
|
35 | 38 | from rhodecode.model.user_group import UserGroupModel |
|
36 | 39 | |
@@ -143,7 +146,7 b' class HomeView(BaseAppView):' | |||
|
143 | 146 | 'text': obj.group_name, |
|
144 | 147 | 'type': 'group', |
|
145 | 148 | 'obj': {}, |
|
146 |
'url': h. |
|
|
149 | 'url': h.route_path('repo_group_home', repo_group_name=obj.group_name) | |
|
147 | 150 | } |
|
148 | 151 | for obj in repo_groups_iter] |
|
149 | 152 | |
@@ -246,3 +249,56 b' class HomeView(BaseAppView):' | |||
|
246 | 249 | 'results': res |
|
247 | 250 | } |
|
248 | 251 | return data |
|
252 | ||
|
253 | def _get_groups_and_repos(self, repo_group_id=None): | |
|
254 | # repo groups groups | |
|
255 | repo_group_list = RepoGroup.get_all_repo_groups(group_id=repo_group_id) | |
|
256 | _perms = ['group.read', 'group.write', 'group.admin'] | |
|
257 | repo_group_list_acl = RepoGroupList(repo_group_list, perm_set=_perms) | |
|
258 | repo_group_data = RepoGroupModel().get_repo_groups_as_dict( | |
|
259 | repo_group_list=repo_group_list_acl, admin=False) | |
|
260 | ||
|
261 | # repositories | |
|
262 | repo_list = Repository.get_all_repos(group_id=repo_group_id) | |
|
263 | _perms = ['repository.read', 'repository.write', 'repository.admin'] | |
|
264 | repo_list_acl = RepoList(repo_list, perm_set=_perms) | |
|
265 | repo_data = RepoModel().get_repos_as_dict( | |
|
266 | repo_list=repo_list_acl, admin=False) | |
|
267 | ||
|
268 | return repo_data, repo_group_data | |
|
269 | ||
|
270 | @LoginRequired() | |
|
271 | @view_config( | |
|
272 | route_name='home', request_method='GET', | |
|
273 | renderer='rhodecode:templates/index.mako') | |
|
274 | def main_page(self): | |
|
275 | c = self.load_default_context() | |
|
276 | c.repo_group = None | |
|
277 | ||
|
278 | repo_data, repo_group_data = self._get_groups_and_repos() | |
|
279 | # json used to render the grids | |
|
280 | c.repos_data = json.dumps(repo_data) | |
|
281 | c.repo_groups_data = json.dumps(repo_group_data) | |
|
282 | ||
|
283 | return self._get_template_context(c) | |
|
284 | ||
|
285 | @LoginRequired() | |
|
286 | @HasRepoGroupPermissionAnyDecorator( | |
|
287 | 'group.read', 'group.write', 'group.admin') | |
|
288 | @view_config( | |
|
289 | route_name='repo_group_home', request_method='GET', | |
|
290 | renderer='rhodecode:templates/index_repo_group.mako') | |
|
291 | @view_config( | |
|
292 | route_name='repo_group_home_slash', request_method='GET', | |
|
293 | renderer='rhodecode:templates/index_repo_group.mako') | |
|
294 | def repo_group_main_page(self): | |
|
295 | c = self.load_default_context() | |
|
296 | c.repo_group = self.request.db_repo_group | |
|
297 | repo_data, repo_group_data = self._get_groups_and_repos( | |
|
298 | c.repo_group.group_id) | |
|
299 | ||
|
300 | # json used to render the grids | |
|
301 | c.repos_data = json.dumps(repo_data) | |
|
302 | c.repo_groups_data = json.dumps(repo_group_data) | |
|
303 | ||
|
304 | return self._get_template_context(c) |
@@ -25,7 +25,6 b' import formencode' | |||
|
25 | 25 | import logging |
|
26 | 26 | import urlparse |
|
27 | 27 | |
|
28 | from pylons import url | |
|
29 | 28 | from pyramid.httpexceptions import HTTPFound |
|
30 | 29 | from pyramid.view import view_config |
|
31 | 30 | from recaptcha.client.captcha import submit |
@@ -91,20 +90,21 b' def get_came_from(request):' | |||
|
91 | 90 | came_from = safe_str(request.GET.get('came_from', '')) |
|
92 | 91 | parsed = urlparse.urlparse(came_from) |
|
93 | 92 | allowed_schemes = ['http', 'https'] |
|
93 | default_came_from = h.route_path('home') | |
|
94 | 94 | if parsed.scheme and parsed.scheme not in allowed_schemes: |
|
95 | 95 | log.error('Suspicious URL scheme detected %s for url %s' % |
|
96 | 96 | (parsed.scheme, parsed)) |
|
97 |
came_from = |
|
|
97 | came_from = default_came_from | |
|
98 | 98 | elif parsed.netloc and request.host != parsed.netloc: |
|
99 | 99 | log.error('Suspicious NETLOC detected %s for url %s server url ' |
|
100 | 100 | 'is: %s' % (parsed.netloc, parsed, request.host)) |
|
101 |
came_from = |
|
|
101 | came_from = default_came_from | |
|
102 | 102 | elif any(bad_str in parsed.path for bad_str in ('\r', '\n')): |
|
103 | 103 | log.error('Header injection detected `%s` for url %s server url ' % |
|
104 | 104 | (parsed.path, parsed)) |
|
105 |
came_from = |
|
|
105 | came_from = default_came_from | |
|
106 | 106 | |
|
107 |
return came_from or |
|
|
107 | return came_from or default_came_from | |
|
108 | 108 | |
|
109 | 109 | |
|
110 | 110 | class LoginView(BaseAppView): |
@@ -215,7 +215,7 b' class LoginView(BaseAppView):' | |||
|
215 | 215 | action='user.logout', action_data=action_data, |
|
216 | 216 | user=auth_user, commit=True) |
|
217 | 217 | self.session.delete() |
|
218 |
return HTTPFound( |
|
|
218 | return HTTPFound(h.route_path('home')) | |
|
219 | 219 | |
|
220 | 220 | @HasPermissionAnyDecorator( |
|
221 | 221 | 'hg.admin', 'hg.register.auto_activate', 'hg.register.manual_activate') |
@@ -132,6 +132,7 b' class TestMyAccountPassword(TestControll' | |||
|
132 | 132 | self.app.post(route_path('my_account_password'), form_data) |
|
133 | 133 | |
|
134 | 134 | response = self.app.get(route_path('home')) |
|
135 | new_password_hash = response.session['rhodecode_user']['password'] | |
|
135 | session = response.get_session_from_response() | |
|
136 | new_password_hash = session['rhodecode_user']['password'] | |
|
136 | 137 | |
|
137 | 138 | assert old_password_hash != new_password_hash No newline at end of file |
@@ -23,6 +23,10 b' def includeme(config):' | |||
|
23 | 23 | |
|
24 | 24 | # Summary |
|
25 | 25 | config.add_route( |
|
26 | name='repo_summary', | |
|
27 | pattern='/{repo_name:.*?[^/]}', repo_route=True) | |
|
28 | ||
|
29 | config.add_route( | |
|
26 | 30 | name='repo_summary_explicit', |
|
27 | 31 | pattern='/{repo_name:.*?[^/]}/summary', repo_route=True) |
|
28 | 32 |
@@ -292,6 +292,7 b' def includeme(config):' | |||
|
292 | 292 | config.include('rhodecode.apps.login') |
|
293 | 293 | config.include('rhodecode.apps.home') |
|
294 | 294 | config.include('rhodecode.apps.repository') |
|
295 | config.include('rhodecode.apps.repo_group') | |
|
295 | 296 | config.include('rhodecode.apps.search') |
|
296 | 297 | config.include('rhodecode.apps.user_profile') |
|
297 | 298 | config.include('rhodecode.apps.my_account') |
@@ -184,9 +184,6 b' def make_map(config):' | |||
|
184 | 184 | # CUSTOM ROUTES HERE |
|
185 | 185 | #========================================================================== |
|
186 | 186 | |
|
187 | # MAIN PAGE | |
|
188 | rmap.connect('home', '/', controller='home', action='index') | |
|
189 | ||
|
190 | 187 | # ping and pylons error test |
|
191 | 188 | rmap.connect('ping', '%s/ping' % (ADMIN_PREFIX,), controller='home', action='ping') |
|
192 | 189 | rmap.connect('error_test', '%s/error_test' % (ADMIN_PREFIX,), controller='home', action='error_test') |
@@ -1002,13 +999,6 b' def make_map(config):' | |||
|
1002 | 999 | conditions={'function': check_repo}, |
|
1003 | 1000 | requirements=URL_NAME_REQUIREMENTS) |
|
1004 | 1001 | |
|
1005 | # must be here for proper group/repo catching pattern | |
|
1006 | _connect_with_slash( | |
|
1007 | rmap, 'repo_group_home', '/{group_name}', | |
|
1008 | controller='home', action='index_repo_group', | |
|
1009 | conditions={'function': check_group}, | |
|
1010 | requirements=URL_NAME_REQUIREMENTS) | |
|
1011 | ||
|
1012 | 1002 | # catch all, at the end |
|
1013 | 1003 | _connect_with_slash( |
|
1014 | 1004 | rmap, 'summary_home', '/{repo_name}', jsroute=True, |
@@ -193,10 +193,10 b' class RepoGroupsController(BaseControlle' | |||
|
193 | 193 | _new_group_name = form_result['group_name_full'] |
|
194 | 194 | repo_group_url = h.link_to( |
|
195 | 195 | _new_group_name, |
|
196 |
h. |
|
|
196 | h.route_path('repo_group_home', repo_group_name=_new_group_name)) | |
|
197 | 197 | h.flash(h.literal(_('Created repository group %s') |
|
198 | 198 | % repo_group_url), category='success') |
|
199 | # TODO: in futureaction_logger(, '', '', '', self.sa) | |
|
199 | # TODO: in future action_logger(, '', '', '', self.sa) | |
|
200 | 200 | except formencode.Invalid as errors: |
|
201 | 201 | return htmlfill.render( |
|
202 | 202 | render('admin/repo_groups/repo_group_add.mako'), |
@@ -234,7 +234,6 b' class RepoGroupsController(BaseControlle' | |||
|
234 | 234 | # <input type="hidden" name="_method" value="PUT" /> |
|
235 | 235 | # Or using helpers: |
|
236 | 236 | # h.form(url('repos_group', group_name=GROUP_NAME), method='put') |
|
237 | # url('repo_group_home', group_name=GROUP_NAME) | |
|
238 | 237 | |
|
239 | 238 | c.repo_group = RepoGroupModel()._get_repo_group(group_name) |
|
240 | 239 | can_create_in_root = self._can_create_repo_group() |
@@ -284,7 +283,6 b' class RepoGroupsController(BaseControlle' | |||
|
284 | 283 | # <input type="hidden" name="_method" value="DELETE" /> |
|
285 | 284 | # Or using helpers: |
|
286 | 285 | # h.form(url('repos_group', group_name=GROUP_NAME), method='delete') |
|
287 | # url('repo_group_home', group_name=GROUP_NAME) | |
|
288 | 286 | |
|
289 | 287 | gr = c.repo_group = RepoGroupModel()._get_repo_group(group_name) |
|
290 | 288 | repos = gr.repositories.all() |
@@ -185,7 +185,7 b' class ReposController(BaseRepoController' | |||
|
185 | 185 | except Exception as e: |
|
186 | 186 | msg = self._log_creation_exception(e, form_result.get('repo_name')) |
|
187 | 187 | h.flash(msg, category='error') |
|
188 |
return redirect( |
|
|
188 | return redirect(h.route_path('home')) | |
|
189 | 189 | |
|
190 | 190 | return redirect(h.url('repo_creating_home', |
|
191 | 191 | repo_name=form_result['repo_name_full'], |
@@ -265,7 +265,7 b' class ReposController(BaseRepoController' | |||
|
265 | 265 | if task.failed(): |
|
266 | 266 | msg = self._log_creation_exception(task.result, c.repo) |
|
267 | 267 | h.flash(msg, category='error') |
|
268 |
return redirect( |
|
|
268 | return redirect(h.route_path('home'), code=501) | |
|
269 | 269 | |
|
270 | 270 | repo = Repository.get_by_repo_name(repo_name) |
|
271 | 271 | if repo and repo.repo_state == Repository.STATE_CREATED: |
@@ -139,7 +139,7 b' class ForksController(BaseRepoController' | |||
|
139 | 139 | c.repo_info = Repository.get_by_repo_name(repo_name) |
|
140 | 140 | if not c.repo_info: |
|
141 | 141 | h.not_mapped_error(repo_name) |
|
142 |
return redirect( |
|
|
142 | return redirect(h.route_path('home')) | |
|
143 | 143 | |
|
144 | 144 | defaults = self.__load_data(repo_name) |
|
145 | 145 |
@@ -65,46 +65,3 b' class HomeController(BaseController):' | |||
|
65 | 65 | msg = ('RhodeCode Enterprise %s test exception. Generation time: %s' |
|
66 | 66 | % (c.rhodecode_name, time.time())) |
|
67 | 67 | raise TestException(msg) |
|
68 | ||
|
69 | def _get_groups_and_repos(self, repo_group_id=None): | |
|
70 | # repo groups groups | |
|
71 | repo_group_list = RepoGroup.get_all_repo_groups(group_id=repo_group_id) | |
|
72 | _perms = ['group.read', 'group.write', 'group.admin'] | |
|
73 | repo_group_list_acl = RepoGroupList(repo_group_list, perm_set=_perms) | |
|
74 | repo_group_data = RepoGroupModel().get_repo_groups_as_dict( | |
|
75 | repo_group_list=repo_group_list_acl, admin=False) | |
|
76 | ||
|
77 | # repositories | |
|
78 | repo_list = Repository.get_all_repos(group_id=repo_group_id) | |
|
79 | _perms = ['repository.read', 'repository.write', 'repository.admin'] | |
|
80 | repo_list_acl = RepoList(repo_list, perm_set=_perms) | |
|
81 | repo_data = RepoModel().get_repos_as_dict( | |
|
82 | repo_list=repo_list_acl, admin=False) | |
|
83 | ||
|
84 | return repo_data, repo_group_data | |
|
85 | ||
|
86 | @LoginRequired() | |
|
87 | def index(self): | |
|
88 | c.repo_group = None | |
|
89 | ||
|
90 | repo_data, repo_group_data = self._get_groups_and_repos() | |
|
91 | # json used to render the grids | |
|
92 | c.repos_data = json.dumps(repo_data) | |
|
93 | c.repo_groups_data = json.dumps(repo_group_data) | |
|
94 | ||
|
95 | return render('/index.mako') | |
|
96 | ||
|
97 | @LoginRequired() | |
|
98 | @HasRepoGroupPermissionAnyDecorator('group.read', 'group.write', | |
|
99 | 'group.admin') | |
|
100 | def index_repo_group(self, group_name): | |
|
101 | """GET /repo_group_name: Show a specific item""" | |
|
102 | c.repo_group = RepoGroupModel()._get_repo_group(group_name) | |
|
103 | repo_data, repo_group_data = self._get_groups_and_repos( | |
|
104 | c.repo_group.group_id) | |
|
105 | ||
|
106 | # json used to render the grids | |
|
107 | c.repos_data = json.dumps(repo_data) | |
|
108 | c.repo_groups_data = json.dumps(repo_group_data) | |
|
109 | ||
|
110 | return render('index_repo_group.mako') |
@@ -82,7 +82,7 b' class RhodecodeEvent(object):' | |||
|
82 | 82 | if self.request: |
|
83 | 83 | from rhodecode.lib import helpers as h |
|
84 | 84 | try: |
|
85 |
return h.url('home' |
|
|
85 | return h.route_url('home') | |
|
86 | 86 | except Exception: |
|
87 | 87 | log.exception('Failed to fetch URL for server') |
|
88 | 88 | return default |
@@ -1377,7 +1377,7 b' class PermsDecorator(object):' | |||
|
1377 | 1377 | if anonymous: |
|
1378 | 1378 | came_from = self._get_came_from() |
|
1379 | 1379 | h.flash(_('You need to be signed in to view this page'), |
|
1380 |
|
|
|
1380 | category='warning') | |
|
1381 | 1381 | raise HTTPFound( |
|
1382 | 1382 | h.route_path('login', _query={'came_from': came_from})) |
|
1383 | 1383 | |
@@ -1429,10 +1429,16 b' class HasRepoPermissionAllDecorator(Perm' | |||
|
1429 | 1429 | def check_permissions(self, user): |
|
1430 | 1430 | perms = user.permissions |
|
1431 | 1431 | repo_name = self._get_repo_name() |
|
1432 | ||
|
1432 | 1433 | try: |
|
1433 | 1434 | user_perms = set([perms['repositories'][repo_name]]) |
|
1434 | 1435 | except KeyError: |
|
1436 | log.debug('cannot locate repo with name: `%s` in permissions defs', | |
|
1437 | repo_name) | |
|
1435 | 1438 | return False |
|
1439 | ||
|
1440 | log.debug('checking `%s` permissions for repo `%s`', | |
|
1441 | user_perms, repo_name) | |
|
1436 | 1442 | if self.required_perms.issubset(user_perms): |
|
1437 | 1443 | return True |
|
1438 | 1444 | return False |
@@ -1450,11 +1456,16 b' class HasRepoPermissionAnyDecorator(Perm' | |||
|
1450 | 1456 | def check_permissions(self, user): |
|
1451 | 1457 | perms = user.permissions |
|
1452 | 1458 | repo_name = self._get_repo_name() |
|
1459 | ||
|
1453 | 1460 | try: |
|
1454 | 1461 | user_perms = set([perms['repositories'][repo_name]]) |
|
1455 | 1462 | except KeyError: |
|
1463 | log.debug('cannot locate repo with name: `%s` in permissions defs', | |
|
1464 | repo_name) | |
|
1456 | 1465 | return False |
|
1457 | 1466 | |
|
1467 | log.debug('checking `%s` permissions for repo `%s`', | |
|
1468 | user_perms, repo_name) | |
|
1458 | 1469 | if self.required_perms.intersection(user_perms): |
|
1459 | 1470 | return True |
|
1460 | 1471 | return False |
@@ -1476,8 +1487,12 b' class HasRepoGroupPermissionAllDecorator' | |||
|
1476 | 1487 | try: |
|
1477 | 1488 | user_perms = set([perms['repositories_groups'][group_name]]) |
|
1478 | 1489 | except KeyError: |
|
1490 | log.debug('cannot locate repo group with name: `%s` in permissions defs', | |
|
1491 | group_name) | |
|
1479 | 1492 | return False |
|
1480 | 1493 | |
|
1494 | log.debug('checking `%s` permissions for repo group `%s`', | |
|
1495 | user_perms, group_name) | |
|
1481 | 1496 | if self.required_perms.issubset(user_perms): |
|
1482 | 1497 | return True |
|
1483 | 1498 | return False |
@@ -1496,11 +1511,16 b' class HasRepoGroupPermissionAnyDecorator' | |||
|
1496 | 1511 | def check_permissions(self, user): |
|
1497 | 1512 | perms = user.permissions |
|
1498 | 1513 | group_name = self._get_repo_group_name() |
|
1514 | ||
|
1499 | 1515 | try: |
|
1500 | 1516 | user_perms = set([perms['repositories_groups'][group_name]]) |
|
1501 | 1517 | except KeyError: |
|
1518 | log.debug('cannot locate repo group with name: `%s` in permissions defs', | |
|
1519 | group_name) | |
|
1502 | 1520 | return False |
|
1503 | 1521 | |
|
1522 | log.debug('checking `%s` permissions for repo group `%s`', | |
|
1523 | user_perms, group_name) | |
|
1504 | 1524 | if self.required_perms.intersection(user_perms): |
|
1505 | 1525 | return True |
|
1506 | 1526 | return False |
@@ -555,7 +555,7 b' class BaseRepoController(BaseController)' | |||
|
555 | 555 | "The repository at %(repo_name)s cannot be located.") % |
|
556 | 556 | {'repo_name': c.repo_name}, |
|
557 | 557 | category='error', ignore_duplicate=True) |
|
558 |
redirect( |
|
|
558 | redirect(h.route_path('home')) | |
|
559 | 559 | |
|
560 | 560 | # update last change according to VCS data |
|
561 | 561 | if not missing_requirements: |
@@ -1534,7 +1534,7 b' def breadcrumb_repo_link(repo):' | |||
|
1534 | 1534 | """ |
|
1535 | 1535 | |
|
1536 | 1536 | path = [ |
|
1537 |
link_to(group.name, |
|
|
1537 | link_to(group.name, route_path('repo_group_home', repo_group_name=group.group_name)) | |
|
1538 | 1538 | for group in repo.groups_with_parents |
|
1539 | 1539 | ] + [ |
|
1540 | 1540 | link_to(repo.just_name, url('summary_home', repo_name=repo.repo_name)) |
@@ -1960,24 +1960,24 b' def get_last_path_part(file_node):' | |||
|
1960 | 1960 | return u'../' + path |
|
1961 | 1961 | |
|
1962 | 1962 | |
|
1963 |
def route_url(*args, **kw |
|
|
1963 | def route_url(*args, **kwargs): | |
|
1964 | 1964 | """ |
|
1965 | 1965 | Wrapper around pyramids `route_url` (fully qualified url) function. |
|
1966 | 1966 | It is used to generate URLs from within pylons views or templates. |
|
1967 | 1967 | This will be removed when pyramid migration if finished. |
|
1968 | 1968 | """ |
|
1969 | 1969 | req = get_current_request() |
|
1970 |
return req.route_url(*args, **kw |
|
|
1970 | return req.route_url(*args, **kwargs) | |
|
1971 | 1971 | |
|
1972 | 1972 | |
|
1973 |
def route_path(*args, **kw |
|
|
1973 | def route_path(*args, **kwargs): | |
|
1974 | 1974 | """ |
|
1975 | 1975 | Wrapper around pyramids `route_path` function. It is used to generate |
|
1976 | 1976 | URLs from within pylons views or templates. This will be removed when |
|
1977 | 1977 | pyramid migration if finished. |
|
1978 | 1978 | """ |
|
1979 | 1979 | req = get_current_request() |
|
1980 |
return req.route_path(*args, **kw |
|
|
1980 | return req.route_path(*args, **kwargs) | |
|
1981 | 1981 | |
|
1982 | 1982 | |
|
1983 | 1983 | def route_path_or_none(*args, **kwargs): |
@@ -96,10 +96,11 b' def repo_name_slug(value):' | |||
|
96 | 96 | # PERM DECORATOR HELPERS FOR EXTRACTING NAMES FOR PERM CHECKS |
|
97 | 97 | #============================================================================== |
|
98 | 98 | def get_repo_slug(request): |
|
99 |
if isinstance(request, Request) and getattr(request, ' |
|
|
99 | if isinstance(request, Request) and getattr(request, 'db_repo', None): | |
|
100 | 100 | # pyramid |
|
101 |
_repo = request. |
|
|
101 | _repo = request.db_repo.repo_name | |
|
102 | 102 | else: |
|
103 | # TODO(marcink): remove after pylons migration... | |
|
103 | 104 | _repo = request.environ['pylons.routes_dict'].get('repo_name') |
|
104 | 105 | |
|
105 | 106 | if _repo: |
@@ -110,7 +111,7 b' def get_repo_slug(request):' | |||
|
110 | 111 | def get_repo_group_slug(request): |
|
111 | 112 | if isinstance(request, Request) and getattr(request, 'matchdict', None): |
|
112 | 113 | # pyramid |
|
113 | _group = request.matchdict.get('group_name') | |
|
114 | _group = request.matchdict.get('repo_group_name') | |
|
114 | 115 | else: |
|
115 | 116 | _group = request.environ['pylons.routes_dict'].get('group_name') |
|
116 | 117 |
@@ -572,7 +572,8 b' def credentials_filter(uri):' | |||
|
572 | 572 | return ''.join(uri) |
|
573 | 573 | |
|
574 | 574 | |
|
575 |
def get_clone_url( |
|
|
575 | def get_clone_url(request, uri_tmpl, repo_name, repo_id, **override): | |
|
576 | qualifed_home_url = request.route_url('home') | |
|
576 | 577 | parsed_url = urlobject.URLObject(qualifed_home_url) |
|
577 | 578 | decoded_path = safe_unicode(urllib.unquote(parsed_url.path.rstrip('/'))) |
|
578 | 579 | args = { |
@@ -44,8 +44,8 b' from sqlalchemy.sql.expression import tr' | |||
|
44 | 44 | from beaker.cache import cache_region |
|
45 | 45 | from zope.cachedescriptors.property import Lazy as LazyProperty |
|
46 | 46 | |
|
47 | from pylons import url | |
|
48 | 47 | from pylons.i18n.translation import lazy_ugettext as _ |
|
48 | from pyramid.threadlocal import get_current_request | |
|
49 | 49 | |
|
50 | 50 | from rhodecode.lib.vcs import get_vcs_instance |
|
51 | 51 | from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference |
@@ -1774,7 +1774,7 b' class Repository(Base, BaseModel):' | |||
|
1774 | 1774 | 'repo_name': repo.repo_name, |
|
1775 | 1775 | 'repo_type': repo.repo_type, |
|
1776 | 1776 | 'clone_uri': repo.clone_uri or '', |
|
1777 | 'url': url('summary_home', repo_name=self.repo_name, qualified=True), | |
|
1777 | 'url': repo.home_url(), | |
|
1778 | 1778 | 'private': repo.private, |
|
1779 | 1779 | 'created_on': repo.created_on, |
|
1780 | 1780 | 'description': repo.description, |
@@ -1908,7 +1908,6 b' class Repository(Base, BaseModel):' | |||
|
1908 | 1908 | return clone_uri |
|
1909 | 1909 | |
|
1910 | 1910 | def clone_url(self, **override): |
|
1911 | qualified_home_url = url('home', qualified=True) | |
|
1912 | 1911 | |
|
1913 | 1912 | uri_tmpl = None |
|
1914 | 1913 | if 'with_id' in override: |
@@ -1930,11 +1929,16 b' class Repository(Base, BaseModel):' | |||
|
1930 | 1929 | # ie, not having tmpl_context set up |
|
1931 | 1930 | pass |
|
1932 | 1931 | |
|
1933 | return get_clone_url(uri_tmpl=uri_tmpl, | |
|
1934 | qualifed_home_url=qualified_home_url, | |
|
1932 | request = get_current_request() | |
|
1933 | return get_clone_url(request=request, | |
|
1934 | uri_tmpl=uri_tmpl, | |
|
1935 | 1935 | repo_name=self.repo_name, |
|
1936 | 1936 | repo_id=self.repo_id, **override) |
|
1937 | 1937 | |
|
1938 | def home_url(self): | |
|
1939 | request = get_current_request() | |
|
1940 | return request.route_url('repo_summary', repo_name=self.repo_name) | |
|
1941 | ||
|
1938 | 1942 | def set_state(self, state): |
|
1939 | 1943 | self.repo_state = state |
|
1940 | 1944 | Session().add(self) |
@@ -3299,6 +3303,7 b' class _PullRequestBase(BaseModel):' | |||
|
3299 | 3303 | return None |
|
3300 | 3304 | |
|
3301 | 3305 | def get_api_data(self): |
|
3306 | from pylons import url | |
|
3302 | 3307 | from rhodecode.model.pull_request import PullRequestModel |
|
3303 | 3308 | pull_request = self |
|
3304 | 3309 | merge_status = PullRequestModel().merge_status(pull_request) |
@@ -3690,6 +3695,8 b' class Gist(Base, BaseModel):' | |||
|
3690 | 3695 | |
|
3691 | 3696 | def gist_url(self): |
|
3692 | 3697 | import rhodecode |
|
3698 | from pylons import url | |
|
3699 | ||
|
3693 | 3700 | alias_url = rhodecode.CONFIG.get('gist_alias_url') |
|
3694 | 3701 | if alias_url: |
|
3695 | 3702 | return alias_url.replace('{gistid}', self.gist_access_id) |
@@ -334,9 +334,9 b' class EmailNotificationModel(BaseModel):' | |||
|
334 | 334 | """ |
|
335 | 335 | |
|
336 | 336 | kwargs['rhodecode_instance_name'] = self.rhodecode_instance_name |
|
337 | ||
|
337 | instance_url = h.route_url('home') | |
|
338 | 338 | _kwargs = { |
|
339 |
'instance_url': |
|
|
339 | 'instance_url': instance_url, | |
|
340 | 340 | 'whitespace_filter': self.whitespace_filter |
|
341 | 341 | } |
|
342 | 342 | _kwargs.update(kwargs) |
@@ -131,6 +131,7 b' class RepoModel(BaseModel):' | |||
|
131 | 131 | :param repo_name: |
|
132 | 132 | :return: repo object if matched else None |
|
133 | 133 | """ |
|
134 | ||
|
134 | 135 | try: |
|
135 | 136 | _repo_id = self._extract_id_from_repo_name(repo_name) |
|
136 | 137 | if _repo_id: |
@@ -99,6 +99,7 b' function registerRCRoutes() {' | |||
|
99 | 99 | pyroutes.register('user_group_autocomplete_data', '/_user_groups', []); |
|
100 | 100 | pyroutes.register('repo_list_data', '/_repos', []); |
|
101 | 101 | pyroutes.register('goto_switcher_data', '/_goto_data', []); |
|
102 | pyroutes.register('repo_summary', '/%(repo_name)s', ['repo_name']); | |
|
102 | 103 | pyroutes.register('repo_summary_explicit', '/%(repo_name)s/summary', ['repo_name']); |
|
103 | 104 | pyroutes.register('tags_home', '/%(repo_name)s/tags', ['repo_name']); |
|
104 | 105 | pyroutes.register('branches_home', '/%(repo_name)s/branches', ['repo_name']); |
@@ -121,6 +122,8 b' function registerRCRoutes() {' | |||
|
121 | 122 | pyroutes.register('strip', '/%(repo_name)s/settings/strip', ['repo_name']); |
|
122 | 123 | pyroutes.register('strip_check', '/%(repo_name)s/settings/strip_check', ['repo_name']); |
|
123 | 124 | pyroutes.register('strip_execute', '/%(repo_name)s/settings/strip_execute', ['repo_name']); |
|
125 | pyroutes.register('repo_group_home', '/%(repo_group_name)s', ['repo_group_name']); | |
|
126 | pyroutes.register('repo_group_home_slash', '/%(repo_group_name)s/', ['repo_group_name']); | |
|
124 | 127 | pyroutes.register('search', '/_admin/search', []); |
|
125 | 128 | pyroutes.register('search_repo', '/%(repo_name)s/search', ['repo_name']); |
|
126 | 129 | pyroutes.register('user_profile', '/_profiles/%(username)s', ['username']); |
@@ -164,7 +164,7 b'' | |||
|
164 | 164 | ${_('repo')}:${integration.repo.repo_name} |
|
165 | 165 | </a> |
|
166 | 166 | %elif integration.repo_group: |
|
167 |
<a href="${h. |
|
|
167 | <a href="${h.route_path('repo_group_home', repo_group_name=integration.repo_group.group_name)}"> | |
|
168 | 168 | ${_('repogroup')}:${integration.repo_group.group_name} |
|
169 | 169 | %if integration.child_repos_only: |
|
170 | 170 | ${_('child repos only')} |
@@ -13,7 +13,7 b'' | |||
|
13 | 13 | » |
|
14 | 14 | ${h.link_to(_('Repository Groups'),h.url('repo_groups'))} |
|
15 | 15 | %if c.repo_group.parent_group: |
|
16 |
» ${h.link_to(c.repo_group.parent_group.name,h. |
|
|
16 | » ${h.link_to(c.repo_group.parent_group.name, h.route_path('repo_group_home', repo_group_name=c.repo_group.parent_group.group_name))} | |
|
17 | 17 | %endif |
|
18 | 18 | » ${c.repo_group.name} |
|
19 | 19 | </%def> |
@@ -61,7 +61,7 b'' | |||
|
61 | 61 | } |
|
62 | 62 | } |
|
63 | 63 | else { |
|
64 |
window.location = "${h. |
|
|
64 | window.location = "${h.route_path('home')}"; | |
|
65 | 65 | } |
|
66 | 66 | } |
|
67 | 67 | }); |
@@ -59,7 +59,7 b'' | |||
|
59 | 59 | ${h.secure_form(h.url('create_personal_repo_group', user_id=c.user.user_id), method='post')} |
|
60 | 60 | |
|
61 | 61 | %if c.personal_repo_group: |
|
62 |
<div class="panel-body-title-text">${_('Users personal repository group')} : ${h.link_to(c.personal_repo_group.group_name, |
|
|
62 | <div class="panel-body-title-text">${_('Users personal repository group')} : ${h.link_to(c.personal_repo_group.group_name, h.route_path('repo_group_home', repo_group_name=c.personal_repo_group.group_name))}</div> | |
|
63 | 63 | %else: |
|
64 | 64 | <div class="panel-body-title-text"> |
|
65 | 65 | ${_('This user currently does not have a personal repository group')} |
@@ -7,7 +7,7 b'' | |||
|
7 | 7 | <div id="header-inner" class="wrapper"> |
|
8 | 8 | <div id="logo"> |
|
9 | 9 | <div class="logo-wrapper"> |
|
10 |
<a href="${h. |
|
|
10 | <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-216x60.png')}" alt="RhodeCode"/></a> | |
|
11 | 11 | </div> |
|
12 | 12 | %if c.rhodecode_name: |
|
13 | 13 | <div class="branding">- ${h.branding(c.rhodecode_name)}</div> |
@@ -343,7 +343,7 b'' | |||
|
343 | 343 | <ol class="links"> |
|
344 | 344 | <li>${h.link_to(_(u'My account'),h.route_path('my_account_profile'))}</li> |
|
345 | 345 | % if c.rhodecode_user.personal_repo_group: |
|
346 |
<li>${h.link_to(_(u'My personal group'), h. |
|
|
346 | <li>${h.link_to(_(u'My personal group'), h.route_path('repo_group_home', repo_group_name=c.rhodecode_user.personal_repo_group.group_name))}</li> | |
|
347 | 347 | % endif |
|
348 | 348 | <li class="logout"> |
|
349 | 349 | ${h.secure_form(h.route_path('logout'))} |
@@ -126,7 +126,7 b'' | |||
|
126 | 126 | %if section == 'repositories': |
|
127 | 127 | <a href="${h.url('summary_home',repo_name=k)}">${k}</a> |
|
128 | 128 | %elif section == 'repositories_groups': |
|
129 |
<a href="${h. |
|
|
129 | <a href="${h.route_path('repo_group_home', repo_group_name=k)}">${k}</a> | |
|
130 | 130 | %elif section == 'user_groups': |
|
131 | 131 | ##<a href="${h.url('edit_users_group',user_group_id=k)}">${k}</a> |
|
132 | 132 | ${k} |
@@ -84,7 +84,7 b" c.template_context['default_user'] = {" | |||
|
84 | 84 | // register templateContext to pass template variables to JS |
|
85 | 85 | var templateContext = ${h.json.dumps(c.template_context)|n}; |
|
86 | 86 | |
|
87 |
var APPLICATION_URL = "${h. |
|
|
87 | var APPLICATION_URL = "${h.route_path('home').rstrip('/')}"; | |
|
88 | 88 | var ASSET_URL = "${h.asset('')}"; |
|
89 | 89 | var DEFAULT_RENDERER = "${h.get_visual_attr(c, 'default_renderer')}"; |
|
90 | 90 | var CSRF_TOKEN = "${getattr(c, 'csrf_token', '')}"; |
@@ -146,7 +146,7 b'' | |||
|
146 | 146 | <div class="menu_items_container hidden"> |
|
147 | 147 | <ul class="menu_items"> |
|
148 | 148 | <li> |
|
149 |
<a href="${h. |
|
|
149 | <a href="${h.route_path('repo_group_home', repo_group_name=repo_group_name)}"> | |
|
150 | 150 | <span class="icon"> |
|
151 | 151 | <i class="icon-file-text"></i> |
|
152 | 152 | </span> |
@@ -160,7 +160,7 b'' | |||
|
160 | 160 | |
|
161 | 161 | <%def name="repo_group_name(repo_group_name, children_groups=None)"> |
|
162 | 162 | <div> |
|
163 |
<a href="${h. |
|
|
163 | <a href="${h.route_path('repo_group_home', repo_group_name=repo_group_name)}"> | |
|
164 | 164 | <i class="icon-folder-close" title="${_('Repository group')}"></i> |
|
165 | 165 | %if children_groups: |
|
166 | 166 | ${h.literal(' » '.join(children_groups))} |
@@ -10,9 +10,9 b'' | |||
|
10 | 10 | |
|
11 | 11 | <%def name="breadcrumbs()"> |
|
12 | 12 | <span class="groups_breadcrumbs"> |
|
13 |
${h.link_to(_(u'Home'),h. |
|
|
13 | ${h.link_to(_(u'Home'), h.route_path('home'))} | |
|
14 | 14 | %if c.repo_group.parent_group: |
|
15 |
» ${h.link_to(c.repo_group.parent_group.name,h. |
|
|
15 | » ${h.link_to(c.repo_group.parent_group.name, h.route_path('repo_group_home', repo_group_name=c.repo_group.parent_group.group_name))} | |
|
16 | 16 | %endif |
|
17 | 17 | » ${c.repo_group.name} |
|
18 | 18 | </span> |
@@ -14,7 +14,7 b'' | |||
|
14 | 14 | <div id="header-inner" class="title"> |
|
15 | 15 | <div id="logo"> |
|
16 | 16 | <div class="logo-wrapper"> |
|
17 |
<a href="${h. |
|
|
17 | <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-216x60.png')}" alt="RhodeCode"/></a> | |
|
18 | 18 | </div> |
|
19 | 19 | %if c.rhodecode_name: |
|
20 | 20 | <div class="branding"> ${h.branding(c.rhodecode_name)}</div> |
@@ -14,7 +14,7 b'' | |||
|
14 | 14 | <div id="header-inner" class="title"> |
|
15 | 15 | <div id="logo"> |
|
16 | 16 | <div class="logo-wrapper"> |
|
17 |
<a href="${h. |
|
|
17 | <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-216x60.png')}" alt="RhodeCode"/></a> | |
|
18 | 18 | </div> |
|
19 | 19 | %if c.rhodecode_name: |
|
20 | 20 | <div class="branding"> ${h.branding(c.rhodecode_name)}</div> |
@@ -14,7 +14,7 b'' | |||
|
14 | 14 | <div id="header-inner" class="title"> |
|
15 | 15 | <div id="logo"> |
|
16 | 16 | <div class="logo-wrapper"> |
|
17 |
<a href="${h. |
|
|
17 | <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-216x60.png')}" alt="RhodeCode"/></a> | |
|
18 | 18 | </div> |
|
19 | 19 | %if c.rhodecode_name: |
|
20 | 20 | <div class="branding"> ${h.branding(c.rhodecode_name)}</div> |
@@ -48,7 +48,6 b' from rhodecode.model.db import User' | |||
|
48 | 48 | from rhodecode.lib import auth |
|
49 | 49 | from rhodecode.lib.helpers import flash, link_to |
|
50 | 50 | from rhodecode.lib.utils2 import safe_unicode, safe_str |
|
51 | from rhodecode.tests.utils import get_session_from_response | |
|
52 | 51 | |
|
53 | 52 | |
|
54 | 53 | log = logging.getLogger(__name__) |
@@ -178,7 +177,7 b' def login_user_session(' | |||
|
178 | 177 | response = response.follow() |
|
179 | 178 | assert response.status == '200 OK' |
|
180 | 179 | |
|
181 |
session = get_session_from_response( |
|
|
180 | session = response.get_session_from_response() | |
|
182 | 181 | assert 'rhodecode_user' in session |
|
183 | 182 | rc_user = session['rhodecode_user'] |
|
184 | 183 | assert rc_user.get('username') == username |
@@ -42,7 +42,7 b' from rhodecode.events import (' | |||
|
42 | 42 | PullRequestMergeEvent, |
|
43 | 43 | PullRequestCloseEvent, |
|
44 | 44 | ]) |
|
45 |
def test_pullrequest_events_serialized(pr_util, |
|
|
45 | def test_pullrequest_events_serialized(EventClass, pr_util, config_stub): | |
|
46 | 46 | pr = pr_util.create_pull_request() |
|
47 | 47 | event = EventClass(pr) |
|
48 | 48 | data = event.as_dict() |
@@ -51,15 +51,17 b' def test_pullrequest_events_serialized(p' | |||
|
51 | 51 | assert data['pullrequest']['pull_request_id'] == pr.pull_request_id |
|
52 | 52 | assert data['pullrequest']['url'] |
|
53 | 53 | |
|
54 | ||
|
54 | 55 | @pytest.mark.backends("git", "hg") |
|
55 | def test_create_pull_request_events(pr_util): | |
|
56 | def test_create_pull_request_events(pr_util, config_stub): | |
|
56 | 57 | with EventCatcher() as event_catcher: |
|
57 | 58 | pr_util.create_pull_request() |
|
58 | 59 | |
|
59 | 60 | assert PullRequestCreateEvent in event_catcher.events_types |
|
60 | 61 | |
|
62 | ||
|
61 | 63 | @pytest.mark.backends("git", "hg") |
|
62 | def test_pullrequest_comment_events_serialized(pr_util): | |
|
64 | def test_pullrequest_comment_events_serialized(pr_util, config_stub): | |
|
63 | 65 | pr = pr_util.create_pull_request() |
|
64 | 66 | comment = CommentsModel().get_comments( |
|
65 | 67 | pr.target_repo.repo_id, pull_request=pr)[0] |
@@ -73,7 +75,7 b' def test_pullrequest_comment_events_seri' | |||
|
73 | 75 | |
|
74 | 76 | |
|
75 | 77 | @pytest.mark.backends("git", "hg") |
|
76 | def test_close_pull_request_events(pr_util, user_admin): | |
|
78 | def test_close_pull_request_events(pr_util, user_admin, config_stub): | |
|
77 | 79 | pr = pr_util.create_pull_request() |
|
78 | 80 | |
|
79 | 81 | with EventCatcher() as event_catcher: |
@@ -83,7 +85,7 b' def test_close_pull_request_events(pr_ut' | |||
|
83 | 85 | |
|
84 | 86 | |
|
85 | 87 | @pytest.mark.backends("git", "hg") |
|
86 | def test_close_pull_request_with_comment_events(pr_util, user_admin): | |
|
88 | def test_close_pull_request_with_comment_events(pr_util, user_admin, config_stub): | |
|
87 | 89 | pr = pr_util.create_pull_request() |
|
88 | 90 | |
|
89 | 91 | with EventCatcher() as event_catcher: |
@@ -75,7 +75,6 b' def test_vcs_repo_events_serialize(repo_' | |||
|
75 | 75 | assert data['repo']['url'] |
|
76 | 76 | |
|
77 | 77 | |
|
78 | ||
|
79 | 78 | @pytest.mark.parametrize('EventClass', [RepoPushEvent]) |
|
80 | 79 | def test_vcs_repo_push_event_serialize(repo_stub, scm_extras, EventClass): |
|
81 | 80 | event = EventClass(repo_name=repo_stub.repo_name, |
@@ -28,7 +28,6 b' from rhodecode.model.meta import Session' | |||
|
28 | 28 | from rhodecode.tests import ( |
|
29 | 29 | TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS, |
|
30 | 30 | TestController, assert_session_flash, url) |
|
31 | from rhodecode.tests.utils import AssertResponse | |
|
32 | 31 | |
|
33 | 32 | |
|
34 | 33 | class GistUtility(object): |
@@ -273,7 +272,7 b' class TestGistsController(TestController' | |||
|
273 | 272 | |
|
274 | 273 | response.mustcontain('added file: gist-show-me<') |
|
275 | 274 | |
|
276 |
assert_response = |
|
|
275 | assert_response = response.assert_response() | |
|
277 | 276 | assert_response.element_equals_to( |
|
278 | 277 | 'div.rc-user span.user', |
|
279 | 278 | '<a href="/_profiles/test_admin">test_admin</a></span>') |
@@ -296,7 +295,7 b' class TestGistsController(TestController' | |||
|
296 | 295 | response = self.app.get(url('gist', gist_id=gist.gist_access_id)) |
|
297 | 296 | response.mustcontain('added file: gist-show-me-only-when-im-logged-in') |
|
298 | 297 | |
|
299 |
assert_response = |
|
|
298 | assert_response = response.assert_response() | |
|
300 | 299 | assert_response.element_equals_to( |
|
301 | 300 | 'div.rc-user span.user', |
|
302 | 301 | '<a href="/_profiles/test_admin">test_admin</a></span>') |
@@ -31,6 +31,12 b' from rhodecode.tests.utils import Assert' | |||
|
31 | 31 | fixture = Fixture() |
|
32 | 32 | |
|
33 | 33 | |
|
34 | def route_path(name, **kwargs): | |
|
35 | return { | |
|
36 | 'home': '/', | |
|
37 | }[name].format(**kwargs) | |
|
38 | ||
|
39 | ||
|
34 | 40 | class TestMyAccountController(TestController): |
|
35 | 41 | test_user_1 = 'testme' |
|
36 | 42 | test_user_1_password = '0jd83nHNS/d23n' |
@@ -41,7 +47,7 b' class TestMyAccountController(TestContro' | |||
|
41 | 47 | fixture.destroy_users(cls.destroy_users) |
|
42 | 48 | |
|
43 | 49 | def test_logout_form_contains_csrf(self, autologin_user, csrf_token): |
|
44 |
response = self.app.get( |
|
|
50 | response = self.app.get(route_path('home')) | |
|
45 | 51 | assert_response = AssertResponse(response) |
|
46 | 52 | element = assert_response.get_element('.logout #csrf_token') |
|
47 | 53 | assert element.value == csrf_token |
@@ -31,6 +31,7 b' from rhodecode.tests.fixture import Fixt' | |||
|
31 | 31 | fixture = Fixture() |
|
32 | 32 | |
|
33 | 33 | |
|
34 | ||
|
34 | 35 | def test_update(app, csrf_token, autologin_user, user_util): |
|
35 | 36 | repo_group = user_util.create_repo_group() |
|
36 | 37 | description = 'description for newly created repo group' |
@@ -123,11 +124,13 b' class _BaseTest(TestController):' | |||
|
123 | 124 | # run the check page that triggers the flash message |
|
124 | 125 | # response = self.app.get(url('repo_check_home', repo_name=repo_name)) |
|
125 | 126 | # assert response.json == {u'result': True} |
|
127 | repo_gr_url = h.route_path( | |
|
128 | 'repo_group_home', repo_group_name=repo_group_name) | |
|
129 | ||
|
126 | 130 | assert_session_flash( |
|
127 | 131 | response, |
|
128 |
|
|
|
129 |
|
|
|
130 | repo_group_name_unicode)) | |
|
132 | 'Created repository group <a href="%s">%s</a>' % ( | |
|
133 | repo_gr_url, repo_group_name_unicode)) | |
|
131 | 134 | |
|
132 | 135 | # # test if the repo group was created in the database |
|
133 | 136 | new_repo_group = RepoGroupModel()._get_repo_group( |
@@ -138,8 +141,7 b' class _BaseTest(TestController):' | |||
|
138 | 141 | assert new_repo_group.group_description == description |
|
139 | 142 | |
|
140 | 143 | # test if the repository is visible in the list ? |
|
141 | response = self.app.get( | |
|
142 | url('repo_group_home', group_name=repo_group_name)) | |
|
144 | response = self.app.get(repo_gr_url) | |
|
143 | 145 | response.mustcontain(repo_group_name) |
|
144 | 146 | |
|
145 | 147 | # test if the repository group was created on filesystem |
@@ -173,7 +175,7 b' class _BaseTest(TestController):' | |||
|
173 | 175 | assert_session_flash( |
|
174 | 176 | response, |
|
175 | 177 | u'Created repository group <a href="%s">%s</a>' % ( |
|
176 |
h. |
|
|
178 | h.route_path('repo_group_home', repo_group_name=expected_group_name), | |
|
177 | 179 | expected_group_name_unicode)) |
|
178 | 180 | finally: |
|
179 | 181 | RepoGroupModel().delete(expected_group_name_unicode) |
@@ -199,6 +201,13 b' class TestRepoGroupsControllerGIT(_BaseT' | |||
|
199 | 201 | REPO_TYPE = 'git' |
|
200 | 202 | |
|
201 | 203 | |
|
204 | class TestRepoGroupsControllerNonAsciiGit(_BaseTest): | |
|
205 | REPO_GROUP = None | |
|
206 | NEW_REPO_GROUP = 'git_repo_Δ Δ' | |
|
207 | REPO = GIT_REPO | |
|
208 | REPO_TYPE = 'git' | |
|
209 | ||
|
210 | ||
|
202 | 211 | class TestRepoGroupsControllerHG(_BaseTest): |
|
203 | 212 | REPO_GROUP = None |
|
204 | 213 | NEW_REPO_GROUP = 'hg_repo' |
@@ -30,6 +30,12 b' from rhodecode.tests.fixture import Fixt' | |||
|
30 | 30 | fixture = Fixture() |
|
31 | 31 | |
|
32 | 32 | |
|
33 | def route_path(name, **kwargs): | |
|
34 | return { | |
|
35 | 'home': '/', | |
|
36 | }[name].format(**kwargs) | |
|
37 | ||
|
38 | ||
|
33 | 39 | class TestAdminUsersGroupsController(TestController): |
|
34 | 40 | |
|
35 | 41 | def test_regular_user_cannot_see_admin_interfaces(self, user_util): |
@@ -37,7 +43,7 b' class TestAdminUsersGroupsController(Tes' | |||
|
37 | 43 | self.log_user(user.username, 'qweqwe') |
|
38 | 44 | |
|
39 | 45 | # check if in home view, such user doesn't see the "admin" menus |
|
40 |
response = self.app.get( |
|
|
46 | response = self.app.get(route_path('home')) | |
|
41 | 47 | |
|
42 | 48 | assert_response = response.assert_response() |
|
43 | 49 | |
@@ -69,7 +75,7 b' class TestAdminUsersGroupsController(Tes' | |||
|
69 | 75 | |
|
70 | 76 | self.log_user(username, 'qweqwe') |
|
71 | 77 | # check if in home view, such user doesn't see the "admin" menus |
|
72 |
response = self.app.get( |
|
|
78 | response = self.app.get(route_path('home')) | |
|
73 | 79 | |
|
74 | 80 | assert_response = response.assert_response() |
|
75 | 81 | |
@@ -109,7 +115,7 b' class TestAdminUsersGroupsController(Tes' | |||
|
109 | 115 | |
|
110 | 116 | self.log_user(username, 'qweqwe') |
|
111 | 117 | # check if in home view, such user doesn't see the "admin" menus |
|
112 |
response = self.app.get( |
|
|
118 | response = self.app.get(route_path('home')) | |
|
113 | 119 | |
|
114 | 120 | assert_response = response.assert_response() |
|
115 | 121 |
@@ -28,7 +28,6 b' from rhodecode.tests import (' | |||
|
28 | 28 | assert_session_flash, url, HG_REPO, TEST_USER_ADMIN_LOGIN, |
|
29 | 29 | no_newline_id_generator) |
|
30 | 30 | from rhodecode.tests.fixture import Fixture |
|
31 | from rhodecode.tests.utils import AssertResponse, get_session_from_response | |
|
32 | 31 | from rhodecode.lib.auth import check_password |
|
33 | 32 | from rhodecode.model.auth_token import AuthTokenModel |
|
34 | 33 | from rhodecode.model import validators |
@@ -72,7 +71,7 b' class TestLoginController(object):' | |||
|
72 | 71 | {'username': 'test_admin', |
|
73 | 72 | 'password': 'test12'}) |
|
74 | 73 | assert response.status == '302 Found' |
|
75 |
session = get_session_from_response( |
|
|
74 | session = response.get_session_from_response() | |
|
76 | 75 | username = session['rhodecode_user'].get('username') |
|
77 | 76 | assert username == 'test_admin' |
|
78 | 77 | response = response.follow() |
@@ -84,7 +83,7 b' class TestLoginController(object):' | |||
|
84 | 83 | 'password': 'test12'}) |
|
85 | 84 | |
|
86 | 85 | assert response.status == '302 Found' |
|
87 |
session = get_session_from_response( |
|
|
86 | session = response.get_session_from_response() | |
|
88 | 87 | username = session['rhodecode_user'].get('username') |
|
89 | 88 | assert username == 'test_regular' |
|
90 | 89 | response = response.follow() |
@@ -184,7 +183,7 b' class TestLoginController(object):' | |||
|
184 | 183 | 'password': 'test123'}) |
|
185 | 184 | |
|
186 | 185 | assert response.status == '302 Found' |
|
187 |
session = get_session_from_response( |
|
|
186 | session = response.get_session_from_response() | |
|
188 | 187 | username = session['rhodecode_user'].get('username') |
|
189 | 188 | assert username == temp_user |
|
190 | 189 | response = response.follow() |
@@ -213,7 +212,7 b' class TestLoginController(object):' | |||
|
213 | 212 | } |
|
214 | 213 | ) |
|
215 | 214 | |
|
216 |
assertr = |
|
|
215 | assertr = response.assert_response() | |
|
217 | 216 | msg = validators.ValidUsername()._messages['username_exists'] |
|
218 | 217 | msg = msg % {'username': uname} |
|
219 | 218 | assertr.element_contains('#username+.error-message', msg) |
@@ -231,7 +230,7 b' class TestLoginController(object):' | |||
|
231 | 230 | } |
|
232 | 231 | ) |
|
233 | 232 | |
|
234 |
assertr = |
|
|
233 | assertr = response.assert_response() | |
|
235 | 234 | msg = validators.UniqSystemEmail()()._messages['email_taken'] |
|
236 | 235 | assertr.element_contains('#email+.error-message', msg) |
|
237 | 236 | |
@@ -247,7 +246,7 b' class TestLoginController(object):' | |||
|
247 | 246 | 'lastname': 'test' |
|
248 | 247 | } |
|
249 | 248 | ) |
|
250 |
assertr = |
|
|
249 | assertr = response.assert_response() | |
|
251 | 250 | msg = validators.UniqSystemEmail()()._messages['email_taken'] |
|
252 | 251 | assertr.element_contains('#email+.error-message', msg) |
|
253 | 252 | |
@@ -301,7 +300,7 b' class TestLoginController(object):' | |||
|
301 | 300 | } |
|
302 | 301 | ) |
|
303 | 302 | |
|
304 |
assertr = |
|
|
303 | assertr = response.assert_response() | |
|
305 | 304 | msg = validators.ValidUsername()._messages['username_exists'] |
|
306 | 305 | msg = msg % {'username': usr} |
|
307 | 306 | assertr.element_contains('#username+.error-message', msg) |
@@ -21,8 +21,13 b'' | |||
|
21 | 21 | import mock |
|
22 | 22 | import pytest |
|
23 | 23 | |
|
24 |
from rhodecode.tests import TEST_USER_ADMIN_LOGIN |
|
|
25 | from rhodecode.tests.utils import AssertResponse | |
|
24 | from rhodecode.tests import TEST_USER_ADMIN_LOGIN | |
|
25 | ||
|
26 | ||
|
27 | def route_path(name, **kwargs): | |
|
28 | return { | |
|
29 | 'home': '/', | |
|
30 | }[name].format(**kwargs) | |
|
26 | 31 | |
|
27 | 32 | |
|
28 | 33 | class TestSessionBehaviorOnPasswordChange(object): |
@@ -39,18 +44,23 b' class TestSessionBehaviorOnPasswordChang' | |||
|
39 | 44 | |
|
40 | 45 | def test_sessions_are_ok_when_password_is_not_changed( |
|
41 | 46 | self, app, autologin_user): |
|
42 |
response = app.get( |
|
|
43 |
assert_response = |
|
|
47 | response = app.get(route_path('home')) | |
|
48 | assert_response = response.assert_response() | |
|
44 | 49 | assert_response.element_contains( |
|
45 | 50 | '#quick_login_link .menu_link_user', TEST_USER_ADMIN_LOGIN) |
|
46 | assert 'rhodecode_user' in response.session | |
|
47 | assert response.session.was_invalidated is False | |
|
51 | ||
|
52 | session = response.get_session_from_response() | |
|
53 | ||
|
54 | assert 'rhodecode_user' in session | |
|
55 | assert session.was_invalidated is False | |
|
48 | 56 | |
|
49 | 57 | def test_sessions_invalidated_when_password_is_changed( |
|
50 | 58 | self, app, autologin_user): |
|
51 | 59 | self.password_changed_mock.return_value = True |
|
52 |
response = app.get( |
|
|
53 |
assert_response = |
|
|
60 | response = app.get(route_path('home')) | |
|
61 | assert_response = response.assert_response() | |
|
54 | 62 | assert_response.element_contains('#quick_login_link .user', 'Sign in') |
|
55 | assert 'rhodecode_user' not in response.session | |
|
56 | assert response.session.was_invalidated is True | |
|
63 | ||
|
64 | session = response.get_session_from_response() | |
|
65 | assert 'rhodecode_user' not in session | |
|
66 | assert session.was_invalidated is True |
@@ -41,7 +41,7 b' fixture = Fixture()' | |||
|
41 | 41 | |
|
42 | 42 | |
|
43 | 43 | class TestSummaryController(TestController): |
|
44 | def test_index(self, backend): | |
|
44 | def test_index(self, backend, http_host_only_stub): | |
|
45 | 45 | self.log_user() |
|
46 | 46 | repo_id = backend.repo.repo_id |
|
47 | 47 | repo_name = backend.repo_name |
@@ -61,12 +61,12 b' class TestSummaryController(TestControll' | |||
|
61 | 61 | # clone url... |
|
62 | 62 | response.mustcontain( |
|
63 | 63 | 'id="clone_url" readonly="readonly"' |
|
64 |
' value="http://test_admin@ |
|
|
64 | ' value="http://test_admin@%s/%s"' % (http_host_only_stub, repo_name, )) | |
|
65 | 65 | response.mustcontain( |
|
66 | 66 | 'id="clone_url_id" readonly="readonly"' |
|
67 |
' value="http://test_admin@ |
|
|
67 | ' value="http://test_admin@%s/_%s"' % (http_host_only_stub, repo_id, )) | |
|
68 | 68 | |
|
69 | def test_index_svn_without_proxy(self, backend_svn): | |
|
69 | def test_index_svn_without_proxy(self, backend_svn, http_host_only_stub): | |
|
70 | 70 | self.log_user() |
|
71 | 71 | repo_id = backend_svn.repo.repo_id |
|
72 | 72 | repo_name = backend_svn.repo_name |
@@ -74,12 +74,13 b' class TestSummaryController(TestControll' | |||
|
74 | 74 | # clone url... |
|
75 | 75 | response.mustcontain( |
|
76 | 76 | 'id="clone_url" disabled' |
|
77 |
' value="http://test_admin@ |
|
|
77 | ' value="http://test_admin@%s/%s"' % (http_host_only_stub, repo_name, )) | |
|
78 | 78 | response.mustcontain( |
|
79 | 79 | 'id="clone_url_id" disabled' |
|
80 |
' value="http://test_admin@ |
|
|
80 | ' value="http://test_admin@%s/_%s"' % (http_host_only_stub, repo_id, )) | |
|
81 | 81 | |
|
82 |
def test_index_with_trailing_slash(self, autologin_user, backend |
|
|
82 | def test_index_with_trailing_slash(self, autologin_user, backend, | |
|
83 | http_host_only_stub): | |
|
83 | 84 | repo_id = backend.repo.repo_id |
|
84 | 85 | repo_name = backend.repo_name |
|
85 | 86 | with mock.patch('rhodecode.lib.helpers.is_svn_without_proxy', |
@@ -91,10 +92,10 b' class TestSummaryController(TestControll' | |||
|
91 | 92 | # clone url... |
|
92 | 93 | response.mustcontain( |
|
93 | 94 | 'id="clone_url" readonly="readonly"' |
|
94 |
' value="http://test_admin@ |
|
|
95 | ' value="http://test_admin@%s/%s"' % (http_host_only_stub, repo_name, )) | |
|
95 | 96 | response.mustcontain( |
|
96 | 97 | 'id="clone_url_id" readonly="readonly"' |
|
97 |
' value="http://test_admin@ |
|
|
98 | ' value="http://test_admin@%s/_%s"' % (http_host_only_stub, repo_id, )) | |
|
98 | 99 | |
|
99 | 100 | def test_index_by_id(self, backend): |
|
100 | 101 | self.log_user() |
@@ -35,7 +35,6 b' from rhodecode.model.meta import Session' | |||
|
35 | 35 | from rhodecode.tests import ( |
|
36 | 36 | HG_REPO, TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS) |
|
37 | 37 | from rhodecode.tests.lib.middleware import mock_scm_app |
|
38 | from rhodecode.tests.utils import set_anonymous_access | |
|
39 | 38 | |
|
40 | 39 | |
|
41 | 40 | class StubVCSController(simplevcs.SimpleVCS): |
@@ -70,7 +69,7 b' def vcscontroller(pylonsapp, config_stub' | |||
|
70 | 69 | config_stub.testing_securitypolicy() |
|
71 | 70 | config_stub.include('rhodecode.authentication') |
|
72 | 71 | |
|
73 | set_anonymous_access(True) | |
|
72 | #set_anonymous_access(True) | |
|
74 | 73 | controller = StubVCSController(pylonsapp, pylonsapp.config, None) |
|
75 | 74 | app = HttpsFixup(controller, pylonsapp.config) |
|
76 | 75 | app = CustomTestApp(app) |
@@ -93,13 +92,6 b' def _remove_default_user_from_query_cach' | |||
|
93 | 92 | Session().expire(user) |
|
94 | 93 | |
|
95 | 94 | |
|
96 | @pytest.fixture | |
|
97 | def disable_anonymous_user(request, pylonsapp): | |
|
98 | set_anonymous_access(False) | |
|
99 | ||
|
100 | @request.addfinalizer | |
|
101 | def cleanup(): | |
|
102 | set_anonymous_access(True) | |
|
103 | 95 | |
|
104 | 96 | |
|
105 | 97 | def test_handles_exceptions_during_permissions_checks( |
@@ -275,7 +267,7 b' class TestShadowRepoExposure(object):' | |||
|
275 | 267 | controller.vcs_repo_name == |
|
276 | 268 | controller._get_repository_name(environ_stub)) |
|
277 | 269 | |
|
278 | def test_set_repo_names_with_shadow(self, pylonsapp, pr_util): | |
|
270 | def test_set_repo_names_with_shadow(self, pylonsapp, pr_util, config_stub): | |
|
279 | 271 | """ |
|
280 | 272 | Check that the set_repo_names method sets correct names on a request |
|
281 | 273 | to a shadow repo. |
@@ -304,7 +296,7 b' class TestShadowRepoExposure(object):' | |||
|
304 | 296 | assert controller.is_shadow_repo |
|
305 | 297 | |
|
306 | 298 | def test_set_repo_names_with_shadow_but_missing_pr( |
|
307 | self, pylonsapp, pr_util): | |
|
299 | self, pylonsapp, pr_util, config_stub): | |
|
308 | 300 | """ |
|
309 | 301 | Checks that the set_repo_names method enforces matching target repos |
|
310 | 302 | and pull request IDs. |
@@ -326,7 +318,7 b' class TestShadowRepoExposure(object):' | |||
|
326 | 318 | |
|
327 | 319 | |
|
328 | 320 | @pytest.mark.usefixtures('db') |
|
329 | class TestGenerateVcsResponse: | |
|
321 | class TestGenerateVcsResponse(object): | |
|
330 | 322 | |
|
331 | 323 | def test_ensures_that_start_response_is_called_early_enough(self): |
|
332 | 324 | self.call_controller_with_response_body(iter(['a', 'b'])) |
@@ -418,7 +410,7 b' class TestGenerateVcsResponse:' | |||
|
418 | 410 | return self.controller._invalidate_cache.called |
|
419 | 411 | |
|
420 | 412 | |
|
421 | class TestInitializeGenerator: | |
|
413 | class TestInitializeGenerator(object): | |
|
422 | 414 | |
|
423 | 415 | def test_drains_first_element(self): |
|
424 | 416 | gen = self.factory(['__init__', 1, 2]) |
@@ -19,11 +19,12 b'' | |||
|
19 | 19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
20 | 20 | |
|
21 | 21 | import pytest |
|
22 | from pygments.lexers import get_lexer_by_name | |
|
22 | 23 | |
|
24 | from rhodecode.tests import no_newline_id_generator | |
|
23 | 25 | from rhodecode.lib.codeblocks import ( |
|
24 | 26 | tokenize_string, split_token_stream, rollup_tokenstream, |
|
25 | 27 | render_tokenstream) |
|
26 | from pygments.lexers import get_lexer_by_name | |
|
27 | 28 | |
|
28 | 29 | |
|
29 | 30 | class TestTokenizeString(object): |
@@ -298,7 +299,7 b' class TestRenderTokenStream(object):' | |||
|
298 | 299 | [('A', '', u'hel'), ('B', 'ins', u'lo')], |
|
299 | 300 | '<span class="A">hel</span><span class="B"><ins>lo</ins></span>', |
|
300 | 301 | ), |
|
301 | ]) | |
|
302 | ], ids=no_newline_id_generator) | |
|
302 | 303 | def test_render_tokenstream_with_ops(self, tokenstream, output): |
|
303 | 304 | html = render_tokenstream(tokenstream) |
|
304 | 305 | assert html == output |
@@ -27,6 +27,7 b' from pylons.util import ContextObj' | |||
|
27 | 27 | from rhodecode.lib import helpers |
|
28 | 28 | from rhodecode.lib.utils2 import AttributeDict |
|
29 | 29 | from rhodecode.model.settings import IssueTrackerSettingsModel |
|
30 | from rhodecode.tests import no_newline_id_generator | |
|
30 | 31 | |
|
31 | 32 | |
|
32 | 33 | @pytest.mark.parametrize('url, expected_url', [ |
@@ -204,7 +205,7 b' def test_get_visual_attr(pylonsapp):' | |||
|
204 | 205 | ('just a string\n', False, 'just a string'), |
|
205 | 206 | ('just a string\n next line', False, 'just a string...'), |
|
206 | 207 | ('just a string\n next line', True, 'just a string\n...'), |
|
207 | ]) | |
|
208 | ], ids=no_newline_id_generator) | |
|
208 | 209 | def test_chop_at(test_text, inclusive, expected_text): |
|
209 | 210 | assert helpers.chop_at_smart( |
|
210 | 211 | test_text, '\n', inclusive, '...') == expected_text |
@@ -7,13 +7,13 b' from rhodecode.lib.utils2 import Attribu' | |||
|
7 | 7 | from rhodecode.model.notification import EmailNotificationModel |
|
8 | 8 | |
|
9 | 9 | |
|
10 |
def test_get_template_obj( |
|
|
10 | def test_get_template_obj(app): | |
|
11 | 11 | template = EmailNotificationModel().get_renderer( |
|
12 | 12 | EmailNotificationModel.TYPE_TEST) |
|
13 | 13 | assert isinstance(template, PartialRenderer) |
|
14 | 14 | |
|
15 | 15 | |
|
16 |
def test_render_email( |
|
|
16 | def test_render_email(app, http_host_only_stub): | |
|
17 | 17 | kwargs = {} |
|
18 | 18 | subject, headers, body, body_plaintext = EmailNotificationModel().render_email( |
|
19 | 19 | EmailNotificationModel.TYPE_TEST, **kwargs) |
@@ -28,12 +28,13 b' def test_render_email(pylonsapp):' | |||
|
28 | 28 | assert body_plaintext == 'Email Plaintext Body' |
|
29 | 29 | |
|
30 | 30 | # body |
|
31 | assert 'This is a notification ' \ | |
|
32 | 'from RhodeCode. http://test.example.com:80/' in body | |
|
31 | notification_footer = 'This is a notification from RhodeCode. http://%s/' \ | |
|
32 | % http_host_only_stub | |
|
33 | assert notification_footer in body | |
|
33 | 34 | assert 'Email Body' in body |
|
34 | 35 | |
|
35 | 36 | |
|
36 |
def test_render_pr_email( |
|
|
37 | def test_render_pr_email(app, user_admin): | |
|
37 | 38 | |
|
38 | 39 | ref = collections.namedtuple('Ref', |
|
39 | 40 | 'name, type')( |
@@ -77,7 +78,7 b' def test_render_pr_email(pylonsapp, user' | |||
|
77 | 78 | EmailNotificationModel.TYPE_COMMIT_COMMENT, |
|
78 | 79 | EmailNotificationModel.TYPE_PULL_REQUEST_COMMENT |
|
79 | 80 | ]) |
|
80 |
def test_render_comment_subject_no_newlines( |
|
|
81 | def test_render_comment_subject_no_newlines(app, mention, email_type): | |
|
81 | 82 | ref = collections.namedtuple('Ref', |
|
82 | 83 | 'name, type')( |
|
83 | 84 | 'fxies123', 'book' |
@@ -30,7 +30,7 b' pytestmark = [' | |||
|
30 | 30 | ] |
|
31 | 31 | |
|
32 | 32 | |
|
33 | def test_new_pull_request_is_under_review(pr_util): | |
|
33 | def test_new_pull_request_is_under_review(pr_util, config_stub): | |
|
34 | 34 | pull_request = pr_util.create_pull_request() |
|
35 | 35 | |
|
36 | 36 | # Expect that review status "Under Review" |
@@ -44,7 +44,7 b' def test_new_pull_request_is_under_revie' | |||
|
44 | 44 | db.ChangesetStatus.STATUS_UNDER_REVIEW, |
|
45 | 45 | ]) |
|
46 | 46 | def test_pull_request_under_review_if_one_reviewer_voted( |
|
47 | pr_util, voted_status): | |
|
47 | pr_util, voted_status, config_stub): | |
|
48 | 48 | pull_request = pr_util.create_pull_request() |
|
49 | 49 | pr_util.create_status_votes( |
|
50 | 50 | voted_status, pull_request.reviewers[0]) |
@@ -59,7 +59,7 b' def test_pull_request_under_review_if_on' | |||
|
59 | 59 | db.ChangesetStatus.STATUS_REJECTED, |
|
60 | 60 | db.ChangesetStatus.STATUS_UNDER_REVIEW, |
|
61 | 61 | ]) |
|
62 | def test_pull_request_has_voted_status_if_all_voted(pr_util, voted_status): | |
|
62 | def test_pull_request_has_voted_status_if_all_voted(pr_util, voted_status, config_stub): | |
|
63 | 63 | pull_request = pr_util.create_pull_request() |
|
64 | 64 | pr_util.create_status_votes( |
|
65 | 65 | voted_status, *pull_request.reviewers) |
@@ -74,7 +74,8 b' def test_pull_request_has_voted_status_i' | |||
|
74 | 74 | db.ChangesetStatus.STATUS_REJECTED, |
|
75 | 75 | db.ChangesetStatus.STATUS_UNDER_REVIEW, |
|
76 | 76 | ]) |
|
77 |
def test_pull_request_stays_if_update_without_change( |
|
|
77 | def test_pull_request_stays_if_update_without_change( | |
|
78 | pr_util, voted_status, config_stub): | |
|
78 | 79 | pull_request = pr_util.create_pull_request() |
|
79 | 80 | pr_util.create_status_votes( |
|
80 | 81 | voted_status, *pull_request.reviewers) |
@@ -92,7 +93,7 b' def test_pull_request_stays_if_update_wi' | |||
|
92 | 93 | db.ChangesetStatus.STATUS_REJECTED, |
|
93 | 94 | db.ChangesetStatus.STATUS_UNDER_REVIEW, |
|
94 | 95 | ]) |
|
95 | def test_pull_request_under_review_if_update(pr_util, voted_status): | |
|
96 | def test_pull_request_under_review_if_update(pr_util, voted_status, config_stub): | |
|
96 | 97 | pull_request = pr_util.create_pull_request() |
|
97 | 98 | pr_util.create_status_votes( |
|
98 | 99 | voted_status, *pull_request.reviewers) |
@@ -106,7 +107,7 b' def test_pull_request_under_review_if_up' | |||
|
106 | 107 | assert pull_request.calculated_review_status() == expected_review_status |
|
107 | 108 | |
|
108 | 109 | |
|
109 | def test_commit_under_review_if_part_of_new_pull_request(pr_util): | |
|
110 | def test_commit_under_review_if_part_of_new_pull_request(pr_util, config_stub): | |
|
110 | 111 | pull_request = pr_util.create_pull_request() |
|
111 | 112 | for commit_id in pull_request.revisions: |
|
112 | 113 | status = ChangesetStatusModel().get_status( |
@@ -120,7 +121,7 b' def test_commit_under_review_if_part_of_' | |||
|
120 | 121 | db.ChangesetStatus.STATUS_UNDER_REVIEW, |
|
121 | 122 | ]) |
|
122 | 123 | def test_commit_has_voted_status_after_vote_on_pull_request( |
|
123 | pr_util, voted_status): | |
|
124 | pr_util, voted_status, config_stub): | |
|
124 | 125 | pull_request = pr_util.create_pull_request() |
|
125 | 126 | pr_util.create_status_votes( |
|
126 | 127 | voted_status, pull_request.reviewers[0]) |
@@ -130,7 +131,7 b' def test_commit_has_voted_status_after_v' | |||
|
130 | 131 | assert status == voted_status |
|
131 | 132 | |
|
132 | 133 | |
|
133 | def test_commit_under_review_if_added_to_pull_request(pr_util): | |
|
134 | def test_commit_under_review_if_added_to_pull_request(pr_util, config_stub): | |
|
134 | 135 | pull_request = pr_util.create_pull_request() |
|
135 | 136 | pr_util.create_status_votes( |
|
136 | 137 | db.ChangesetStatus.STATUS_APPROVED, pull_request.reviewers[0]) |
@@ -147,7 +148,7 b' def test_commit_under_review_if_added_to' | |||
|
147 | 148 | db.ChangesetStatus.STATUS_UNDER_REVIEW, |
|
148 | 149 | ]) |
|
149 | 150 | def test_commit_keeps_status_if_removed_from_pull_request( |
|
150 | pr_util, voted_status): | |
|
151 | pr_util, voted_status, config_stub): | |
|
151 | 152 | pull_request = pr_util.create_pull_request() |
|
152 | 153 | pr_util.add_one_commit() |
|
153 | 154 | pr_util.create_status_votes(voted_status, pull_request.reviewers[0]) |
@@ -165,7 +166,7 b' def test_commit_keeps_status_if_removed_' | |||
|
165 | 166 | db.ChangesetStatus.STATUS_UNDER_REVIEW, |
|
166 | 167 | ]) |
|
167 | 168 | def test_commit_keeps_status_if_unchanged_after_update_of_pull_request( |
|
168 | pr_util, voted_status): | |
|
169 | pr_util, voted_status, config_stub): | |
|
169 | 170 | pull_request = pr_util.create_pull_request() |
|
170 | 171 | commit_id = pull_request.revisions[-1] |
|
171 | 172 | pr_util.create_status_votes(voted_status, pull_request.reviewers[0]) |
@@ -30,7 +30,7 b' from rhodecode.model.user import UserMod' | |||
|
30 | 30 | fixture = Fixture() |
|
31 | 31 | |
|
32 | 32 | |
|
33 | class TestNotifications: | |
|
33 | class TestNotifications(object): | |
|
34 | 34 | destroy_users = set() |
|
35 | 35 | |
|
36 | 36 | @classmethod |
@@ -38,7 +38,7 b' class TestNotifications:' | |||
|
38 | 38 | fixture.destroy_users(cls.destroy_users) |
|
39 | 39 | |
|
40 | 40 | @pytest.fixture(autouse=True) |
|
41 |
def create_users(self, request, |
|
|
41 | def create_users(self, request, app): | |
|
42 | 42 | Session.remove() |
|
43 | 43 | self.u1 = UserModel().create_or_update( |
|
44 | 44 | username=u'u1', password=u'qweqwe', |
@@ -62,7 +62,7 b' class TestNotifications:' | |||
|
62 | 62 | self.destroy_users.add('u3') |
|
63 | 63 | |
|
64 | 64 | @pytest.fixture(autouse=True) |
|
65 |
def _clean_notifications(self, request, |
|
|
65 | def _clean_notifications(self, request, app): | |
|
66 | 66 | for n in Notification.query().all(): |
|
67 | 67 | Session().delete(n) |
|
68 | 68 |
@@ -41,7 +41,8 b' pytestmark = [' | |||
|
41 | 41 | ] |
|
42 | 42 | |
|
43 | 43 | |
|
44 | class TestPullRequestModel: | |
|
44 | @pytest.mark.usefixtures('config_stub') | |
|
45 | class TestPullRequestModel(object): | |
|
45 | 46 | |
|
46 | 47 | @pytest.fixture |
|
47 | 48 | def pull_request(self, request, backend, pr_util): |
@@ -372,6 +373,7 b' class TestPullRequestModel:' | |||
|
372 | 373 | assert type(title) == unicode |
|
373 | 374 | |
|
374 | 375 | |
|
376 | @pytest.mark.usefixtures('config_stub') | |
|
375 | 377 | class TestIntegrationMerge(object): |
|
376 | 378 | @pytest.mark.parametrize('extra_config', ( |
|
377 | 379 | {'vcs.hooks.protocol': 'http', 'vcs.hooks.direct_calls': False}, |
@@ -433,7 +435,7 b' class TestIntegrationMerge(object):' | |||
|
433 | 435 | (True, 0, 1), |
|
434 | 436 | ]) |
|
435 | 437 | def test_outdated_comments( |
|
436 | pr_util, use_outdated, inlines_count, outdated_count): | |
|
438 | pr_util, use_outdated, inlines_count, outdated_count, config_stub): | |
|
437 | 439 | pull_request = pr_util.create_pull_request() |
|
438 | 440 | pr_util.create_inline_comment(file_path='not_in_updated_diff') |
|
439 | 441 | |
@@ -465,6 +467,7 b' def merge_extras(user_regular):' | |||
|
465 | 467 | return extras |
|
466 | 468 | |
|
467 | 469 | |
|
470 | @pytest.mark.usefixtures('config_stub') | |
|
468 | 471 | class TestUpdateCommentHandling(object): |
|
469 | 472 | |
|
470 | 473 | @pytest.fixture(autouse=True, scope='class') |
@@ -572,6 +575,7 b' class TestUpdateCommentHandling(object):' | |||
|
572 | 575 | assert_inline_comments(pull_request, visible=0, outdated=1) |
|
573 | 576 | |
|
574 | 577 | |
|
578 | @pytest.mark.usefixtures('config_stub') | |
|
575 | 579 | class TestUpdateChangedFiles(object): |
|
576 | 580 | |
|
577 | 581 | def test_no_changes_on_unchanged_diff(self, pr_util): |
@@ -681,7 +685,7 b' class TestUpdateChangedFiles(object):' | |||
|
681 | 685 | removed=['file_a', 'file_b', 'file_c']) |
|
682 | 686 | |
|
683 | 687 | |
|
684 | def test_update_writes_snapshot_into_pull_request_version(pr_util): | |
|
688 | def test_update_writes_snapshot_into_pull_request_version(pr_util, config_stub): | |
|
685 | 689 | model = PullRequestModel() |
|
686 | 690 | pull_request = pr_util.create_pull_request() |
|
687 | 691 | pr_util.update_source_repository() |
@@ -692,7 +696,7 b' def test_update_writes_snapshot_into_pul' | |||
|
692 | 696 | assert len(model.get_versions(pull_request)) == 1 |
|
693 | 697 | |
|
694 | 698 | |
|
695 | def test_update_skips_new_version_if_unchanged(pr_util): | |
|
699 | def test_update_skips_new_version_if_unchanged(pr_util, config_stub): | |
|
696 | 700 | pull_request = pr_util.create_pull_request() |
|
697 | 701 | model = PullRequestModel() |
|
698 | 702 | model.update_commits(pull_request) |
@@ -701,7 +705,7 b' def test_update_skips_new_version_if_unc' | |||
|
701 | 705 | assert len(model.get_versions(pull_request)) == 0 |
|
702 | 706 | |
|
703 | 707 | |
|
704 | def test_update_assigns_comments_to_the_new_version(pr_util): | |
|
708 | def test_update_assigns_comments_to_the_new_version(pr_util, config_stub): | |
|
705 | 709 | model = PullRequestModel() |
|
706 | 710 | pull_request = pr_util.create_pull_request() |
|
707 | 711 | comment = pr_util.create_comment() |
@@ -713,7 +717,7 b' def test_update_assigns_comments_to_the_' | |||
|
713 | 717 | assert comment.pull_request_version == model.get_versions(pull_request)[0] |
|
714 | 718 | |
|
715 | 719 | |
|
716 | def test_update_adds_a_comment_to_the_pull_request_about_the_change(pr_util): | |
|
720 | def test_update_adds_a_comment_to_the_pull_request_about_the_change(pr_util, config_stub): | |
|
717 | 721 | model = PullRequestModel() |
|
718 | 722 | pull_request = pr_util.create_pull_request() |
|
719 | 723 | pr_util.update_source_repository() |
@@ -745,7 +749,7 b' def test_update_adds_a_comment_to_the_pu' | |||
|
745 | 749 | assert update_comment.text == expected_message |
|
746 | 750 | |
|
747 | 751 | |
|
748 | def test_create_version_from_snapshot_updates_attributes(pr_util): | |
|
752 | def test_create_version_from_snapshot_updates_attributes(pr_util, config_stub): | |
|
749 | 753 | pull_request = pr_util.create_pull_request() |
|
750 | 754 | |
|
751 | 755 | # Avoiding default values |
@@ -784,7 +788,7 b' def test_create_version_from_snapshot_up' | |||
|
784 | 788 | assert version.pull_request == pull_request |
|
785 | 789 | |
|
786 | 790 | |
|
787 | def test_link_comments_to_version_only_updates_unlinked_comments(pr_util): | |
|
791 | def test_link_comments_to_version_only_updates_unlinked_comments(pr_util, config_stub): | |
|
788 | 792 | version1 = pr_util.create_version_of_pull_request() |
|
789 | 793 | comment_linked = pr_util.create_comment(linked_to=version1) |
|
790 | 794 | comment_unlinked = pr_util.create_comment() |
@@ -25,6 +25,7 b' from rhodecode.lib.vcs.exceptions import' | |||
|
25 | 25 | from rhodecode.model.pull_request import PullRequestModel |
|
26 | 26 | |
|
27 | 27 | |
|
28 | @pytest.mark.usefixtures('config_stub') | |
|
28 | 29 | @pytest.mark.backends('git') |
|
29 | 30 | class TestGetDiffForPrOrVersion(object): |
|
30 | 31 |
@@ -332,8 +332,18 b' def test_initials_gravatar_mapping_algo(' | |||
|
332 | 332 | ]) |
|
333 | 333 | def test_clone_url_generator(tmpl, repo_name, overrides, prefix, expected): |
|
334 | 334 | from rhodecode.lib.utils2 import get_clone_url |
|
335 | clone_url = get_clone_url(uri_tmpl=tmpl, qualifed_home_url='http://vps1:8000'+prefix, | |
|
336 | repo_name=repo_name, repo_id=23, **overrides) | |
|
335 | ||
|
336 | class RequestStub(object): | |
|
337 | def request_url(self, name): | |
|
338 | return 'http://vps1:8000' + prefix | |
|
339 | ||
|
340 | def route_url(self, name): | |
|
341 | return self.request_url(name) | |
|
342 | ||
|
343 | clone_url = get_clone_url( | |
|
344 | request=RequestStub(), | |
|
345 | uri_tmpl=tmpl, | |
|
346 | repo_name=repo_name, repo_id=23, **overrides) | |
|
337 | 347 | assert clone_url == expected |
|
338 | 348 | |
|
339 | 349 |
@@ -41,8 +41,7 b' from rhodecode.model.settings import Set' | |||
|
41 | 41 | from rhodecode.tests import ( |
|
42 | 42 | GIT_REPO, HG_REPO, TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS,) |
|
43 | 43 | from rhodecode.tests.fixture import Fixture |
|
44 |
from rhodecode.tests.utils import |
|
|
45 | set_anonymous_access, is_url_reachable, wait_for_url) | |
|
44 | from rhodecode.tests.utils import is_url_reachable, wait_for_url | |
|
46 | 45 | |
|
47 | 46 | RC_LOG = os.path.join(tempfile.gettempdir(), 'rc.log') |
|
48 | 47 | REPO_GROUP = 'a_repo_group' |
@@ -188,11 +187,6 b' def rc_web_server(' | |||
|
188 | 187 | return RcWebServer(rc_web_server_config) |
|
189 | 188 | |
|
190 | 189 | |
|
191 | @pytest.fixture(scope='class', autouse=True) | |
|
192 | def disable_anonymous_user_access(pylonsapp): | |
|
193 | set_anonymous_access(False) | |
|
194 | ||
|
195 | ||
|
196 | 190 | @pytest.fixture |
|
197 | 191 | def disable_locking(pylonsapp): |
|
198 | 192 | r = Repository.get_by_repo_name(GIT_REPO) |
@@ -43,8 +43,8 b' def rc_web_server_config(testini_factory' | |||
|
43 | 43 | return testini_factory(CUSTOM_PARAMS) |
|
44 | 44 | |
|
45 | 45 | |
|
46 | @pytest.mark.usefixtures("disable_locking") | |
|
47 | class TestVCSOperationsOnCustomIniConfig: | |
|
46 | @pytest.mark.usefixtures("disable_locking", "disable_anonymous_user") | |
|
47 | class TestVCSOperationsOnCustomIniConfig(object): | |
|
48 | 48 | |
|
49 | 49 | def test_clone_wrong_credentials_hg_ret_code(self, rc_web_server, tmpdir): |
|
50 | 50 | clone_url = rc_web_server.repo_clone_url(HG_REPO, passwd='bad!') |
@@ -43,8 +43,8 b' def rc_web_server_config(testini_factory' | |||
|
43 | 43 | return testini_factory(CUSTOM_PARAMS) |
|
44 | 44 | |
|
45 | 45 | |
|
46 | @pytest.mark.usefixtures("disable_locking") | |
|
47 | class TestVCSOperationsOnCustomIniConfig: | |
|
46 | @pytest.mark.usefixtures("disable_locking", "disable_anonymous_user") | |
|
47 | class TestVCSOperationsOnCustomIniConfig(object): | |
|
48 | 48 | |
|
49 | 49 | def test_clone_wrong_credentials_hg_ret_code(self, rc_web_server, tmpdir): |
|
50 | 50 | clone_url = rc_web_server.repo_clone_url(HG_REPO, passwd='bad!') |
@@ -43,8 +43,8 b' def rc_web_server_config(testini_factory' | |||
|
43 | 43 | return testini_factory(CUSTOM_PARAMS) |
|
44 | 44 | |
|
45 | 45 | |
|
46 | @pytest.mark.usefixtures("disable_locking") | |
|
47 | class TestVCSOperationsOnCustomIniConfig: | |
|
46 | @pytest.mark.usefixtures("disable_locking", "disable_anonymous_user") | |
|
47 | class TestVCSOperationsOnCustomIniConfig(object): | |
|
48 | 48 | |
|
49 | 49 | def test_clone_wrong_credentials_hg_ret_code(self, rc_web_server, tmpdir): |
|
50 | 50 | clone_url = rc_web_server.repo_clone_url(HG_REPO, passwd='bad!') |
@@ -48,7 +48,7 b' from rhodecode.tests.other.vcs_operation' | |||
|
48 | 48 | HG_REPO_WITH_GROUP, GIT_REPO_WITH_GROUP) |
|
49 | 49 | |
|
50 | 50 | |
|
51 | @pytest.mark.usefixtures("disable_locking") | |
|
51 | @pytest.mark.usefixtures("disable_locking", "disable_anonymous_user") | |
|
52 | 52 | class TestVCSOperations(object): |
|
53 | 53 | |
|
54 | 54 | def test_clone_hg_repo_by_admin(self, rc_web_server, tmpdir): |
@@ -50,8 +50,8 b' def rc_web_server_config(testini_factory' | |||
|
50 | 50 | return testini_factory(CUSTOM_PARAMS) |
|
51 | 51 | |
|
52 | 52 | |
|
53 | @pytest.mark.usefixtures("disable_locking") | |
|
54 | class TestVCSOperationsOnCustomIniConfig: | |
|
53 | @pytest.mark.usefixtures("disable_locking", "disable_anonymous_user") | |
|
54 | class TestVCSOperationsOnCustomIniConfig(object): | |
|
55 | 55 | |
|
56 | 56 | def test_clone_and_create_lock_hg(self, rc_web_server, tmpdir): |
|
57 | 57 | # enable locking |
@@ -49,8 +49,8 b' def rc_web_server_config(testini_factory' | |||
|
49 | 49 | return testini_factory(CUSTOM_PARAMS) |
|
50 | 50 | |
|
51 | 51 | |
|
52 | @pytest.mark.usefixtures("disable_locking") | |
|
53 | class TestVCSOperationsOnCustomIniConfig: | |
|
52 | @pytest.mark.usefixtures("disable_locking", "disable_anonymous_user") | |
|
53 | class TestVCSOperationsOnCustomIniConfig(object): | |
|
54 | 54 | |
|
55 | 55 | def test_clone_after_repo_was_locked_hg(self, rc_web_server, tmpdir): |
|
56 | 56 | # lock repo |
@@ -62,7 +62,7 b' from rhodecode.tests import (' | |||
|
62 | 62 | login_user_session, get_new_dir, utils, TESTS_TMP_PATH, |
|
63 | 63 | TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR2_LOGIN, |
|
64 | 64 | TEST_USER_REGULAR_PASS) |
|
65 | from rhodecode.tests.utils import CustomTestApp | |
|
65 | from rhodecode.tests.utils import CustomTestApp, set_anonymous_access, add_test_routes | |
|
66 | 66 | from rhodecode.tests.fixture import Fixture |
|
67 | 67 | |
|
68 | 68 | |
@@ -191,7 +191,15 b' def http_host_stub():' | |||
|
191 | 191 | """ |
|
192 | 192 | Value of HTTP_HOST in the test run. |
|
193 | 193 | """ |
|
194 |
return ' |
|
|
194 | return 'example.com:80' | |
|
195 | ||
|
196 | ||
|
197 | @pytest.fixture | |
|
198 | def http_host_only_stub(): | |
|
199 | """ | |
|
200 | Value of HTTP_HOST in the test run. | |
|
201 | """ | |
|
202 | return http_host_stub().split(':')[0] | |
|
195 | 203 | |
|
196 | 204 | |
|
197 | 205 | @pytest.fixture |
@@ -204,7 +212,7 b' def http_environ(http_host_stub):' | |||
|
204 | 212 | to override this for a specific test case. |
|
205 | 213 | """ |
|
206 | 214 | return { |
|
207 |
'SERVER_NAME': http_host_stub |
|
|
215 | 'SERVER_NAME': http_host_only_stub(), | |
|
208 | 216 | 'SERVER_PORT': http_host_stub.split(':')[1], |
|
209 | 217 | 'HTTP_HOST': http_host_stub, |
|
210 | 218 | 'HTTP_USER_AGENT': 'rc-test-agent', |
@@ -213,7 +221,7 b' def http_environ(http_host_stub):' | |||
|
213 | 221 | |
|
214 | 222 | |
|
215 | 223 | @pytest.fixture(scope='function') |
|
216 | def app(request, pylonsapp, http_environ): | |
|
224 | def app(request, config_stub, pylonsapp, http_environ): | |
|
217 | 225 | app = CustomTestApp( |
|
218 | 226 | pylonsapp, |
|
219 | 227 | extra_environ=http_environ) |
@@ -1680,6 +1688,7 b' def config_stub(request, request_stub):' | |||
|
1680 | 1688 | Set up pyramid.testing and return the Configurator. |
|
1681 | 1689 | """ |
|
1682 | 1690 | config = pyramid.testing.setUp(request=request_stub) |
|
1691 | add_test_routes(config) | |
|
1683 | 1692 | |
|
1684 | 1693 | @request.addfinalizer |
|
1685 | 1694 | def cleanup(): |
@@ -1700,7 +1709,7 b' def StubIntegrationType():' | |||
|
1700 | 1709 | |
|
1701 | 1710 | def __init__(self, settings): |
|
1702 | 1711 | super(_StubIntegrationType, self).__init__(settings) |
|
1703 | self.sent_events = [] # for testing | |
|
1712 | self.sent_events = [] # for testing | |
|
1704 | 1713 | |
|
1705 | 1714 | def send_event(self, event): |
|
1706 | 1715 | self.sent_events.append(event) |
@@ -1811,3 +1820,12 b' def local_dt_to_utc():' | |||
|
1811 | 1820 | return dt.replace(tzinfo=dateutil.tz.tzlocal()).astimezone( |
|
1812 | 1821 | dateutil.tz.tzutc()).replace(tzinfo=None) |
|
1813 | 1822 | return _factory |
|
1823 | ||
|
1824 | ||
|
1825 | @pytest.fixture | |
|
1826 | def disable_anonymous_user(request, pylonsapp): | |
|
1827 | set_anonymous_access(False) | |
|
1828 | ||
|
1829 | @request.addfinalizer | |
|
1830 | def cleanup(): | |
|
1831 | set_anonymous_access(True) |
@@ -138,14 +138,6 b' def create_test_repo(force=True):' | |||
|
138 | 138 | print 'done' |
|
139 | 139 | |
|
140 | 140 | |
|
141 | def set_anonymous_access(enable=True): | |
|
142 | sa = get_session() | |
|
143 | user = sa.query(User).filter(User.username == 'default').one() | |
|
144 | user.active = enable | |
|
145 | sa.add(user) | |
|
146 | sa.commit() | |
|
147 | ||
|
148 | ||
|
149 | 141 | def get_anonymous_access(): |
|
150 | 142 | sa = get_session() |
|
151 | 143 | return sa.query(User).filter(User.username == 'default').one().active |
@@ -94,6 +94,14 b' class CustomTestResponse(TestResponse):' | |||
|
94 | 94 | def assert_response(self): |
|
95 | 95 | return AssertResponse(self) |
|
96 | 96 | |
|
97 | def get_session_from_response(self): | |
|
98 | """ | |
|
99 | This returns the session from a response object. Pylons has some magic | |
|
100 | to make the session available as `response.session`. But pyramid | |
|
101 | doesn't expose it. | |
|
102 | """ | |
|
103 | return self.request.environ['beaker.session'] | |
|
104 | ||
|
97 | 105 | |
|
98 | 106 | class TestRequest(Request): |
|
99 | 107 | |
@@ -109,9 +117,6 b' class CustomTestApp(TestApp):' | |||
|
109 | 117 | RequestClass = TestRequest |
|
110 | 118 | |
|
111 | 119 | |
|
112 | ||
|
113 | ||
|
114 | ||
|
115 | 120 | def set_anonymous_access(enabled): |
|
116 | 121 | """(Dis)allows anonymous access depending on parameter `enabled`""" |
|
117 | 122 | user = User.get_default_user() |
@@ -357,16 +362,6 b' def is_url_reachable(url):' | |||
|
357 | 362 | return True |
|
358 | 363 | |
|
359 | 364 | |
|
360 | def get_session_from_response(response): | |
|
361 | """ | |
|
362 | This returns the session from a response object. Pylons has some magic | |
|
363 | to make the session available as `response.session`. But pyramid | |
|
364 | doesn't expose it. | |
|
365 | """ | |
|
366 | # TODO: Try to look up the session key also. | |
|
367 | return response.request.environ['beaker.session'] | |
|
368 | ||
|
369 | ||
|
370 | 365 | def repo_on_filesystem(repo_name): |
|
371 | 366 | from rhodecode.lib import vcs |
|
372 | 367 | from rhodecode.tests import TESTS_TMP_PATH |
@@ -407,3 +402,13 b' def commit_change(' | |||
|
407 | 402 | f_path=filename |
|
408 | 403 | ) |
|
409 | 404 | return commit |
|
405 | ||
|
406 | ||
|
407 | def add_test_routes(config): | |
|
408 | """ | |
|
409 | Adds test routing that can be used in different functional tests | |
|
410 | ||
|
411 | """ | |
|
412 | config.add_route(name='home', pattern='/') | |
|
413 | config.add_route(name='repo_summary', pattern='/{repo_name}') | |
|
414 | config.add_route(name='repo_group_home', pattern='/{repo_group_name}') |
@@ -114,7 +114,7 b' class TestMercurialRemoteRepoInvalidatio' | |||
|
114 | 114 | return shadow_repo, source_ref, target_ref |
|
115 | 115 | |
|
116 | 116 | @pytest.mark.backends('hg') |
|
117 |
def test_commit_does_not_exist_error_happens(self, pr_util, |
|
|
117 | def test_commit_does_not_exist_error_happens(self, pr_util, app): | |
|
118 | 118 | """ |
|
119 | 119 | This test is somewhat special. It does not really test the system |
|
120 | 120 | instead it is more or less a precondition for the |
@@ -152,8 +152,7 b' class TestMercurialRemoteRepoInvalidatio' | |||
|
152 | 152 | shadow_repo.get_commit(source_ref.commit_id) |
|
153 | 153 | |
|
154 | 154 | @pytest.mark.backends('hg') |
|
155 | def test_commit_does_not_exist_error_does_not_happen( | |
|
156 | self, pr_util, pylonsapp): | |
|
155 | def test_commit_does_not_exist_error_does_not_happen(self, pr_util, app): | |
|
157 | 156 | """ |
|
158 | 157 | This test simulates a pull request merge in which the pull operations |
|
159 | 158 | are handled by a different VCSServer process than all other operations. |
General Comments 0
You need to be logged in to leave comments.
Login now