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 |
|
|
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 re |
|
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 |
|
|
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 |
|
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 |
|
87 | revision=revision, | |
87 |
anchor |
|
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 |
|
95 | body=body, recipients=recipients, | |
95 |
type_ |
|
96 | type_=Notification.TYPE_CHANGESET_COMMENT) | |
96 |
|
97 | |||
97 | return comment |
|
98 | return comment | |
98 |
|
99 | |||
99 |
def delete(self, comment |
|
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 = |
|
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). |
|
898 | .filter(cls.permission == perm).one() | |
903 |
Session |
|
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). |
|
961 | .filter(cls.permission == perm).one() | |
965 |
Session |
|
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 = |
|
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 |
|
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_ |
|
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', |
|
1186 | user = relationship('User', lazy="joined") | |
1187 |
notification = relationship('Notification', |
|
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 |
|
91 | def delete(self, user, notification): | |
92 |
# we don't want to remove actual |
|
92 | # we don't want to remove actual notification just the assignment | |
93 | try: |
|
93 | try: | |
94 |
notification |
|
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. |
|
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 |
|
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 |
|
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 |
|
113 | .filter(UserNotification.user == user).count() | |
110 |
|
114 | |||
111 |
def get_unread_for_user(self, user |
|
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 |
|
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']). |
|
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 |
|
|
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)). |
|
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 = |
|
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 |
|
|
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. |
|
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 |
|
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( |
|
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. |
|
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. |
|
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. |
|
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. |
|
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. |
|
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. |
|
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. |
|
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. |
|
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. |
|
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. |
|
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. |
|
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. |
|
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. |
|
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. |
|
19 | # usr = self.Session().query(User).filter(User.username == 'test_admin').one() | |
20 |
# repo = self. |
|
20 | # repo = self.Session().query(Repository).filter(Repository.repo_name == HG_REPO).one() | |
21 | # |
|
21 | # | |
22 |
# followings = self. |
|
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. |
|
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. |
|
227 | self.Session().add(new) | |
228 |
self. |
|
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. |
|
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. |
|
46 | self.Session().add(r) | |
47 |
self. |
|
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 |
|
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, [ |
|
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