Dot-Notation for Users.fp_token_expire
[mediagoblin.git] / mediagoblin / tests / test_submission.py
CommitLineData
1975b5dd 1# GNU MediaGoblin -- federated, autonomous media hosting
12a100e4 2# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS.
1975b5dd
CM
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
9df37e8a 18import pkg_resources
1975b5dd 19
afe4e513 20from nose.tools import assert_equal, assert_true, assert_false
1975b5dd 21
9754802d
E
22from mediagoblin.tests.tools import setup_fresh_app, get_test_app, \
23 fixture_add_user
1975b5dd 24from mediagoblin import mg_globals
ae3bc7fa 25from mediagoblin.tools import template, common
1975b5dd 26
9df37e8a
CM
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')
75ce65cf 37
8ff4dec7
CFD
38GOOD_TAG_STRING = 'yin,yang'
39BAD_TAG_STRING = 'rage,' + 'f' * 26 + 'u' * 26
40
1975b5dd 41
1975b5dd
CM
42class TestSubmission:
43 def setUp(self):
0a78be3e
CM
44 self.test_app = get_test_app()
45
75ce65cf
CM
46 # TODO: Possibly abstract into a decorator like:
47 # @as_authenticated_user('chris')
9754802d 48 test_user = fixture_add_user()
1975b5dd 49
afe4e513
JW
50 self.test_user = test_user
51
75ce65cf
CM
52 self.test_app.post(
53 '/auth/login/', {
54 'username': u'chris',
55 'password': 'toast'})
56
57 def test_missing_fields(self):
ad35dd49
CM
58 # Test blank form
59 # ---------------
ae3bc7fa 60 template.clear_test_template_context()
ad35dd49
CM
61 response = self.test_app.post(
62 '/submit/', {})
ae3bc7fa 63 context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/submit/start.html']
ad35dd49
CM
64 form = context['submit_form']
65 assert form.file.errors == [u'You must provide a file.']
66
67 # Test blank file
68 # ---------------
ae3bc7fa 69 template.clear_test_template_context()
ad35dd49
CM
70 response = self.test_app.post(
71 '/submit/', {
72 'title': 'test title'})
ae3bc7fa 73 context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/submit/start.html']
ad35dd49
CM
74 form = context['submit_form']
75 assert form.file.errors == [u'You must provide a file.']
76
75ce65cf
CM
77
78 def test_normal_uploads(self):
75ce65cf 79 # Test JPG
ad35dd49 80 # --------
ae3bc7fa 81 template.clear_test_template_context()
ad35dd49
CM
82 response = self.test_app.post(
83 '/submit/', {
84 'title': 'Normal upload 1'
85 }, upload_files=[(
9df37e8a 86 'file', GOOD_JPG)])
ad35dd49
CM
87
88 # User should be redirected
89 response.follow()
90 assert_equal(
91 urlparse.urlsplit(response.location)[2],
9df37e8a 92 '/u/chris/')
ae3bc7fa 93 assert template.TEMPLATE_TEST_CONTEXT.has_key(
9df37e8a 94 'mediagoblin/user_pages/user.html')
ad35dd49 95
75ce65cf 96 # Test PNG
ad35dd49 97 # --------
ae3bc7fa 98 template.clear_test_template_context()
ad35dd49
CM
99 response = self.test_app.post(
100 '/submit/', {
101 'title': 'Normal upload 2'
102 }, upload_files=[(
9df37e8a 103 'file', GOOD_PNG)])
ad35dd49
CM
104
105 response.follow()
106 assert_equal(
107 urlparse.urlsplit(response.location)[2],
9df37e8a 108 '/u/chris/')
ae3bc7fa 109 assert template.TEMPLATE_TEST_CONTEXT.has_key(
9df37e8a 110 'mediagoblin/user_pages/user.html')
75ce65cf 111
8ff4dec7
CFD
112 def test_tags(self):
113 # Good tag string
114 # --------
ae3bc7fa 115 template.clear_test_template_context()
8ff4dec7
CFD
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()
ae3bc7fa 125 context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/user_pages/user.html']
8ff4dec7
CFD
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 # ---------------
ae3bc7fa 134 template.clear_test_template_context()
8ff4dec7
CFD
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
ae3bc7fa 143 context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/submit/start.html']
8ff4dec7
CFD
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']
75ce65cf 148
afe4e513 149 def test_delete(self):
ae3bc7fa 150 template.clear_test_template_context()
afe4e513
JW
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
ae3bc7fa 160 request = template.TEMPLATE_TEST_CONTEXT[
afe4e513
JW
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(
502073f2 171 request.urlgen('mediagoblin.user_pages.media_confirm_delete',
afe4e513 172 # No work: user=media.uploader().username,
5a4e3ff1 173 user=self.test_user.username,
bcc9ee32 174 media=media._id),
9a64272e
CAW
175 # no value means no confirm
176 {})
afe4e513
JW
177
178 response.follow()
179
ae3bc7fa 180 request = template.TEMPLATE_TEST_CONTEXT[
afe4e513
JW
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(
502073f2 191 request.urlgen('mediagoblin.user_pages.media_confirm_delete',
afe4e513 192 # No work: user=media.uploader().username,
5a4e3ff1 193 user=self.test_user.username,
bcc9ee32 194 media=media._id),
9a64272e 195 {'confirm': 'y'})
afe4e513
JW
196
197 response.follow()
198
ae3bc7fa 199 request = template.TEMPLATE_TEST_CONTEXT[
afe4e513
JW
200 'mediagoblin/user_pages/user.html']['request']
201
202 # Does media entry still exist?
203 assert_false(
204 request.db.MediaEntry.find(
eabe6b67 205 {'_id': media._id}).count())
afe4e513 206
75ce65cf 207 def test_malicious_uploads(self):
ad35dd49
CM
208 # Test non-suppoerted file with non-supported extension
209 # -----------------------------------------------------
ae3bc7fa 210 template.clear_test_template_context()
ad35dd49
CM
211 response = self.test_app.post(
212 '/submit/', {
68f3ffbe 213 'title': 'Malicious Upload 1'
ad35dd49 214 }, upload_files=[(
9df37e8a 215 'file', EVIL_FILE)])
ad35dd49 216
ae3bc7fa 217 context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/submit/start.html']
ad35dd49 218 form = context['submit_form']
0bce749b 219 assert form.file.errors == [u'Invalid file type.']
ad35dd49 220
68f3ffbe
CAW
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.
9df37e8a 224
75ce65cf 225 # Test non-supported file with .jpg extension
ad35dd49 226 # -------------------------------------------
ae3bc7fa 227 template.clear_test_template_context()
68f3ffbe
CAW
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/')
ad35dd49 237
68f3ffbe
CAW
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'],
0bce749b 243 u'mediagoblin.processing:BadMediaFail')
ad35dd49 244
75ce65cf 245 # Test non-supported file with .png extension
ad35dd49 246 # -------------------------------------------
ae3bc7fa 247 template.clear_test_template_context()
68f3ffbe
CAW
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/')
0a78be3e 257
68f3ffbe
CAW
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'],
0bce749b 263 u'mediagoblin.processing:BadMediaFail')