##// END OF EJS Templates
core: moved repo_list data to pyramid.
marcink -
r1667:be1f7a06 default
parent child Browse files
Show More
@@ -0,0 +1,103 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
21 import json
22
23 from . import assert_and_get_content
24 from rhodecode.tests import TestController
25 from rhodecode.tests.fixture import Fixture
26 from rhodecode.model.db import Repository
27
28 fixture = Fixture()
29
30
31 def route_path(name, params=None, **kwargs):
32 import urllib
33
34 base_url = {
35 'repo_list_data': '/_repos',
36 }[name].format(**kwargs)
37
38 if params:
39 base_url = '{}?{}'.format(base_url, urllib.urlencode(params))
40 return base_url
41
42
43 class TestRepoListData(TestController):
44
45 def test_returns_list_of_repos_and_groups(self, xhr_header):
46 self.log_user()
47
48 response = self.app.get(
49 route_path('repo_list_data'),
50 extra_environ=xhr_header, status=200)
51 result = json.loads(response.body)['results']
52
53 repos, groups, commits = assert_and_get_content(result)
54
55 assert len(repos) == len(Repository.get_all())
56 assert len(groups) == 0
57 assert len(commits) == 0
58
59 def test_returns_list_of_repos_and_groups_filtered(self, xhr_header):
60 self.log_user()
61
62 response = self.app.get(
63 route_path('repo_list_data'),
64 params={'query': 'vcs_test_git'},
65 extra_environ=xhr_header, status=200)
66 result = json.loads(response.body)['results']
67
68 repos, groups, commits = assert_and_get_content(result)
69
70 assert len(repos) == len(Repository.query().filter(
71 Repository.repo_name.ilike('%vcs_test_git%')).all())
72 assert len(groups) == 0
73 assert len(commits) == 0
74
75 def test_returns_list_of_repos_and_groups_filtered_with_type(self, xhr_header):
76 self.log_user()
77
78 response = self.app.get(
79 route_path('repo_list_data'),
80 params={'query': 'vcs_test_git', 'repo_type': 'git'},
81 extra_environ=xhr_header, status=200)
82 result = json.loads(response.body)['results']
83
84 repos, groups, commits = assert_and_get_content(result)
85
86 assert len(repos) == len(Repository.query().filter(
87 Repository.repo_name.ilike('%vcs_test_git%')).all())
88 assert len(groups) == 0
89 assert len(commits) == 0
90
91 def test_returns_list_of_repos_non_ascii_query(self, xhr_header):
92 self.log_user()
93 response = self.app.get(
94 route_path('repo_list_data'),
95 params={'query': 'ć_vcs_test_ą', 'repo_type': 'git'},
96 extra_environ=xhr_header, status=200)
97 result = json.loads(response.body)['results']
98
99 repos, groups, commits = assert_and_get_content(result)
100
101 assert len(repos) == 0
102 assert len(groups) == 0
103 assert len(commits) == 0
@@ -29,5 +29,9 b' def includeme(config):'
29 name='user_group_autocomplete_data',
29 name='user_group_autocomplete_data',
30 pattern='/_user_groups')
30 pattern='/_user_groups')
31
31
32 config.add_route(
33 name='repo_list_data',
34 pattern='/_repos')
35
32 # Scan module for configuration decorators.
36 # Scan module for configuration decorators.
33 config.scan()
37 config.scan()
@@ -17,3 +17,24 b''
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
21
22 def assert_and_get_content(result):
23 repos = []
24 groups = []
25 commits = []
26 for data in result:
27 for data_item in data['children']:
28 assert data_item['id']
29 assert data_item['text']
30 assert data_item['url']
31 if data_item['type'] == 'repo':
32 repos.append(data_item)
33 elif data_item['type'] == 'group':
34 groups.append(data_item)
35 elif data_item['type'] == 'commit':
36 commits.append(data_item)
37 else:
38 raise Exception('invalid type %s' % data_item['type'])
39
40 return repos, groups, commits No newline at end of file
@@ -23,9 +23,13 b' import logging'
23 from pyramid.view import view_config
23 from pyramid.view import view_config
24
24
25 from rhodecode.apps._base import BaseAppView
25 from rhodecode.apps._base import BaseAppView
26 from rhodecode.lib import helpers as h
26 from rhodecode.lib.auth import LoginRequired, NotAnonymous
27 from rhodecode.lib.auth import LoginRequired, NotAnonymous
27 from rhodecode.lib.utils2 import str2bool
28 from rhodecode.lib.utils2 import safe_unicode, str2bool
29 from rhodecode.model.db import func, Repository
28 from rhodecode.model.repo import RepoModel
30 from rhodecode.model.repo import RepoModel
31 from rhodecode.model.scm import ScmModel
32
29
33
30 log = logging.getLogger(__name__)
34 log = logging.getLogger(__name__)
31
35
@@ -79,3 +83,56 b' class HomeView(BaseAppView):'
79 _user_groups = _user_groups
83 _user_groups = _user_groups
80
84
81 return {'suggestions': _user_groups}
85 return {'suggestions': _user_groups}
86
87 def _get_repo_list(self, name_contains=None, repo_type=None, limit=20):
88 query = Repository.query()\
89 .order_by(func.length(Repository.repo_name))\
90 .order_by(Repository.repo_name)
91
92 if repo_type:
93 query = query.filter(Repository.repo_type == repo_type)
94
95 if name_contains:
96 ilike_expression = u'%{}%'.format(safe_unicode(name_contains))
97 query = query.filter(
98 Repository.repo_name.ilike(ilike_expression))
99 query = query.limit(limit)
100
101 all_repos = query.all()
102 # permission checks are inside this function
103 repo_iter = ScmModel().get_repos(all_repos)
104 return [
105 {
106 'id': obj['name'],
107 'text': obj['name'],
108 'type': 'repo',
109 'obj': obj['dbrepo'],
110 'url': h.url('summary_home', repo_name=obj['name'])
111 }
112 for obj in repo_iter]
113
114 @LoginRequired()
115 @view_config(
116 route_name='repo_list_data', request_method='GET',
117 renderer='json_ext', xhr=True)
118 def repo_list_data(self):
119 _ = self.request.translate
120
121 query = self.request.GET.get('query')
122 repo_type = self.request.GET.get('repo_type')
123 log.debug('generating repo list, query:%s, repo_type:%s',
124 query, repo_type)
125
126 res = []
127 repos = self._get_repo_list(query, repo_type=repo_type)
128 if repos:
129 res.append({
130 'text': _('Repositories'),
131 'children': repos
132 })
133
134 data = {
135 'more': False,
136 'results': res
137 }
138 return data
@@ -190,8 +190,6 b' def make_map(config):'
190 rmap.connect('home', '/', controller='home', action='index', jsroute=True)
190 rmap.connect('home', '/', controller='home', action='index', jsroute=True)
191 rmap.connect('goto_switcher_data', '/_goto_data', controller='home',
191 rmap.connect('goto_switcher_data', '/_goto_data', controller='home',
192 action='goto_switcher_data')
192 action='goto_switcher_data')
193 rmap.connect('repo_list_data', '/_repos', controller='home',
194 action='repo_list_data')
195
193
196 # TODO: johbo: Static links, to be replaced by our redirection mechanism
194 # TODO: johbo: Static links, to be replaced by our redirection mechanism
197 rmap.connect('rst_help',
195 rmap.connect('rst_help',
@@ -233,25 +233,3 b' class HomeController(BaseController):'
233 'results': res
233 'results': res
234 }
234 }
235 return data
235 return data
236
237 @LoginRequired()
238 @XHRRequired()
239 @jsonify
240 def repo_list_data(self):
241 query = request.GET.get('query')
242 repo_type = request.GET.get('repo_type')
243 log.debug('generating repo list, query:%s', query)
244
245 res = []
246 repos = self._get_repo_list(query, repo_type=repo_type)
247 if repos:
248 res.append({
249 'text': _('Repositories'),
250 'children': repos
251 })
252
253 data = {
254 'more': False,
255 'results': res
256 }
257 return data
@@ -13,8 +13,6 b''
13 function registerRCRoutes() {
13 function registerRCRoutes() {
14 // routes registration
14 // routes registration
15 pyroutes.register('home', '/', []);
15 pyroutes.register('home', '/', []);
16 pyroutes.register('user_autocomplete_data', '/_users', []);
17 pyroutes.register('user_group_autocomplete_data', '/_user_groups', []);
18 pyroutes.register('new_repo', '/_admin/create_repository', []);
16 pyroutes.register('new_repo', '/_admin/create_repository', []);
19 pyroutes.register('edit_user', '/_admin/users/%(user_id)s/edit', ['user_id']);
17 pyroutes.register('edit_user', '/_admin/users/%(user_id)s/edit', ['user_id']);
20 pyroutes.register('edit_user_group_members', '/_admin/user_groups/%(user_group_id)s/edit/members', ['user_group_id']);
18 pyroutes.register('edit_user_group_members', '/_admin/user_groups/%(user_group_id)s/edit/members', ['user_group_id']);
@@ -95,6 +93,9 b' function registerRCRoutes() {'
95 pyroutes.register('register', '/_admin/register', []);
93 pyroutes.register('register', '/_admin/register', []);
96 pyroutes.register('reset_password', '/_admin/password_reset', []);
94 pyroutes.register('reset_password', '/_admin/password_reset', []);
97 pyroutes.register('reset_password_confirmation', '/_admin/password_reset_confirmation', []);
95 pyroutes.register('reset_password_confirmation', '/_admin/password_reset_confirmation', []);
96 pyroutes.register('user_autocomplete_data', '/_users', []);
97 pyroutes.register('user_group_autocomplete_data', '/_user_groups', []);
98 pyroutes.register('repo_list_data', '/_repos', []);
98 pyroutes.register('repo_maintenance', '/%(repo_name)s/maintenance', ['repo_name']);
99 pyroutes.register('repo_maintenance', '/%(repo_name)s/maintenance', ['repo_name']);
99 pyroutes.register('repo_maintenance_execute', '/%(repo_name)s/maintenance/execute', ['repo_name']);
100 pyroutes.register('repo_maintenance_execute', '/%(repo_name)s/maintenance/execute', ['repo_name']);
100 pyroutes.register('strip', '/%(repo_name)s/strip', ['repo_name']);
101 pyroutes.register('strip', '/%(repo_name)s/strip', ['repo_name']);
@@ -139,7 +139,7 b' var repoFilter = function(data) {'
139 query.callback({results: cachedData.results});
139 query.callback({results: cachedData.results});
140 } else {
140 } else {
141 $.ajax({
141 $.ajax({
142 url: "${h.url('repo_list_data')}",
142 url: pyroutes.url('repo_list_data'),
143 data: {'query': query.term},
143 data: {'query': query.term},
144 dataType: 'json',
144 dataType: 'json',
145 type: 'GET',
145 type: 'GET',
@@ -191,7 +191,7 b' var repoTypeFilter = function(data) {'
191 query.callback({results: cachedData.results});
191 query.callback({results: cachedData.results});
192 } else {
192 } else {
193 $.ajax({
193 $.ajax({
194 url: "${h.url('repo_list_data')}",
194 url: pyroutes.url('repo_list_data'),
195 data: {'query': query.term, repo_type: '${c.repo_info.repo_type}'},
195 data: {'query': query.term, repo_type: '${c.repo_info.repo_type}'},
196 dataType: 'json',
196 dataType: 'json',
197 type: 'GET',
197 type: 'GET',
@@ -136,7 +136,7 b' var repoFilter = function(data) {'
136 query.callback({results: cachedData.results});
136 query.callback({results: cachedData.results});
137 } else {
137 } else {
138 $.ajax({
138 $.ajax({
139 url: "${h.url('repo_list_data')}",
139 url: pyroutes.url('repo_list_data'),
140 data: {'query': query.term},
140 data: {'query': query.term},
141 dataType: 'json',
141 dataType: 'json',
142 type: 'GET',
142 type: 'GET',
@@ -255,65 +255,3 b' class TestGotoSwitcherData(TestControlle'
255 test_groups = [x['text'] for x in groups[:4]]
255 test_groups = [x['text'] for x in groups[:4]]
256 assert ['abc_repos', 'repos_abc',
256 assert ['abc_repos', 'repos_abc',
257 'forked-abc', 'forked-abc/a'] == test_groups
257 'forked-abc', 'forked-abc/a'] == test_groups
258
259
260 class TestRepoListData(TestController):
261 def test_returns_list_of_repos_and_groups(self, user_util):
262 self.log_user()
263
264 response = self.app.get(
265 url(controller='home', action='repo_list_data'),
266 headers={'X-REQUESTED-WITH': 'XMLHttpRequest', }, status=200)
267 result = json.loads(response.body)['results']
268
269 repos, groups, commits = assert_and_get_content(result)
270
271 assert len(repos) == len(Repository.get_all())
272 assert len(groups) == 0
273 assert len(commits) == 0
274
275 def test_returns_list_of_repos_and_groups_filtered(self):
276 self.log_user()
277
278 response = self.app.get(
279 url(controller='home', action='repo_list_data'),
280 headers={'X-REQUESTED-WITH': 'XMLHttpRequest', },
281 params={'query': 'vcs_test_git'}, status=200)
282 result = json.loads(response.body)['results']
283
284 repos, groups, commits = assert_and_get_content(result)
285
286 assert len(repos) == len(Repository.query().filter(
287 Repository.repo_name.ilike('%vcs_test_git%')).all())
288 assert len(groups) == 0
289 assert len(commits) == 0
290
291 def test_returns_list_of_repos_and_groups_filtered_with_type(self):
292 self.log_user()
293
294 response = self.app.get(
295 url(controller='home', action='repo_list_data'),
296 headers={'X-REQUESTED-WITH': 'XMLHttpRequest', },
297 params={'query': 'vcs_test_git', 'repo_type': 'git'}, status=200)
298 result = json.loads(response.body)['results']
299
300 repos, groups, commits = assert_and_get_content(result)
301
302 assert len(repos) == len(Repository.query().filter(
303 Repository.repo_name.ilike('%vcs_test_git%')).all())
304 assert len(groups) == 0
305 assert len(commits) == 0
306
307 def test_returns_list_of_repos_non_ascii_query(self):
308 self.log_user()
309 response = self.app.get(
310 url(controller='home', action='repo_list_data'),
311 headers={'X-REQUESTED-WITH': 'XMLHttpRequest', },
312 params={'query': 'ć_vcs_test_ą', 'repo_type': 'git'}, status=200)
313 result = json.loads(response.body)['results']
314
315 repos, groups, commits = assert_and_get_content(result)
316
317 assert len(repos) == 0
318 assert len(groups) == 0
319 assert len(commits) == 0
General Comments 0
You need to be logged in to leave comments. Login now