Merge branch Generic Foreign Key changes
[mediagoblin.git] / mediagoblin / tests / test_edit.py
CommitLineData
c8ccd23e 1# GNU MediaGoblin -- federated, autonomous media hosting
cf29e8a8 2# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
c8ccd23e
JK
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
6430ae97 17import six
9459fa3c 18import six.moves.urllib.parse as urlparse
f6bad0eb 19import pytest
a3b98853 20
c8ccd23e 21from mediagoblin import mg_globals
414c682f 22from mediagoblin.db.models import User, MediaEntry
23from mediagoblin.tests.tools import fixture_add_user, fixture_media_entry
b194f29f 24from mediagoblin import auth
377db0e7 25from mediagoblin.tools import template, mail
fa723291 26
c8ccd23e 27
a3b98853 28class TestUserEdit(object):
958080be 29 def setup(self):
a3b98853
SS
30 # set up new user
31 self.user_password = u'toast'
2c901db0 32 self.user = fixture_add_user(password = self.user_password,
33 privileges=[u'active'])
a3b98853 34
5c2ece74
CAW
35 def login(self, test_app):
36 test_app.post(
a3b98853
SS
37 '/auth/login/', {
38 'username': self.user.username,
39 'password': self.user_password})
40
41
5c2ece74 42 def test_user_deletion(self, test_app):
6deb589d 43 """Delete user via web interface"""
5c2ece74
CAW
44 self.login(test_app)
45
6deb589d
SS
46 # Make sure user exists
47 assert User.query.filter_by(username=u'chris').first()
48
5c2ece74 49 res = test_app.post('/edit/account/delete/', {'confirmed': 'y'})
6deb589d
SS
50
51 # Make sure user has been deleted
52 assert User.query.filter_by(username=u'chris').first() == None
53
54 #TODO: make sure all corresponding items comments etc have been
55 # deleted too. Perhaps in submission test?
56
57 #Restore user at end of test
2c901db0 58 self.user = fixture_add_user(password = self.user_password,
59 privileges=[u'active'])
5c2ece74 60 self.login(test_app)
6deb589d
SS
61
62
5c2ece74 63 def test_change_bio_url(self, test_app):
a3b98853 64 """Test changing bio and URL"""
5c2ece74
CAW
65 self.login(test_app)
66
a3b98853 67 # Test if legacy profile editing URL redirects correctly
5c2ece74 68 res = test_app.post(
a3b98853
SS
69 '/edit/profile/', {
70 'bio': u'I love toast!',
71 'url': u'http://dustycloud.org/'}, expect_errors=True)
72
73 # Should redirect to /u/chris/edit/
7d503a89 74 assert res.status_int == 302
a3b98853
SS
75 assert res.headers['Location'].endswith("/u/chris/edit/")
76
5c2ece74 77 res = test_app.post(
a3b98853
SS
78 '/u/chris/edit/', {
79 'bio': u'I love toast!',
80 'url': u'http://dustycloud.org/'})
81
82 test_user = User.query.filter_by(username=u'chris').first()
7d503a89
CAW
83 assert test_user.bio == u'I love toast!'
84 assert test_user.url == u'http://dustycloud.org/'
a3b98853
SS
85
86 # change a different user than the logged in (should fail with 403)
2c901db0 87 fixture_add_user(username=u"foo",
88 privileges=[u'active'])
5c2ece74 89 res = test_app.post(
a3b98853
SS
90 '/u/foo/edit/', {
91 'bio': u'I love toast!',
92 'url': u'http://dustycloud.org/'}, expect_errors=True)
7d503a89 93 assert res.status_int == 403
a3b98853
SS
94
95 # test changing the bio and the URL inproperly
96 too_long_bio = 150 * 'T' + 150 * 'o' + 150 * 'a' + 150 * 's' + 150* 't'
97
5c2ece74 98 test_app.post(
a3b98853
SS
99 '/u/chris/edit/', {
100 # more than 500 characters
101 'bio': too_long_bio,
102 'url': 'this-is-no-url'})
103
104 # Check form errors
7d503a89
CAW
105 context = template.TEMPLATE_TEST_CONTEXT[
106 'mediagoblin/edit/edit_profile.html']
a3b98853
SS
107 form = context['form']
108
7d503a89
CAW
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']
a3b98853 113
377db0e7
RE
114 def test_email_change(self, test_app):
115 self.login(test_app)
116
377db0e7
RE
117 # Test email already in db
118 template.clear_test_template_context()
119 test_app.post(
4710097b 120 '/edit/email/', {
377db0e7
RE
121 'new_email': 'chris@example.com',
122 'password': 'toast'})
123
124 # Check form errors
125 context = template.TEMPLATE_TEST_CONTEXT[
4710097b 126 'mediagoblin/edit/change_email.html']
377db0e7
RE
127 assert context['form'].new_email.errors == [
128 u'Sorry, a user with that email address already exists.']
129
377db0e7
RE
130 # Test successful email change
131 template.clear_test_template_context()
132 res = test_app.post(
4710097b 133 '/edit/email/', {
377db0e7
RE
134 'new_email': 'new@example.com',
135 'password': 'toast'})
136 res.follow()
137
138 # Correct redirect?
4710097b 139 assert urlparse.urlsplit(res.location)[2] == '/edit/account/'
377db0e7
RE
140
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']
cda3055b 147 assert email_context['verification_url'].encode('ascii') in message.get_payload(decode=True)
377db0e7
RE
148
149 path = urlparse.urlsplit(email_context['verification_url'])[2]
150 assert path == u'/edit/verify_email/'
151
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()
157
158 # Correct redirect?
159 assert urlparse.urlsplit(res.location)[2] == '/'
160
161 # Email shouldn't be saved
44082b12
RE
162 email_in_db = mg_globals.database.User.query.filter_by(
163 email='new@example.com').first()
377db0e7
RE
164 email = User.query.filter_by(username='chris').first().email
165 assert email_in_db is None
166 assert email == 'chris@example.com'
167
168 # Verify email activation works
169 template.clear_test_template_context()
170 get_params = urlparse.urlsplit(email_context['verification_url'])[3]
171 res = test_app.get('%s?%s' % (path, get_params))
172 res.follow()
173
174 # New email saved?
175 email = User.query.filter_by(username='chris').first().email
176 assert email == 'new@example.com'
a3b98853 177# test changing the url inproperly
414c682f 178
179class TestMetaDataEdit:
180 @pytest.fixture(autouse=True)
181 def setup(self, test_app):
182 # set up new user
183 self.user_password = u'toast'
184 self.user = fixture_add_user(password = self.user_password,
185 privileges=[u'active',u'admin'])
186 self.test_app = test_app
187
188 def login(self, test_app):
189 test_app.post(
190 '/auth/login/', {
191 'username': self.user.username,
192 'password': self.user_password})
193
194 def do_post(self, data, *context_keys, **kwargs):
195 url = kwargs.pop('url', '/submit/')
196 do_follow = kwargs.pop('do_follow', False)
197 template.clear_test_template_context()
198 response = self.test_app.post(url, data, **kwargs)
199 if do_follow:
200 response.follow()
201 context_data = template.TEMPLATE_TEST_CONTEXT
202 for key in context_keys:
203 context_data = context_data[key]
204 return response, context_data
205
206 def test_edit_metadata(self, test_app):
207 media_entry = fixture_media_entry(uploader=self.user.id,
208 state=u'processed')
209 media_slug = "/u/{username}/m/{media_id}/metadata/".format(
210 username = str(self.user.username),
211 media_id = str(media_entry.id))
212
213 self.login(test_app)
214 response = test_app.get(media_slug)
215 assert response.status == '200 OK'
216 assert media_entry.media_metadata == {}
217 # First test adding in metadata
218 ################################
219 response, context = self.do_post({
220 "media_metadata-0-identifier":"dc:title",
221 "media_metadata-0-value":"Some title",
222 "media_metadata-1-identifier":"dc:creator",
223 "media_metadata-1-value":"Me"},url=media_slug)
224
225 media_entry = MediaEntry.query.first()
226 new_metadata = media_entry.media_metadata
227 assert new_metadata != {}
228 assert new_metadata.get("dc:title") == "Some title"
229 assert new_metadata.get("dc:creator") == "Me"
230 # Now test removing the metadata
231 ################################
232 response, context = self.do_post({
233 "media_metadata-0-identifier":"dc:title",
234 "media_metadata-0-value":"Some title"},url=media_slug)
235
236 media_entry = MediaEntry.query.first()
237 new_metadata = media_entry.media_metadata
238 assert new_metadata.get("dc:title") == "Some title"
239 assert new_metadata.get("dc:creator") is None
240 # Now test adding bad metadata
241 ###############################
242 response, context = self.do_post({
243 "media_metadata-0-identifier":"dc:title",
244 "media_metadata-0-value":"Some title",
245 "media_metadata-1-identifier":"dc:creator",
246 "media_metadata-1-value":"Me",
247 "media_metadata-2-identifier":"dc:created",
248 "media_metadata-2-value":"On the worst day"},url=media_slug)
249
250 media_entry = MediaEntry.query.first()
251 old_metadata = new_metadata
252 new_metadata = media_entry.media_metadata
253 assert new_metadata == old_metadata
dd41141d
CAW
254 context = template.TEMPLATE_TEST_CONTEXT[
255 'mediagoblin/edit/metadata.html']
6430ae97
CAW
256 if six.PY2:
257 expected = "u'On the worst day' is not a 'date-time'"
258 else:
259 expected = "'On the worst day' is not a 'date-time'"
260 assert context['form'].errors[
261 'media_metadata'][0]['identifier'][0] == expected