test_user_avatar_api.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. import json
  2. from path import Path
  3. from django.contrib.auth import get_user_model
  4. from django.core.urlresolvers import reverse
  5. from misago.acl.testutils import override_acl
  6. from misago.conf import settings
  7. from misago.users.avatars import store
  8. from misago.users.testutils import AuthenticatedUserTestCase
  9. class UserAvatarTests(AuthenticatedUserTestCase):
  10. """
  11. tests for user avatar RPC (/api/users/1/avatar/)
  12. """
  13. def setUp(self):
  14. super(UserAvatarTests, self).setUp()
  15. self.link = '/api/users/%s/avatar/' % self.user.pk
  16. def test_avatars_off(self):
  17. """custom avatars are not allowed"""
  18. with self.settings(allow_custom_avatars=False):
  19. response = self.client.get(self.link)
  20. self.assertEqual(response.status_code, 200)
  21. options = json.loads(response.content)
  22. self.assertTrue(options['generated'])
  23. self.assertFalse(options['gravatar'])
  24. self.assertFalse(options['crop_org'])
  25. self.assertFalse(options['crop_tmp'])
  26. self.assertFalse(options['upload'])
  27. self.assertTrue(options['galleries'])
  28. def test_avatars_on(self):
  29. """custom avatars are not allowed"""
  30. with self.settings(allow_custom_avatars=True):
  31. response = self.client.get(self.link)
  32. self.assertEqual(response.status_code, 200)
  33. options = json.loads(response.content)
  34. self.assertTrue(options['generated'])
  35. self.assertTrue(options['gravatar'])
  36. self.assertFalse(options['crop_org'])
  37. self.assertFalse(options['crop_tmp'])
  38. self.assertTrue(options['upload'])
  39. self.assertTrue(options['galleries'])
  40. def test_avatar_locked(self):
  41. """requests to api error if user's avatar is locked"""
  42. self.user.is_avatar_locked = True
  43. self.user.avatar_lock_user_message = 'Your avatar is pwnt.'
  44. self.user.save()
  45. response = self.client.get(self.link)
  46. self.assertEqual(response.status_code, 403)
  47. self.assertIn('Your avatar is pwnt', response.content)
  48. def test_other_user_avatar(self):
  49. """requests to api error if user tries to access other user"""
  50. self.logout_user();
  51. response = self.client.get(self.link)
  52. self.assertEqual(response.status_code, 403)
  53. self.assertIn('You have to sign in', response.content)
  54. User = get_user_model()
  55. self.login_user(User.objects.create_user(
  56. "BobUser", "bob@bob.com", self.USER_PASSWORD))
  57. response = self.client.get(self.link)
  58. self.assertEqual(response.status_code, 403)
  59. self.assertIn('can\'t change other users avatars', response.content)
  60. def test_empty_requests(self):
  61. """empty request errors with code 400"""
  62. response = self.client.post(self.link)
  63. self.assertEqual(response.status_code, 400)
  64. self.assertIn('Unknown avatar type.', response.content)
  65. def test_failed_gravatar_request(self):
  66. """no gravatar RPC fails"""
  67. self.user.email_hash = 'wolololo'
  68. self.user.save()
  69. response = self.client.post(self.link, data={'avatar': 'gravatar'})
  70. self.assertEqual(response.status_code, 400)
  71. self.assertIn('No Gravatar is associated', response.content)
  72. def test_successful_gravatar_request(self):
  73. """gravatar RPC fails"""
  74. self.user.set_email('rafio.xudb@gmail.com')
  75. self.user.save()
  76. response = self.client.post(self.link, data={'avatar': 'gravatar'})
  77. self.assertEqual(response.status_code, 200)
  78. self.assertIn('Gravatar was downloaded and set', response.content)
  79. def test_generation_request(self):
  80. """generated avatar is set"""
  81. response = self.client.post(self.link, data={'avatar': 'generated'})
  82. self.assertEqual(response.status_code, 200)
  83. self.assertIn('New avatar based on your account', response.content)
  84. def test_avatar_upload_and_crop(self):
  85. """avatar can be uploaded and cropped"""
  86. response = self.client.post(self.link, data={'avatar': 'generated'})
  87. self.assertEqual(response.status_code, 200)
  88. response = self.client.post(self.link, data={'avatar': 'upload'})
  89. self.assertEqual(response.status_code, 400)
  90. self.assertIn('No file was sent.', response.content)
  91. avatar_path = (settings.MEDIA_ROOT, 'avatars', 'blank.png')
  92. with open('/'.join(avatar_path)) as avatar:
  93. response = self.client.post(self.link,
  94. data={
  95. 'avatar': 'upload',
  96. 'image': avatar
  97. })
  98. self.assertEqual(response.status_code, 200)
  99. response_json = json.loads(response.content)
  100. self.assertTrue(response_json['options']['crop_tmp'])
  101. avatar_dir = store.get_existing_avatars_dir(self.user)
  102. avatar = Path('%s/%s_tmp.png' % (avatar_dir, self.user.pk))
  103. self.assertTrue(avatar.exists())
  104. self.assertTrue(avatar.isfile())
  105. tmp_avatar_kwargs = {
  106. 'secret': response_json['options']['crop_tmp']['secret'],
  107. 'hash': response_json['avatar_hash'],
  108. 'user_id': self.user.pk
  109. }
  110. tmp_avatar_path = reverse('misago:user_avatar_source',
  111. kwargs=tmp_avatar_kwargs)
  112. response = self.client.get(tmp_avatar_path)
  113. self.assertEqual(response.status_code, 200)
  114. response = self.client.post(self.link, json.dumps({
  115. 'avatar': 'crop_tmp',
  116. 'crop': {
  117. 'offset': {
  118. 'x': 0, 'y': 0
  119. },
  120. 'zoom': 1
  121. }
  122. }),
  123. content_type="application/json")
  124. response_json = json.loads(response.content)
  125. self.assertEqual(response.status_code, 200)
  126. self.assertIn('Uploaded avatar was set.', response.content)
  127. avatar_dir = store.get_existing_avatars_dir(self.user)
  128. avatar = Path('%s/%s_tmp.png' % (avatar_dir, self.user.pk))
  129. self.assertFalse(avatar.exists())
  130. avatar = Path('%s/%s_org.png' % (avatar_dir, self.user.pk))
  131. self.assertTrue(avatar.exists())
  132. self.assertTrue(avatar.isfile())
  133. org_avatar_kwargs = {
  134. 'secret': response_json['options']['crop_org']['secret'],
  135. 'hash': response_json['avatar_hash'],
  136. 'user_id': self.user.pk
  137. }
  138. org_avatar_path = reverse('misago:user_avatar_source',
  139. kwargs=tmp_avatar_kwargs)
  140. response = self.client.get(org_avatar_path)
  141. self.assertEqual(response.status_code, 200)
  142. response = self.client.post(self.link, json.dumps({
  143. 'avatar': 'crop_tmp',
  144. 'crop': {
  145. 'offset': {
  146. 'x': 0, 'y': 0
  147. },
  148. 'zoom': 1
  149. }
  150. }),
  151. content_type="application/json")
  152. self.assertEqual(response.status_code, 400)
  153. self.assertIn('This avatar type is not allowed.', response.content)
  154. response = self.client.post(self.link, json.dumps({
  155. 'avatar': 'crop_org',
  156. 'crop': {
  157. 'offset': {
  158. 'x': 0, 'y': 0
  159. },
  160. 'zoom': 1
  161. }
  162. }),
  163. content_type="application/json")
  164. self.assertEqual(response.status_code, 200)
  165. self.assertIn('Avatar was re-cropped.', response.content)
  166. def test_gallery(self):
  167. """its possible to set avatar from gallery"""
  168. response = self.client.get(self.link)
  169. self.assertEqual(response.status_code, 200)
  170. options = json.loads(response.content)
  171. self.assertTrue(options['galleries'])
  172. for gallery in options['galleries']:
  173. for image in gallery['images']:
  174. response = self.client.post(self.link, data={
  175. 'avatar': 'galleries',
  176. 'image': image
  177. })
  178. self.assertEqual(response.status_code, 200)
  179. self.assertIn('Avatar from gallery was set.', response.content)
  180. class UserAvatarModerationTests(AuthenticatedUserTestCase):
  181. """
  182. tests for moderate user avatar RPC (/api/users/1/moderate-avatar/)
  183. """
  184. def setUp(self):
  185. super(UserAvatarModerationTests, self).setUp()
  186. User = get_user_model()
  187. self.other_user = User.objects.create_user(
  188. "OtherUser", "other@user.com", "pass123")
  189. self.link = '/api/users/%s/moderate-avatar/' % self.other_user.pk
  190. def test_no_permission(self):
  191. """no permission to moderate avatar"""
  192. override_acl(self.user, {
  193. 'can_moderate_avatars': 0,
  194. })
  195. response = self.client.get(self.link)
  196. self.assertEqual(response.status_code, 403)
  197. self.assertIn("can't moderate avatars", response.content)
  198. override_acl(self.user, {
  199. 'can_moderate_avatars': 0,
  200. })
  201. response = self.client.post(self.link)
  202. self.assertEqual(response.status_code, 403)
  203. self.assertIn("can't moderate avatars", response.content)
  204. def test_moderate_avatar(self):
  205. """moderate avatar"""
  206. override_acl(self.user, {
  207. 'can_moderate_avatars': 1,
  208. })
  209. response = self.client.get(self.link)
  210. self.assertEqual(response.status_code, 200)
  211. options = json.loads(response.content)
  212. self.assertEqual(options['is_avatar_locked'],
  213. self.other_user.is_avatar_locked)
  214. self.assertEqual(options['avatar_lock_user_message'],
  215. self.other_user.avatar_lock_user_message)
  216. self.assertEqual(options['avatar_lock_staff_message'],
  217. self.other_user.avatar_lock_staff_message)
  218. override_acl(self.user, {
  219. 'can_moderate_avatars': 1,
  220. })
  221. response = self.client.post(self.link, json.dumps({
  222. 'is_avatar_locked': True,
  223. 'avatar_lock_user_message': "Test user message.",
  224. 'avatar_lock_staff_message': "Test staff message.",
  225. }),
  226. content_type="application/json")
  227. self.assertEqual(response.status_code, 200)
  228. User = get_user_model()
  229. other_user = User.objects.get(pk=self.other_user.pk)
  230. options = json.loads(response.content)
  231. self.assertEqual(other_user.is_avatar_locked, True)
  232. self.assertEqual(
  233. other_user.avatar_lock_user_message, "Test user message.")
  234. self.assertEqual(
  235. other_user.avatar_lock_staff_message, "Test staff message.")
  236. self.assertEqual(options['avatar_hash'],
  237. other_user.avatar_hash)
  238. self.assertEqual(options['is_avatar_locked'],
  239. other_user.is_avatar_locked)
  240. self.assertEqual(options['avatar_lock_user_message'],
  241. other_user.avatar_lock_user_message)
  242. self.assertEqual(options['avatar_lock_staff_message'],
  243. other_user.avatar_lock_staff_message)
  244. override_acl(self.user, {
  245. 'can_moderate_avatars': 1,
  246. })
  247. response = self.client.post(self.link, json.dumps({
  248. 'is_avatar_locked': False,
  249. 'avatar_lock_user_message': None,
  250. 'avatar_lock_staff_message': None,
  251. }),
  252. content_type="application/json")
  253. self.assertEqual(response.status_code, 200)
  254. other_user = User.objects.get(pk=self.other_user.pk)
  255. options = json.loads(response.content)
  256. self.assertEqual(options['avatar_hash'],
  257. other_user.avatar_hash)
  258. self.assertEqual(options['is_avatar_locked'],
  259. other_user.is_avatar_locked)
  260. self.assertEqual(options['avatar_lock_user_message'],
  261. other_user.avatar_lock_user_message)
  262. self.assertEqual(options['avatar_lock_staff_message'],
  263. other_user.avatar_lock_staff_message)
  264. def test_moderate_own_avatar(self):
  265. """moderate own avatar"""
  266. override_acl(self.user, {
  267. 'can_moderate_avatars': 1,
  268. })
  269. response = self.client.get(
  270. '/api/users/%s/moderate-avatar/' % self.user.pk)
  271. self.assertEqual(response.status_code, 200)