| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance |
| # with the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, |
| # software distributed under the License is distributed on an |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| # KIND, either express or implied. See the License for the |
| # specific language governing permissions and limitations |
| # under the License. |
| |
| import mock |
| import tg |
| from nose.tools import assert_equal, assert_in, assert_not_in |
| |
| from alluratest.controller import TestRestApiBase |
| from allura.model import Project, User |
| from allura.tests import decorators as td |
| from allura.tests import TestController |
| |
| |
| class TestUserProfile(TestController): |
| |
| @td.with_user_project('test-admin') |
| def test_profile(self): |
| r = self.app.get('/u/test-admin/profile/') |
| assert_equal('Test Admin', |
| r.html.find('h1', 'project_title').find('a').text) |
| sections = set([c for s in r.html.findAll(None, 'profile-section') for c in s['class']]) |
| assert_in('personal-data', sections) |
| assert_in('Username:\ntest-admin', r.html.find(None, 'personal-data').getText().replace(' ', '')) |
| assert_in('projects', sections) |
| assert_in('Test Project', r.html.find(None, 'projects').getText()) |
| assert_in('Last Updated:', r.html.find(None, 'projects').getText()) |
| assert_in('tools', sections) |
| assert_in('Admin', r.html.find(None, 'tools').getText()) |
| assert_in('skills', sections) |
| assert_in('No skills entered', r.html.find(None, 'skills').getText()) |
| |
| @td.with_user_project('test-admin') |
| def test_profile_user_card(self): |
| user = User.by_username('test-admin') |
| locals = { |
| 'city': 'test-city', |
| 'country': 'US' |
| } |
| webpages = ['http://allura.apache.org/'] |
| user.set_pref('localization', locals) |
| user.set_pref('webpages', webpages) |
| r = self.app.get('/u/test-admin/profile/user_card') |
| |
| assert user.icon_url() in r.html.find('img').attrs['src'] |
| assert user.display_name == r.html.find('div', attrs={'class': 'name'}).getText() |
| assert user.get_pref('localization')['city'] in r.html.find('span', attrs={'class': 'subitem-loc'}).getText() |
| assert user.get_pref('localization')['country'] in r.html.find('span', attrs={'class': 'subitem-loc'}).getText() |
| assert user.get_pref('webpages')[0] in str(r.html.find('span', attrs={'class': 'subitem-web'})) |
| |
| def test_wrong_profile(self): |
| self.app.get('/u/no-such-user/profile/', status=404) |
| |
| @td.with_user_project('test-user') |
| def test_missing_user(self): |
| User.query.remove(dict(username='test-user')) |
| p = Project.query.get(shortname='u/test-user') |
| assert p is not None and p.is_user_project |
| response = self.app.get('/u/test-user/profile/', status=404) |
| |
| def test_differing_profile_proj_shortname(self): |
| User.upsert('foo_bar') |
| # default auth provider's user_project_shortname() converts _ to - (for subdomain name validation reasons) |
| # but can access user URL with "_" still |
| self.app.get('/u/foo_bar/profile/') |
| |
| # and accessing it by "-" which was the previous way, will redirect |
| response = self.app.get('/u/foo-bar/', status=302) |
| assert_equal(response.location, 'http://localhost/u/foo_bar/') |
| response = self.app.get('/u/foo-bar/profile/xyz?a=b', status=302) |
| assert_equal(response.location, 'http://localhost/u/foo_bar/profile/xyz?a=b') |
| |
| def test_differing_profile_proj_shortname_rest_api(self): |
| User.upsert('foo_bar') |
| # default auth provider's user_project_shortname() converts _ to - (for subdomain name validation reasons) |
| # but can access user URL with "_" still |
| self.app.get('/rest/u/foo_bar/') |
| # and with "-" too, no redirect here to avoid api clients having to deal with unexpected redirects |
| self.app.get('/rest/u/foo-bar/') |
| |
| @td.with_user_project('test-admin') |
| @td.with_wiki |
| def test_feed(self): |
| for ext in ['', '.rss', '.atom']: |
| r = self.app.get('/u/test-admin/profile/feed%s' % ext, status=200) |
| assert 'Recent posts by Test Admin' in r |
| assert 'Home modified by Test Admin' in r |
| |
| @td.with_user_project('test-admin') |
| @td.with_user_project('test-user') |
| @mock.patch('allura.tasks.mail_tasks.sendsimplemail') |
| @mock.patch('allura.lib.helpers.gen_message_id') |
| @mock.patch('allura.model.User.can_send_user_message') |
| def test_send_message(self, check, gen_message_id, sendsimplemail): |
| check.return_value = True |
| gen_message_id.return_value = 'id' |
| test_user = User.by_username('test-user') |
| test_user.set_pref('email_address', 'test-user@example.com') |
| response = self.app.get( |
| '/u/test-user/profile/send_message', status=200) |
| assert 'you currently have user messages disabled' not in response |
| assert '<b>From:</b> "Test Admin" <test-admin@users.localhost>' in response |
| |
| self.app.post('/u/test-user/profile/send_user_message', |
| params={'subject': 'test subject', |
| 'message': 'test message', |
| 'cc': 'on'}) |
| |
| sendsimplemail.post.assert_called_once_with( |
| cc=User.by_username('test-admin').get_pref('email_address'), |
| text=u'test message\n\n---\n\nThis message was sent to you via the Allura web mail form. You may reply to this message directly, or send a message to Test Admin at http://localhost/u/test-admin/profile/send_message\n', |
| toaddr=User.by_username('test-user').get_pref('email_address'), |
| fromaddr=User.by_username('test-admin').get_pref('email_address'), |
| reply_to=User.by_username('test-admin').get_pref('email_address'), |
| message_id=u'id', |
| subject=u'test subject') |
| sendsimplemail.reset_mock() |
| self.app.post('/u/test-user/profile/send_user_message', |
| params={'subject': 'test subject', |
| 'message': 'test message'}) |
| |
| sendsimplemail.post.assert_called_once_with( |
| cc=None, |
| text=u'test message\n\n---\n\nThis message was sent to you via the Allura web mail form. You may reply to this message directly, or send a message to Test Admin at http://localhost/u/test-admin/profile/send_message\n', |
| toaddr=User.by_username('test-user').get_pref('email_address'), |
| fromaddr=User.by_username('test-admin').get_pref('email_address'), |
| reply_to=User.by_username('test-admin').get_pref('email_address'), |
| message_id=u'id', |
| subject=u'test subject') |
| |
| check.return_value = False |
| response = self.app.get( |
| '/u/test-user/profile/send_message', status=200) |
| assert 'Sorry, messaging is rate-limited' in response |
| |
| @td.with_user_project('test-user') |
| def test_send_message_for_anonymous(self): |
| r = self.app.get('/u/test-user/profile/send_message', |
| extra_environ={'username': '*anonymous'}, |
| status=302) |
| assert 'You must be logged in to send user messages.' in self.webflash( |
| r) |
| |
| r = self.app.post('/u/test-user/profile/send_user_message', |
| params={'subject': 'test subject', |
| 'message': 'test message', |
| 'cc': 'on'}, |
| extra_environ={'username': '*anonymous'}, |
| status=302) |
| assert 'You must be logged in to send user messages.' in self.webflash( |
| r) |
| |
| @td.with_user_project('test-user') |
| def test_link_to_send_message_form(self): |
| User.by_username('test-admin').set_pref('email_address', |
| 'admin@example.com') |
| User.by_username('test-user').set_pref('email_address', |
| 'user@example.com') |
| r = self.app.get('/u/test-user/profile', |
| status=200) |
| assert r.html.find('a', dict(href='/u/test-user/profile/send_message')) |
| |
| @td.with_user_project('test-user') |
| def test_disable_user_messages(self): |
| User.by_username('test-admin').set_pref('email_address', |
| 'admin@example.com') |
| test_user = User.by_username('test-user') |
| test_user.set_pref('email_address', 'user@example.com') |
| test_user.set_pref('disable_user_messages', True) |
| r = self.app.get('/u/test-user/profile') |
| assert '<a href="send_message">Send me a message</a>' not in r |
| r = self.app.get('/u/test-user/profile/send_message', status=302) |
| assert 'This user has disabled direct email messages' in self.webflash( |
| r) |
| |
| @td.with_user_project('test-admin') |
| @td.with_user_project('test-user') |
| def test_user_messages_sender_disabled(self): |
| admin_user = User.by_username('test-admin') |
| admin_user.set_pref('email_address', 'admin@example.com') |
| admin_user.set_pref('disable_user_messages', True) |
| |
| test_user = User.by_username('test-user') |
| test_user.set_pref('email_address', 'user@example.com') |
| |
| r = self.app.get('/u/test-user/profile/send_message', status=200) |
| assert 'you currently have user messages disabled' in r |
| |
| @td.with_user_project('test-user') |
| def test_profile_sections(self): |
| project = Project.query.get(shortname='u/test-user') |
| app = project.app_instance('profile') |
| |
| def ep(n): |
| m = mock.Mock() |
| m.name = n |
| m.load()().display.return_value = 'Section %s' % n |
| return m |
| eps = map(ep, ['a', 'b', 'c', 'd']) |
| order = {'user_profile_sections.order': 'b, d,c , f '} |
| if hasattr(type(app), '_sections'): |
| delattr(type(app), '_sections') |
| with mock.patch('allura.lib.helpers.iter_entry_points') as iep: |
| with mock.patch.dict(tg.config, order): |
| iep.return_value = eps |
| sections = app.profile_sections |
| assert_equal(sections, [ |
| eps[1].load(), |
| eps[3].load(), |
| eps[2].load(), |
| eps[0].load()]) |
| r = self.app.get('/u/test-user/profile') |
| assert_in('Section a', r.body) |
| assert_in('Section b', r.body) |
| assert_in('Section c', r.body) |
| assert_in('Section d', r.body) |
| assert_not_in('Section f', r.body) |
| |
| |
| class TestUserProfileHasAccessAPI(TestRestApiBase): |
| |
| @td.with_user_project('test-admin') |
| def test_has_access_no_params(self): |
| self.api_get('/rest/u/test-admin/profile/has_access', status=404) |
| self.api_get('/rest/u/test-admin/profile/has_access?user=root', status=404) |
| self.api_get('/rest/u/test-admin/profile/has_access?perm=read', status=404) |
| |
| @td.with_user_project('test-admin') |
| def test_has_access_unknown_params(self): |
| """Unknown user and/or permission always False for has_access API""" |
| r = self.api_get( |
| '/rest/u/test-admin/profile/has_access?user=babadook&perm=read', |
| user='root') |
| assert_equal(r.status_int, 200) |
| assert_equal(r.json['result'], False) |
| r = self.api_get( |
| '/rest/u/test-admin/profile/has_access?user=test-user&perm=jump', |
| user='root') |
| assert_equal(r.status_int, 200) |
| assert_equal(r.json['result'], False) |
| |
| @td.with_user_project('test-admin') |
| def test_has_access_not_admin(self): |
| """ |
| User which has no 'admin' permission on neighborhood can't use |
| has_access API |
| """ |
| self.api_get( |
| '/rest/u/test-admin/profile/has_access?user=test-admin&perm=admin', |
| user='test-user', |
| status=403) |
| |
| @td.with_user_project('test-admin') |
| def test_has_access(self): |
| r = self.api_get( |
| '/rest/u/test-admin/profile/has_access?user=test-admin&perm=admin', |
| user='root') |
| assert_equal(r.status_int, 200) |
| assert_equal(r.json['result'], True) |
| r = self.api_get( |
| '/rest/u/test-admin/profile/has_access?user=test-user&perm=admin', |
| user='root') |
| assert_equal(r.status_int, 200) |
| assert_equal(r.json['result'], False) |