2 # GNU MediaGoblin -- federated, autonomous media hosting
3 # Copyright (C) 2011 MediaGoblin contributors. See AUTHORS.
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU Affero General Public License for more details.
15 # You should have received a copy of the GNU Affero General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 from nose
.tools
import assert_equal
, assert_true
, assert_false
24 from mediagoblin
.tests
.tools
import setup_fresh_app
, get_test_app
, \
26 from mediagoblin
import mg_globals
27 from mediagoblin
.tools
import template
, common
29 GOOD_JPG
= pkg_resources
.resource_filename(
30 'mediagoblin.tests', 'test_submission/good.jpg')
31 GOOD_PNG
= pkg_resources
.resource_filename(
32 'mediagoblin.tests', 'test_submission/good.png')
33 EVIL_FILE
= pkg_resources
.resource_filename(
34 'mediagoblin.tests', 'test_submission/evil')
35 EVIL_JPG
= pkg_resources
.resource_filename(
36 'mediagoblin.tests', 'test_submission/evil.jpg')
37 EVIL_PNG
= pkg_resources
.resource_filename(
38 'mediagoblin.tests', 'test_submission/evil.png')
40 GOOD_TAG_STRING
= 'yin,yang'
41 BAD_TAG_STRING
= 'rage,' + 'f' * 26 + 'u' * 26
46 self
.test_app
= get_test_app()
48 # TODO: Possibly abstract into a decorator like:
49 # @as_authenticated_user('chris')
50 test_user
= fixture_add_user()
52 self
.test_user
= test_user
63 self
.test_app
.get('/auth/logout/')
65 def test_missing_fields(self
):
68 template
.clear_test_template_context()
69 response
= self
.test_app
.post(
71 context
= template
.TEMPLATE_TEST_CONTEXT
['mediagoblin/submit/start.html']
72 form
= context
['submit_form']
73 assert form
.file.errors
== [u
'You must provide a file.']
77 template
.clear_test_template_context()
78 response
= self
.test_app
.post(
80 'title': 'test title'})
81 context
= template
.TEMPLATE_TEST_CONTEXT
['mediagoblin/submit/start.html']
82 form
= context
['submit_form']
83 assert form
.file.errors
== [u
'You must provide a file.']
86 def test_normal_uploads(self
):
89 template
.clear_test_template_context()
90 response
= self
.test_app
.post(
92 'title': 'Normal upload 1'
96 # User should be redirected
99 urlparse
.urlsplit(response
.location
)[2],
101 assert template
.TEMPLATE_TEST_CONTEXT
.has_key(
102 'mediagoblin/user_pages/user.html')
104 # Make sure the media view is at least reachable, logged in...
105 self
.test_app
.get('/u/chris/m/normal-upload-1/')
106 # ... and logged out too.
108 self
.test_app
.get('/u/chris/m/normal-upload-1/')
109 # Log back in for the remaining tests.
114 template
.clear_test_template_context()
115 response
= self
.test_app
.post(
117 'title': 'Normal upload 2'
123 urlparse
.urlsplit(response
.location
)[2],
125 assert template
.TEMPLATE_TEST_CONTEXT
.has_key(
126 'mediagoblin/user_pages/user.html')
131 template
.clear_test_template_context()
132 response
= self
.test_app
.post(
134 'title': 'Balanced Goblin',
135 'tags': GOOD_TAG_STRING
139 # New media entry with correct tags should be created
141 context
= template
.TEMPLATE_TEST_CONTEXT
['mediagoblin/user_pages/user.html']
142 request
= context
['request']
143 media
= request
.db
.MediaEntry
.find({'title': 'Balanced Goblin'})[0]
144 assert_equal(media
['tags'],
145 [{'name': u
'yin', 'slug': u
'yin'},
146 {'name': u
'yang', 'slug': u
'yang'}])
148 # Test tags that are too long
150 template
.clear_test_template_context()
151 response
= self
.test_app
.post(
153 'title': 'Balanced Goblin',
154 'tags': BAD_TAG_STRING
158 # Too long error should be raised
159 context
= template
.TEMPLATE_TEST_CONTEXT
['mediagoblin/submit/start.html']
160 form
= context
['submit_form']
161 assert form
.tags
.errors
== [
162 u
'Tags must be shorter than 50 characters. Tags that are too long'\
163 ': ffffffffffffffffffffffffffuuuuuuuuuuuuuuuuuuuuuuuuuu']
165 def test_delete(self
):
166 template
.clear_test_template_context()
167 response
= self
.test_app
.post(
169 'title': 'Balanced Goblin',
176 request
= template
.TEMPLATE_TEST_CONTEXT
[
177 'mediagoblin/user_pages/user.html']['request']
179 media
= request
.db
.MediaEntry
.find({'title': 'Balanced Goblin'})[0]
181 # Does media entry exist?
184 # Do not confirm deletion
185 # ---------------------------------------------------
186 response
= self
.test_app
.post(
187 request
.urlgen('mediagoblin.user_pages.media_confirm_delete',
188 # No work: user=media.uploader().username,
189 user
=self
.test_user
.username
,
191 # no value means no confirm
196 request
= template
.TEMPLATE_TEST_CONTEXT
[
197 'mediagoblin/user_pages/user.html']['request']
199 media
= request
.db
.MediaEntry
.find({'title': 'Balanced Goblin'})[0]
201 # Does media entry still exist?
205 # ---------------------------------------------------
206 response
= self
.test_app
.post(
207 request
.urlgen('mediagoblin.user_pages.media_confirm_delete',
208 # No work: user=media.uploader().username,
209 user
=self
.test_user
.username
,
215 request
= template
.TEMPLATE_TEST_CONTEXT
[
216 'mediagoblin/user_pages/user.html']['request']
218 # Does media entry still exist?
220 request
.db
.MediaEntry
.find(
221 {'_id': media
._id
}).count())
223 def test_malicious_uploads(self
):
224 # Test non-suppoerted file with non-supported extension
225 # -----------------------------------------------------
226 template
.clear_test_template_context()
227 response
= self
.test_app
.post(
229 'title': 'Malicious Upload 1'
233 context
= template
.TEMPLATE_TEST_CONTEXT
['mediagoblin/submit/start.html']
234 form
= context
['submit_form']
235 assert re
.match(r
'^Could not extract any file extension from ".*?"$', str(form
.file.errors
[0]))
236 assert len(form
.file.errors
) == 1
238 # NOTE: The following 2 tests will ultimately fail, but they
239 # *will* pass the initial form submission step. Instead,
240 # they'll be caught as failures during the processing step.
242 # Test non-supported file with .jpg extension
243 # -------------------------------------------
244 template
.clear_test_template_context()
245 response
= self
.test_app
.post(
247 'title': 'Malicious Upload 2'
252 urlparse
.urlsplit(response
.location
)[2],
255 entry
= mg_globals
.database
.MediaEntry
.find_one(
256 {'title': 'Malicious Upload 2'})
257 assert_equal(entry
.state
, 'failed')
260 u
'mediagoblin.processing:BadMediaFail')
262 # Test non-supported file with .png extension
263 # -------------------------------------------
264 template
.clear_test_template_context()
265 response
= self
.test_app
.post(
267 'title': 'Malicious Upload 3'
272 urlparse
.urlsplit(response
.location
)[2],
275 entry
= mg_globals
.database
.MediaEntry
.find_one(
276 {'title': 'Malicious Upload 3'})
277 assert_equal(entry
.state
, 'failed')
280 u
'mediagoblin.processing:BadMediaFail')