Remove <br/> from safe string indicating that CSRF cooking is missing.
[larjonas-mediagoblin.git] / mediagoblin / tests / test_edit.py
blob632c8e3c368f56161dd8b8a9e64be96891e7879c
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/>.
17 import six
18 import six.moves.urllib.parse as urlparse
19 import pytest
21 from mediagoblin import mg_globals
22 from mediagoblin.db.models import User, LocalUser, MediaEntry
23 from mediagoblin.tests.tools import fixture_add_user, fixture_media_entry
24 from mediagoblin import auth
25 from mediagoblin.tools import template, mail
28 class TestUserEdit(object):
29 def setup(self):
30 # set up new user
31 self.user_password = u'toast'
32 self.user = fixture_add_user(password = self.user_password,
33 privileges=[u'active'])
35 def login(self, test_app):
36 test_app.post(
37 '/auth/login/', {
38 'username': self.user.username,
39 'password': self.user_password})
42 def test_user_deletion(self, test_app):
43 """Delete user via web interface"""
44 self.login(test_app)
46 # Make sure user exists
47 assert LocalUser.query.filter(LocalUser.username==u'chris').first()
49 res = test_app.post('/edit/account/delete/', {'confirmed': 'y'})
51 # Make sure user has been deleted
52 assert LocalUser.query.filter(LocalUser.username==u'chris').first() == None
54 #TODO: make sure all corresponding items comments etc have been
55 # deleted too. Perhaps in submission test?
57 #Restore user at end of test
58 self.user = fixture_add_user(password = self.user_password,
59 privileges=[u'active'])
60 self.login(test_app)
63 def test_change_bio_url(self, test_app):
64 """Test changing bio and URL"""
65 self.login(test_app)
67 # Test if legacy profile editing URL redirects correctly
68 res = test_app.post(
69 '/edit/profile/', {
70 'bio': u'I love toast!',
71 'url': u'http://dustycloud.org/'}, expect_errors=True)
73 # Should redirect to /u/chris/edit/
74 assert res.status_int == 302
75 assert res.headers['Location'].endswith("/u/chris/edit/")
77 res = test_app.post(
78 '/u/chris/edit/', {
79 'bio': u'I love toast!',
80 'url': u'http://dustycloud.org/'})
82 test_user = LocalUser.query.filter(LocalUser.username==u'chris').first()
83 assert test_user.bio == u'I love toast!'
84 assert test_user.url == u'http://dustycloud.org/'
86 # change a different user than the logged in (should fail with 403)
87 fixture_add_user(username=u"foo",
88 privileges=[u'active'])
89 res = test_app.post(
90 '/u/foo/edit/', {
91 'bio': u'I love toast!',
92 'url': u'http://dustycloud.org/'}, expect_errors=True)
93 assert res.status_int == 403
95 # test changing the bio and the URL inproperly
96 too_long_bio = 150 * 'T' + 150 * 'o' + 150 * 'a' + 150 * 's' + 150* 't'
98 test_app.post(
99 '/u/chris/edit/', {
100 # more than 500 characters
101 'bio': too_long_bio,
102 'url': 'this-is-no-url'})
104 # Check form errors
105 context = template.TEMPLATE_TEST_CONTEXT[
106 'mediagoblin/edit/edit_profile.html']
107 form = context['form']
109 assert form.bio.errors == [
110 u'Field must be between 0 and 500 characters long.']
111 assert form.url.errors == [
112 u'This address contains errors']
114 def test_email_change(self, test_app):
115 self.login(test_app)
117 # Test email already in db
118 template.clear_test_template_context()
119 test_app.post(
120 '/edit/email/', {
121 'new_email': 'chris@example.com',
122 'password': 'toast'})
124 # Check form errors
125 context = template.TEMPLATE_TEST_CONTEXT[
126 'mediagoblin/edit/change_email.html']
127 assert context['form'].new_email.errors == [
128 u'Sorry, a user with that email address already exists.']
130 # Test successful email change
131 template.clear_test_template_context()
132 res = test_app.post(
133 '/edit/email/', {
134 'new_email': 'new@example.com',
135 'password': 'toast'})
136 res.follow()
138 # Correct redirect?
139 assert urlparse.urlsplit(res.location)[2] == '/edit/account/'
141 # Make sure we get email verification and try verifying
142 assert len(mail.EMAIL_TEST_INBOX) == 1
143 message = mail.EMAIL_TEST_INBOX.pop()
144 assert message['To'] == 'new@example.com'
145 email_context = template.TEMPLATE_TEST_CONTEXT[
146 'mediagoblin/edit/verification.txt']
147 assert email_context['verification_url'].encode('ascii') in message.get_payload(decode=True)
149 path = urlparse.urlsplit(email_context['verification_url'])[2]
150 assert path == u'/edit/verify_email/'
152 ## Try verifying with bs verification key, shouldn't work
153 template.clear_test_template_context()
154 res = test_app.get(
155 "/edit/verify_email/?token=total_bs")
156 res.follow()
158 # Correct redirect?
159 assert urlparse.urlsplit(res.location)[2] == '/'
161 # Email shouldn't be saved
162 email_in_db = mg_globals.database.LocalUser.query.filter(
163 LocalUser.email=='new@example.com'
164 ).first()
165 email = LocalUser.query.filter(LocalUser.username=='chris').first().email
166 assert email_in_db is None
167 assert email == 'chris@example.com'
169 # Verify email activation works
170 template.clear_test_template_context()
171 get_params = urlparse.urlsplit(email_context['verification_url'])[3]
172 res = test_app.get('%s?%s' % (path, get_params))
173 res.follow()
175 # New email saved?
176 email = LocalUser.query.filter(LocalUser.username=='chris').first().email
177 assert email == 'new@example.com'
178 # test changing the url inproperly
180 class TestMetaDataEdit:
181 @pytest.fixture(autouse=True)
182 def setup(self, test_app):
183 # set up new user
184 self.user_password = u'toast'
185 self.user = fixture_add_user(
186 password = self.user_password,
187 privileges=[u'active',u'admin']
189 self.test_app = test_app
191 def login(self, test_app):
192 test_app.post(
193 '/auth/login/', {
194 'username': self.user.username,
195 'password': self.user_password})
197 def do_post(self, data, *context_keys, **kwargs):
198 url = kwargs.pop('url', '/submit/')
199 do_follow = kwargs.pop('do_follow', False)
200 template.clear_test_template_context()
201 response = self.test_app.post(url, data, **kwargs)
202 if do_follow:
203 response.follow()
204 context_data = template.TEMPLATE_TEST_CONTEXT
205 for key in context_keys:
206 context_data = context_data[key]
207 return response, context_data
209 def test_edit_metadata(self, test_app):
210 media_entry = fixture_media_entry(uploader=self.user.id,
211 state=u'processed')
212 media_slug = "/u/{username}/m/{media_id}/metadata/".format(
213 username = str(self.user.username),
214 media_id = str(media_entry.id))
216 self.login(test_app)
217 response = test_app.get(media_slug)
218 assert response.status == '200 OK'
219 assert media_entry.media_metadata == {}
220 # First test adding in metadata
221 ################################
222 response, context = self.do_post({
223 "media_metadata-0-identifier":"dc:title",
224 "media_metadata-0-value":"Some title",
225 "media_metadata-1-identifier":"dc:creator",
226 "media_metadata-1-value":"Me"},url=media_slug)
228 media_entry = MediaEntry.query.first()
229 new_metadata = media_entry.media_metadata
230 assert new_metadata != {}
231 assert new_metadata.get("dc:title") == "Some title"
232 assert new_metadata.get("dc:creator") == "Me"
233 # Now test removing the metadata
234 ################################
235 response, context = self.do_post({
236 "media_metadata-0-identifier":"dc:title",
237 "media_metadata-0-value":"Some title"},url=media_slug)
239 media_entry = MediaEntry.query.first()
240 new_metadata = media_entry.media_metadata
241 assert new_metadata.get("dc:title") == "Some title"
242 assert new_metadata.get("dc:creator") is None
243 # Now test adding bad metadata
244 ###############################
245 response, context = self.do_post({
246 "media_metadata-0-identifier":"dc:title",
247 "media_metadata-0-value":"Some title",
248 "media_metadata-1-identifier":"dc:creator",
249 "media_metadata-1-value":"Me",
250 "media_metadata-2-identifier":"dc:created",
251 "media_metadata-2-value":"On the worst day"},url=media_slug)
253 media_entry = MediaEntry.query.first()
254 old_metadata = new_metadata
255 new_metadata = media_entry.media_metadata
256 assert new_metadata == old_metadata
257 context = template.TEMPLATE_TEST_CONTEXT[
258 'mediagoblin/edit/metadata.html']
259 if six.PY2:
260 expected = "u'On the worst day' is not a 'date-time'"
261 else:
262 expected = "'On the worst day' is not a 'date-time'"
263 assert context['form'].errors[
264 'media_metadata'][0]['identifier'][0] == expected