Dot-Notation for Users.fp_token_expire
[mediagoblin.git] / mediagoblin / tests / test_submission.py
... / ...
CommitLineData
1# GNU MediaGoblin -- federated, autonomous media hosting
2# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS.
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
17import urlparse
18import pkg_resources
19
20from nose.tools import assert_equal, assert_true, assert_false
21
22from mediagoblin.tests.tools import setup_fresh_app, get_test_app, \
23 fixture_add_user
24from mediagoblin import mg_globals
25from mediagoblin.tools import template, common
26
27GOOD_JPG = pkg_resources.resource_filename(
28 'mediagoblin.tests', 'test_submission/good.jpg')
29GOOD_PNG = pkg_resources.resource_filename(
30 'mediagoblin.tests', 'test_submission/good.png')
31EVIL_FILE = pkg_resources.resource_filename(
32 'mediagoblin.tests', 'test_submission/evil')
33EVIL_JPG = pkg_resources.resource_filename(
34 'mediagoblin.tests', 'test_submission/evil.jpg')
35EVIL_PNG = pkg_resources.resource_filename(
36 'mediagoblin.tests', 'test_submission/evil.png')
37
38GOOD_TAG_STRING = 'yin,yang'
39BAD_TAG_STRING = 'rage,' + 'f' * 26 + 'u' * 26
40
41
42class TestSubmission:
43 def setUp(self):
44 self.test_app = get_test_app()
45
46 # TODO: Possibly abstract into a decorator like:
47 # @as_authenticated_user('chris')
48 test_user = fixture_add_user()
49
50 self.test_user = test_user
51
52 self.test_app.post(
53 '/auth/login/', {
54 'username': u'chris',
55 'password': 'toast'})
56
57 def test_missing_fields(self):
58 # Test blank form
59 # ---------------
60 template.clear_test_template_context()
61 response = self.test_app.post(
62 '/submit/', {})
63 context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/submit/start.html']
64 form = context['submit_form']
65 assert form.file.errors == [u'You must provide a file.']
66
67 # Test blank file
68 # ---------------
69 template.clear_test_template_context()
70 response = self.test_app.post(
71 '/submit/', {
72 'title': 'test title'})
73 context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/submit/start.html']
74 form = context['submit_form']
75 assert form.file.errors == [u'You must provide a file.']
76
77
78 def test_normal_uploads(self):
79 # Test JPG
80 # --------
81 template.clear_test_template_context()
82 response = self.test_app.post(
83 '/submit/', {
84 'title': 'Normal upload 1'
85 }, upload_files=[(
86 'file', GOOD_JPG)])
87
88 # User should be redirected
89 response.follow()
90 assert_equal(
91 urlparse.urlsplit(response.location)[2],
92 '/u/chris/')
93 assert template.TEMPLATE_TEST_CONTEXT.has_key(
94 'mediagoblin/user_pages/user.html')
95
96 # Test PNG
97 # --------
98 template.clear_test_template_context()
99 response = self.test_app.post(
100 '/submit/', {
101 'title': 'Normal upload 2'
102 }, upload_files=[(
103 'file', GOOD_PNG)])
104
105 response.follow()
106 assert_equal(
107 urlparse.urlsplit(response.location)[2],
108 '/u/chris/')
109 assert template.TEMPLATE_TEST_CONTEXT.has_key(
110 'mediagoblin/user_pages/user.html')
111
112 def test_tags(self):
113 # Good tag string
114 # --------
115 template.clear_test_template_context()
116 response = self.test_app.post(
117 '/submit/', {
118 'title': 'Balanced Goblin',
119 'tags': GOOD_TAG_STRING
120 }, upload_files=[(
121 'file', GOOD_JPG)])
122
123 # New media entry with correct tags should be created
124 response.follow()
125 context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/user_pages/user.html']
126 request = context['request']
127 media = request.db.MediaEntry.find({'title': 'Balanced Goblin'})[0]
128 assert_equal(media['tags'],
129 [{'name': u'yin', 'slug': u'yin'},
130 {'name': u'yang', 'slug': u'yang'}])
131
132 # Test tags that are too long
133 # ---------------
134 template.clear_test_template_context()
135 response = self.test_app.post(
136 '/submit/', {
137 'title': 'Balanced Goblin',
138 'tags': BAD_TAG_STRING
139 }, upload_files=[(
140 'file', GOOD_JPG)])
141
142 # Too long error should be raised
143 context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/submit/start.html']
144 form = context['submit_form']
145 assert form.tags.errors == [
146 u'Tags must be shorter than 50 characters. Tags that are too long'\
147 ': ffffffffffffffffffffffffffuuuuuuuuuuuuuuuuuuuuuuuuuu']
148
149 def test_delete(self):
150 template.clear_test_template_context()
151 response = self.test_app.post(
152 '/submit/', {
153 'title': 'Balanced Goblin',
154 }, upload_files=[(
155 'file', GOOD_JPG)])
156
157 # Post image
158 response.follow()
159
160 request = template.TEMPLATE_TEST_CONTEXT[
161 'mediagoblin/user_pages/user.html']['request']
162
163 media = request.db.MediaEntry.find({'title': 'Balanced Goblin'})[0]
164
165 # Does media entry exist?
166 assert_true(media)
167
168 # Do not confirm deletion
169 # ---------------------------------------------------
170 response = self.test_app.post(
171 request.urlgen('mediagoblin.user_pages.media_confirm_delete',
172 # No work: user=media.uploader().username,
173 user=self.test_user.username,
174 media=media._id),
175 # no value means no confirm
176 {})
177
178 response.follow()
179
180 request = template.TEMPLATE_TEST_CONTEXT[
181 'mediagoblin/user_pages/user.html']['request']
182
183 media = request.db.MediaEntry.find({'title': 'Balanced Goblin'})[0]
184
185 # Does media entry still exist?
186 assert_true(media)
187
188 # Confirm deletion
189 # ---------------------------------------------------
190 response = self.test_app.post(
191 request.urlgen('mediagoblin.user_pages.media_confirm_delete',
192 # No work: user=media.uploader().username,
193 user=self.test_user.username,
194 media=media._id),
195 {'confirm': 'y'})
196
197 response.follow()
198
199 request = template.TEMPLATE_TEST_CONTEXT[
200 'mediagoblin/user_pages/user.html']['request']
201
202 # Does media entry still exist?
203 assert_false(
204 request.db.MediaEntry.find(
205 {'_id': media._id}).count())
206
207 def test_malicious_uploads(self):
208 # Test non-suppoerted file with non-supported extension
209 # -----------------------------------------------------
210 template.clear_test_template_context()
211 response = self.test_app.post(
212 '/submit/', {
213 'title': 'Malicious Upload 1'
214 }, upload_files=[(
215 'file', EVIL_FILE)])
216
217 context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/submit/start.html']
218 form = context['submit_form']
219 assert form.file.errors == [u'Invalid file type.']
220
221 # NOTE: The following 2 tests will ultimately fail, but they
222 # *will* pass the initial form submission step. Instead,
223 # they'll be caught as failures during the processing step.
224
225 # Test non-supported file with .jpg extension
226 # -------------------------------------------
227 template.clear_test_template_context()
228 response = self.test_app.post(
229 '/submit/', {
230 'title': 'Malicious Upload 2'
231 }, upload_files=[(
232 'file', EVIL_JPG)])
233 response.follow()
234 assert_equal(
235 urlparse.urlsplit(response.location)[2],
236 '/u/chris/')
237
238 entry = mg_globals.database.MediaEntry.find_one(
239 {'title': 'Malicious Upload 2'})
240 assert_equal(entry['state'], 'failed')
241 assert_equal(
242 entry['fail_error'],
243 u'mediagoblin.processing:BadMediaFail')
244
245 # Test non-supported file with .png extension
246 # -------------------------------------------
247 template.clear_test_template_context()
248 response = self.test_app.post(
249 '/submit/', {
250 'title': 'Malicious Upload 3'
251 }, upload_files=[(
252 'file', EVIL_PNG)])
253 response.follow()
254 assert_equal(
255 urlparse.urlsplit(response.location)[2],
256 '/u/chris/')
257
258 entry = mg_globals.database.MediaEntry.find_one(
259 {'title': 'Malicious Upload 3'})
260 assert_equal(entry['state'], 'failed')
261 assert_equal(
262 entry['fail_error'],
263 u'mediagoblin.processing:BadMediaFail')