##// END OF EJS Templates
Tests updates, Session refactoring
marcink -
r1713:54687aa0 beta
parent child Browse files
Show More
@@ -1,6 +1,7 b''
1 import logging
1 import logging
2 import traceback
2
3
3 from pylons import tmpl_context as c
4 from pylons import tmpl_context as c, url
4
5
5 from rhodecode.lib.base import BaseController, render
6 from rhodecode.lib.base import BaseController, render
6 from rhodecode.model.db import Notification
7 from rhodecode.model.db import Notification
@@ -8,6 +9,8 b' from rhodecode.model.db import Notificat'
8 from rhodecode.model.notification import NotificationModel
9 from rhodecode.model.notification import NotificationModel
9 from rhodecode.lib.auth import LoginRequired
10 from rhodecode.lib.auth import LoginRequired
10 from rhodecode.lib import helpers as h
11 from rhodecode.lib import helpers as h
12 from rhodecode.model.meta import Session
13 from pylons.controllers.util import redirect
11
14
12 log = logging.getLogger(__name__)
15 log = logging.getLogger(__name__)
13
16
@@ -57,27 +60,42 b' class NotificationsController(BaseContro'
57 # method='delete')
60 # method='delete')
58 # url('notification', notification_id=ID)
61 # url('notification', notification_id=ID)
59
62
60 no = Notification.get(notification_id)
63 try:
61 owner = lambda: no.notifications_to_users.user.user_id == c.rhodecode_user.user_id
64 no = Notification.get(notification_id)
62 if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
65 owner = lambda: (no.notifications_to_users.user.user_id
63 NotificationModel().delete(notification_id)
66 == c.rhodecode_user.user_id)
64 return 'ok'
67 if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
68 NotificationModel().delete(c.rhodecode_user.user_id, no)
69 Session.commit()
70 return 'ok'
71 except Exception:
72 Session.rollback()
73 log.error(traceback.format_exc())
65 return 'fail'
74 return 'fail'
66
75
67 def show(self, notification_id, format='html'):
76 def show(self, notification_id, format='html'):
68 """GET /_admin/notifications/id: Show a specific item"""
77 """GET /_admin/notifications/id: Show a specific item"""
69 # url('notification', notification_id=ID)
78 # url('notification', notification_id=ID)
70 c.user = self.rhodecode_user
79 c.user = self.rhodecode_user
71 c.notification = Notification.get(notification_id)
80 no = Notification.get(notification_id)
81
82 owner = lambda: (no.notifications_to_users.user.user_id
83 == c.user.user_id)
84 if no and (h.HasPermissionAny('hg.admin', 'repository.admin')() or owner):
85 unotification = NotificationModel()\
86 .get_user_notification(c.user.user_id, no)
72
87
73 unotification = NotificationModel()\
88 # if this association to user is not valid, we don't want to show
74 .get_user_notification(c.user.user_id,
89 # this message
75 c.notification)
90 if unotification:
91 if unotification.read is False:
92 unotification.mark_as_read()
93 Session.commit()
94 c.notification = no
76
95
77 if unotification.read is False:
96 return render('admin/notifications/show_notification.html')
78 unotification.mark_as_read()
79
97
80 return render('admin/notifications/show_notification.html')
98 return redirect(url('notifications'))
81
99
82 def edit(self, notification_id, format='html'):
100 def edit(self, notification_id, format='html'):
83 """GET /_admin/notifications/id/edit: Form to edit an existing item"""
101 """GET /_admin/notifications/id/edit: Form to edit an existing item"""
@@ -44,6 +44,7 b' from vcs.exceptions import RepositoryErr'
44 from vcs.nodes import FileNode
44 from vcs.nodes import FileNode
45 from vcs.utils import diffs as differ
45 from vcs.utils import diffs as differ
46 from webob.exc import HTTPForbidden
46 from webob.exc import HTTPForbidden
47 from rhodecode.model.meta import Session
47
48
48 log = logging.getLogger(__name__)
49 log = logging.getLogger(__name__)
49
50
@@ -279,7 +280,7 b' class ChangesetController(BaseRepoContro'
279 revision=revision,
280 revision=revision,
280 f_path=request.POST.get('f_path'),
281 f_path=request.POST.get('f_path'),
281 line_no=request.POST.get('line'))
282 line_no=request.POST.get('line'))
282
283 Session.commit()
283 return redirect(h.url('changeset_home', repo_name=repo_name,
284 return redirect(h.url('changeset_home', repo_name=repo_name,
284 revision=revision))
285 revision=revision))
285
286
@@ -288,8 +289,8 b' class ChangesetController(BaseRepoContro'
288 co = ChangesetComment.get(comment_id)
289 co = ChangesetComment.get(comment_id)
289 owner = lambda : co.author.user_id == c.rhodecode_user.user_id
290 owner = lambda : co.author.user_id == c.rhodecode_user.user_id
290 if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
291 if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
291 ccmodel = ChangesetCommentsModel()
292 ChangesetCommentsModel().delete(comment=co)
292 ccmodel.delete(comment_id=comment_id)
293 Session.commit()
293 return True
294 return True
294 else:
295 else:
295 raise HTTPForbidden()
296 raise HTTPForbidden()
@@ -24,6 +24,7 b''
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import os
26 import os
27 import re
27
28
28 def __get_lem():
29 def __get_lem():
29 from pygments import lexers
30 from pygments import lexers
@@ -78,9 +79,9 b' ALL_READMES = ['
78
79
79 # extension together with weights to search lower is first
80 # extension together with weights to search lower is first
80 RST_EXTS = [
81 RST_EXTS = [
81 ('', 0), ('.rst', 1),('.rest', 1),
82 ('', 0), ('.rst', 1), ('.rest', 1),
82 ('.RST', 2) ,('.REST', 2),
83 ('.RST', 2) , ('.REST', 2),
83 ('.txt', 3), ('.TXT', 3)
84 ('.txt', 3), ('.TXT', 3)
84 ]
85 ]
85
86
86 MARKDOWN_EXTS = [
87 MARKDOWN_EXTS = [
@@ -90,7 +91,7 b' MARKDOWN_EXTS = ['
90 ('.markdown', 4), ('.MARKDOWN', 4)
91 ('.markdown', 4), ('.MARKDOWN', 4)
91 ]
92 ]
92
93
93 PLAIN_EXTS = [('.text', 2),('.TEXT', 2)]
94 PLAIN_EXTS = [('.text', 2), ('.TEXT', 2)]
94
95
95 ALL_EXTS = MARKDOWN_EXTS + RST_EXTS + PLAIN_EXTS
96 ALL_EXTS = MARKDOWN_EXTS + RST_EXTS + PLAIN_EXTS
96
97
@@ -223,7 +224,7 b" def safe_str(unicode_, to_encoding='utf8"
223 :rtype: str
224 :rtype: str
224 :returns: str object
225 :returns: str object
225 """
226 """
226
227
227 if not isinstance(unicode_, basestring):
228 if not isinstance(unicode_, basestring):
228 return str(unicode_)
229 return str(unicode_)
229
230
@@ -436,3 +437,14 b' def get_current_revision(quiet=False):'
436 "was: %s" % err)
437 "was: %s" % err)
437 return None
438 return None
438
439
440 def extract_mentioned_users(s):
441 """
442 Returns unique usernames from given string s that have @mention
443
444 :param s: string to get mentions
445 """
446 usrs = {}
447 for username in re.findall(r'(?:^@|\s@)(\w+)', s):
448 usrs[username] = username
449
450 return sorted(usrs.keys())
@@ -55,8 +55,6 b' from sqlalchemy import engine_from_confi'
55
55
56 add_cache(config)
56 add_cache(config)
57
57
58
59
60 __all__ = ['whoosh_index', 'get_commits_stats',
58 __all__ = ['whoosh_index', 'get_commits_stats',
61 'reset_user_password', 'send_email']
59 'reset_user_password', 'send_email']
62
60
@@ -101,6 +99,7 b' def get_commits_stats(repo_name, ts_min_'
101
99
102 log.info('running task with lockkey %s', lockkey)
100 log.info('running task with lockkey %s', lockkey)
103 try:
101 try:
102 sa = get_session()
104 lock = l = DaemonLock(file_=jn(lockkey_path, lockkey))
103 lock = l = DaemonLock(file_=jn(lockkey_path, lockkey))
105
104
106 #for js data compatibilty cleans the key for person from '
105 #for js data compatibilty cleans the key for person from '
@@ -122,8 +121,6 b' def get_commits_stats(repo_name, ts_min_'
122 last_cs = None
121 last_cs = None
123 timegetter = itemgetter('time')
122 timegetter = itemgetter('time')
124
123
125 sa = get_session()
126
127 dbrepo = sa.query(Repository)\
124 dbrepo = sa.query(Repository)\
128 .filter(Repository.repo_name == repo_name).scalar()
125 .filter(Repository.repo_name == repo_name).scalar()
129 cur_stats = sa.query(Statistics)\
126 cur_stats = sa.query(Statistics)\
@@ -71,4 +71,22 b' class BaseModel(object):'
71 if sa is not None:
71 if sa is not None:
72 self.sa = sa
72 self.sa = sa
73 else:
73 else:
74 self.sa = meta.Session
74 self.sa = meta.Session()
75
76 def __get_instance(self, cls, instance):
77 """
78 Get's instance of given cls using some simple lookup mechanism
79
80 :param cls: class to fetch
81 :param instance: int or Instance
82 """
83
84 if isinstance(instance, cls):
85 return instance
86 elif isinstance(instance, int) or str(instance).isdigit():
87 return cls.get(instance)
88 else:
89 if instance:
90 raise Exception('given object must be int or Instance'
91 ' of %s got %s' % (type(cls),
92 type(instance)))
@@ -23,13 +23,13 b''
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import re
27 import logging
26 import logging
28 import traceback
27 import traceback
29
28
30 from pylons.i18n.translation import _
29 from pylons.i18n.translation import _
31 from sqlalchemy.util.compat import defaultdict
30 from sqlalchemy.util.compat import defaultdict
32
31
32 from rhodecode.lib import extract_mentioned_users
33 from rhodecode.lib import helpers as h
33 from rhodecode.lib import helpers as h
34 from rhodecode.model import BaseModel
34 from rhodecode.model import BaseModel
35 from rhodecode.model.db import ChangesetComment, User, Repository, Notification
35 from rhodecode.model.db import ChangesetComment, User, Repository, Notification
@@ -40,15 +40,16 b' log = logging.getLogger(__name__)'
40
40
41 class ChangesetCommentsModel(BaseModel):
41 class ChangesetCommentsModel(BaseModel):
42
42
43 def __get_changeset_comment(self, changeset_comment):
44 return self.__get_instance(ChangesetComment, changeset_comment)
43
45
44 def _extract_mentions(self, s):
46 def _extract_mentions(self, s):
45 usrs = []
47 user_objects = []
46 for username in re.findall(r'(?:^@|\s@)(\w+)', s):
48 for username in extract_mentioned_users(s):
47 user_obj = User.get_by_username(username, case_insensitive=True)
49 user_obj = User.get_by_username(username, case_insensitive=True)
48 if user_obj:
50 if user_obj:
49 usrs.append(user_obj)
51 user_objects.append(user_obj)
50
52 return user_objects
51 return usrs
52
53
53 def create(self, text, repo_id, user_id, revision, f_path=None,
54 def create(self, text, repo_id, user_id, revision, f_path=None,
54 line_no=None):
55 line_no=None):
@@ -81,30 +82,30 b' class ChangesetCommentsModel(BaseModel):'
81 if line_no:
82 if line_no:
82 line = _('on line %s') % line_no
83 line = _('on line %s') % line_no
83 subj = h.link_to('Re commit: %(commit_desc)s %(line)s' % \
84 subj = h.link_to('Re commit: %(commit_desc)s %(line)s' % \
84 {'commit_desc':desc,'line':line},
85 {'commit_desc':desc, 'line':line},
85 h.url('changeset_home', repo_name=repo.repo_name,
86 h.url('changeset_home', repo_name=repo.repo_name,
86 revision = revision,
87 revision=revision,
87 anchor = 'comment-%s' % comment.comment_id
88 anchor='comment-%s' % comment.comment_id
88 )
89 )
89 )
90 )
90 body = text
91 body = text
91 recipients = ChangesetComment.get_users(revision=revision)
92 recipients = ChangesetComment.get_users(revision=revision)
92 recipients += self._extract_mentions(body)
93 recipients += self._extract_mentions(body)
93 NotificationModel().create(created_by=user_id, subject=subj,
94 NotificationModel().create(created_by=user_id, subject=subj,
94 body = body, recipients = recipients,
95 body=body, recipients=recipients,
95 type_ = Notification.TYPE_CHANGESET_COMMENT)
96 type_=Notification.TYPE_CHANGESET_COMMENT)
96
97
97 return comment
98 return comment
98
99
99 def delete(self, comment_id):
100 def delete(self, comment):
100 """
101 """
101 Deletes given comment
102 Deletes given comment
102
103
103 :param comment_id:
104 :param comment_id:
104 """
105 """
105 comment = ChangesetComment.get(comment_id)
106 comment = self.__get_changeset_comment(comment)
106 self.sa.delete(comment)
107 self.sa.delete(comment)
107 self.sa.commit()
108
108 return comment
109 return comment
109
110
110
111
@@ -48,7 +48,6 b' from rhodecode.lib.caching_query import '
48
48
49 from rhodecode.model.meta import Base, Session
49 from rhodecode.model.meta import Base, Session
50
50
51
52 log = logging.getLogger(__name__)
51 log = logging.getLogger(__name__)
53
52
54 #==============================================================================
53 #==============================================================================
@@ -122,7 +121,7 b' class BaseModel(object):'
122
121
123 @classmethod
122 @classmethod
124 def query(cls):
123 def query(cls):
125 return Session.query(cls)
124 return Session().query(cls)
126
125
127 @classmethod
126 @classmethod
128 def get(cls, id_):
127 def get(cls, id_):
@@ -136,8 +135,7 b' class BaseModel(object):'
136 @classmethod
135 @classmethod
137 def delete(cls, id_):
136 def delete(cls, id_):
138 obj = cls.query().get(id_)
137 obj = cls.query().get(id_)
139 Session.delete(obj)
138 Session().delete(obj)
140 Session.commit()
141
139
142
140
143 class RhodeCodeSetting(Base, BaseModel):
141 class RhodeCodeSetting(Base, BaseModel):
@@ -257,8 +255,8 b' class RhodeCodeUi(Base, BaseModel):'
257 new_ui.ui_key = key
255 new_ui.ui_key = key
258 new_ui.ui_value = val
256 new_ui.ui_value = val
259
257
260 Session.add(new_ui)
258 Session().add(new_ui)
261 Session.commit()
259 Session().commit()
262
260
263
261
264 class User(Base, BaseModel):
262 class User(Base, BaseModel):
@@ -285,9 +283,7 b' class User(Base, BaseModel):'
285
283
286 group_member = relationship('UsersGroupMember', cascade='all')
284 group_member = relationship('UsersGroupMember', cascade='all')
287
285
288 notifications = relationship('Notification',
286 notifications = relationship('UserNotification')
289 secondary='user_to_notification',
290 order_by=lambda :Notification.created_on.desc())
291
287
292 @property
288 @property
293 def full_contact(self):
289 def full_contact(self):
@@ -331,8 +327,8 b' class User(Base, BaseModel):'
331 """Update user lastlogin"""
327 """Update user lastlogin"""
332
328
333 self.last_login = datetime.datetime.now()
329 self.last_login = datetime.datetime.now()
334 Session.add(self)
330 Session().add(self)
335 Session.commit()
331 Session().commit()
336 log.debug('updated user %s lastlogin', self.username)
332 log.debug('updated user %s lastlogin', self.username)
337
333
338
334
@@ -397,12 +393,12 b' class UsersGroup(Base, BaseModel):'
397 for k, v in form_data.items():
393 for k, v in form_data.items():
398 setattr(new_users_group, k, v)
394 setattr(new_users_group, k, v)
399
395
400 Session.add(new_users_group)
396 Session().add(new_users_group)
401 Session.commit()
397 Session().commit()
402 return new_users_group
398 return new_users_group
403 except:
399 except:
404 log.error(traceback.format_exc())
400 log.error(traceback.format_exc())
405 Session.rollback()
401 Session().rollback()
406 raise
402 raise
407
403
408 @classmethod
404 @classmethod
@@ -414,7 +410,7 b' class UsersGroup(Base, BaseModel):'
414 for k, v in form_data.items():
410 for k, v in form_data.items():
415 if k == 'users_group_members':
411 if k == 'users_group_members':
416 users_group.members = []
412 users_group.members = []
417 Session.flush()
413 Session().flush()
418 members_list = []
414 members_list = []
419 if v:
415 if v:
420 v = [v] if isinstance(v, basestring) else v
416 v = [v] if isinstance(v, basestring) else v
@@ -424,11 +420,11 b' class UsersGroup(Base, BaseModel):'
424 setattr(users_group, 'members', members_list)
420 setattr(users_group, 'members', members_list)
425 setattr(users_group, k, v)
421 setattr(users_group, k, v)
426
422
427 Session.add(users_group)
423 Session().add(users_group)
428 Session.commit()
424 Session().commit()
429 except:
425 except:
430 log.error(traceback.format_exc())
426 log.error(traceback.format_exc())
431 Session.rollback()
427 Session().rollback()
432 raise
428 raise
433
429
434 @classmethod
430 @classmethod
@@ -445,11 +441,11 b' class UsersGroup(Base, BaseModel):'
445 assigned_groups)
441 assigned_groups)
446
442
447 users_group = cls.get(users_group_id, cache=False)
443 users_group = cls.get(users_group_id, cache=False)
448 Session.delete(users_group)
444 Session().delete(users_group)
449 Session.commit()
445 Session().commit()
450 except:
446 except:
451 log.error(traceback.format_exc())
447 log.error(traceback.format_exc())
452 Session.rollback()
448 Session().rollback()
453 raise
449 raise
454
450
455 class UsersGroupMember(Base, BaseModel):
451 class UsersGroupMember(Base, BaseModel):
@@ -472,8 +468,8 b' class UsersGroupMember(Base, BaseModel):'
472 ugm = UsersGroupMember()
468 ugm = UsersGroupMember()
473 ugm.users_group = group
469 ugm.users_group = group
474 ugm.user = user
470 ugm.user = user
475 Session.add(ugm)
471 Session().add(ugm)
476 Session.commit()
472 Session().commit()
477 return ugm
473 return ugm
478
474
479 class Repository(Base, BaseModel):
475 class Repository(Base, BaseModel):
@@ -516,7 +512,7 b' class Repository(Base, BaseModel):'
516
512
517 @classmethod
513 @classmethod
518 def get_by_repo_name(cls, repo_name):
514 def get_by_repo_name(cls, repo_name):
519 q = Session.query(cls).filter(cls.repo_name == repo_name)
515 q = Session().query(cls).filter(cls.repo_name == repo_name)
520 q = q.options(joinedload(Repository.fork))\
516 q = q.options(joinedload(Repository.fork))\
521 .options(joinedload(Repository.user))\
517 .options(joinedload(Repository.user))\
522 .options(joinedload(Repository.group))
518 .options(joinedload(Repository.group))
@@ -533,7 +529,7 b' class Repository(Base, BaseModel):'
533
529
534 :param cls:
530 :param cls:
535 """
531 """
536 q = Session.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key ==
532 q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key ==
537 cls.url_sep())
533 cls.url_sep())
538 q.options(FromCache("sql_cache_short", "repository_repo_path"))
534 q.options(FromCache("sql_cache_short", "repository_repo_path"))
539 return q.one().ui_value
535 return q.one().ui_value
@@ -569,7 +565,7 b' class Repository(Base, BaseModel):'
569 Returns base full path for that repository means where it actually
565 Returns base full path for that repository means where it actually
570 exists on a filesystem
566 exists on a filesystem
571 """
567 """
572 q = Session.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key ==
568 q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key ==
573 Repository.url_sep())
569 Repository.url_sep())
574 q.options(FromCache("sql_cache_short", "repository_repo_path"))
570 q.options(FromCache("sql_cache_short", "repository_repo_path"))
575 return q.one().ui_value
571 return q.one().ui_value
@@ -886,10 +882,10 b' class UserToPerm(Base, BaseModel):'
886 new.user_id = user_id
882 new.user_id = user_id
887 new.permission = perm
883 new.permission = perm
888 try:
884 try:
889 Session.add(new)
885 Session().add(new)
890 Session.commit()
886 Session().commit()
891 except:
887 except:
892 Session.rollback()
888 Session().rollback()
893
889
894
890
895 @classmethod
891 @classmethod
@@ -898,11 +894,12 b' class UserToPerm(Base, BaseModel):'
898 raise Exception('perm needs to be an instance of Permission class')
894 raise Exception('perm needs to be an instance of Permission class')
899
895
900 try:
896 try:
901 cls.query().filter(cls.user_id == user_id)\
897 obj = cls.query().filter(cls.user_id == user_id)\
902 .filter(cls.permission == perm).delete()
898 .filter(cls.permission == perm).one()
903 Session.commit()
899 Session().delete(obj)
900 Session().commit()
904 except:
901 except:
905 Session.rollback()
902 Session().rollback()
906
903
907 class UsersGroupRepoToPerm(Base, BaseModel):
904 class UsersGroupRepoToPerm(Base, BaseModel):
908 __tablename__ = 'users_group_repo_to_perm'
905 __tablename__ = 'users_group_repo_to_perm'
@@ -948,10 +945,10 b' class UsersGroupToPerm(Base, BaseModel):'
948 new.users_group_id = users_group_id
945 new.users_group_id = users_group_id
949 new.permission = perm
946 new.permission = perm
950 try:
947 try:
951 Session.add(new)
948 Session().add(new)
952 Session.commit()
949 Session().commit()
953 except:
950 except:
954 Session.rollback()
951 Session().rollback()
955
952
956
953
957 @classmethod
954 @classmethod
@@ -960,11 +957,12 b' class UsersGroupToPerm(Base, BaseModel):'
960 raise Exception('perm needs to be an instance of Permission class')
957 raise Exception('perm needs to be an instance of Permission class')
961
958
962 try:
959 try:
963 cls.query().filter(cls.users_group_id == users_group_id)\
960 obj = cls.query().filter(cls.users_group_id == users_group_id)\
964 .filter(cls.permission == perm).delete()
961 .filter(cls.permission == perm).one()
965 Session.commit()
962 Session().delete(obj)
963 Session().commit()
966 except:
964 except:
967 Session.rollback()
965 Session().rollback()
968
966
969
967
970 class UserRepoGroupToPerm(Base, BaseModel):
968 class UserRepoGroupToPerm(Base, BaseModel):
@@ -1077,11 +1075,11 b' class CacheInvalidation(Base, BaseModel)'
1077 inv_obj = CacheInvalidation(key)
1075 inv_obj = CacheInvalidation(key)
1078
1076
1079 try:
1077 try:
1080 Session.add(inv_obj)
1078 Session().add(inv_obj)
1081 Session.commit()
1079 Session().commit()
1082 except Exception:
1080 except Exception:
1083 log.error(traceback.format_exc())
1081 log.error(traceback.format_exc())
1084 Session.rollback()
1082 Session().rollback()
1085
1083
1086 @classmethod
1084 @classmethod
1087 def set_valid(cls, key):
1085 def set_valid(cls, key):
@@ -1090,11 +1088,11 b' class CacheInvalidation(Base, BaseModel)'
1090
1088
1091 :param key:
1089 :param key:
1092 """
1090 """
1093 inv_obj = Session().query(CacheInvalidation)\
1091 inv_obj = CacheInvalidation.query()\
1094 .filter(CacheInvalidation.cache_key == key).scalar()
1092 .filter(CacheInvalidation.cache_key == key).scalar()
1095 inv_obj.cache_active = True
1093 inv_obj.cache_active = True
1096 Session.add(inv_obj)
1094 Session().add(inv_obj)
1097 Session.commit()
1095 Session().commit()
1098
1096
1099
1097
1100 class ChangesetComment(Base, BaseModel):
1098 class ChangesetComment(Base, BaseModel):
@@ -1122,7 +1120,7 b' class ChangesetComment(Base, BaseModel):'
1122 :param cls:
1120 :param cls:
1123 :param revision:
1121 :param revision:
1124 """
1122 """
1125 return Session.query(User)\
1123 return Session().query(User)\
1126 .filter(cls.revision == revision)\
1124 .filter(cls.revision == revision)\
1127 .join(ChangesetComment.author).all()
1125 .join(ChangesetComment.author).all()
1128
1126
@@ -1146,7 +1144,7 b' class Notification(Base, BaseModel):'
1146 notifications_to_users = relationship('UserNotification',
1144 notifications_to_users = relationship('UserNotification',
1147 primaryjoin='Notification.notification_id==UserNotification.notification_id',
1145 primaryjoin='Notification.notification_id==UserNotification.notification_id',
1148 lazy='joined',
1146 lazy='joined',
1149 cascade = "all, delete, delete-orphan")
1147 cascade="all, delete, delete-orphan")
1150
1148
1151 @property
1149 @property
1152 def recipients(self):
1150 def recipients(self):
@@ -1163,9 +1161,12 b' class Notification(Base, BaseModel):'
1163 notification.subject = subject
1161 notification.subject = subject
1164 notification.body = body
1162 notification.body = body
1165 notification.type_ = type_
1163 notification.type_ = type_
1166 Session.add(notification)
1164
1167 for u in recipients:
1165 for u in recipients:
1168 u.notifications.append(notification)
1166 assoc = UserNotification()
1167 assoc.notification = notification
1168 u.notifications.append(assoc)
1169 Session().add(notification)
1169 return notification
1170 return notification
1170
1171
1171 @property
1172 @property
@@ -1177,19 +1178,17 b' class UserNotification(Base, BaseModel):'
1177 __tablename__ = 'user_to_notification'
1178 __tablename__ = 'user_to_notification'
1178 __table_args__ = (UniqueConstraint('user_id', 'notification_id'),
1179 __table_args__ = (UniqueConstraint('user_id', 'notification_id'),
1179 {'extend_existing':True})
1180 {'extend_existing':True})
1180 user_to_notification_id = Column("user_to_notification_id", Integer(), nullable=False, unique=True, primary_key=True)
1181 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), primary_key=True)
1181 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
1182 notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True)
1182 notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), nullable=False)
1183 read = Column('read', Boolean, default=False)
1183 read = Column('read', Boolean, default=False)
1184 sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None)
1184 sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None)
1185
1185
1186 user = relationship('User', single_parent=True, lazy="joined")
1186 user = relationship('User', lazy="joined")
1187 notification = relationship('Notification', single_parent=True,)
1187 notification = relationship('Notification', lazy="joined", cascade='all')
1188
1188
1189 def mark_as_read(self):
1189 def mark_as_read(self):
1190 self.read = True
1190 self.read = True
1191 Session.add(self)
1191 Session().add(self)
1192 Session.commit()
1193
1192
1194 class DbMigrateVersion(Base, BaseModel):
1193 class DbMigrateVersion(Base, BaseModel):
1195 __tablename__ = 'db_migrate_version'
1194 __tablename__ = 'db_migrate_version'
@@ -88,30 +88,35 b' class NotificationModel(BaseModel):'
88 body=body, recipients=recipients_objs,
88 body=body, recipients=recipients_objs,
89 type_=type_)
89 type_=type_)
90
90
91 def delete(self, notification_id):
91 def delete(self, user, notification):
92 # we don't want to remove actuall notification just the assignment
92 # we don't want to remove actual notification just the assignment
93 try:
93 try:
94 notification_id = int(notification_id)
94 notification = self.__get_notification(notification)
95 no = self.__get_notification(notification_id)
95 user = self.__get_user(user)
96 if no:
96 if notification and user:
97 UserNotification.delete(no.notifications_to_users.user_to_notification_id)
97 obj = UserNotification.query().filter(UserNotification.user == user)\
98 .filter(UserNotification.notification == notification).one()
99 self.sa.delete(obj)
98 return True
100 return True
99 except Exception:
101 except Exception:
100 log.error(traceback.format_exc())
102 log.error(traceback.format_exc())
101 raise
103 raise
102
104
103 def get_for_user(self, user_id):
105 def get_for_user(self, user):
104 return User.get(user_id).notifications
106 user = self.__get_user(user)
107 return user.notifications
105
108
106 def get_unread_cnt_for_user(self, user_id):
109 def get_unread_cnt_for_user(self, user):
110 user = self.__get_user(user)
107 return UserNotification.query()\
111 return UserNotification.query()\
108 .filter(UserNotification.read == False)\
112 .filter(UserNotification.read == False)\
109 .filter(UserNotification.user_id == user_id).count()
113 .filter(UserNotification.user == user).count()
110
114
111 def get_unread_for_user(self, user_id):
115 def get_unread_for_user(self, user):
116 user = self.__get_user(user)
112 return [x.notification for x in UserNotification.query()\
117 return [x.notification for x in UserNotification.query()\
113 .filter(UserNotification.read == False)\
118 .filter(UserNotification.read == False)\
114 .filter(UserNotification.user_id == user_id).all()]
119 .filter(UserNotification.user == user).all()]
115
120
116 def get_user_notification(self, user, notification):
121 def get_user_notification(self, user, notification):
117 user = self.__get_user(user)
122 user = self.__get_user(user)
@@ -300,10 +300,11 b' class RepoModel(BaseModel):'
300
300
301 def delete_perm_user(self, form_data, repo_name):
301 def delete_perm_user(self, form_data, repo_name):
302 try:
302 try:
303 self.sa.query(UserRepoToPerm)\
303 obj = self.sa.query(UserRepoToPerm)\
304 .filter(UserRepoToPerm.repository \
304 .filter(UserRepoToPerm.repository \
305 == self.get_by_repo_name(repo_name))\
305 == self.get_by_repo_name(repo_name))\
306 .filter(UserRepoToPerm.user_id == form_data['user_id']).delete()
306 .filter(UserRepoToPerm.user_id == form_data['user_id']).one()
307 self.sa.delete(obj)
307 self.sa.commit()
308 self.sa.commit()
308 except:
309 except:
309 log.error(traceback.format_exc())
310 log.error(traceback.format_exc())
@@ -312,11 +313,12 b' class RepoModel(BaseModel):'
312
313
313 def delete_perm_users_group(self, form_data, repo_name):
314 def delete_perm_users_group(self, form_data, repo_name):
314 try:
315 try:
315 self.sa.query(UsersGroupRepoToPerm)\
316 obj = self.sa.query(UsersGroupRepoToPerm)\
316 .filter(UsersGroupRepoToPerm.repository \
317 .filter(UsersGroupRepoToPerm.repository \
317 == self.get_by_repo_name(repo_name))\
318 == self.get_by_repo_name(repo_name))\
318 .filter(UsersGroupRepoToPerm.users_group_id \
319 .filter(UsersGroupRepoToPerm.users_group_id \
319 == form_data['users_group_id']).delete()
320 == form_data['users_group_id']).one()
321 self.sa.delete(obj)
320 self.sa.commit()
322 self.sa.commit()
321 except:
323 except:
322 log.error(traceback.format_exc())
324 log.error(traceback.format_exc())
@@ -325,9 +327,10 b' class RepoModel(BaseModel):'
325
327
326 def delete_stats(self, repo_name):
328 def delete_stats(self, repo_name):
327 try:
329 try:
328 self.sa.query(Statistics)\
330 obj = self.sa.query(Statistics)\
329 .filter(Statistics.repository == \
331 .filter(Statistics.repository == \
330 self.get_by_repo_name(repo_name)).delete()
332 self.get_by_repo_name(repo_name)).one()
333 self.sa.delete(obj)
331 self.sa.commit()
334 self.sa.commit()
332 except:
335 except:
333 log.error(traceback.format_exc())
336 log.error(traceback.format_exc())
@@ -353,7 +353,7 b' class UserModel(BaseModel):'
353 #======================================================================
353 #======================================================================
354 # fetch default permissions
354 # fetch default permissions
355 #======================================================================
355 #======================================================================
356 default_user = self.get_by_username('default')
356 default_user = User.get_by_username('default')
357
357
358 default_perms = self.sa.query(UserRepoToPerm, Repository, Permission)\
358 default_perms = self.sa.query(UserRepoToPerm, Repository, Permission)\
359 .join((Repository, UserRepoToPerm.repository_id ==
359 .join((Repository, UserRepoToPerm.repository_id ==
@@ -35,23 +35,14 b' log = logging.getLogger(__name__)'
35
35
36 class UsersGroupModel(BaseModel):
36 class UsersGroupModel(BaseModel):
37
37
38 def __get_users_group(self, users_group):
39 return self.__get_instance(UsersGroup, users_group)
40
38 def get(self, users_group_id, cache = False):
41 def get(self, users_group_id, cache = False):
39 users_group = UsersGroup.query()
42 return UsersGroup.get(users_group_id)
40 if cache:
41 users_group = users_group.options(FromCache("sql_cache_short",
42 "get_users_group_%s" % users_group_id))
43 return users_group.get(users_group_id)
44
43
45 def get_by_name(self, name, cache = False, case_insensitive = False):
44 def get_by_name(self, name, cache = False, case_insensitive = False):
46 users_group = UsersGroup.query()
45 return UsersGroup.get_by_group_name(name, cache, case_insensitive)
47 if case_insensitive:
48 users_group = users_group.filter(UsersGroup.users_group_name.ilike(name))
49 else:
50 users_group = users_group.filter(UsersGroup.users_group_name == name)
51 if cache:
52 users_group = users_group.options(FromCache("sql_cache_short",
53 "get_users_group_%s" % name))
54 return users_group.scalar()
55
46
56 def create(self, form_data):
47 def create(self, form_data):
57 try:
48 try:
@@ -67,6 +58,18 b' class UsersGroupModel(BaseModel):'
67 self.sa.rollback()
58 self.sa.rollback()
68 raise
59 raise
69
60
61
62 def create_(self, name, active=True):
63 new = UsersGroup()
64 new.users_group_name = name
65 new.users_group_active = active
66 self.sa.add(new)
67 return new
68
69 def delete(self, users_group):
70 obj = self.__get_users_group(users_group)
71 self.sa.delete(obj)
72
70 def add_user_to_group(self, users_group, user):
73 def add_user_to_group(self, users_group, user):
71 for m in users_group.members:
74 for m in users_group.members:
72 u = m.user
75 u = m.user
@@ -30,19 +30,19 b''
30 %>
30 %>
31 <div class="table">
31 <div class="table">
32 %for notification in c.notifications:
32 %for notification in c.notifications:
33 <div id="notification_${notification.notification_id}">
33 <div id="notification_${notification.notification.notification_id}">
34 <div class="notification-header">
34 <div class="notification-header">
35 <div class="gravatar">
35 <div class="gravatar">
36 <img alt="gravatar" src="${h.gravatar_url(h.email(notification.created_by_user.email),24)}"/>
36 <img alt="gravatar" src="${h.gravatar_url(h.email(notification.notification.created_by_user.email),24)}"/>
37 </div>
37 </div>
38 <div class="desc">
38 <div class="desc ${unread(notification.read)}">
39 <a href="${url('notification', notification_id=notification.notification_id)}">${notification.description}</a>
39 <a href="${url('notification', notification_id=notification.notification.notification_id)}">${notification.notification.description}</a>
40 </div>
40 </div>
41 <div class="delete-notifications">
41 <div class="delete-notifications">
42 <span id="${notification.notification_id}" class="delete-notification delete_icon action"></span>
42 <span id="${notification.notification.notification_id}" class="delete-notification delete_icon action"></span>
43 </div>
43 </div>
44 </div>
44 </div>
45 <div class="notification-subject">${h.urlify_text(notification.subject)}</div>
45 <div class="notification-subject">${h.urlify_text(notification.notification.subject)}</div>
46 </div>
46 </div>
47 %endfor
47 %endfor
48 </div>
48 </div>
@@ -64,7 +64,7 b' class TestController(TestCase):'
64
64
65 self.app = TestApp(wsgiapp)
65 self.app = TestApp(wsgiapp)
66 url._push_object(URLGenerator(config['routes.map'], environ))
66 url._push_object(URLGenerator(config['routes.map'], environ))
67 self.sa = meta.Session
67 self.Session = meta.Session
68 self.index_location = config['app_conf']['index_dir']
68 self.index_location = config['app_conf']['index_dir']
69 TestCase.__init__(self, *args, **kwargs)
69 TestCase.__init__(self, *args, **kwargs)
70
70
@@ -42,6 +42,7 b' class TestLdapSettingsController(TestCon'
42 'ldap_attr_email':'test@example.com' })
42 'ldap_attr_email':'test@example.com' })
43
43
44 new_settings = RhodeCodeSetting.get_ldap_settings()
44 new_settings = RhodeCodeSetting.get_ldap_settings()
45 print new_settings
45 self.assertEqual(new_settings['ldap_host'], u'dc.example.com',
46 self.assertEqual(new_settings['ldap_host'], u'dc.example.com',
46 'fail db write compare')
47 'fail db write compare')
47
48
@@ -3,19 +3,23 b' from rhodecode.model.db import Notificat'
3
3
4 from rhodecode.model.user import UserModel
4 from rhodecode.model.user import UserModel
5 from rhodecode.model.notification import NotificationModel
5 from rhodecode.model.notification import NotificationModel
6 from rhodecode.model.meta import Session
6
7
7 class TestNotificationsController(TestController):
8 class TestNotificationsController(TestController):
8
9
10
11 def tearDown(self):
12 for n in Notification.query().all():
13 inst = Notification.get(n.notification_id)
14 Session().delete(inst)
15 Session().commit()
16
9 def test_index(self):
17 def test_index(self):
10 self.log_user()
18 self.log_user()
11
19
12
13 u1 = UserModel().create_or_update(username='u1', password='qweqwe',
20 u1 = UserModel().create_or_update(username='u1', password='qweqwe',
14 email='u1@rhodecode.org',
21 email='u1@rhodecode.org',
15 name='u1', lastname='u1').user_id
22 name='u1', lastname='u1').user_id
16 u2 = UserModel().create_or_update(username='u2', password='qweqwe',
17 email='u2@rhodecode.org',
18 name='u2', lastname='u2').user_id
19
23
20 response = self.app.get(url('notifications'))
24 response = self.app.get(url('notifications'))
21 self.assertTrue('''<div class="table">No notifications here yet</div>'''
25 self.assertTrue('''<div class="table">No notifications here yet</div>'''
@@ -23,15 +27,12 b' class TestNotificationsController(TestCo'
23
27
24 cur_user = self._get_logged_user()
28 cur_user = self._get_logged_user()
25
29
26 NotificationModel().create(created_by=u1, subject=u'test',
30 NotificationModel().create(created_by=u1, subject=u'test_notification_1',
27 body=u'notification_1',
31 body=u'notification_1',
28 recipients=[cur_user])
32 recipients=[cur_user])
33 Session().commit()
29 response = self.app.get(url('notifications'))
34 response = self.app.get(url('notifications'))
30
35 self.assertTrue(u'test_notification_1' in response.body)
31 self.assertTrue(u'notification_1' in response.body)
32
33 User.delete(u1)
34 User.delete(u2)
35
36
36 # def test_index_as_xml(self):
37 # def test_index_as_xml(self):
37 # response = self.app.get(url('formatted_notifications', format='xml'))
38 # response = self.app.get(url('formatted_notifications', format='xml'))
@@ -62,27 +63,29 b' class TestNotificationsController(TestCo'
62 email='u2@rhodecode.org',
63 email='u2@rhodecode.org',
63 name='u2', lastname='u2')
64 name='u2', lastname='u2')
64
65
65 # make two notifications
66 # make notifications
66 notification = NotificationModel().create(created_by=cur_user,
67 notification = NotificationModel().create(created_by=cur_user,
67 subject=u'test',
68 subject=u'test',
68 body=u'hi there',
69 body=u'hi there',
69 recipients=[cur_user, u1, u2])
70 recipients=[cur_user, u1, u2])
70
71 Session().commit()
71 u1 = User.get(u1.user_id)
72 u1 = User.get(u1.user_id)
72 u2 = User.get(u2.user_id)
73 u2 = User.get(u2.user_id)
73
74
74 # check DB
75 # check DB
75 self.assertEqual(u1.notifications, [notification])
76 get_notif = lambda un:[x.notification for x in un]
76 self.assertEqual(u2.notifications, [notification])
77 self.assertEqual(get_notif(cur_user.notifications), [notification])
78 self.assertEqual(get_notif(u1.notifications), [notification])
79 self.assertEqual(get_notif(u2.notifications), [notification])
77 cur_usr_id = cur_user.user_id
80 cur_usr_id = cur_user.user_id
78 response = self.app.delete(url('notification',
81
79 notification_id=cur_usr_id))
80
82
81 cur_user = self._get_logged_user()
83 response = self.app.delete(url('notification',
82 self.assertEqual(cur_user.notifications, [])
84 notification_id=
85 notification.notification_id))
83
86
84 User.delete(u1.user_id)
87 cur_user = User.get(cur_usr_id)
85 User.delete(u2.user_id)
88 self.assertEqual(cur_user.notifications, [])
86
89
87
90
88 # def test_delete_browser_fakeout(self):
91 # def test_delete_browser_fakeout(self):
@@ -100,7 +103,7 b' class TestNotificationsController(TestCo'
100
103
101 notification = NotificationModel().create(created_by=cur_user,
104 notification = NotificationModel().create(created_by=cur_user,
102 subject='test',
105 subject='test',
103 body='hi there',
106 body=u'hi there',
104 recipients=[cur_user, u1, u2])
107 recipients=[cur_user, u1, u2])
105
108
106 response = self.app.get(url('notification',
109 response = self.app.get(url('notification',
@@ -114,4 +117,3 b' class TestNotificationsController(TestCo'
114 #
117 #
115 # def test_edit_as_xml(self):
118 # def test_edit_as_xml(self):
116 # response = self.app.get(url('formatted_edit_notification', notification_id=1, format='xml'))
119 # response = self.app.get(url('formatted_edit_notification', notification_id=1, format='xml'))
117
@@ -36,7 +36,7 b' class TestAdminReposController(TestContr'
36 self.checkSessionFlash(response, 'created repository %s' % (repo_name))
36 self.checkSessionFlash(response, 'created repository %s' % (repo_name))
37
37
38 #test if the repo was created in the database
38 #test if the repo was created in the database
39 new_repo = self.sa.query(Repository).filter(Repository.repo_name ==
39 new_repo = self.Session().query(Repository).filter(Repository.repo_name ==
40 repo_name).one()
40 repo_name).one()
41
41
42 self.assertEqual(new_repo.repo_name, repo_name)
42 self.assertEqual(new_repo.repo_name, repo_name)
@@ -73,7 +73,7 b' class TestAdminReposController(TestContr'
73 'created repository %s' % (repo_name_unicode))
73 'created repository %s' % (repo_name_unicode))
74
74
75 #test if the repo was created in the database
75 #test if the repo was created in the database
76 new_repo = self.sa.query(Repository).filter(Repository.repo_name ==
76 new_repo = self.Session().query(Repository).filter(Repository.repo_name ==
77 repo_name_unicode).one()
77 repo_name_unicode).one()
78
78
79 self.assertEqual(new_repo.repo_name, repo_name_unicode)
79 self.assertEqual(new_repo.repo_name, repo_name_unicode)
@@ -113,7 +113,7 b' class TestAdminReposController(TestContr'
113 assert '''created repository %s''' % (repo_name) in response.session['flash'][0], 'No flash message about new repo'
113 assert '''created repository %s''' % (repo_name) in response.session['flash'][0], 'No flash message about new repo'
114
114
115 #test if the fork was created in the database
115 #test if the fork was created in the database
116 new_repo = self.sa.query(Repository).filter(Repository.repo_name == repo_name).one()
116 new_repo = self.Session().query(Repository).filter(Repository.repo_name == repo_name).one()
117
117
118 assert new_repo.repo_name == repo_name, 'wrong name of repo name in db'
118 assert new_repo.repo_name == repo_name, 'wrong name of repo name in db'
119 assert new_repo.description == description, 'wrong description'
119 assert new_repo.description == description, 'wrong description'
@@ -162,7 +162,7 b' class TestAdminReposController(TestContr'
162 response.session['flash'][0])
162 response.session['flash'][0])
163
163
164 #test if the repo was created in the database
164 #test if the repo was created in the database
165 new_repo = self.sa.query(Repository).filter(Repository.repo_name ==
165 new_repo = self.Session().query(Repository).filter(Repository.repo_name ==
166 repo_name).one()
166 repo_name).one()
167
167
168 self.assertEqual(new_repo.repo_name, repo_name)
168 self.assertEqual(new_repo.repo_name, repo_name)
@@ -182,7 +182,7 b' class TestAdminReposController(TestContr'
182 response.follow()
182 response.follow()
183
183
184 #check if repo was deleted from db
184 #check if repo was deleted from db
185 deleted_repo = self.sa.query(Repository).filter(Repository.repo_name
185 deleted_repo = self.Session().query(Repository).filter(Repository.repo_name
186 == repo_name).scalar()
186 == repo_name).scalar()
187
187
188 self.assertEqual(deleted_repo, None)
188 self.assertEqual(deleted_repo, None)
@@ -145,7 +145,7 b' class TestAdminSettingsController(TestCo'
145 response.follow()
145 response.follow()
146
146
147 assert 'Your account was updated successfully' in response.session['flash'][0][1], 'no flash message about success of change'
147 assert 'Your account was updated successfully' in response.session['flash'][0][1], 'no flash message about success of change'
148 user = self.sa.query(User).filter(User.username == 'test_admin').one()
148 user = self.Session().query(User).filter(User.username == 'test_admin').one()
149 assert user.email == new_email , 'incorrect user email after update got %s vs %s' % (user.email, new_email)
149 assert user.email == new_email , 'incorrect user email after update got %s vs %s' % (user.email, new_email)
150 assert user.name == new_name, 'updated field mismatch %s vs %s' % (user.name, new_name)
150 assert user.name == new_name, 'updated field mismatch %s vs %s' % (user.name, new_name)
151 assert user.lastname == new_lastname, 'updated field mismatch %s vs %s' % (user.lastname, new_lastname)
151 assert user.lastname == new_lastname, 'updated field mismatch %s vs %s' % (user.lastname, new_lastname)
@@ -171,7 +171,7 b' class TestAdminSettingsController(TestCo'
171 self.checkSessionFlash(response,
171 self.checkSessionFlash(response,
172 'Your account was updated successfully')
172 'Your account was updated successfully')
173
173
174 user = self.sa.query(User).filter(User.username == 'test_admin').one()
174 user = self.Session().query(User).filter(User.username == 'test_admin').one()
175 assert user.email == old_email , 'incorrect user email after update got %s vs %s' % (user.email, old_email)
175 assert user.email == old_email , 'incorrect user email after update got %s vs %s' % (user.email, old_email)
176
176
177 assert user.email == old_email , 'incorrect user email after update got %s vs %s' % (user.email, old_email)
177 assert user.email == old_email , 'incorrect user email after update got %s vs %s' % (user.email, old_email)
@@ -32,7 +32,7 b' class TestAdminUsersController(TestContr'
32
32
33 assert '''created user %s''' % (username) in response.session['flash'][0], 'No flash message about new user'
33 assert '''created user %s''' % (username) in response.session['flash'][0], 'No flash message about new user'
34
34
35 new_user = self.sa.query(User).filter(User.username == username).one()
35 new_user = self.Session().query(User).filter(User.username == username).one()
36
36
37
37
38 assert new_user.username == username, 'wrong info about username'
38 assert new_user.username == username, 'wrong info about username'
@@ -66,7 +66,7 b' class TestAdminUsersController(TestContr'
66 assert """<span class="error-message">An email address must contain a single @</span>""" in response.body
66 assert """<span class="error-message">An email address must contain a single @</span>""" in response.body
67
67
68 def get_user():
68 def get_user():
69 self.sa.query(User).filter(User.username == username).one()
69 self.Session().query(User).filter(User.username == username).one()
70
70
71 self.assertRaises(NoResultFound, get_user), 'found user in database'
71 self.assertRaises(NoResultFound, get_user), 'found user in database'
72
72
@@ -100,7 +100,7 b' class TestAdminUsersController(TestContr'
100
100
101 response = response.follow()
101 response = response.follow()
102
102
103 new_user = self.sa.query(User).filter(User.username == username).one()
103 new_user = self.Session().query(User).filter(User.username == username).one()
104 response = self.app.delete(url('user', id=new_user.user_id))
104 response = self.app.delete(url('user', id=new_user.user_id))
105
105
106 assert """successfully deleted user""" in response.session['flash'][0], 'No info about user deletion'
106 assert """successfully deleted user""" in response.session['flash'][0], 'No info about user deletion'
@@ -52,13 +52,13 b' class TestAdminUsersGroupsController(Tes'
52 'created users group %s' % users_group_name)
52 'created users group %s' % users_group_name)
53
53
54
54
55 gr = self.sa.query(UsersGroup)\
55 gr = self.Session().query(UsersGroup)\
56 .filter(UsersGroup.users_group_name ==
56 .filter(UsersGroup.users_group_name ==
57 users_group_name).one()
57 users_group_name).one()
58
58
59 response = self.app.delete(url('users_group', id=gr.users_group_id))
59 response = self.app.delete(url('users_group', id=gr.users_group_id))
60
60
61 gr = self.sa.query(UsersGroup)\
61 gr = self.Session().query(UsersGroup)\
62 .filter(UsersGroup.users_group_name ==
62 .filter(UsersGroup.users_group_name ==
63 users_group_name).scalar()
63 users_group_name).scalar()
64
64
@@ -16,10 +16,10 b' class TestJournalController(TestControll'
16
16
17 def test_stop_following_repository(self):
17 def test_stop_following_repository(self):
18 session = self.log_user()
18 session = self.log_user()
19 # usr = self.sa.query(User).filter(User.username == 'test_admin').one()
19 # usr = self.Session().query(User).filter(User.username == 'test_admin').one()
20 # repo = self.sa.query(Repository).filter(Repository.repo_name == HG_REPO).one()
20 # repo = self.Session().query(Repository).filter(Repository.repo_name == HG_REPO).one()
21 #
21 #
22 # followings = self.sa.query(UserFollowing)\
22 # followings = self.Session().query(UserFollowing)\
23 # .filter(UserFollowing.user == usr)\
23 # .filter(UserFollowing.user == usr)\
24 # .filter(UserFollowing.follows_repository == repo).all()
24 # .filter(UserFollowing.follows_repository == repo).all()
25 #
25 #
@@ -192,7 +192,7 b' class TestLoginController(TestController'
192 self.assertEqual(response.status , '302 Found')
192 self.assertEqual(response.status , '302 Found')
193 assert 'You have successfully registered into rhodecode' in response.session['flash'][0], 'No flash message about user registration'
193 assert 'You have successfully registered into rhodecode' in response.session['flash'][0], 'No flash message about user registration'
194
194
195 ret = self.sa.query(User).filter(User.username == 'test_regular4').one()
195 ret = self.Session().query(User).filter(User.username == 'test_regular4').one()
196 assert ret.username == username , 'field mismatch %s %s' % (ret.username, username)
196 assert ret.username == username , 'field mismatch %s %s' % (ret.username, username)
197 assert check_password(password, ret.password) == True , 'password mismatch'
197 assert check_password(password, ret.password) == True , 'password mismatch'
198 assert ret.email == email , 'field mismatch %s %s' % (ret.email, email)
198 assert ret.email == email , 'field mismatch %s %s' % (ret.email, email)
@@ -224,8 +224,8 b' class TestLoginController(TestController'
224 new.name = name
224 new.name = name
225 new.lastname = lastname
225 new.lastname = lastname
226 new.api_key = generate_api_key(username)
226 new.api_key = generate_api_key(username)
227 self.sa.add(new)
227 self.Session().add(new)
228 self.sa.commit()
228 self.Session().commit()
229
229
230 response = self.app.post(url(controller='login',
230 response = self.app.post(url(controller='login',
231 action='password_reset'),
231 action='password_reset'),
@@ -32,7 +32,7 b' class TestSettingsController(TestControl'
32 % (repo_name, fork_name) in response.session['flash'][0], 'No flash message about fork'
32 % (repo_name, fork_name) in response.session['flash'][0], 'No flash message about fork'
33
33
34 #test if the fork was created in the database
34 #test if the fork was created in the database
35 fork_repo = self.sa.query(Repository).filter(Repository.repo_name == fork_name).one()
35 fork_repo = self.Session().query(Repository).filter(Repository.repo_name == fork_name).one()
36
36
37 assert fork_repo.repo_name == fork_name, 'wrong name of repo name in new db fork repo'
37 assert fork_repo.repo_name == fork_name, 'wrong name of repo name in new db fork repo'
38 assert fork_repo.fork.repo_name == repo_name, 'wrong fork parrent'
38 assert fork_repo.fork.repo_name == repo_name, 'wrong fork parrent'
@@ -43,5 +43,5 b' class TestSummaryController(TestControll'
43 def _enable_stats(self):
43 def _enable_stats(self):
44 r = Repository.get_by_repo_name(HG_REPO)
44 r = Repository.get_by_repo_name(HG_REPO)
45 r.enable_statistics = True
45 r.enable_statistics = True
46 self.sa.add(r)
46 self.Session().add(r)
47 self.sa.commit()
47 self.Session().commit()
@@ -103,3 +103,14 b' class TestLibs(unittest.TestCase):'
103 for case in test_cases:
103 for case in test_cases:
104 self.assertEqual(str2bool(case[0]), case[1])
104 self.assertEqual(str2bool(case[0]), case[1])
105
105
106
107 def test_mention_extractor(self):
108 from rhodecode.lib import extract_mentioned_users
109 sample = ("@first hi there @marcink here's my email marcin@email.com "
110 "@lukaszb check it pls @ ttwelve @D[] @one@two@three "
111 "@MARCIN @maRCiN @2one_more22")
112 s = ['2one_more22', 'D', 'MARCIN', 'first', 'lukaszb',
113 'maRCiN', 'marcink', 'one']
114 self.assertEqual(s, extract_mentioned_users(sample))
115
116
@@ -4,13 +4,14 b' from rhodecode.tests import *'
4
4
5 from rhodecode.model.repos_group import ReposGroupModel
5 from rhodecode.model.repos_group import ReposGroupModel
6 from rhodecode.model.repo import RepoModel
6 from rhodecode.model.repo import RepoModel
7 from rhodecode.model.db import RepoGroup, User, Notification, UserNotification
7 from rhodecode.model.db import RepoGroup, User, Notification, UserNotification, \
8 UsersGroup, UsersGroupMember
8 from sqlalchemy.exc import IntegrityError
9 from sqlalchemy.exc import IntegrityError
9 from rhodecode.model.user import UserModel
10 from rhodecode.model.user import UserModel
10
11
11 from rhodecode.model import meta
12 from rhodecode.model.meta import Session
12
13 from rhodecode.model.notification import NotificationModel
13 Session = meta.Session()
14 from rhodecode.model.users_group import UsersGroupModel
14
15
15 class TestReposGroups(unittest.TestCase):
16 class TestReposGroups(unittest.TestCase):
16
17
@@ -155,67 +156,108 b' class TestReposGroups(unittest.TestCase)'
155 # test repo
156 # test repo
156 self.assertEqual(r.repo_name, os.path.join('g2', 'g1', r.just_name))
157 self.assertEqual(r.repo_name, os.path.join('g2', 'g1', r.just_name))
157
158
159 class TestUser(unittest.TestCase):
160
161 def test_create_and_remove(self):
162 usr = UserModel().create_or_update(username=u'test_user', password=u'qweqwe',
163 email=u'u232@rhodecode.org',
164 name=u'u1', lastname=u'u1')
165 self.assertEqual(User.get_by_username(u'test_user'), usr)
166
167 # make users group
168 users_group = UsersGroupModel().create_('some_example_group')
169 Session().commit()
170 UsersGroupModel().add_user_to_group(users_group, usr)
171
172 self.assertEqual(UsersGroup.get(users_group.users_group_id), users_group)
173 self.assertEqual(UsersGroupMember.query().count(), 1)
174 UserModel().delete(usr.user_id)
175
176 self.assertEqual(UsersGroupMember.query().all(), [])
177
158
178
159 class TestNotifications(unittest.TestCase):
179 class TestNotifications(unittest.TestCase):
160
180
161
181 def __init__(self, methodName='runTest'):
182 self.u1 = UserModel().create_or_update(username=u'u1',
183 password=u'qweqwe',
184 email=u'u1@rhodecode.org',
185 name=u'u1', lastname=u'u1').user_id
186 self.u2 = UserModel().create_or_update(username=u'u2',
187 password=u'qweqwe',
188 email=u'u2@rhodecode.org',
189 name=u'u2', lastname=u'u3').user_id
190 self.u3 = UserModel().create_or_update(username=u'u3',
191 password=u'qweqwe',
192 email=u'u3@rhodecode.org',
193 name=u'u3', lastname=u'u3').user_id
194 super(TestNotifications, self).__init__(methodName=methodName)
162
195
163 def setUp(self):
196 def _clean_notifications(self):
164 self.u1 = UserModel().create_or_update(username=u'u1', password=u'qweqwe',
197 for n in Notification.query().all():
165 email=u'u1@rhodecode.org',
198 Session().delete(n)
166 name=u'u1', lastname=u'u1')
199
167 self.u2 = UserModel().create_or_update(username=u'u2', password=u'qweqwe',
200 Session().commit()
168 email=u'u2@rhodecode.org',
201 self.assertEqual(Notification.query().all(), [])
169 name=u'u2', lastname=u'u3')
170 self.u3 = UserModel().create_or_update(username=u'u3', password=u'qweqwe',
171 email=u'u3@rhodecode.org',
172 name=u'u3', lastname=u'u3')
173 def tearDown(self):
174 User.delete(self.u1.user_id)
175 User.delete(self.u2.user_id)
176 User.delete(self.u3.user_id)
177
202
178
203
179 def test_create_notification(self):
204 def test_create_notification(self):
205 self.assertEqual([], Notification.query().all())
206 self.assertEqual([], UserNotification.query().all())
207
180 usrs = [self.u1, self.u2]
208 usrs = [self.u1, self.u2]
181 notification = Notification.create(created_by=self.u1,
209 notification = NotificationModel().create(created_by=self.u1,
182 subject=u'subj', body=u'hi there',
210 subject=u'subj', body=u'hi there',
183 recipients=usrs)
211 recipients=usrs)
184 Session.commit()
212 Session().commit()
185
213 u1 = User.get(self.u1)
186
214 u2 = User.get(self.u2)
215 u3 = User.get(self.u3)
187 notifications = Notification.query().all()
216 notifications = Notification.query().all()
188 self.assertEqual(len(notifications), 1)
217 self.assertEqual(len(notifications), 1)
189
218
190 unotification = UserNotification.query()\
219 unotification = UserNotification.query()\
191 .filter(UserNotification.notification == notification).all()
220 .filter(UserNotification.notification == notification).all()
192
221
193 self.assertEqual(notifications[0].recipients, [self.u1, self.u2])
222 self.assertEqual(notifications[0].recipients, [u1, u2])
194 self.assertEqual(notification.notification_id,
223 self.assertEqual(notification.notification_id,
195 notifications[0].notification_id)
224 notifications[0].notification_id)
196 self.assertEqual(len(unotification), len(usrs))
225 self.assertEqual(len(unotification), len(usrs))
197 self.assertEqual([x.user.user_id for x in unotification],
226 self.assertEqual([x.user.user_id for x in unotification], usrs)
198 [x.user_id for x in usrs])
227
228 self._clean_notifications()
199
229
200 def test_user_notifications(self):
230 def test_user_notifications(self):
201 notification1 = Notification.create(created_by=self.u1,
231 self.assertEqual([], Notification.query().all())
202 subject=u'subj', body=u'hi there',
232 self.assertEqual([], UserNotification.query().all())
233
234 notification1 = NotificationModel().create(created_by=self.u1,
235 subject=u'subj', body=u'hi there1',
203 recipients=[self.u3])
236 recipients=[self.u3])
204 notification2 = Notification.create(created_by=self.u1,
237 Session().commit()
205 subject=u'subj', body=u'hi there',
238 notification2 = NotificationModel().create(created_by=self.u1,
239 subject=u'subj', body=u'hi there2',
206 recipients=[self.u3])
240 recipients=[self.u3])
207 self.assertEqual(self.u3.notifications, [notification1, notification2])
241 Session().commit()
242 u3 = Session().query(User).get(self.u3)
243
244 self.assertEqual(sorted([x.notification for x in u3.notifications]),
245 sorted([notification2, notification1]))
246 self._clean_notifications()
208
247
209 def test_delete_notifications(self):
248 def test_delete_notifications(self):
210 notification = Notification.create(created_by=self.u1,
249 self.assertEqual([], Notification.query().all())
250 self.assertEqual([], UserNotification.query().all())
251
252 notification = NotificationModel().create(created_by=self.u1,
211 subject=u'title', body=u'hi there3',
253 subject=u'title', body=u'hi there3',
212 recipients=[self.u3, self.u1, self.u2])
254 recipients=[self.u3, self.u1, self.u2])
213 Session.commit()
255 Session().commit()
214 notifications = Notification.query().all()
256 notifications = Notification.query().all()
215 self.assertTrue(notification in notifications)
257 self.assertTrue(notification in notifications)
216
258
217 Notification.delete(notification.notification_id)
259 Notification.delete(notification.notification_id)
218 Session.commit()
260 Session().commit()
219
261
220 notifications = Notification.query().all()
262 notifications = Notification.query().all()
221 self.assertFalse(notification in notifications)
263 self.assertFalse(notification in notifications)
@@ -223,3 +265,65 b' class TestNotifications(unittest.TestCas'
223 un = UserNotification.query().filter(UserNotification.notification
265 un = UserNotification.query().filter(UserNotification.notification
224 == notification).all()
266 == notification).all()
225 self.assertEqual(un, [])
267 self.assertEqual(un, [])
268
269 self._clean_notifications()
270 def test_delete_association(self):
271
272 self.assertEqual([], Notification.query().all())
273 self.assertEqual([], UserNotification.query().all())
274
275 notification = NotificationModel().create(created_by=self.u1,
276 subject=u'title', body=u'hi there3',
277 recipients=[self.u3, self.u1, self.u2])
278 Session().commit()
279
280 unotification = UserNotification.query()\
281 .filter(UserNotification.notification ==
282 notification)\
283 .filter(UserNotification.user_id == self.u3)\
284 .scalar()
285
286 self.assertEqual(unotification.user_id, self.u3)
287
288 NotificationModel().delete(self.u3,
289 notification.notification_id)
290 Session().commit()
291
292 unotification = UserNotification.query()\
293 .filter(UserNotification.notification ==
294 notification)\
295 .filter(UserNotification.user_id == self.u3)\
296 .scalar()
297
298 self.assertEqual(unotification, None)
299 self._clean_notifications()
300
301 def test_notification_counter(self):
302 self._clean_notifications()
303 self.assertEqual([], Notification.query().all())
304 self.assertEqual([], UserNotification.query().all())
305
306 NotificationModel().create(created_by=self.u1,
307 subject=u'title', body=u'hi there_delete',
308 recipients=[self.u3, self.u1])
309 Session().commit()
310
311 self.assertEqual(NotificationModel()
312 .get_unread_cnt_for_user(self.u1), 1)
313 self.assertEqual(NotificationModel()
314 .get_unread_cnt_for_user(self.u2), 0)
315 self.assertEqual(NotificationModel()
316 .get_unread_cnt_for_user(self.u3), 1)
317
318 notification = NotificationModel().create(created_by=self.u1,
319 subject=u'title', body=u'hi there3',
320 recipients=[self.u3, self.u1, self.u2])
321 Session().commit()
322
323 self.assertEqual(NotificationModel()
324 .get_unread_cnt_for_user(self.u1), 2)
325 self.assertEqual(NotificationModel()
326 .get_unread_cnt_for_user(self.u2), 1)
327 self.assertEqual(NotificationModel()
328 .get_unread_cnt_for_user(self.u3), 2)
329 self._clean_notifications()
General Comments 0
You need to be logged in to leave comments. Login now