diff --git a/rhodecode/apps/my_account/__init__.py b/rhodecode/apps/my_account/__init__.py --- a/rhodecode/apps/my_account/__init__.py +++ b/rhodecode/apps/my_account/__init__.py @@ -56,6 +56,26 @@ def includeme(config): name='my_account_emails_delete', pattern=ADMIN_PREFIX + '/my_account/emails/delete') + config.add_route( + name='my_account_repos', + pattern=ADMIN_PREFIX + '/my_account/repos') + + config.add_route( + name='my_account_watched', + pattern=ADMIN_PREFIX + '/my_account/watched') + + config.add_route( + name='my_account_perms', + pattern=ADMIN_PREFIX + '/my_account/perms') + + config.add_route( + name='my_account_notifications', + pattern=ADMIN_PREFIX + '/my_account/notifications') + + config.add_route( + name='my_account_notifications_toggle_visibility', + pattern=ADMIN_PREFIX + '/my_account/toggle_visibility') + # channelstream test config.add_route( name='my_account_notifications_test_channelstream', diff --git a/rhodecode/apps/my_account/tests/test_my_account_simple_views.py b/rhodecode/apps/my_account/tests/test_my_account_simple_views.py new file mode 100644 --- /dev/null +++ b/rhodecode/apps/my_account/tests/test_my_account_simple_views.py @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2010-2017 RhodeCode GmbH +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License, version 3 +# (only), as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +# This program is dual-licensed. If you wish to learn more about the +# RhodeCode Enterprise Edition, including its added features, Support services, +# and proprietary license terms, please see https://rhodecode.com/licenses/ + +import pytest + +from rhodecode.apps._base import ADMIN_PREFIX +from rhodecode.model.db import User, UserEmailMap, Repository, UserFollowing +from rhodecode.tests import ( + TestController, TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_EMAIL, + assert_session_flash) +from rhodecode.tests.fixture import Fixture + +fixture = Fixture() + + +def route_path(name, **kwargs): + return { + 'my_account_repos': + ADMIN_PREFIX + '/my_account/repos', + 'my_account_watched': + ADMIN_PREFIX + '/my_account/watched', + 'my_account_perms': + ADMIN_PREFIX + '/my_account/perms', + 'my_account_notifications': + ADMIN_PREFIX + '/my_account/notifications', + }[name].format(**kwargs) + + +class TestMyAccountSimpleViews(TestController): + + def test_my_account_my_repos(self, autologin_user): + response = self.app.get(route_path('my_account_repos')) + repos = Repository.query().filter( + Repository.user == User.get_by_username( + TEST_USER_ADMIN_LOGIN)).all() + for repo in repos: + response.mustcontain('"name_raw": "%s"' % repo.repo_name) + + def test_my_account_my_watched(self, autologin_user): + response = self.app.get(route_path('my_account_watched')) + + repos = UserFollowing.query().filter( + UserFollowing.user == User.get_by_username( + TEST_USER_ADMIN_LOGIN)).all() + for repo in repos: + response.mustcontain( + '"name_raw": "%s"' % repo.follows_repository.repo_name) + + def test_my_account_perms(self, autologin_user): + response = self.app.get(route_path('my_account_perms')) + assert_response = response.assert_response() + assert assert_response.get_elements('.perm_tag.none') + assert assert_response.get_elements('.perm_tag.read') + assert assert_response.get_elements('.perm_tag.write') + assert assert_response.get_elements('.perm_tag.admin') + + def test_my_account_notifications(self, autologin_user): + response = self.app.get(route_path('my_account_notifications')) + response.mustcontain('Test flash message') diff --git a/rhodecode/apps/my_account/views.py b/rhodecode/apps/my_account/views.py --- a/rhodecode/apps/my_account/views.py +++ b/rhodecode/apps/my_account/views.py @@ -28,14 +28,18 @@ from pyramid.view import view_config from rhodecode.apps._base import BaseAppView from rhodecode import forms from rhodecode.lib import helpers as h +from rhodecode.lib.ext_json import json from rhodecode.lib.auth import LoginRequired, NotAnonymous, CSRFRequired from rhodecode.lib.channelstream import channelstream_request, \ ChannelstreamException from rhodecode.lib.utils2 import safe_int, md5 from rhodecode.model.auth_token import AuthTokenModel -from rhodecode.model.db import UserEmailMap +from rhodecode.model.db import ( + Repository, PullRequest, UserEmailMap, User, UserFollowing, joinedload) from rhodecode.model.meta import Session +from rhodecode.model.scm import RepoList from rhodecode.model.user import UserModel +from rhodecode.model.repo import RepoModel from rhodecode.model.validation_schema.schemas import user_schema log = logging.getLogger(__name__) @@ -290,3 +294,85 @@ class MyAccountView(BaseAppView): return {"response": 'ERROR: {}'.format(e.__class__.__name__)} return {"response": 'Channelstream data sent. ' 'You should see a new live message now.'} + + def _load_my_repos_data(self, watched=False): + if watched: + admin = False + follows_repos = Session().query(UserFollowing)\ + .filter(UserFollowing.user_id == self._rhodecode_user.user_id)\ + .options(joinedload(UserFollowing.follows_repository))\ + .all() + repo_list = [x.follows_repository for x in follows_repos] + else: + admin = True + repo_list = Repository.get_all_repos( + user_id=self._rhodecode_user.user_id) + repo_list = RepoList(repo_list, perm_set=[ + 'repository.read', 'repository.write', 'repository.admin']) + + repos_data = RepoModel().get_repos_as_dict( + repo_list=repo_list, admin=admin) + # json used to render the grid + return json.dumps(repos_data) + + @LoginRequired() + @NotAnonymous() + @view_config( + route_name='my_account_repos', request_method='GET', + renderer='rhodecode:templates/admin/my_account/my_account.mako') + def my_account_repos(self): + c = self.load_default_context() + c.active = 'repos' + + # json used to render the grid + c.data = self._load_my_repos_data() + return self._get_template_context(c) + + @LoginRequired() + @NotAnonymous() + @view_config( + route_name='my_account_watched', request_method='GET', + renderer='rhodecode:templates/admin/my_account/my_account.mako') + def my_account_watched(self): + c = self.load_default_context() + c.active = 'watched' + + # json used to render the grid + c.data = self._load_my_repos_data(watched=True) + return self._get_template_context(c) + + @LoginRequired() + @NotAnonymous() + @view_config( + route_name='my_account_perms', request_method='GET', + renderer='rhodecode:templates/admin/my_account/my_account.mako') + def my_account_perms(self): + c = self.load_default_context() + c.active = 'perms' + + c.perm_user = c.auth_user + return self._get_template_context(c) + + @LoginRequired() + @NotAnonymous() + @view_config( + route_name='my_account_notifications', request_method='GET', + renderer='rhodecode:templates/admin/my_account/my_account.mako') + def my_notifications(self): + c = self.load_default_context() + c.active = 'notifications' + + return self._get_template_context(c) + + @LoginRequired() + @NotAnonymous() + @CSRFRequired() + @view_config( + route_name='my_account_notifications_toggle_visibility', + request_method='POST', renderer='json_ext') + def my_notifications_toggle_visibility(self): + user = self._rhodecode_db_user + new_status = not user.user_data.get('notification_status', True) + user.update_userdata(notification_status=new_status) + Session().commit() + return user.user_data['notification_status'] \ No newline at end of file diff --git a/rhodecode/config/routing.py b/rhodecode/config/routing.py --- a/rhodecode/config/routing.py +++ b/rhodecode/config/routing.py @@ -485,26 +485,9 @@ def make_map(config): m.connect('my_account_password', '/my_account/password', action='my_account_password', conditions={'method': ['GET']}) - m.connect('my_account_repos', '/my_account/repos', - action='my_account_repos', conditions={'method': ['GET']}) - - m.connect('my_account_watched', '/my_account/watched', - action='my_account_watched', conditions={'method': ['GET']}) - m.connect('my_account_pullrequests', '/my_account/pull_requests', action='my_account_pullrequests', conditions={'method': ['GET']}) - m.connect('my_account_perms', '/my_account/perms', - action='my_account_perms', conditions={'method': ['GET']}) - - m.connect('my_account_notifications', '/my_account/notifications', - action='my_notifications', - conditions={'method': ['GET']}) - m.connect('my_account_notifications_toggle_visibility', - '/my_account/toggle_visibility', - action='my_notifications_toggle_visibility', - conditions={'method': ['POST']}) - # NOTIFICATION REST ROUTES with rmap.submapper(path_prefix=ADMIN_PREFIX, controller='admin/notifications') as m: diff --git a/rhodecode/controllers/admin/my_account.py b/rhodecode/controllers/admin/my_account.py --- a/rhodecode/controllers/admin/my_account.py +++ b/rhodecode/controllers/admin/my_account.py @@ -29,26 +29,22 @@ import formencode from formencode import htmlfill from pyramid.httpexceptions import HTTPFound -from pylons import request, tmpl_context as c, url +from pylons import request, tmpl_context as c from pylons.controllers.util import redirect from pylons.i18n.translation import _ -from sqlalchemy.orm import joinedload from rhodecode.lib import helpers as h from rhodecode.lib import auth from rhodecode.lib.auth import ( LoginRequired, NotAnonymous, AuthUser) from rhodecode.lib.base import BaseController, render -from rhodecode.lib.utils import jsonify from rhodecode.lib.utils2 import safe_int, str2bool from rhodecode.lib.ext_json import json from rhodecode.model.db import ( Repository, PullRequest, UserEmailMap, User, UserFollowing) from rhodecode.model.forms import UserForm -from rhodecode.model.scm import RepoList from rhodecode.model.user import UserModel -from rhodecode.model.repo import RepoModel from rhodecode.model.meta import Session from rhodecode.model.pull_request import PullRequestModel from rhodecode.model.comment import CommentsModel @@ -78,26 +74,6 @@ class MyAccountController(BaseController c.auth_user = AuthUser( user_id=c.rhodecode_user.user_id, ip_addr=self.ip_addr) - def _load_my_repos_data(self, watched=False): - if watched: - admin = False - follows_repos = Session().query(UserFollowing)\ - .filter(UserFollowing.user_id == c.rhodecode_user.user_id)\ - .options(joinedload(UserFollowing.follows_repository))\ - .all() - repo_list = [x.follows_repository for x in follows_repos] - else: - admin = True - repo_list = Repository.get_all_repos( - user_id=c.rhodecode_user.user_id) - repo_list = RepoList(repo_list, perm_set=[ - 'repository.read', 'repository.write', 'repository.admin']) - - repos_data = RepoModel().get_repos_as_dict( - repo_list=repo_list, admin=admin) - # json used to render the grid - return json.dumps(repos_data) - @auth.CSRFRequired() def my_account_update(self): """ @@ -177,29 +153,6 @@ class MyAccountController(BaseController force_defaults=False ) - def my_account_repos(self): - c.active = 'repos' - self.__load_data() - - # json used to render the grid - c.data = self._load_my_repos_data() - return render('admin/my_account/my_account.mako') - - def my_account_watched(self): - c.active = 'watched' - self.__load_data() - - # json used to render the grid - c.data = self._load_my_repos_data(watched=True) - return render('admin/my_account/my_account.mako') - - def my_account_perms(self): - c.active = 'perms' - self.__load_data() - c.perm_user = c.auth_user - - return render('admin/my_account/my_account.mako') - def _extract_ordering(self, request): column_index = safe_int(request.GET.get('order[0][column]')) order_dir = request.GET.get('order[0][dir]', 'desc') @@ -280,15 +233,4 @@ class MyAccountController(BaseController else: return json.dumps(data) - def my_notifications(self): - c.active = 'notifications' - return render('admin/my_account/my_account.mako') - @auth.CSRFRequired() - @jsonify - def my_notifications_toggle_visibility(self): - user = c.rhodecode_user.get_instance() - new_status = not user.user_data.get('notification_status', True) - user.update_userdata(notification_status=new_status) - Session().commit() - return user.user_data['notification_status'] diff --git a/rhodecode/public/js/rhodecode/routes.js b/rhodecode/public/js/rhodecode/routes.js --- a/rhodecode/public/js/rhodecode/routes.js +++ b/rhodecode/public/js/rhodecode/routes.js @@ -134,6 +134,14 @@ function registerRCRoutes() { pyroutes.register('my_account_auth_tokens', '/_admin/my_account/auth_tokens', []); pyroutes.register('my_account_auth_tokens_add', '/_admin/my_account/auth_tokens/new', []); pyroutes.register('my_account_auth_tokens_delete', '/_admin/my_account/auth_tokens/delete', []); + pyroutes.register('my_account_emails', '/_admin/my_account/emails', []); + pyroutes.register('my_account_emails_add', '/_admin/my_account/emails/new', []); + pyroutes.register('my_account_emails_delete', '/_admin/my_account/emails/delete', []); + pyroutes.register('my_account_repos', '/_admin/my_account/repos', []); + pyroutes.register('my_account_watched', '/_admin/my_account/watched', []); + pyroutes.register('my_account_perms', '/_admin/my_account/perms', []); + pyroutes.register('my_account_notifications', '/_admin/my_account/notifications', []); + pyroutes.register('my_account_notifications_toggle_visibility', '/_admin/my_account/toggle_visibility', []); pyroutes.register('my_account_notifications_test_channelstream', '/_admin/my_account/test_channelstream', []); pyroutes.register('apiv2', '/_admin/api', []); } diff --git a/rhodecode/templates/admin/my_account/my_account.mako b/rhodecode/templates/admin/my_account/my_account.mako --- a/rhodecode/templates/admin/my_account/my_account.mako +++ b/rhodecode/templates/admin/my_account/my_account.mako @@ -35,11 +35,11 @@
  • ${_('OAuth Identities')}
  • % endif
  • ${_('Emails')}
  • -
  • ${_('Repositories')}
  • -
  • ${_('Watched')}
  • +
  • ${_('Repositories')}
  • +
  • ${_('Watched')}
  • ${_('Pull Requests')}
  • -
  • ${_('Permissions')}
  • -
  • ${_('Live Notifications')}
  • +
  • ${_('Permissions')}
  • +
  • ${_('Live Notifications')}
  • diff --git a/rhodecode/templates/admin/my_account/my_account_notifications.mako b/rhodecode/templates/admin/my_account/my_account_notifications.mako --- a/rhodecode/templates/admin/my_account/my_account_notifications.mako +++ b/rhodecode/templates/admin/my_account/my_account_notifications.mako @@ -1,7 +1,7 @@