test_attachments_api.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. import json
  2. import os
  3. from django.core.urlresolvers import reverse
  4. from django.utils.encoding import smart_str
  5. from misago.acl.models import Role
  6. from misago.acl.testutils import override_acl
  7. from misago.users.testutils import AuthenticatedUserTestCase
  8. from ..models import Attachment, AttachmentType
  9. TESTFILES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'testfiles')
  10. TEST_DOCUMENT_PATH = os.path.join(TESTFILES_DIR, 'document.pdf')
  11. TEST_LARGEPNG_PATH = os.path.join(TESTFILES_DIR, 'large.png')
  12. TEST_SMALLJPG_PATH = os.path.join(TESTFILES_DIR, 'small.jpg')
  13. TEST_CORRUPTEDIMG_PATH = os.path.join(TESTFILES_DIR, 'corrupted.gif')
  14. class AttachmentsApiTestCase(AuthenticatedUserTestCase):
  15. def setUp(self):
  16. super(AttachmentsApiTestCase, self).setUp()
  17. AttachmentType.objects.all().delete()
  18. self.api_link = reverse('misago:api:attachment-list')
  19. def override_acl(self, new_acl=None):
  20. if new_acl:
  21. acl = self.user.acl.copy()
  22. acl.update(new_acl)
  23. override_acl(self.user, acl)
  24. def test_anonymous(self):
  25. """user has to be authenticated to be able to upload files"""
  26. self.logout_user()
  27. response = self.client.post(self.api_link)
  28. self.assertEqual(response.status_code, 403)
  29. def test_no_permission(self):
  30. """user needs permission to upload files"""
  31. self.override_acl({
  32. 'max_attachment_size': 0
  33. })
  34. response = self.client.post(self.api_link)
  35. self.assertContains(response, "don't have permission to upload new files", status_code=403)
  36. def test_no_file_uploaded(self):
  37. """no file uploaded scenario is handled"""
  38. response = self.client.post(self.api_link)
  39. self.assertContains(response, "No file has been uploaded.", status_code=400)
  40. def test_invalid_extension(self):
  41. """uploaded file's extension is rejected as invalid"""
  42. AttachmentType.objects.create(
  43. name="Test extension",
  44. extensions='jpg,jpeg',
  45. mimetypes=None
  46. )
  47. with open(TEST_DOCUMENT_PATH, 'rb') as upload:
  48. response = self.client.post(self.api_link, data={
  49. 'upload': upload
  50. })
  51. self.assertContains(response, "You can't upload files of this type.", status_code=400)
  52. def test_invalid_mime(self):
  53. """uploaded file's mimetype is rejected as invalid"""
  54. AttachmentType.objects.create(
  55. name="Test extension",
  56. extensions='png',
  57. mimetypes='loremipsum'
  58. )
  59. with open(TEST_DOCUMENT_PATH, 'rb') as upload:
  60. response = self.client.post(self.api_link, data={
  61. 'upload': upload
  62. })
  63. self.assertContains(response, "You can't upload files of this type.", status_code=400)
  64. def test_no_perm_to_type(self):
  65. """user needs permission to upload files of this type"""
  66. attachment_type = AttachmentType.objects.create(
  67. name="Test extension",
  68. extensions='png',
  69. mimetypes='application/pdf'
  70. )
  71. user_roles = (r.pk for r in self.user.get_roles())
  72. attachment_type.limit_uploads_to.set(Role.objects.exclude(id__in=user_roles))
  73. with open(TEST_DOCUMENT_PATH, 'rb') as upload:
  74. response = self.client.post(self.api_link, data={
  75. 'upload': upload
  76. })
  77. self.assertContains(response, "You can't upload files of this type.", status_code=400)
  78. def test_type_is_locked(self):
  79. """new uploads for this filetype are locked"""
  80. attachment_type = AttachmentType.objects.create(
  81. name="Test extension",
  82. extensions='png',
  83. mimetypes='application/pdf',
  84. status=AttachmentType.LOCKED
  85. )
  86. with open(TEST_DOCUMENT_PATH, 'rb') as upload:
  87. response = self.client.post(self.api_link, data={
  88. 'upload': upload
  89. })
  90. self.assertContains(response, "You can't upload files of this type.", status_code=400)
  91. def test_type_is_disabled(self):
  92. """new uploads for this filetype are disabled"""
  93. attachment_type = AttachmentType.objects.create(
  94. name="Test extension",
  95. extensions='png',
  96. mimetypes='application/pdf',
  97. status=AttachmentType.DISABLED
  98. )
  99. with open(TEST_DOCUMENT_PATH, 'rb') as upload:
  100. response = self.client.post(self.api_link, data={
  101. 'upload': upload
  102. })
  103. self.assertContains(response, "You can't upload files of this type.", status_code=400)
  104. def test_upload_too_big_for_type(self):
  105. """too big uploads are rejected"""
  106. AttachmentType.objects.create(
  107. name="Test extension",
  108. extensions='png',
  109. mimetypes='image/png',
  110. size_limit=100
  111. )
  112. with open(TEST_LARGEPNG_PATH, 'rb') as upload:
  113. response = self.client.post(self.api_link, data={
  114. 'upload': upload
  115. })
  116. self.assertContains(response, "can't upload files of this type larger than", status_code=400)
  117. def test_upload_too_big_for_user(self):
  118. """too big uploads are rejected"""
  119. self.override_acl({
  120. 'max_attachment_size': 100
  121. })
  122. AttachmentType.objects.create(
  123. name="Test extension",
  124. extensions='png',
  125. mimetypes='image/png'
  126. )
  127. with open(TEST_LARGEPNG_PATH, 'rb') as upload:
  128. response = self.client.post(self.api_link, data={
  129. 'upload': upload
  130. })
  131. self.assertContains(response, "can't upload files larger than", status_code=400)
  132. def test_corrupted_image_upload(self):
  133. """corrupted image upload is handled"""
  134. attachment_type = AttachmentType.objects.create(
  135. name="Test extension",
  136. extensions='gif'
  137. )
  138. with open(TEST_CORRUPTEDIMG_PATH, 'rb') as upload:
  139. response = self.client.post(self.api_link, data={
  140. 'upload': upload
  141. })
  142. self.assertContains(response, "Uploaded image was corrupted or invalid.", status_code=400)
  143. def test_document_upload(self):
  144. """successful upload creates orphan attachment"""
  145. attachment_type = AttachmentType.objects.create(
  146. name="Test extension",
  147. extensions='pdf',
  148. mimetypes='application/pdf'
  149. )
  150. with open(TEST_DOCUMENT_PATH, 'rb') as upload:
  151. response = self.client.post(self.api_link, data={
  152. 'upload': upload
  153. })
  154. self.assertEqual(response.status_code, 200)
  155. response_json = json.loads(smart_str(response.content))
  156. attachment = Attachment.objects.get(id=response_json['id'])
  157. self.assertEqual(attachment.filename, 'document.pdf')
  158. self.assertIsNotNone(attachment.file)
  159. self.assertTrue(not attachment.image)
  160. self.assertTrue(not attachment.thumbnail)
  161. self.assertIsNone(response_json['post'])
  162. self.assertEqual(response_json['uploader_name'], self.user.username)
  163. self.assertEqual(response_json['url']['uploader'], self.user.get_absolute_url())
  164. def test_image_upload(self):
  165. """successful upload creates orphan attachment with thumbnail"""
  166. attachment_type = AttachmentType.objects.create(
  167. name="Test extension",
  168. extensions='jpeg,jpg',
  169. mimetypes='image/jpeg'
  170. )
  171. with open(TEST_SMALLJPG_PATH, 'rb') as upload:
  172. response = self.client.post(self.api_link, data={
  173. 'upload': upload
  174. })
  175. self.assertEqual(response.status_code, 200)
  176. response_json = json.loads(smart_str(response.content))
  177. attachment = Attachment.objects.get(id=response_json['id'])
  178. self.assertEqual(attachment.filename, 'small.jpg')
  179. self.assertTrue(not attachment.file)
  180. self.assertIsNotNone(attachment.image)
  181. self.assertIsNotNone(attachment.thumbnail)
  182. self.assertIsNone(response_json['post'])
  183. self.assertEqual(response_json['uploader_name'], self.user.username)
  184. self.assertEqual(response_json['url']['uploader'], self.user.get_absolute_url())