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/>.
21 from nose
.tools
import assert_equal
, assert_true
, assert_false
23 from mediagoblin
.tests
.tools
import setup_fresh_app
, get_test_app
, \
25 from mediagoblin
import mg_globals
26 from mediagoblin
.tools
import template
, common
28 GOOD_JPG
= pkg_resources
.resource_filename(
29 'mediagoblin.tests', 'test_submission/good.jpg')
30 GOOD_PNG
= pkg_resources
.resource_filename(
31 'mediagoblin.tests', 'test_submission/good.png')
32 EVIL_FILE
= pkg_resources
.resource_filename(
33 'mediagoblin.tests', 'test_submission/evil')
34 EVIL_JPG
= pkg_resources
.resource_filename(
35 'mediagoblin.tests', 'test_submission/evil.jpg')
36 EVIL_PNG
= pkg_resources
.resource_filename(
37 'mediagoblin.tests', 'test_submission/evil.png')
39 GOOD_TAG_STRING
= 'yin,yang'
40 BAD_TAG_STRING
= 'rage,' + 'f' * 26 + 'u' * 26
45 self
.test_app
= get_test_app()
47 # TODO: Possibly abstract into a decorator like:
48 # @as_authenticated_user('chris')
49 test_user
= fixture_add_user()
51 self
.test_user
= test_user
62 self
.test_app
.get('/auth/logout/')
64 def test_missing_fields(self
):
67 template
.clear_test_template_context()
68 response
= self
.test_app
.post(
70 context
= template
.TEMPLATE_TEST_CONTEXT
['mediagoblin/submit/start.html']
71 form
= context
['submit_form']
72 assert form
.file.errors
== [u
'You must provide a file.']
76 template
.clear_test_template_context()
77 response
= self
.test_app
.post(
79 'title': 'test title'})
80 context
= template
.TEMPLATE_TEST_CONTEXT
['mediagoblin/submit/start.html']
81 form
= context
['submit_form']
82 assert form
.file.errors
== [u
'You must provide a file.']
85 def test_normal_uploads(self
):
88 template
.clear_test_template_context()
89 response
= self
.test_app
.post(
91 'title': 'Normal upload 1'
95 # User should be redirected
98 urlparse
.urlsplit(response
.location
)[2],
100 assert template
.TEMPLATE_TEST_CONTEXT
.has_key(
101 'mediagoblin/user_pages/user.html')
103 # Make sure the media view is at least reachable, logged in...
104 self
.test_app
.get('/u/chris/m/normal-upload-1/')
105 # ... and logged out too.
107 self
.test_app
.get('/u/chris/m/normal-upload-1/')
108 # Log back in for the remaining tests.
113 template
.clear_test_template_context()
114 response
= self
.test_app
.post(
116 'title': 'Normal upload 2'
122 urlparse
.urlsplit(response
.location
)[2],
124 assert template
.TEMPLATE_TEST_CONTEXT
.has_key(
125 'mediagoblin/user_pages/user.html')
130 template
.clear_test_template_context()
131 response
= self
.test_app
.post(
133 'title': 'Balanced Goblin',
134 'tags': GOOD_TAG_STRING
138 # New media entry with correct tags should be created
140 context
= template
.TEMPLATE_TEST_CONTEXT
['mediagoblin/user_pages/user.html']
141 request
= context
['request']
142 media
= request
.db
.MediaEntry
.find({'title': 'Balanced Goblin'})[0]
143 assert_equal(media
.tags
,
144 [{'name': u
'yin', 'slug': u
'yin'},
145 {'name': u
'yang', 'slug': u
'yang'}])
147 # Test tags that are too long
149 template
.clear_test_template_context()
150 response
= self
.test_app
.post(
152 'title': 'Balanced Goblin',
153 'tags': BAD_TAG_STRING
157 # Too long error should be raised
158 context
= template
.TEMPLATE_TEST_CONTEXT
['mediagoblin/submit/start.html']
159 form
= context
['submit_form']
160 assert form
.tags
.errors
== [
161 u
'Tags must be shorter than 50 characters. Tags that are too long'\
162 ': ffffffffffffffffffffffffffuuuuuuuuuuuuuuuuuuuuuuuuuu']
164 def test_delete(self
):
165 template
.clear_test_template_context()
166 response
= self
.test_app
.post(
168 'title': 'Balanced Goblin',
175 request
= template
.TEMPLATE_TEST_CONTEXT
[
176 'mediagoblin/user_pages/user.html']['request']
178 media
= request
.db
.MediaEntry
.find({'title': 'Balanced Goblin'})[0]
180 # Does media entry exist?
183 # Do not confirm deletion
184 # ---------------------------------------------------
185 response
= self
.test_app
.post(
186 request
.urlgen('mediagoblin.user_pages.media_confirm_delete',
187 # No work: user=media.uploader().username,
188 user
=self
.test_user
.username
,
190 # no value means no confirm
195 request
= template
.TEMPLATE_TEST_CONTEXT
[
196 'mediagoblin/user_pages/user.html']['request']
198 media
= request
.db
.MediaEntry
.find({'title': 'Balanced Goblin'})[0]
200 # Does media entry still exist?
204 # ---------------------------------------------------
205 response
= self
.test_app
.post(
206 request
.urlgen('mediagoblin.user_pages.media_confirm_delete',
207 # No work: user=media.uploader().username,
208 user
=self
.test_user
.username
,
214 request
= template
.TEMPLATE_TEST_CONTEXT
[
215 'mediagoblin/user_pages/user.html']['request']
217 # Does media entry still exist?
219 request
.db
.MediaEntry
.find(
220 {'_id': media
._id
}).count())
222 def test_malicious_uploads(self
):
223 # Test non-suppoerted file with non-supported extension
224 # -----------------------------------------------------
225 template
.clear_test_template_context()
226 response
= self
.test_app
.post(
228 'title': 'Malicious Upload 1'
232 context
= template
.TEMPLATE_TEST_CONTEXT
['mediagoblin/submit/start.html']
233 form
= context
['submit_form']
234 assert re
.match(r
'^Could not extract any file extension from ".*?"$', str(form
.file.errors
[0]))
235 assert len(form
.file.errors
) == 1
237 # NOTE: The following 2 tests will ultimately fail, but they
238 # *will* pass the initial form submission step. Instead,
239 # they'll be caught as failures during the processing step.
241 # Test non-supported file with .jpg extension
242 # -------------------------------------------
243 template
.clear_test_template_context()
244 response
= self
.test_app
.post(
246 'title': 'Malicious Upload 2'
251 urlparse
.urlsplit(response
.location
)[2],
254 entry
= mg_globals
.database
.MediaEntry
.find_one(
255 {'title': 'Malicious Upload 2'})
256 assert_equal(entry
.state
, 'failed')
259 u
'mediagoblin.processing:BadMediaFail')
261 # Test non-supported file with .png extension
262 # -------------------------------------------
263 template
.clear_test_template_context()
264 response
= self
.test_app
.post(
266 'title': 'Malicious Upload 3'
271 urlparse
.urlsplit(response
.location
)[2],
274 entry
= mg_globals
.database
.MediaEntry
.find_one(
275 {'title': 'Malicious Upload 3'})
276 assert_equal(entry
.state
, 'failed')
279 u
'mediagoblin.processing:BadMediaFail')