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