This should be my final code update before I am ready for review! Basically, in
[mediagoblin.git] / mediagoblin / tests / test_moderation.py
CommitLineData
dfd66b78 1# GNU MediaGoblin -- federated, autonomous media hosting
2# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
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 Affero 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
17import pytest
18
19from mediagoblin.tests.tools import (fixture_add_user,
20 fixture_add_comment_report, fixture_add_comment)
21from mediagoblin.db.models import User, CommentReport, MediaComment, UserBan
22from mediagoblin.moderation.tools import take_away_privileges, give_privileges
23from mediagoblin.tools import template, mail
1bb367f6 24from datetime import date, timedelta
dfd66b78 25
26from webtest import AppError
27
28class TestModerationViews:
29 @pytest.fixture(autouse=True)
30 def _setup(self, test_app):
31 self.test_app = test_app
32
33 fixture_add_user(u'admin',
34 privileges=[u'admin',u'active'])
35 fixture_add_user(u'moderator',
36 privileges=[u'moderator',u'active'])
37 fixture_add_user(u'regular',
38 privileges=[u'active',u'commenter'])
39 self.query_for_users()
40
41 def login(self, username):
42 self.test_app.post(
43 '/auth/login/', {
44 'username': username,
45 'password': 'toast'})
46 self.query_for_users()
47
48 def logout(self):
49 self.test_app.get('/auth/logout/')
50 self.query_for_users()
51
52 def query_for_users(self):
53 self.admin_user = User.query.filter(User.username==u'admin').first()
54 self.mod_user = User.query.filter(User.username==u'moderator').first()
55 self.user = User.query.filter(User.username==u'regular').first()
56
57 def do_post(self, data, *context_keys, **kwargs):
58 url = kwargs.pop('url', '/submit/')
59 do_follow = kwargs.pop('do_follow', False)
60 template.clear_test_template_context()
61 response = self.test_app.post(url, data, **kwargs)
62 if do_follow:
63 response.follow()
64 context_data = template.TEMPLATE_TEST_CONTEXT
65 for key in context_keys:
66 context_data = context_data[key]
67 return response, context_data
68
69 def testGiveOrTakeAwayPrivileges(self):
70 self.login(u'admin')
71 # First, test an admin taking away a privilege from a user
72 #----------------------------------------------------------------------
73 response, context = self.do_post({'privilege_name':u'commenter'},
74 url='/mod/users/{0}/privilege/'.format(self.user.username))
75 assert response.status == '302 FOUND'
76 self.query_for_users()
77 assert not self.user.has_privilege(u'commenter')
78
79 # Then, test an admin giving a privilege to a user
80 #----------------------------------------------------------------------
81 response, context = self.do_post({'privilege_name':u'commenter'},
82 url='/mod/users/{0}/privilege/'.format(self.user.username))
83 assert response.status == '302 FOUND'
84 self.query_for_users()
85 assert self.user.has_privilege(u'commenter')
86
87 # Then, test a mod trying to take away a privilege from a user
88 # they are not allowed to do this, so this will raise an error
89 #----------------------------------------------------------------------
90 self.logout()
91 self.login(u'moderator')
92
93 with pytest.raises(AppError) as excinfo:
94 response, context = self.do_post({'privilege_name':u'commenter'},
95 url='/mod/users/{0}/privilege/'.format(self.user.username))
96 assert 'Bad response: 403 FORBIDDEN' in str(excinfo)
97 self.query_for_users()
98
99 assert self.user.has_privilege(u'commenter')
100
101 def testReportResolution(self):
102 self.login(u'moderator')
103
104 # First, test a moderators taking away a user's privilege in response
105 # to a reported comment
106 #----------------------------------------------------------------------
107 fixture_add_comment_report(reported_user=self.user)
108 comment_report = CommentReport.query.filter(
109 CommentReport.reported_user==self.user).first()
110
111 response = self.test_app.get('/mod/reports/{0}/'.format(
112 comment_report.id))
113 assert response.status == '200 OK'
114 self.query_for_users()
115 comment_report = CommentReport.query.filter(
116 CommentReport.reported_user==self.user).first()
117
118 response, context = self.do_post({'action_to_resolve':[u'takeaway'],
119 'take_away_privileges':[u'commenter'],
120 'targeted_user':self.user.id},
121 url='/mod/reports/{0}/'.format(comment_report.id))
122
123 assert response.status == '302 FOUND'
124 fixture_add_comment_report(reported_user=self.user)
125 comment_report = CommentReport.query.filter(
126 CommentReport.reported_user==self.user).first()
127
128 assert not self.user.has_privilege(u'commenter')
129
130 # Then, test a moderator sending an email to a user in response to a
131 # reported comment
132 #----------------------------------------------------------------------
133 self.query_for_users()
134
135 response, context = self.do_post({'action_to_resolve':[u'sendmessage'],
136 'message_to_user':'This is your last warning, regular....',
137 'targeted_user':self.user.id},
138 url='/mod/reports/{0}/'.format(comment_report.id))
139
140 assert response.status == '302 FOUND'
141 assert mail.EMAIL_TEST_MBOX_INBOX == [{'to': [u'regular@example.com'],
142 'message': 'Content-Type: text/plain; charset="utf-8"\n\
143MIME-Version: 1.0\nContent-Transfer-Encoding: base64\nSubject: Warning from- \
144moderator \nFrom: notice@mediagoblin.example.org\nTo: regular@example.com\n\n\
145VGhpcyBpcyB5b3VyIGxhc3Qgd2FybmluZywgcmVndWxhci4uLi4=\n',
146 'from': 'notice@mediagoblin.example.org'}]
147
148 # Then test a moderator banning a user AND a moderator deleting the
149 # offending comment. This also serves as a test for taking multiple
150 # actions to resolve a report
151 #----------------------------------------------------------------------
152 self.query_for_users()
153 fixture_add_comment(author=self.user.id,
154 comment=u'Comment will be removed')
155 test_comment = MediaComment.query.filter(
156 MediaComment.author==self.user.id).first()
157 fixture_add_comment_report(comment=test_comment,
158 reported_user=self.user)
159 comment_report = CommentReport.query.filter(
160 CommentReport.reported_user==self.user).first()
161
162 response, context = self.do_post(
163 {'action_to_resolve':[u'userban', u'delete'],
1bb367f6 164 'targeted_user':self.user.id,
165 'why_user_was_banned':u'',
166 'user_banned_until':u''},
dfd66b78 167 url='/mod/reports/{0}/'.format(comment_report.id))
168 assert response.status == '302 FOUND'
169 self.query_for_users()
170 test_user_ban = UserBan.query.filter(
171 UserBan.user_id == self.user.id).first()
172 assert test_user_ban is not None
173 test_comment = MediaComment.query.filter(
174 MediaComment.author==self.user.id).first()
175 assert test_comment is None
176
177 # Then, test what happens when a moderator attempts to punish an admin
178 # from a reported comment on an admin.
179 #----------------------------------------------------------------------
180 fixture_add_comment_report(reported_user=self.admin_user)
181 comment_report = CommentReport.query.filter(
182 CommentReport.reported_user==self.admin_user).first()
183
184 response, context = self.do_post({'action_to_resolve':[u'takeaway'],
185 'take_away_privileges':[u'active'],
186 'targeted_user':self.admin_user.id},
187 url='/mod/reports/{0}/'.format(comment_report.id))
188 self.query_for_users()
189
190 assert response.status == '200 OK'
191 assert self.admin_user.has_privilege(u'active')
192
193 def testAllModerationViews(self):
194 self.login(u'moderator')
1bb367f6 195 username = self.user.username
6acf4ee6 196 self.query_for_users()
1bb367f6 197 fixture_add_comment_report(reported_user=self.admin_user)
198 response = self.test_app.get('/mod/reports/')
199 assert response.status == "200 OK"
200
201 response = self.test_app.get('/mod/reports/1/')
202 assert response.status == "200 OK"
203
204 response = self.test_app.get('/mod/users/')
205 assert response.status == "200 OK"
206
207 user_page_url = '/mod/users/{0}/'.format(username)
208 response = self.test_app.get(user_page_url)
209 assert response.status == "200 OK"
210
dfd66b78 211 self.test_app.get('/mod/media/')
1bb367f6 212 assert response.status == "200 OK"
213
214 def testBanUnBanUser(self):
215 self.login(u'admin')
216 username = self.user.username
217 user_id = self.user.id
218 ban_url = '/mod/users/{0}/ban/'.format(username)
219 response, context = self.do_post({
220 'user_banned_until':u'',
221 'why_user_was_banned':u'Because I said so'},
222 url=ban_url)
223
224 assert response.status == "302 FOUND"
225 user_banned = UserBan.query.filter(UserBan.user_id==user_id).first()
226 assert user_banned is not None
227 assert user_banned.expiration_date is None
228 assert user_banned.reason == u'Because I said so'
229
230 response, context = self.do_post({},
231 url=ban_url)
232
233 assert response.status == "302 FOUND"
234 user_banned = UserBan.query.filter(UserBan.user_id==user_id).first()
235 assert user_banned is None