| # 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 os |
| import allura |
| from StringIO import StringIO |
| import logging |
| |
| import PIL |
| from alluratest.controller import TestController |
| from allura.lib import helpers as h |
| from allura import model as M |
| |
| from forgediscussion import model as FM |
| |
| log = logging.getLogger(__name__) |
| |
| |
| class TestForumAdmin(TestController): |
| |
| def setUp(self): |
| TestController.setUp(self) |
| self.app.get('/discussion/') |
| |
| def test_forum_CRUD(self): |
| r = self.app.get('/admin/discussion/forums') |
| r.forms[3]['add_forum.shortname'] = 'testforum' |
| r.forms[3]['add_forum.name'] = 'Test Forum' |
| r = r.forms[3].submit().follow() |
| assert 'Test Forum' in r |
| h.set_context('test', 'Forum', neighborhood='Projects') |
| frm = FM.Forum.query.get(shortname='testforum') |
| r = self.app.post('/admin/discussion/update_forums', |
| params={'forum-0.delete': '', |
| 'forum-0.id': str(frm._id), |
| 'forum-0.name': 'New Test Forum', |
| 'forum-0.shortname': 'NewTestForum', |
| 'forum-0.description': 'My desc', |
| 'forum-0.monitoring_email': ''}) |
| r = self.app.get('/admin/discussion/forums') |
| assert 'New Test Forum' in r |
| assert 'My desc' in r |
| |
| def test_forum_CRUD_hier(self): |
| r = self.app.get('/admin/discussion/forums') |
| r.forms[3]['add_forum.shortname'] = 'testforum' |
| r.forms[3]['add_forum.name'] = 'Test Forum' |
| r = r.forms[3].submit().follow() |
| r = self.app.get('/admin/discussion/forums') |
| assert 'testforum' in r |
| h.set_context('test', 'discussion', neighborhood='Projects') |
| frm = FM.Forum.query.get(shortname='testforum') |
| r = self.app.get('/admin/discussion/forums') |
| r.forms[3]['add_forum.shortname'] = 'childforum' |
| r.forms[3]['add_forum.name'] = 'Child Forum' |
| r.forms[3]['add_forum.parent'] = str(frm._id) |
| r.forms[3].submit() |
| r = self.app.get('/admin/discussion/forums') |
| assert 'Child Forum' in r |
| |
| def test_bad_forum_names(self): |
| r = self.app.get('/admin/discussion/forums') |
| r.forms[3]['add_forum.shortname'] = 'Test.Forum' |
| r.forms[3]['add_forum.name'] = 'Test Forum' |
| r = r.forms[3].submit() |
| assert 'error' in r |
| r = self.app.get('/admin/discussion/forums') |
| r.forms[3]['add_forum.shortname'] = 'Test/Forum' |
| r.forms[3]['add_forum.name'] = 'Test Forum' |
| r = r.forms[3].submit() |
| assert 'error' in r |
| r = self.app.get('/admin/discussion/forums') |
| r.forms[3]['add_forum.shortname'] = 'Test Forum' |
| r.forms[3]['add_forum.name'] = 'Test Forum' |
| r = r.forms[3].submit() |
| assert 'error' in r |
| |
| def test_duplicate_forum_names(self): |
| r = self.app.get('/admin/discussion/forums') |
| r.forms[3]['add_forum.shortname'] = 'a' |
| r.forms[3]['add_forum.name'] = 'Forum A' |
| r = r.forms[3].submit() |
| r = self.app.get('/admin/discussion/forums') |
| r.forms[3]['add_forum.shortname'] = 'b' |
| r.forms[3]['add_forum.name'] = 'Forum B' |
| r = r.forms[3].submit() |
| h.set_context('test', 'Forum', neighborhood='Projects') |
| forum_a = FM.Forum.query.get(shortname='a') |
| self.app.post('/admin/discussion/update_forums', |
| params={'forum-0.delete': 'on', |
| 'forum-0.id': str(forum_a._id), |
| 'forum-0.name': 'Forum A', |
| 'forum-0.description': '' |
| }) |
| # Now we have two forums: 'a', and 'b'. 'a' is deleted. |
| # Let's try to create new forums with these names. |
| r = self.app.get('/admin/discussion/forums') |
| r.forms[3]['add_forum.shortname'] = 'a' |
| r.forms[3]['add_forum.name'] = 'Forum A' |
| r = r.forms[3].submit() |
| assert 'error' in r |
| r = self.app.get('/admin/discussion/forums') |
| r.forms[3]['add_forum.shortname'] = 'b' |
| r.forms[3]['add_forum.name'] = 'Forum B' |
| r = r.forms[3].submit() |
| assert 'error' in r |
| |
| def test_delete_undelete(self): |
| r = self.app.get('/admin/discussion/forums') |
| r = self.app.get('/admin/discussion/forums') |
| r.forms[3]['add_forum.shortname'] = 'testforum' |
| r.forms[3]['add_forum.name'] = 'Test Forum' |
| r = r.forms[3].submit() |
| r = self.app.get('/admin/discussion/forums') |
| soup_form = r.html.find('form', action='update_forums') |
| assert len(soup_form.findAll('input', {'value': 'Delete'})) == 2 |
| h.set_context('test', 'Forum', neighborhood='Projects') |
| frm = FM.Forum.query.get(shortname='testforum') |
| |
| r = self.app.post('/admin/discussion/update_forums', |
| params={'forum-0.delete': 'on', |
| 'forum-0.id': str(frm._id), |
| 'forum-0.name': 'New Test Forum', |
| 'forum-0.description': 'My desc'}) |
| r = self.app.get('/admin/discussion/forums') |
| soup_form = r.html.find('form', action='update_forums') |
| assert len(soup_form.findAll('input', {'value': 'Delete'})) == 1 |
| r = self.app.post('/admin/discussion/update_forums', |
| params={'forum-0.undelete': 'on', |
| 'forum-0.id': str(frm._id), |
| 'forum-0.name': 'New Test Forum', |
| 'forum-0.description': 'My desc'}) |
| r = self.app.get('/admin/discussion/forums') |
| soup_form = r.html.find('form', action='update_forums') |
| assert len(soup_form.findAll('input', {'value': 'Delete'})) == 2 |
| |
| def test_members_only(self): |
| # make a forum anyone can see |
| r = self.app.get('/admin/discussion/forums') |
| r.forms[3]['add_forum.shortname'] = 'secret' |
| r.forms[3]['add_forum.name'] = 'Secret' |
| r.forms[3].submit() |
| # forum can be viewed by member and non-member |
| self.app.get('/discussion/secret') |
| self.app.get('/discussion/secret', |
| extra_environ=dict(username='test-user')) |
| # make a post in the forum and confirm it is also viewable by member |
| # and non-member |
| r = self.app.get('/discussion/create_topic/') |
| f = r.html.find( |
| 'form', {'action': '/p/test/discussion/save_new_topic'}) |
| params = dict() |
| inputs = f.findAll('input') |
| for field in inputs: |
| if field.has_key('name'): # nopep8 - beautifulsoup3 actually uses has_key |
| params[field['name']] = field.get('value') or '' |
| params[f.find('textarea')['name']] = 'secret text' |
| params[f.find('select')['name']] = 'secret' |
| params[f.find('input', {'style': 'width: 90%'}) |
| ['name']] = 'secret topic' |
| r = self.app.post('/discussion/save_new_topic', params=params).follow() |
| thread_url = r.request.url |
| self.app.get(thread_url) |
| self.app.get(thread_url, extra_environ=dict(username='test-user')) |
| # link shows up in app for member and non-member |
| r = self.app.get('/discussion/') |
| assert '/secret/' in r |
| r = self.app.get('/discussion/', |
| extra_environ=dict(username='test-user')) |
| assert '/secret/' in r |
| # make the forum member only viewable |
| secret = FM.Forum.query.get(shortname='secret') |
| self.app.post('/admin/discussion/update_forums', |
| params={'forum-0.members_only': 'on', |
| 'forum-0.id': str(secret._id), |
| 'forum-0.name': 'Secret', |
| 'forum-0.shortname': 'secret', |
| 'forum-0.description': '', |
| 'forum-0.monitoring_email': '' |
| }) |
| # member can see the forum, but non-member gets 403 |
| self.app.get('/discussion/secret') |
| self.app.get('/discussion/secret', |
| extra_environ=dict(username='test-user'), status=403) |
| # member can see a thread in the forum, but non-member gets 403 |
| self.app.get(thread_url) |
| self.app.get(thread_url, |
| extra_environ=dict(username='test-user'), status=403) |
| # link shows up in app for member but not non-member |
| r = self.app.get('/discussion/') |
| assert '/secret/' in r |
| r = self.app.get('/discussion/', |
| extra_environ=dict(username='test-user')) |
| assert '/secret/' not in r |
| |
| def test_anon_posts(self): |
| # make a forum anons can't post in |
| r = self.app.get('/admin/discussion/forums') |
| r.forms[3]['add_forum.shortname'] = 'testforum' |
| r.forms[3]['add_forum.name'] = 'Test Forum' |
| r.forms[3].submit() |
| # try to post in the forum and get a 403 |
| r = self.app.get('/discussion/create_topic/') |
| f = r.html.find( |
| 'form', {'action': '/p/test/discussion/save_new_topic'}) |
| params = dict() |
| inputs = f.findAll('input') |
| for field in inputs: |
| if field.has_key('name'): # nopep8 - beautifulsoup3 actually uses has_key |
| params[field['name']] = field.get('value') or '' |
| params[f.find('textarea')['name']] = 'post text' |
| params[f.find('select')['name']] = 'testforum' |
| params[f.find('input', {'style': 'width: 90%'})['name']] = 'post topic' |
| r = self.app.post('/discussion/save_new_topic', |
| params=params, extra_environ=dict(username='*anonymous')) |
| assert r.location == 'http://localhost/auth/' |
| # allow anon posts in the forum |
| testforum = FM.Forum.query.get(shortname='testforum') |
| self.app.post('/admin/discussion/update_forums', |
| params={'forum-0.anon_posts': 'on', |
| 'forum-0.id': str(testforum._id), |
| 'forum-0.name': 'Test Forum', |
| 'forum-0.shortname': 'testforum', |
| 'forum-0.description': '', |
| 'forum-0.monitoring_email': '' |
| }) |
| # successfully post to the forum |
| r = self.app.get('/discussion/create_topic/') |
| f = r.html.find( |
| 'form', {'action': '/p/test/discussion/save_new_topic'}) |
| params = dict() |
| inputs = f.findAll('input') |
| for field in inputs: |
| if field.has_key('name'): # nopep8 - beautifulsoup3 actually uses has_key |
| params[field['name']] = field.get('value') or '' |
| params[f.find('textarea')['name']] = 'post text' |
| params[f.find('select')['name']] = 'testforum' |
| params[f.find('input', {'style': 'width: 90%'})['name']] = 'post topic' |
| r = self.app.post('/discussion/save_new_topic', params=params) |
| assert 'http://localhost/p/test/discussion/testforum/thread/' in r.location |
| |
| def test_footer_monitoring_email(self): |
| r = self.app.get('/admin/discussion/forums') |
| r.forms[3]['add_forum.shortname'] = 'testforum' |
| r.forms[3]['add_forum.name'] = 'Test Forum' |
| r.forms[3].submit() |
| testforum = FM.Forum.query.get(shortname='testforum') |
| self.app.post('/admin/discussion/update_forums', |
| params={'forum-0.anon_posts': 'on', |
| 'forum-0.id': str(testforum._id), |
| 'forum-0.name': 'Test Forum', |
| 'forum-0.shortname': 'testforum', |
| 'forum-0.description': '', |
| 'forum-0.monitoring_email': 'email@monitoring.com' |
| }) |
| |
| r = self.app.get('/discussion/create_topic/') |
| f = r.html.find( |
| 'form', {'action': '/p/test/discussion/save_new_topic'}) |
| params = dict() |
| inputs = f.findAll('input') |
| for field in inputs: |
| if field.has_key('name'): # nopep8 - beautifulsoup3 actually uses has_key |
| params[field['name']] = field.get('value') or '' |
| params[f.find('textarea')['name']] = 'post text' |
| params[f.find('select')['name']] = 'testforum' |
| params[f.find('input', {'style': 'width: 90%'})['name']] = 'post topic' |
| r = self.app.post('/discussion/save_new_topic', params=params) |
| M.MonQTask.run_ready() |
| email_tasks = M.MonQTask.query.find( |
| dict(task_name='allura.tasks.mail_tasks.sendsimplemail')).all() |
| assert 'Sent from localhost because email@monitoring.com is subscribed '\ |
| 'to http://localhost/p/test/discussion/testforum/' in email_tasks[ |
| 0].kwargs['text'], email_tasks[0].kwargs['text'] |
| assert 'a project admin can change settings at http://localhost/p/test/admin/discussion/forums' in email_tasks[ |
| 0].kwargs['text'] |