1 # GNU MediaGoblin -- federated, autonomous media hosting
2 # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
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.
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.
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/>.
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
22 from mediagoblin
.tools
import template
, mail
23 from webtest
import AppError
25 class TestModerationViews
:
26 @pytest.fixture(autouse
=True)
27 def _setup(self
, test_app
):
28 self
.test_app
= test_app
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()
38 def login(self
, username
):
43 self
.query_for_users()
46 self
.test_app
.get('/auth/logout/')
47 self
.query_for_users()
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()
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
)
61 context_data
= template
.TEMPLATE_TEST_CONTEXT
62 for key
in context_keys
:
63 context_data
= context_data
[key
]
64 return response
, context_data
66 def testGiveOrTakeAwayPrivileges(self
):
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')
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')
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 #----------------------------------------------------------------------
88 self
.login(u
'moderator')
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()
96 assert self
.user
.has_privilege(u
'commenter')
98 def testReportResolution(self
):
99 self
.login(u
'moderator')
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()
108 response
= self
.test_app
.get('/mod/reports/{0}/'.format(
110 assert response
.status
== '200 OK'
111 self
.query_for_users()
112 comment_report
= CommentReport
.query
.filter(
113 CommentReport
.reported_user
==self
.user
).first()
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))
120 self
.query_for_users()
121 comment_report
= CommentReport
.query
.filter(
122 CommentReport
.reported_user
==self
.user
).first()
123 assert response
.status
== '302 FOUND'
124 assert not self
.user
.has_privilege(u
'commenter')
125 assert comment_report
.is_archived_report() is True
127 fixture_add_comment_report(reported_user
=self
.user
)
128 comment_report
= CommentReport
.query
.filter(
129 CommentReport
.reported_user
==self
.user
).first()
131 # Then, test a moderator sending an email to a user in response to a
133 #----------------------------------------------------------------------
134 self
.query_for_users()
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))
141 self
.query_for_users()
142 comment_report
= CommentReport
.query
.filter(
143 CommentReport
.reported_user
==self
.user
).first()
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'}]
151 assert comment_report
.is_archived_report() is True
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(
165 CommentReport
.comment
==test_comment
).filter(
166 CommentReport
.resolved
==None).first()
168 response
, context
= self
.do_post(
169 {'action_to_resolve':[u
'userban', u
'delete'],
170 'targeted_user':self
.user
.id,
171 'why_user_was_banned':u
'',
172 'user_banned_until':u
''},
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
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(
188 CommentReport
.reported_user
==self
.admin_user
).filter(
189 CommentReport
.resolved
==None).first()
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()
197 assert response
.status
== '200 OK'
198 assert self
.admin_user
.has_privilege(u
'active')
200 def testAllModerationViews(self
):
201 self
.login(u
'moderator')
202 username
= self
.user
.username
203 self
.query_for_users()
204 fixture_add_comment_report(reported_user
=self
.admin_user
)
205 response
= self
.test_app
.get('/mod/reports/')
206 assert response
.status
== "200 OK"
208 response
= self
.test_app
.get('/mod/reports/1/')
209 assert response
.status
== "200 OK"
211 response
= self
.test_app
.get('/mod/users/')
212 assert response
.status
== "200 OK"
214 user_page_url
= '/mod/users/{0}/'.format(username
)
215 response
= self
.test_app
.get(user_page_url
)
216 assert response
.status
== "200 OK"
218 self
.test_app
.get('/mod/media/')
219 assert response
.status
== "200 OK"
221 def testBanUnBanUser(self
):
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'},
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'
237 response
, context
= self
.do_post({},
240 assert response
.status
== "302 FOUND"
241 user_banned
= UserBan
.query
.filter(UserBan
.user_id
==user_id
).first()
242 assert user_banned
is None