1 # GNU MediaGoblin -- federated, autonomous media hosting
2 # Copyright (C) 2011 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/>.
20 from nose
.tools
import assert_equal
, assert_true
, assert_false
22 from mediagoblin
.auth
import lib
as auth_lib
23 from mediagoblin
.tests
.tools
import setup_fresh_app
, get_test_app
24 from mediagoblin
import mg_globals
25 from mediagoblin
.tools
import template
, common
27 GOOD_JPG
= pkg_resources
.resource_filename(
28 'mediagoblin.tests', 'test_submission/good.jpg')
29 GOOD_PNG
= pkg_resources
.resource_filename(
30 'mediagoblin.tests', 'test_submission/good.png')
31 EVIL_FILE
= pkg_resources
.resource_filename(
32 'mediagoblin.tests', 'test_submission/evil')
33 EVIL_JPG
= pkg_resources
.resource_filename(
34 'mediagoblin.tests', 'test_submission/evil.jpg')
35 EVIL_PNG
= pkg_resources
.resource_filename(
36 'mediagoblin.tests', 'test_submission/evil.png')
38 GOOD_TAG_STRING
= 'yin,yang'
39 BAD_TAG_STRING
= 'rage,' + 'f' * 26 + 'u' * 26
44 self
.test_app
= get_test_app()
46 # TODO: Possibly abstract into a decorator like:
47 # @as_authenticated_user('chris')
48 test_user
= mg_globals
.database
.User()
49 test_user
['username'] = u
'chris'
50 test_user
['email'] = u
'chris@example.com'
51 test_user
['email_verified'] = True
52 test_user
['status'] = u
'active'
53 test_user
['pw_hash'] = auth_lib
.bcrypt_gen_password_hash('toast')
56 self
.test_user
= test_user
63 def test_missing_fields(self
):
66 template
.clear_test_template_context()
67 response
= self
.test_app
.post(
69 context
= template
.TEMPLATE_TEST_CONTEXT
['mediagoblin/submit/start.html']
70 form
= context
['submit_form']
71 assert form
.file.errors
== [u
'You must provide a file.']
75 template
.clear_test_template_context()
76 response
= self
.test_app
.post(
78 'title': 'test title'})
79 context
= template
.TEMPLATE_TEST_CONTEXT
['mediagoblin/submit/start.html']
80 form
= context
['submit_form']
81 assert form
.file.errors
== [u
'You must provide a file.']
84 def test_normal_uploads(self
):
87 template
.clear_test_template_context()
88 response
= self
.test_app
.post(
90 'title': 'Normal upload 1'
94 # User should be redirected
97 urlparse
.urlsplit(response
.location
)[2],
99 assert template
.TEMPLATE_TEST_CONTEXT
.has_key(
100 'mediagoblin/user_pages/user.html')
104 template
.clear_test_template_context()
105 response
= self
.test_app
.post(
107 'title': 'Normal upload 2'
113 urlparse
.urlsplit(response
.location
)[2],
115 assert template
.TEMPLATE_TEST_CONTEXT
.has_key(
116 'mediagoblin/user_pages/user.html')
121 template
.clear_test_template_context()
122 response
= self
.test_app
.post(
124 'title': 'Balanced Goblin',
125 'tags': GOOD_TAG_STRING
129 # New media entry with correct tags should be created
131 context
= template
.TEMPLATE_TEST_CONTEXT
['mediagoblin/user_pages/user.html']
132 request
= context
['request']
133 media
= request
.db
.MediaEntry
.find({'title': 'Balanced Goblin'})[0]
134 assert_equal(media
['tags'],
135 [{'name': u
'yin', 'slug': u
'yin'},
136 {'name': u
'yang', 'slug': u
'yang'}])
138 # Test tags that are too long
140 template
.clear_test_template_context()
141 response
= self
.test_app
.post(
143 'title': 'Balanced Goblin',
144 'tags': BAD_TAG_STRING
148 # Too long error should be raised
149 context
= template
.TEMPLATE_TEST_CONTEXT
['mediagoblin/submit/start.html']
150 form
= context
['submit_form']
151 assert form
.tags
.errors
== [
152 u
'Tags must be shorter than 50 characters. Tags that are too long'\
153 ': ffffffffffffffffffffffffffuuuuuuuuuuuuuuuuuuuuuuuuuu']
155 def test_delete(self
):
156 template
.clear_test_template_context()
157 response
= self
.test_app
.post(
159 'title': 'Balanced Goblin',
166 request
= template
.TEMPLATE_TEST_CONTEXT
[
167 'mediagoblin/user_pages/user.html']['request']
169 media
= request
.db
.MediaEntry
.find({'title': 'Balanced Goblin'})[0]
171 # Does media entry exist?
174 # Do not confirm deletion
175 # ---------------------------------------------------
176 response
= self
.test_app
.post(
177 request
.urlgen('mediagoblin.user_pages.media_confirm_delete',
178 # No work: user=media.uploader().username,
179 user
=self
.test_user
['username'],
181 # no value means no confirm
186 request
= template
.TEMPLATE_TEST_CONTEXT
[
187 'mediagoblin/user_pages/user.html']['request']
189 media
= request
.db
.MediaEntry
.find({'title': 'Balanced Goblin'})[0]
191 # Does media entry still exist?
195 # ---------------------------------------------------
196 response
= self
.test_app
.post(
197 request
.urlgen('mediagoblin.user_pages.media_confirm_delete',
198 # No work: user=media.uploader().username,
199 user
=self
.test_user
['username'],
205 request
= template
.TEMPLATE_TEST_CONTEXT
[
206 'mediagoblin/user_pages/user.html']['request']
208 # Does media entry still exist?
210 request
.db
.MediaEntry
.find(
211 {'_id': media
._id
}).count())
213 def test_malicious_uploads(self
):
214 # Test non-suppoerted file with non-supported extension
215 # -----------------------------------------------------
216 template
.clear_test_template_context()
217 response
= self
.test_app
.post(
219 'title': 'Malicious Upload 1'
223 context
= template
.TEMPLATE_TEST_CONTEXT
['mediagoblin/submit/start.html']
224 form
= context
['submit_form']
225 assert form
.file.errors
== [u
'Invalid file type.']
227 # NOTE: The following 2 tests will ultimately fail, but they
228 # *will* pass the initial form submission step. Instead,
229 # they'll be caught as failures during the processing step.
231 # Test non-supported file with .jpg extension
232 # -------------------------------------------
233 template
.clear_test_template_context()
234 response
= self
.test_app
.post(
236 'title': 'Malicious Upload 2'
241 urlparse
.urlsplit(response
.location
)[2],
244 entry
= mg_globals
.database
.MediaEntry
.find_one(
245 {'title': 'Malicious Upload 2'})
246 assert_equal(entry
['state'], 'failed')
249 u
'mediagoblin.processing:BadMediaFail')
251 # Test non-supported file with .png extension
252 # -------------------------------------------
253 template
.clear_test_template_context()
254 response
= self
.test_app
.post(
256 'title': 'Malicious Upload 3'
261 urlparse
.urlsplit(response
.location
)[2],
264 entry
= mg_globals
.database
.MediaEntry
.find_one(
265 {'title': 'Malicious Upload 3'})
266 assert_equal(entry
['state'], 'failed')
269 u
'mediagoblin.processing:BadMediaFail')