Show More
@@ -0,0 +1,76 b'' | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | ||||
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |||
|
4 | # | |||
|
5 | # This program is free software: you can redistribute it and/or modify | |||
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |||
|
7 | # (only), as published by the Free Software Foundation. | |||
|
8 | # | |||
|
9 | # This program is distributed in the hope that it will be useful, | |||
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
12 | # GNU General Public License for more details. | |||
|
13 | # | |||
|
14 | # You should have received a copy of the GNU Affero General Public License | |||
|
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
|
16 | # | |||
|
17 | # This program is dual-licensed. If you wish to learn more about the | |||
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |||
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |||
|
20 | ||||
|
21 | import pytest | |||
|
22 | ||||
|
23 | from rhodecode.apps._base import ADMIN_PREFIX | |||
|
24 | from rhodecode.model.db import User, UserEmailMap, Repository, UserFollowing | |||
|
25 | from rhodecode.tests import ( | |||
|
26 | TestController, TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_EMAIL, | |||
|
27 | assert_session_flash) | |||
|
28 | from rhodecode.tests.fixture import Fixture | |||
|
29 | ||||
|
30 | fixture = Fixture() | |||
|
31 | ||||
|
32 | ||||
|
33 | def route_path(name, **kwargs): | |||
|
34 | return { | |||
|
35 | 'my_account_repos': | |||
|
36 | ADMIN_PREFIX + '/my_account/repos', | |||
|
37 | 'my_account_watched': | |||
|
38 | ADMIN_PREFIX + '/my_account/watched', | |||
|
39 | 'my_account_perms': | |||
|
40 | ADMIN_PREFIX + '/my_account/perms', | |||
|
41 | 'my_account_notifications': | |||
|
42 | ADMIN_PREFIX + '/my_account/notifications', | |||
|
43 | }[name].format(**kwargs) | |||
|
44 | ||||
|
45 | ||||
|
46 | class TestMyAccountSimpleViews(TestController): | |||
|
47 | ||||
|
48 | def test_my_account_my_repos(self, autologin_user): | |||
|
49 | response = self.app.get(route_path('my_account_repos')) | |||
|
50 | repos = Repository.query().filter( | |||
|
51 | Repository.user == User.get_by_username( | |||
|
52 | TEST_USER_ADMIN_LOGIN)).all() | |||
|
53 | for repo in repos: | |||
|
54 | response.mustcontain('"name_raw": "%s"' % repo.repo_name) | |||
|
55 | ||||
|
56 | def test_my_account_my_watched(self, autologin_user): | |||
|
57 | response = self.app.get(route_path('my_account_watched')) | |||
|
58 | ||||
|
59 | repos = UserFollowing.query().filter( | |||
|
60 | UserFollowing.user == User.get_by_username( | |||
|
61 | TEST_USER_ADMIN_LOGIN)).all() | |||
|
62 | for repo in repos: | |||
|
63 | response.mustcontain( | |||
|
64 | '"name_raw": "%s"' % repo.follows_repository.repo_name) | |||
|
65 | ||||
|
66 | def test_my_account_perms(self, autologin_user): | |||
|
67 | response = self.app.get(route_path('my_account_perms')) | |||
|
68 | assert_response = response.assert_response() | |||
|
69 | assert assert_response.get_elements('.perm_tag.none') | |||
|
70 | assert assert_response.get_elements('.perm_tag.read') | |||
|
71 | assert assert_response.get_elements('.perm_tag.write') | |||
|
72 | assert assert_response.get_elements('.perm_tag.admin') | |||
|
73 | ||||
|
74 | def test_my_account_notifications(self, autologin_user): | |||
|
75 | response = self.app.get(route_path('my_account_notifications')) | |||
|
76 | response.mustcontain('Test flash message') |
@@ -56,6 +56,26 b' def includeme(config):' | |||||
56 | name='my_account_emails_delete', |
|
56 | name='my_account_emails_delete', | |
57 | pattern=ADMIN_PREFIX + '/my_account/emails/delete') |
|
57 | pattern=ADMIN_PREFIX + '/my_account/emails/delete') | |
58 |
|
58 | |||
|
59 | config.add_route( | |||
|
60 | name='my_account_repos', | |||
|
61 | pattern=ADMIN_PREFIX + '/my_account/repos') | |||
|
62 | ||||
|
63 | config.add_route( | |||
|
64 | name='my_account_watched', | |||
|
65 | pattern=ADMIN_PREFIX + '/my_account/watched') | |||
|
66 | ||||
|
67 | config.add_route( | |||
|
68 | name='my_account_perms', | |||
|
69 | pattern=ADMIN_PREFIX + '/my_account/perms') | |||
|
70 | ||||
|
71 | config.add_route( | |||
|
72 | name='my_account_notifications', | |||
|
73 | pattern=ADMIN_PREFIX + '/my_account/notifications') | |||
|
74 | ||||
|
75 | config.add_route( | |||
|
76 | name='my_account_notifications_toggle_visibility', | |||
|
77 | pattern=ADMIN_PREFIX + '/my_account/toggle_visibility') | |||
|
78 | ||||
59 | # channelstream test |
|
79 | # channelstream test | |
60 | config.add_route( |
|
80 | config.add_route( | |
61 | name='my_account_notifications_test_channelstream', |
|
81 | name='my_account_notifications_test_channelstream', |
@@ -28,14 +28,18 b' from pyramid.view import view_config' | |||||
28 | from rhodecode.apps._base import BaseAppView |
|
28 | from rhodecode.apps._base import BaseAppView | |
29 | from rhodecode import forms |
|
29 | from rhodecode import forms | |
30 | from rhodecode.lib import helpers as h |
|
30 | from rhodecode.lib import helpers as h | |
|
31 | from rhodecode.lib.ext_json import json | |||
31 | from rhodecode.lib.auth import LoginRequired, NotAnonymous, CSRFRequired |
|
32 | from rhodecode.lib.auth import LoginRequired, NotAnonymous, CSRFRequired | |
32 | from rhodecode.lib.channelstream import channelstream_request, \ |
|
33 | from rhodecode.lib.channelstream import channelstream_request, \ | |
33 | ChannelstreamException |
|
34 | ChannelstreamException | |
34 | from rhodecode.lib.utils2 import safe_int, md5 |
|
35 | from rhodecode.lib.utils2 import safe_int, md5 | |
35 | from rhodecode.model.auth_token import AuthTokenModel |
|
36 | from rhodecode.model.auth_token import AuthTokenModel | |
36 |
from rhodecode.model.db import |
|
37 | from rhodecode.model.db import ( | |
|
38 | Repository, PullRequest, UserEmailMap, User, UserFollowing, joinedload) | |||
37 | from rhodecode.model.meta import Session |
|
39 | from rhodecode.model.meta import Session | |
|
40 | from rhodecode.model.scm import RepoList | |||
38 | from rhodecode.model.user import UserModel |
|
41 | from rhodecode.model.user import UserModel | |
|
42 | from rhodecode.model.repo import RepoModel | |||
39 | from rhodecode.model.validation_schema.schemas import user_schema |
|
43 | from rhodecode.model.validation_schema.schemas import user_schema | |
40 |
|
44 | |||
41 | log = logging.getLogger(__name__) |
|
45 | log = logging.getLogger(__name__) | |
@@ -290,3 +294,85 b' class MyAccountView(BaseAppView):' | |||||
290 | return {"response": 'ERROR: {}'.format(e.__class__.__name__)} |
|
294 | return {"response": 'ERROR: {}'.format(e.__class__.__name__)} | |
291 | return {"response": 'Channelstream data sent. ' |
|
295 | return {"response": 'Channelstream data sent. ' | |
292 | 'You should see a new live message now.'} |
|
296 | 'You should see a new live message now.'} | |
|
297 | ||||
|
298 | def _load_my_repos_data(self, watched=False): | |||
|
299 | if watched: | |||
|
300 | admin = False | |||
|
301 | follows_repos = Session().query(UserFollowing)\ | |||
|
302 | .filter(UserFollowing.user_id == self._rhodecode_user.user_id)\ | |||
|
303 | .options(joinedload(UserFollowing.follows_repository))\ | |||
|
304 | .all() | |||
|
305 | repo_list = [x.follows_repository for x in follows_repos] | |||
|
306 | else: | |||
|
307 | admin = True | |||
|
308 | repo_list = Repository.get_all_repos( | |||
|
309 | user_id=self._rhodecode_user.user_id) | |||
|
310 | repo_list = RepoList(repo_list, perm_set=[ | |||
|
311 | 'repository.read', 'repository.write', 'repository.admin']) | |||
|
312 | ||||
|
313 | repos_data = RepoModel().get_repos_as_dict( | |||
|
314 | repo_list=repo_list, admin=admin) | |||
|
315 | # json used to render the grid | |||
|
316 | return json.dumps(repos_data) | |||
|
317 | ||||
|
318 | @LoginRequired() | |||
|
319 | @NotAnonymous() | |||
|
320 | @view_config( | |||
|
321 | route_name='my_account_repos', request_method='GET', | |||
|
322 | renderer='rhodecode:templates/admin/my_account/my_account.mako') | |||
|
323 | def my_account_repos(self): | |||
|
324 | c = self.load_default_context() | |||
|
325 | c.active = 'repos' | |||
|
326 | ||||
|
327 | # json used to render the grid | |||
|
328 | c.data = self._load_my_repos_data() | |||
|
329 | return self._get_template_context(c) | |||
|
330 | ||||
|
331 | @LoginRequired() | |||
|
332 | @NotAnonymous() | |||
|
333 | @view_config( | |||
|
334 | route_name='my_account_watched', request_method='GET', | |||
|
335 | renderer='rhodecode:templates/admin/my_account/my_account.mako') | |||
|
336 | def my_account_watched(self): | |||
|
337 | c = self.load_default_context() | |||
|
338 | c.active = 'watched' | |||
|
339 | ||||
|
340 | # json used to render the grid | |||
|
341 | c.data = self._load_my_repos_data(watched=True) | |||
|
342 | return self._get_template_context(c) | |||
|
343 | ||||
|
344 | @LoginRequired() | |||
|
345 | @NotAnonymous() | |||
|
346 | @view_config( | |||
|
347 | route_name='my_account_perms', request_method='GET', | |||
|
348 | renderer='rhodecode:templates/admin/my_account/my_account.mako') | |||
|
349 | def my_account_perms(self): | |||
|
350 | c = self.load_default_context() | |||
|
351 | c.active = 'perms' | |||
|
352 | ||||
|
353 | c.perm_user = c.auth_user | |||
|
354 | return self._get_template_context(c) | |||
|
355 | ||||
|
356 | @LoginRequired() | |||
|
357 | @NotAnonymous() | |||
|
358 | @view_config( | |||
|
359 | route_name='my_account_notifications', request_method='GET', | |||
|
360 | renderer='rhodecode:templates/admin/my_account/my_account.mako') | |||
|
361 | def my_notifications(self): | |||
|
362 | c = self.load_default_context() | |||
|
363 | c.active = 'notifications' | |||
|
364 | ||||
|
365 | return self._get_template_context(c) | |||
|
366 | ||||
|
367 | @LoginRequired() | |||
|
368 | @NotAnonymous() | |||
|
369 | @CSRFRequired() | |||
|
370 | @view_config( | |||
|
371 | route_name='my_account_notifications_toggle_visibility', | |||
|
372 | request_method='POST', renderer='json_ext') | |||
|
373 | def my_notifications_toggle_visibility(self): | |||
|
374 | user = self._rhodecode_db_user | |||
|
375 | new_status = not user.user_data.get('notification_status', True) | |||
|
376 | user.update_userdata(notification_status=new_status) | |||
|
377 | Session().commit() | |||
|
378 | return user.user_data['notification_status'] No newline at end of file |
@@ -485,26 +485,9 b' def make_map(config):' | |||||
485 | m.connect('my_account_password', '/my_account/password', |
|
485 | m.connect('my_account_password', '/my_account/password', | |
486 | action='my_account_password', conditions={'method': ['GET']}) |
|
486 | action='my_account_password', conditions={'method': ['GET']}) | |
487 |
|
487 | |||
488 | m.connect('my_account_repos', '/my_account/repos', |
|
|||
489 | action='my_account_repos', conditions={'method': ['GET']}) |
|
|||
490 |
|
||||
491 | m.connect('my_account_watched', '/my_account/watched', |
|
|||
492 | action='my_account_watched', conditions={'method': ['GET']}) |
|
|||
493 |
|
||||
494 | m.connect('my_account_pullrequests', '/my_account/pull_requests', |
|
488 | m.connect('my_account_pullrequests', '/my_account/pull_requests', | |
495 | action='my_account_pullrequests', conditions={'method': ['GET']}) |
|
489 | action='my_account_pullrequests', conditions={'method': ['GET']}) | |
496 |
|
490 | |||
497 | m.connect('my_account_perms', '/my_account/perms', |
|
|||
498 | action='my_account_perms', conditions={'method': ['GET']}) |
|
|||
499 |
|
||||
500 | m.connect('my_account_notifications', '/my_account/notifications', |
|
|||
501 | action='my_notifications', |
|
|||
502 | conditions={'method': ['GET']}) |
|
|||
503 | m.connect('my_account_notifications_toggle_visibility', |
|
|||
504 | '/my_account/toggle_visibility', |
|
|||
505 | action='my_notifications_toggle_visibility', |
|
|||
506 | conditions={'method': ['POST']}) |
|
|||
507 |
|
||||
508 | # NOTIFICATION REST ROUTES |
|
491 | # NOTIFICATION REST ROUTES | |
509 | with rmap.submapper(path_prefix=ADMIN_PREFIX, |
|
492 | with rmap.submapper(path_prefix=ADMIN_PREFIX, | |
510 | controller='admin/notifications') as m: |
|
493 | controller='admin/notifications') as m: |
@@ -29,26 +29,22 b' import formencode' | |||||
29 | from formencode import htmlfill |
|
29 | from formencode import htmlfill | |
30 | from pyramid.httpexceptions import HTTPFound |
|
30 | from pyramid.httpexceptions import HTTPFound | |
31 |
|
31 | |||
32 |
from pylons import request, tmpl_context as c |
|
32 | from pylons import request, tmpl_context as c | |
33 | from pylons.controllers.util import redirect |
|
33 | from pylons.controllers.util import redirect | |
34 | from pylons.i18n.translation import _ |
|
34 | from pylons.i18n.translation import _ | |
35 | from sqlalchemy.orm import joinedload |
|
|||
36 |
|
35 | |||
37 | from rhodecode.lib import helpers as h |
|
36 | from rhodecode.lib import helpers as h | |
38 | from rhodecode.lib import auth |
|
37 | from rhodecode.lib import auth | |
39 | from rhodecode.lib.auth import ( |
|
38 | from rhodecode.lib.auth import ( | |
40 | LoginRequired, NotAnonymous, AuthUser) |
|
39 | LoginRequired, NotAnonymous, AuthUser) | |
41 | from rhodecode.lib.base import BaseController, render |
|
40 | from rhodecode.lib.base import BaseController, render | |
42 | from rhodecode.lib.utils import jsonify |
|
|||
43 | from rhodecode.lib.utils2 import safe_int, str2bool |
|
41 | from rhodecode.lib.utils2 import safe_int, str2bool | |
44 | from rhodecode.lib.ext_json import json |
|
42 | from rhodecode.lib.ext_json import json | |
45 |
|
43 | |||
46 | from rhodecode.model.db import ( |
|
44 | from rhodecode.model.db import ( | |
47 | Repository, PullRequest, UserEmailMap, User, UserFollowing) |
|
45 | Repository, PullRequest, UserEmailMap, User, UserFollowing) | |
48 | from rhodecode.model.forms import UserForm |
|
46 | from rhodecode.model.forms import UserForm | |
49 | from rhodecode.model.scm import RepoList |
|
|||
50 | from rhodecode.model.user import UserModel |
|
47 | from rhodecode.model.user import UserModel | |
51 | from rhodecode.model.repo import RepoModel |
|
|||
52 | from rhodecode.model.meta import Session |
|
48 | from rhodecode.model.meta import Session | |
53 | from rhodecode.model.pull_request import PullRequestModel |
|
49 | from rhodecode.model.pull_request import PullRequestModel | |
54 | from rhodecode.model.comment import CommentsModel |
|
50 | from rhodecode.model.comment import CommentsModel | |
@@ -78,26 +74,6 b' class MyAccountController(BaseController' | |||||
78 | c.auth_user = AuthUser( |
|
74 | c.auth_user = AuthUser( | |
79 | user_id=c.rhodecode_user.user_id, ip_addr=self.ip_addr) |
|
75 | user_id=c.rhodecode_user.user_id, ip_addr=self.ip_addr) | |
80 |
|
76 | |||
81 | def _load_my_repos_data(self, watched=False): |
|
|||
82 | if watched: |
|
|||
83 | admin = False |
|
|||
84 | follows_repos = Session().query(UserFollowing)\ |
|
|||
85 | .filter(UserFollowing.user_id == c.rhodecode_user.user_id)\ |
|
|||
86 | .options(joinedload(UserFollowing.follows_repository))\ |
|
|||
87 | .all() |
|
|||
88 | repo_list = [x.follows_repository for x in follows_repos] |
|
|||
89 | else: |
|
|||
90 | admin = True |
|
|||
91 | repo_list = Repository.get_all_repos( |
|
|||
92 | user_id=c.rhodecode_user.user_id) |
|
|||
93 | repo_list = RepoList(repo_list, perm_set=[ |
|
|||
94 | 'repository.read', 'repository.write', 'repository.admin']) |
|
|||
95 |
|
||||
96 | repos_data = RepoModel().get_repos_as_dict( |
|
|||
97 | repo_list=repo_list, admin=admin) |
|
|||
98 | # json used to render the grid |
|
|||
99 | return json.dumps(repos_data) |
|
|||
100 |
|
||||
101 | @auth.CSRFRequired() |
|
77 | @auth.CSRFRequired() | |
102 | def my_account_update(self): |
|
78 | def my_account_update(self): | |
103 | """ |
|
79 | """ | |
@@ -177,29 +153,6 b' class MyAccountController(BaseController' | |||||
177 | force_defaults=False |
|
153 | force_defaults=False | |
178 | ) |
|
154 | ) | |
179 |
|
155 | |||
180 | def my_account_repos(self): |
|
|||
181 | c.active = 'repos' |
|
|||
182 | self.__load_data() |
|
|||
183 |
|
||||
184 | # json used to render the grid |
|
|||
185 | c.data = self._load_my_repos_data() |
|
|||
186 | return render('admin/my_account/my_account.mako') |
|
|||
187 |
|
||||
188 | def my_account_watched(self): |
|
|||
189 | c.active = 'watched' |
|
|||
190 | self.__load_data() |
|
|||
191 |
|
||||
192 | # json used to render the grid |
|
|||
193 | c.data = self._load_my_repos_data(watched=True) |
|
|||
194 | return render('admin/my_account/my_account.mako') |
|
|||
195 |
|
||||
196 | def my_account_perms(self): |
|
|||
197 | c.active = 'perms' |
|
|||
198 | self.__load_data() |
|
|||
199 | c.perm_user = c.auth_user |
|
|||
200 |
|
||||
201 | return render('admin/my_account/my_account.mako') |
|
|||
202 |
|
||||
203 | def _extract_ordering(self, request): |
|
156 | def _extract_ordering(self, request): | |
204 | column_index = safe_int(request.GET.get('order[0][column]')) |
|
157 | column_index = safe_int(request.GET.get('order[0][column]')) | |
205 | order_dir = request.GET.get('order[0][dir]', 'desc') |
|
158 | order_dir = request.GET.get('order[0][dir]', 'desc') | |
@@ -280,15 +233,4 b' class MyAccountController(BaseController' | |||||
280 | else: |
|
233 | else: | |
281 | return json.dumps(data) |
|
234 | return json.dumps(data) | |
282 |
|
235 | |||
283 | def my_notifications(self): |
|
|||
284 | c.active = 'notifications' |
|
|||
285 | return render('admin/my_account/my_account.mako') |
|
|||
286 |
|
236 | |||
287 | @auth.CSRFRequired() |
|
|||
288 | @jsonify |
|
|||
289 | def my_notifications_toggle_visibility(self): |
|
|||
290 | user = c.rhodecode_user.get_instance() |
|
|||
291 | new_status = not user.user_data.get('notification_status', True) |
|
|||
292 | user.update_userdata(notification_status=new_status) |
|
|||
293 | Session().commit() |
|
|||
294 | return user.user_data['notification_status'] |
|
@@ -134,6 +134,14 b' function registerRCRoutes() {' | |||||
134 | pyroutes.register('my_account_auth_tokens', '/_admin/my_account/auth_tokens', []); |
|
134 | pyroutes.register('my_account_auth_tokens', '/_admin/my_account/auth_tokens', []); | |
135 | pyroutes.register('my_account_auth_tokens_add', '/_admin/my_account/auth_tokens/new', []); |
|
135 | pyroutes.register('my_account_auth_tokens_add', '/_admin/my_account/auth_tokens/new', []); | |
136 | pyroutes.register('my_account_auth_tokens_delete', '/_admin/my_account/auth_tokens/delete', []); |
|
136 | pyroutes.register('my_account_auth_tokens_delete', '/_admin/my_account/auth_tokens/delete', []); | |
|
137 | pyroutes.register('my_account_emails', '/_admin/my_account/emails', []); | |||
|
138 | pyroutes.register('my_account_emails_add', '/_admin/my_account/emails/new', []); | |||
|
139 | pyroutes.register('my_account_emails_delete', '/_admin/my_account/emails/delete', []); | |||
|
140 | pyroutes.register('my_account_repos', '/_admin/my_account/repos', []); | |||
|
141 | pyroutes.register('my_account_watched', '/_admin/my_account/watched', []); | |||
|
142 | pyroutes.register('my_account_perms', '/_admin/my_account/perms', []); | |||
|
143 | pyroutes.register('my_account_notifications', '/_admin/my_account/notifications', []); | |||
|
144 | pyroutes.register('my_account_notifications_toggle_visibility', '/_admin/my_account/toggle_visibility', []); | |||
137 | pyroutes.register('my_account_notifications_test_channelstream', '/_admin/my_account/test_channelstream', []); |
|
145 | pyroutes.register('my_account_notifications_test_channelstream', '/_admin/my_account/test_channelstream', []); | |
138 | pyroutes.register('apiv2', '/_admin/api', []); |
|
146 | pyroutes.register('apiv2', '/_admin/api', []); | |
139 | } |
|
147 | } |
@@ -35,11 +35,11 b'' | |||||
35 | <li class="${'active' if c.active=='oauth' else ''}"><a href="${my_account_oauth_url}">${_('OAuth Identities')}</a></li> |
|
35 | <li class="${'active' if c.active=='oauth' else ''}"><a href="${my_account_oauth_url}">${_('OAuth Identities')}</a></li> | |
36 | % endif |
|
36 | % endif | |
37 | <li class="${'active' if c.active=='emails' else ''}"><a href="${h.route_path('my_account_emails')}">${_('Emails')}</a></li> |
|
37 | <li class="${'active' if c.active=='emails' else ''}"><a href="${h.route_path('my_account_emails')}">${_('Emails')}</a></li> | |
38 |
<li class="${'active' if c.active=='repos' else ''}"><a href="${h. |
|
38 | <li class="${'active' if c.active=='repos' else ''}"><a href="${h.route_path('my_account_repos')}">${_('Repositories')}</a></li> | |
39 |
<li class="${'active' if c.active=='watched' else ''}"><a href="${h. |
|
39 | <li class="${'active' if c.active=='watched' else ''}"><a href="${h.route_path('my_account_watched')}">${_('Watched')}</a></li> | |
40 | <li class="${'active' if c.active=='pullrequests' else ''}"><a href="${h.url('my_account_pullrequests')}">${_('Pull Requests')}</a></li> |
|
40 | <li class="${'active' if c.active=='pullrequests' else ''}"><a href="${h.url('my_account_pullrequests')}">${_('Pull Requests')}</a></li> | |
41 |
<li class="${'active' if c.active=='perms' else ''}"><a href="${h. |
|
41 | <li class="${'active' if c.active=='perms' else ''}"><a href="${h.route_path('my_account_perms')}">${_('Permissions')}</a></li> | |
42 |
<li class="${'active' if c.active=='my_notifications' else ''}"><a href="${h. |
|
42 | <li class="${'active' if c.active=='my_notifications' else ''}"><a href="${h.route_path('my_account_notifications')}">${_('Live Notifications')}</a></li> | |
43 | </ul> |
|
43 | </ul> | |
44 | </div> |
|
44 | </div> | |
45 |
|
45 |
@@ -1,7 +1,7 b'' | |||||
1 | <template is="dom-bind" id="notificationsPage"> |
|
1 | <template is="dom-bind" id="notificationsPage"> | |
2 | <iron-ajax id="toggleNotifications" |
|
2 | <iron-ajax id="toggleNotifications" | |
3 | method="post" |
|
3 | method="post" | |
4 |
url="${ |
|
4 | url="${h.route_path('my_account_notifications_toggle_visibility')}" | |
5 | content-type="application/json" |
|
5 | content-type="application/json" | |
6 | loading="{{changeNotificationsLoading}}" |
|
6 | loading="{{changeNotificationsLoading}}" | |
7 | on-response="handleNotifications" |
|
7 | on-response="handleNotifications" |
@@ -57,26 +57,6 b' class TestMyAccountController(TestContro' | |||||
57 |
|
57 | |||
58 | response.mustcontain('value="test_admin') |
|
58 | response.mustcontain('value="test_admin') | |
59 |
|
59 | |||
60 | def test_my_account_my_repos(self): |
|
|||
61 | self.log_user() |
|
|||
62 | response = self.app.get(url('my_account_repos')) |
|
|||
63 | repos = Repository.query().filter( |
|
|||
64 | Repository.user == User.get_by_username( |
|
|||
65 | TEST_USER_ADMIN_LOGIN)).all() |
|
|||
66 | for repo in repos: |
|
|||
67 | response.mustcontain('"name_raw": "%s"' % repo.repo_name) |
|
|||
68 |
|
||||
69 | def test_my_account_my_watched(self): |
|
|||
70 | self.log_user() |
|
|||
71 | response = self.app.get(url('my_account_watched')) |
|
|||
72 |
|
||||
73 | repos = UserFollowing.query().filter( |
|
|||
74 | UserFollowing.user == User.get_by_username( |
|
|||
75 | TEST_USER_ADMIN_LOGIN)).all() |
|
|||
76 | for repo in repos: |
|
|||
77 | response.mustcontain( |
|
|||
78 | '"name_raw": "%s"' % repo.follows_repository.repo_name) |
|
|||
79 |
|
||||
80 | @pytest.mark.backends("git", "hg") |
|
60 | @pytest.mark.backends("git", "hg") | |
81 | def test_my_account_my_pullrequests(self, pr_util): |
|
61 | def test_my_account_my_pullrequests(self, pr_util): | |
82 | self.log_user() |
|
62 | self.log_user() | |
@@ -89,8 +69,6 b' class TestMyAccountController(TestContro' | |||||
89 | response.mustcontain('"name_raw": %s' % pr.pull_request_id) |
|
69 | response.mustcontain('"name_raw": %s' % pr.pull_request_id) | |
90 | response.mustcontain('TestMyAccountPR') |
|
70 | response.mustcontain('TestMyAccountPR') | |
91 |
|
71 | |||
92 |
|
||||
93 |
|
||||
94 | @pytest.mark.parametrize( |
|
72 | @pytest.mark.parametrize( | |
95 | "name, attrs", [ |
|
73 | "name, attrs", [ | |
96 | ('firstname', {'firstname': 'new_username'}), |
|
74 | ('firstname', {'firstname': 'new_username'}), |
General Comments 0
You need to be logged in to leave comments.
Login now