Show More
@@ -15,4 +15,5 b' List of contributors to RhodeCode projec' | |||
|
15 | 15 | Les Peabody <lpeabody@gmail.com> |
|
16 | 16 | Jonas Oberschweiber <jonas.oberschweiber@d-velop.de> |
|
17 | 17 | Matt Zuba <matt.zuba@goodwillaz.org> |
|
18 | Aras Pranckevicius <aras@unity3d.com> No newline at end of file | |
|
18 | Aras Pranckevicius <aras@unity3d.com> | |
|
19 | Tony Bussieres <t.bussieres@gmail.com> |
@@ -4,6 +4,25 b' Changelog' | |||
|
4 | 4 | ========= |
|
5 | 5 | |
|
6 | 6 | |
|
7 | 1.3.2 (**2012-02-28**) | |
|
8 | ---------------------- | |
|
9 | ||
|
10 | news | |
|
11 | ++++ | |
|
12 | ||
|
13 | ||
|
14 | fixes | |
|
15 | +++++ | |
|
16 | ||
|
17 | - fixed git protocol issues with repos-groups | |
|
18 | - fixed git remote repos validator that prevented from cloning remote git repos | |
|
19 | - fixes #370 ending slashes fixes for repo and groups | |
|
20 | - fixes #368 improved git-protocol detection to handle other clients | |
|
21 | - fixes #366 When Setting Repository Group To Blank Repo Group Wont Be | |
|
22 | Moved To Root | |
|
23 | - fixes #371 fixed issues with beaker/sqlalchemy and non-ascii cache keys | |
|
24 | - fixed #373 missing cascade drop on user_group_to_perm table | |
|
25 | ||
|
7 | 26 | 1.3.1 (**2012-02-27**) |
|
8 | 27 | ---------------------- |
|
9 | 28 |
@@ -13,6 +13,6 b'' | |||
|
13 | 13 | <div style="padding:5px"> |
|
14 | 14 | <a href="http://flattr.com/thing/167489/RhodeCode" target="_blank"> |
|
15 | 15 | <img src="http://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this" border="0" /></a> |
|
16 |
</div> |
|
|
16 | </div> | |
|
17 | 17 | </div> |
|
18 | 18 | {% endblock %}} |
@@ -263,6 +263,11 b' class ReposGroupsController(BaseControll' | |||
|
263 | 263 | raise HTTPInternalServerError() |
|
264 | 264 | |
|
265 | 265 | def show_by_name(self, group_name): |
|
266 | """ | |
|
267 | This is a proxy that does a lookup group_name -> id, and shows | |
|
268 | the group by id view instead | |
|
269 | """ | |
|
270 | group_name = group_name.rstrip('/') | |
|
266 | 271 | id_ = RepoGroup.get_by_group_name(group_name).group_id |
|
267 | 272 | return self.show(id_) |
|
268 | 273 |
@@ -160,11 +160,12 b' class UsersGroupsController(BaseControll' | |||
|
160 | 160 | |
|
161 | 161 | try: |
|
162 | 162 | UsersGroupModel().delete(id) |
|
163 | Session.commit() | |
|
163 | 164 | h.flash(_('successfully deleted users group'), category='success') |
|
164 | Session.commit() | |
|
165 | 165 | except UsersGroupsAssignedException, e: |
|
166 | 166 | h.flash(e, category='error') |
|
167 | 167 | except Exception: |
|
168 | log.error(traceback.format_exc()) | |
|
168 | 169 | h.flash(_('An error occurred during deletion of users group'), |
|
169 | 170 | category='error') |
|
170 | 171 | return redirect(url('users_groups')) |
@@ -231,7 +231,7 b' def safe_str(unicode_, to_encoding=None)' | |||
|
231 | 231 | :rtype: str |
|
232 | 232 | :returns: str object |
|
233 | 233 | """ |
|
234 | ||
|
234 | ||
|
235 | 235 | # if it's not basestr cast to str |
|
236 | 236 | if not isinstance(unicode_, basestring): |
|
237 | 237 | return str(unicode_) |
@@ -24,6 +24,7 b' from beaker.exceptions import BeakerExce' | |||
|
24 | 24 | from sqlalchemy.orm.interfaces import MapperOption |
|
25 | 25 | from sqlalchemy.orm.query import Query |
|
26 | 26 | from sqlalchemy.sql import visitors |
|
27 | from rhodecode.lib import safe_str | |
|
27 | 28 | |
|
28 | 29 | |
|
29 | 30 | class CachingQuery(Query): |
@@ -137,9 +138,10 b' def _get_cache_parameters(query):' | |||
|
137 | 138 | |
|
138 | 139 | if cache_key is None: |
|
139 | 140 | # cache key - the value arguments from this query's parameters. |
|
140 | args = [str(x) for x in _params_from_query(query)] | |
|
141 | args.extend(filter(lambda k:k not in ['None', None, u'None'], | |
|
141 | args = [safe_str(x) for x in _params_from_query(query)] | |
|
142 | args.extend(filter(lambda k: k not in ['None', None, u'None'], | |
|
142 | 143 | [str(query._limit), str(query._offset)])) |
|
144 | ||
|
143 | 145 | cache_key = " ".join(args) |
|
144 | 146 | |
|
145 | 147 | if cache_key is None: |
@@ -42,13 +42,21 b' class HttpsFixup(object):' | |||
|
42 | 42 | middleware you should set this header inside your |
|
43 | 43 | proxy ie. nginx, apache etc. |
|
44 | 44 | """ |
|
45 | proto = environ.get('HTTP_X_URL_SCHEME') | |
|
46 | 45 | |
|
47 | 46 | if str2bool(self.config.get('force_https')): |
|
48 | 47 | proto = 'https' |
|
49 | ||
|
48 | else: | |
|
49 | if 'HTTP_X_URL_SCHEME' in environ: | |
|
50 | proto = environ.get('HTTP_X_URL_SCHEME') | |
|
51 | elif 'HTTP_X_FORWARDED_SCHEME' in environ: | |
|
52 | proto = environ.get('HTTP_X_FORWARDED_SCHEME') | |
|
53 | elif 'HTTP_X_FORWARDED_PROTO' in environ: | |
|
54 | proto = environ.get('HTTP_X_FORWARDED_PROTO') | |
|
55 | else: | |
|
56 | proto = 'http' | |
|
50 | 57 | if proto == 'https': |
|
51 | 58 | environ['wsgi.url_scheme'] = proto |
|
52 | 59 | else: |
|
53 | 60 | environ['wsgi.url_scheme'] = 'http' |
|
61 | ||
|
54 | 62 | return None |
@@ -25,6 +25,7 b'' | |||
|
25 | 25 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
26 | 26 | |
|
27 | 27 | import os |
|
28 | import re | |
|
28 | 29 | import logging |
|
29 | 30 | import traceback |
|
30 | 31 | |
@@ -79,21 +80,20 b' from webob.exc import HTTPNotFound, HTTP' | |||
|
79 | 80 | log = logging.getLogger(__name__) |
|
80 | 81 | |
|
81 | 82 | |
|
82 | def is_git(environ): | |
|
83 | """Returns True if request's target is git server. | |
|
84 | ``HTTP_USER_AGENT`` would then have git client version given. | |
|
83 | GIT_PROTO_PAT = re.compile(r'^/(.+)/(info/refs|git-upload-pack|git-receive-pack)') | |
|
84 | ||
|
85 | 85 | |
|
86 | :param environ: | |
|
87 | """ | |
|
88 | http_user_agent = environ.get('HTTP_USER_AGENT') | |
|
89 | if http_user_agent and http_user_agent.startswith('git'): | |
|
90 | return True | |
|
91 | return False | |
|
86 | def is_git(environ): | |
|
87 | path_info = environ['PATH_INFO'] | |
|
88 | isgit_path = GIT_PROTO_PAT.match(path_info) | |
|
89 | log.debug('is a git path %s pathinfo : %s' % (isgit_path, path_info)) | |
|
90 | return isgit_path | |
|
92 | 91 | |
|
93 | 92 | |
|
94 | 93 | class SimpleGit(BaseVCSController): |
|
95 | 94 | |
|
96 | 95 | def _handle_request(self, environ, start_response): |
|
96 | ||
|
97 | 97 | if not is_git(environ): |
|
98 | 98 | return self.application(environ, start_response) |
|
99 | 99 | |
@@ -218,13 +218,11 b' class SimpleGit(BaseVCSController):' | |||
|
218 | 218 | """ |
|
219 | 219 | try: |
|
220 | 220 | environ['PATH_INFO'] = self._get_by_id(environ['PATH_INFO']) |
|
221 |
repo_name = |
|
|
222 | if repo_name.endswith('/'): | |
|
223 | repo_name = repo_name.rstrip('/') | |
|
221 | repo_name = GIT_PROTO_PAT.match(environ['PATH_INFO']).group(1) | |
|
224 | 222 | except: |
|
225 | 223 | log.error(traceback.format_exc()) |
|
226 | 224 | raise |
|
227 | repo_name = repo_name.split('/')[0] | |
|
225 | ||
|
228 | 226 | return repo_name |
|
229 | 227 | |
|
230 | 228 | def __get_user(self, username): |
@@ -238,9 +236,10 b' class SimpleGit(BaseVCSController):' | |||
|
238 | 236 | service = environ['QUERY_STRING'].split('=') |
|
239 | 237 | if len(service) > 1: |
|
240 | 238 | service_cmd = service[1] |
|
241 |
mapping = { |
|
|
242 |
|
|
|
243 | } | |
|
239 | mapping = { | |
|
240 | 'git-receive-pack': 'push', | |
|
241 | 'git-upload-pack': 'pull', | |
|
242 | } | |
|
244 | 243 | |
|
245 | 244 | return mapping.get(service_cmd, |
|
246 | 245 | service_cmd if service_cmd else 'other') |
@@ -92,11 +92,17 b' def repo_name_slug(value):' | |||
|
92 | 92 | |
|
93 | 93 | |
|
94 | 94 | def get_repo_slug(request): |
|
95 |
|
|
|
95 | _repo = request.environ['pylons.routes_dict'].get('repo_name') | |
|
96 | if _repo: | |
|
97 | _repo = _repo.rstrip('/') | |
|
98 | return _repo | |
|
96 | 99 | |
|
97 | 100 | |
|
98 | 101 | def get_repos_group_slug(request): |
|
99 |
|
|
|
102 | _group = request.environ['pylons.routes_dict'].get('group_name') | |
|
103 | if _group: | |
|
104 | _group = _group.rstrip('/') | |
|
105 | return _group | |
|
100 | 106 | |
|
101 | 107 | |
|
102 | 108 | def action_logger(user, action, repo, ipaddr='', sa=None, commit=False): |
@@ -44,6 +44,7 b' from rhodecode.lib.compat import json' | |||
|
44 | 44 | from rhodecode.lib.caching_query import FromCache |
|
45 | 45 | |
|
46 | 46 | from rhodecode.model.meta import Base, Session |
|
47 | import hashlib | |
|
47 | 48 | |
|
48 | 49 | |
|
49 | 50 | log = logging.getLogger(__name__) |
@@ -52,6 +53,8 b' log = logging.getLogger(__name__)' | |||
|
52 | 53 | # BASE CLASSES |
|
53 | 54 | #============================================================================== |
|
54 | 55 | |
|
56 | _hash_key = lambda k: hashlib.md5(safe_str(k)).hexdigest() | |
|
57 | ||
|
55 | 58 | |
|
56 | 59 | class ModelSerializer(json.JSONEncoder): |
|
57 | 60 | """ |
@@ -337,8 +340,11 b' class User(Base, BaseModel):' | |||
|
337 | 340 | q = cls.query().filter(cls.username == username) |
|
338 | 341 | |
|
339 | 342 | if cache: |
|
340 |
q = q.options(FromCache( |
|
|
341 | "get_user_%s" % username)) | |
|
343 | q = q.options(FromCache( | |
|
344 | "sql_cache_short", | |
|
345 | "get_user_%s" % _hash_key(username) | |
|
346 | ) | |
|
347 | ) | |
|
342 | 348 | return q.scalar() |
|
343 | 349 | |
|
344 | 350 | @classmethod |
@@ -394,7 +400,7 b' class UserLog(Base, BaseModel):' | |||
|
394 | 400 | return datetime.date(*self.action_date.timetuple()[:3]) |
|
395 | 401 | |
|
396 | 402 | user = relationship('User') |
|
397 | repository = relationship('Repository',cascade='') | |
|
403 | repository = relationship('Repository', cascade='') | |
|
398 | 404 | |
|
399 | 405 | |
|
400 | 406 | class UsersGroup(Base, BaseModel): |
@@ -406,6 +412,7 b' class UsersGroup(Base, BaseModel):' | |||
|
406 | 412 | users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) |
|
407 | 413 | |
|
408 | 414 | members = relationship('UsersGroupMember', cascade="all, delete, delete-orphan", lazy="joined") |
|
415 | users_group_to_perm = relationship('UsersGroupToPerm', cascade='all') | |
|
409 | 416 | |
|
410 | 417 | def __repr__(self): |
|
411 | 418 | return '<userGroup(%s)>' % (self.users_group_name) |
@@ -418,8 +425,11 b' class UsersGroup(Base, BaseModel):' | |||
|
418 | 425 | else: |
|
419 | 426 | q = cls.query().filter(cls.users_group_name == group_name) |
|
420 | 427 | if cache: |
|
421 |
q = q.options(FromCache( |
|
|
422 | "get_user_%s" % group_name)) | |
|
428 | q = q.options(FromCache( | |
|
429 | "sql_cache_short", | |
|
430 | "get_user_%s" % _hash_key(group_name) | |
|
431 | ) | |
|
432 | ) | |
|
423 | 433 | return q.scalar() |
|
424 | 434 | |
|
425 | 435 | @classmethod |
@@ -748,8 +758,11 b' class RepoGroup(Base, BaseModel):' | |||
|
748 | 758 | gr = cls.query()\ |
|
749 | 759 | .filter(cls.group_name == group_name) |
|
750 | 760 | if cache: |
|
751 |
gr = gr.options(FromCache( |
|
|
752 | "get_group_%s" % group_name)) | |
|
761 | gr = gr.options(FromCache( | |
|
762 | "sql_cache_short", | |
|
763 | "get_group_%s" % _hash_key(group_name) | |
|
764 | ) | |
|
765 | ) | |
|
753 | 766 | return gr.scalar() |
|
754 | 767 | |
|
755 | 768 | @property |
@@ -1038,7 +1051,7 b' class CacheInvalidation(Base, BaseModel)' | |||
|
1038 | 1051 | prefix = '' |
|
1039 | 1052 | iid = rhodecode.CONFIG.get('instance_id') |
|
1040 | 1053 | if iid: |
|
1041 |
prefix = iid |
|
|
1054 | prefix = iid | |
|
1042 | 1055 | return "%s%s" % (prefix, key) |
|
1043 | 1056 | |
|
1044 | 1057 | @classmethod |
@@ -345,32 +345,46 b' def SlugifyName():' | |||
|
345 | 345 | |
|
346 | 346 | |
|
347 | 347 | def ValidCloneUri(): |
|
348 | from mercurial.httprepo import httprepository, httpsrepository | |
|
349 | 348 | from rhodecode.lib.utils import make_ui |
|
350 | 349 | |
|
350 | def url_handler(repo_type, url, proto, ui=None): | |
|
351 | if repo_type == 'hg': | |
|
352 | from mercurial.httprepo import httprepository, httpsrepository | |
|
353 | if proto == 'https': | |
|
354 | httpsrepository(make_ui('db'), url).capabilities | |
|
355 | elif proto == 'http': | |
|
356 | httprepository(make_ui('db'), url).capabilities | |
|
357 | elif repo_type == 'git': | |
|
358 | #TODO: write a git url validator | |
|
359 | pass | |
|
360 | ||
|
351 | 361 | class _ValidCloneUri(formencode.validators.FancyValidator): |
|
352 | 362 | |
|
353 | 363 | def to_python(self, value, state): |
|
354 | if not value: | |
|
364 | ||
|
365 | repo_type = value.get('repo_type') | |
|
366 | url = value.get('clone_uri') | |
|
367 | e_dict = {'clone_uri': _('invalid clone url')} | |
|
368 | ||
|
369 | if not url: | |
|
355 | 370 | pass |
|
356 |
elif |
|
|
371 | elif url.startswith('https'): | |
|
357 | 372 | try: |
|
358 | httpsrepository(make_ui('db'), value).capabilities | |
|
373 | url_handler(repo_type, url, 'https', make_ui('db')) | |
|
359 | 374 | except Exception: |
|
360 | 375 | log.error(traceback.format_exc()) |
|
361 |
raise formencode.Invalid( |
|
|
362 | state) | |
|
363 | elif value.startswith('http'): | |
|
376 | raise formencode.Invalid('', value, state, error_dict=e_dict) | |
|
377 | elif url.startswith('http'): | |
|
364 | 378 | try: |
|
365 | httprepository(make_ui('db'), value).capabilities | |
|
379 | url_handler(repo_type, url, 'http', make_ui('db')) | |
|
366 | 380 | except Exception: |
|
367 | 381 | log.error(traceback.format_exc()) |
|
368 |
raise formencode.Invalid( |
|
|
369 | state) | |
|
382 | raise formencode.Invalid('', value, state, error_dict=e_dict) | |
|
370 | 383 | else: |
|
371 |
|
|
|
372 |
|
|
|
373 | state) | |
|
384 | e_dict = {'clone_uri': _('Invalid clone url, provide a ' | |
|
385 | 'valid clone http\s url')} | |
|
386 | raise formencode.Invalid('', value, state, error_dict=e_dict) | |
|
387 | ||
|
374 | 388 | return value |
|
375 | 389 | |
|
376 | 390 | return _ValidCloneUri |
@@ -645,8 +659,7 b' def RepoForm(edit=False, old_data={}, su' | |||
|
645 | 659 | filter_extra_fields = False |
|
646 | 660 | repo_name = All(UnicodeString(strip=True, min=1, not_empty=True), |
|
647 | 661 | SlugifyName()) |
|
648 |
clone_uri = All(UnicodeString(strip=True, min=1, not_empty=False) |
|
|
649 | ValidCloneUri()()) | |
|
662 | clone_uri = All(UnicodeString(strip=True, min=1, not_empty=False)) | |
|
650 | 663 | repo_group = OneOf(repo_groups, hideList=True) |
|
651 | 664 | repo_type = OneOf(supported_backends) |
|
652 | 665 | description = UnicodeString(strip=True, min=1, not_empty=True) |
@@ -658,7 +671,9 b' def RepoForm(edit=False, old_data={}, su' | |||
|
658 | 671 | #this is repo owner |
|
659 | 672 | user = All(UnicodeString(not_empty=True), ValidRepoUser) |
|
660 | 673 | |
|
661 |
chained_validators = [Valid |
|
|
674 | chained_validators = [ValidCloneUri()(), | |
|
675 | ValidRepoName(edit, old_data), | |
|
676 | ValidPerms()] | |
|
662 | 677 | return _RepoForm |
|
663 | 678 | |
|
664 | 679 |
@@ -187,20 +187,20 b' class ReposGroupModel(BaseModel):' | |||
|
187 | 187 | # change properties |
|
188 | 188 | repos_group.group_description = form_data['group_description'] |
|
189 | 189 | repos_group.parent_group = RepoGroup.get(form_data['group_parent_id']) |
|
190 | repos_group.group_parent_id = form_data['group_parent_id'] | |
|
190 | 191 | repos_group.group_name = repos_group.get_new_name(form_data['group_name']) |
|
191 | ||
|
192 | 192 | new_path = repos_group.full_path |
|
193 | 193 | |
|
194 | 194 | self.sa.add(repos_group) |
|
195 | 195 | |
|
196 | self.__rename_group(old_path, new_path) | |
|
197 | ||
|
198 | 196 | # we need to get all repositories from this new group and |
|
199 | 197 | # rename them accordingly to new group path |
|
200 | 198 | for r in repos_group.repositories: |
|
201 | 199 | r.repo_name = r.get_new_name(r.just_name) |
|
202 | 200 | self.sa.add(r) |
|
203 | 201 | |
|
202 | self.__rename_group(old_path, new_path) | |
|
203 | ||
|
204 | 204 | return repos_group |
|
205 | 205 | except: |
|
206 | 206 | log.error(traceback.format_exc()) |
@@ -1,8 +1,9 b'' | |||
|
1 | 1 | from rhodecode.tests import * |
|
2 | from rhodecode.model.db import UsersGroup | |
|
2 | from rhodecode.model.db import UsersGroup, UsersGroupToPerm, Permission | |
|
3 | 3 | |
|
4 | 4 | TEST_USERS_GROUP = 'admins_test' |
|
5 | 5 | |
|
6 | ||
|
6 | 7 | class TestAdminUsersGroupsController(TestController): |
|
7 | 8 | |
|
8 | 9 | def test_index(self): |
@@ -16,7 +17,7 b' class TestAdminUsersGroupsController(Tes' | |||
|
16 | 17 | self.log_user() |
|
17 | 18 | users_group_name = TEST_USERS_GROUP |
|
18 | 19 | response = self.app.post(url('users_groups'), |
|
19 | {'users_group_name':users_group_name, | |
|
20 | {'users_group_name': users_group_name, | |
|
20 | 21 | 'active':True}) |
|
21 | 22 | response.follow() |
|
22 | 23 | |
@@ -47,7 +48,6 b' class TestAdminUsersGroupsController(Tes' | |||
|
47 | 48 | self.checkSessionFlash(response, |
|
48 | 49 | 'created users group %s' % users_group_name) |
|
49 | 50 | |
|
50 | ||
|
51 | 51 | gr = self.Session.query(UsersGroup)\ |
|
52 | 52 | .filter(UsersGroup.users_group_name == |
|
53 | 53 | users_group_name).one() |
@@ -60,6 +60,53 b' class TestAdminUsersGroupsController(Tes' | |||
|
60 | 60 | |
|
61 | 61 | self.assertEqual(gr, None) |
|
62 | 62 | |
|
63 | def test_enable_repository_read_on_group(self): | |
|
64 | self.log_user() | |
|
65 | users_group_name = TEST_USERS_GROUP + 'another2' | |
|
66 | response = self.app.post(url('users_groups'), | |
|
67 | {'users_group_name': users_group_name, | |
|
68 | 'active':True}) | |
|
69 | response.follow() | |
|
70 | ||
|
71 | ug = UsersGroup.get_by_group_name(users_group_name) | |
|
72 | self.checkSessionFlash(response, | |
|
73 | 'created users group %s' % users_group_name) | |
|
74 | ||
|
75 | response = self.app.put(url('users_group_perm', id=ug.users_group_id), | |
|
76 | {'create_repo_perm': True}) | |
|
77 | ||
|
78 | response.follow() | |
|
79 | ug = UsersGroup.get_by_group_name(users_group_name) | |
|
80 | p = Permission.get_by_key('hg.create.repository') | |
|
81 | # check if user has this perm | |
|
82 | perms = UsersGroupToPerm.query()\ | |
|
83 | .filter(UsersGroupToPerm.users_group == ug).all() | |
|
84 | perms = [[x.__dict__['users_group_id'], | |
|
85 | x.__dict__['permission_id'],] for x in perms] | |
|
86 | self.assertEqual( | |
|
87 | perms, | |
|
88 | [[ug.users_group_id, p.permission_id]] | |
|
89 | ) | |
|
90 | ||
|
91 | # DELETE ! | |
|
92 | ug = UsersGroup.get_by_group_name(users_group_name) | |
|
93 | ugid = ug.users_group_id | |
|
94 | response = self.app.delete(url('users_group', id=ug.users_group_id)) | |
|
95 | response = response.follow() | |
|
96 | gr = self.Session.query(UsersGroup)\ | |
|
97 | .filter(UsersGroup.users_group_name == | |
|
98 | users_group_name).scalar() | |
|
99 | ||
|
100 | self.assertEqual(gr, None) | |
|
101 | p = Permission.get_by_key('hg.create.repository') | |
|
102 | perms = UsersGroupToPerm.query()\ | |
|
103 | .filter(UsersGroupToPerm.users_group_id == ugid).all() | |
|
104 | perms = [[x.__dict__['users_group_id'], | |
|
105 | x.__dict__['permission_id'],] for x in perms] | |
|
106 | self.assertEqual( | |
|
107 | perms, | |
|
108 | [] | |
|
109 | ) | |
|
63 | 110 | |
|
64 | 111 | def test_delete_browser_fakeout(self): |
|
65 | 112 | response = self.app.post(url('users_group', id=1), |
@@ -23,7 +23,6 b" def _make_group(path, desc='desc', paren" | |||
|
23 | 23 | return gr |
|
24 | 24 | |
|
25 | 25 | gr = ReposGroupModel().create(path, desc, parent_id) |
|
26 | Session.commit() | |
|
27 | 26 | return gr |
|
28 | 27 | |
|
29 | 28 | |
@@ -31,13 +30,19 b' class TestReposGroups(unittest.TestCase)' | |||
|
31 | 30 | |
|
32 | 31 | def setUp(self): |
|
33 | 32 | self.g1 = _make_group('test1', skip_if_exists=True) |
|
33 | Session.commit() | |
|
34 | 34 | self.g2 = _make_group('test2', skip_if_exists=True) |
|
35 | Session.commit() | |
|
35 | 36 | self.g3 = _make_group('test3', skip_if_exists=True) |
|
37 | Session.commit() | |
|
36 | 38 | |
|
37 | 39 | def tearDown(self): |
|
38 | 40 | print 'out' |
|
39 | 41 | |
|
40 | 42 | def __check_path(self, *path): |
|
43 | """ | |
|
44 | Checks the path for existance ! | |
|
45 | """ | |
|
41 | 46 | path = [TESTS_TMP_PATH] + list(path) |
|
42 | 47 | path = os.path.join(*path) |
|
43 | 48 | return os.path.isdir(path) |
@@ -49,12 +54,13 b' class TestReposGroups(unittest.TestCase)' | |||
|
49 | 54 | ReposGroupModel().delete(id_) |
|
50 | 55 | |
|
51 | 56 | def __update_group(self, id_, path, desc='desc', parent_id=None): |
|
52 |
form_data = dict( |
|
|
53 | group_description=desc, | |
|
54 | group_parent_id=parent_id, | |
|
55 | perms_updates=[], | |
|
56 |
|
|
|
57 | ||
|
57 | form_data = dict( | |
|
58 | group_name=path, | |
|
59 | group_description=desc, | |
|
60 | group_parent_id=parent_id, | |
|
61 | perms_updates=[], | |
|
62 | perms_new=[] | |
|
63 | ) | |
|
58 | 64 | gr = ReposGroupModel().update(id_, form_data) |
|
59 | 65 | return gr |
|
60 | 66 | |
@@ -150,6 +156,25 b' class TestReposGroups(unittest.TestCase)' | |||
|
150 | 156 | self.assertEqual(r.repo_name, os.path.join('g2', 'g1', r.just_name)) |
|
151 | 157 | |
|
152 | 158 | |
|
159 | def test_move_to_root(self): | |
|
160 | g1 = _make_group('t11') | |
|
161 | Session.commit() | |
|
162 | g2 = _make_group('t22',parent_id=g1.group_id) | |
|
163 | Session.commit() | |
|
164 | ||
|
165 | self.assertEqual(g2.full_path,'t11/t22') | |
|
166 | self.assertTrue(self.__check_path('t11', 't22')) | |
|
167 | ||
|
168 | g2 = self.__update_group(g2.group_id, 'g22', parent_id=None) | |
|
169 | Session.commit() | |
|
170 | ||
|
171 | self.assertEqual(g2.group_name,'g22') | |
|
172 | # we moved out group from t1 to '' so it's full path should be 'g2' | |
|
173 | self.assertEqual(g2.full_path,'g22') | |
|
174 | self.assertFalse(self.__check_path('t11', 't22')) | |
|
175 | self.assertTrue(self.__check_path('g22')) | |
|
176 | ||
|
177 | ||
|
153 | 178 | class TestUser(unittest.TestCase): |
|
154 | 179 | def __init__(self, methodName='runTest'): |
|
155 | 180 | Session.remove() |
General Comments 0
You need to be logged in to leave comments.
Login now