test_users_mass_actions.py 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. from unittest.mock import call
  2. import pytest
  3. from django.contrib.auth import get_user_model
  4. from django.core import mail
  5. from ....cache.test import assert_invalidates_cache
  6. from ....test import assert_contains, assert_has_error_message, assert_not_contains
  7. from ... import BANS_CACHE
  8. from ...datadownloads import request_user_data_download
  9. from ...models import Ban, DataDownload
  10. from ...test import create_test_user
  11. User = get_user_model()
  12. def create_multiple_users(**kwargs):
  13. return [
  14. create_test_user("User%s" % i, "user%s@gmail.com" % i, **kwargs)
  15. for i in range(5)
  16. ]
  17. def get_multiple_users_ids(**kwargs):
  18. users = create_multiple_users(**kwargs)
  19. return [u.id for u in users]
  20. @pytest.fixture
  21. def users_ids(db):
  22. return get_multiple_users_ids()
  23. def test_multiple_users_can_be_activated_with_mass_action(
  24. admin_client, users_admin_link
  25. ):
  26. users = create_multiple_users(requires_activation=1)
  27. response = admin_client.post(
  28. users_admin_link,
  29. data={"action": "activate", "selected_items": [u.id for u in users]},
  30. )
  31. for user in users:
  32. user.refresh_from_db()
  33. assert not user.requires_activation
  34. def test_activating_multiple_users_sends_email_notifications_to_them(
  35. admin_client, users_admin_link
  36. ):
  37. users_ids = get_multiple_users_ids(requires_activation=1)
  38. response = admin_client.post(
  39. users_admin_link, data={"action": "activate", "selected_items": users_ids}
  40. )
  41. assert len(mail.outbox) == len(users_ids)
  42. assert "has been activated" in mail.outbox[0].subject
  43. def test_ban_multiple_users_form_is_rendered(admin_client, users_admin_link):
  44. users_ids = get_multiple_users_ids()
  45. response = admin_client.post(
  46. users_admin_link, data={"action": "ban", "selected_items": users_ids}
  47. )
  48. assert response.status_code == 200
  49. def test_multiple_users_can_be_banned_with_mass_action(admin_client, users_admin_link):
  50. users = create_multiple_users()
  51. admin_client.post(
  52. users_admin_link,
  53. data={
  54. "action": "ban",
  55. "selected_items": [u.id for u in users],
  56. "ban_type": ["usernames", "emails", "domains"],
  57. "finalize": "",
  58. },
  59. )
  60. for user in users:
  61. Ban.objects.get(banned_value=user.username.lower())
  62. Ban.objects.get(banned_value=user.email)
  63. Ban.objects.get(banned_value="*%s" % user.email[-10:])
  64. def test_option_to_ban_multiple_users_ips_is_disabled_if_user_ips_are_not_available(
  65. admin_client, users_admin_link, users_ids
  66. ):
  67. response = admin_client.post(
  68. users_admin_link, data={"action": "ban", "selected_items": users_ids}
  69. )
  70. assert_not_contains(response, 'value="ip"')
  71. assert_not_contains(response, 'value="ip_first"')
  72. assert_not_contains(response, 'value="ip_two"')
  73. def test_option_to_ban_multiple_users_ips_is_enabled_if_user_ips_are_available(
  74. admin_client, users_admin_link
  75. ):
  76. users_ids = get_multiple_users_ids(joined_from_ip="1.2.3.4")
  77. response = admin_client.post(
  78. users_admin_link, data={"action": "ban", "selected_items": users_ids}
  79. )
  80. assert_contains(response, 'value="ip"')
  81. assert_contains(response, 'value="ip_first"')
  82. assert_contains(response, 'value="ip_two"')
  83. def test_multiple_users_ips_can_be_banned_with_mass_action(
  84. admin_client, users_admin_link
  85. ):
  86. users_ids = get_multiple_users_ids(joined_from_ip="1.2.3.4")
  87. response = admin_client.post(
  88. users_admin_link,
  89. data={
  90. "action": "ban",
  91. "selected_items": users_ids,
  92. "ban_type": ["ip", "ip_first", "ip_two"],
  93. "finalize": "",
  94. },
  95. )
  96. Ban.objects.get(banned_value="1.2.3.4")
  97. Ban.objects.get(banned_value="1.*")
  98. Ban.objects.get(banned_value="1.2.*")
  99. def test_banning_multiple_users_with_mass_action_invalidates_bans_cache(
  100. admin_client, users_admin_link, users_ids
  101. ):
  102. with assert_invalidates_cache(BANS_CACHE):
  103. admin_client.post(
  104. users_admin_link,
  105. data={
  106. "action": "ban",
  107. "selected_items": users_ids,
  108. "ban_type": ["usernames", "emails", "domains"],
  109. "finalize": "",
  110. },
  111. )
  112. def test_data_downloads_can_be_requested_for_multiple_users_with_mass_action(
  113. admin_client, users_admin_link
  114. ):
  115. users = create_multiple_users()
  116. response = admin_client.post(
  117. users_admin_link,
  118. data={
  119. "action": "request_data_download",
  120. "selected_items": [u.id for u in users],
  121. },
  122. )
  123. for user in users:
  124. DataDownload.objects.get(user=user)
  125. def test_mass_action_is_not_requesting_data_downloads_for_users_with_existing_requests(
  126. admin_client, users_admin_link
  127. ):
  128. users = create_multiple_users()
  129. downloads_ids = [request_user_data_download(u).id for u in users]
  130. response = admin_client.post(
  131. users_admin_link,
  132. data={
  133. "action": "request_data_download",
  134. "selected_items": [u.id for u in users],
  135. },
  136. )
  137. assert not DataDownload.objects.exclude(id__in=downloads_ids).exists()
  138. def test_multiple_users_can_be_deleted_with_mass_action(admin_client, users_admin_link):
  139. users = create_multiple_users()
  140. response = admin_client.post(
  141. users_admin_link,
  142. data={"action": "delete_accounts", "selected_items": [u.id for u in users]},
  143. )
  144. for user in users:
  145. with pytest.raises(User.DoesNotExist):
  146. user.refresh_from_db()
  147. def test_delete_users_mass_action_fails_if_user_tries_to_delete_themselves(
  148. admin_client, users_admin_link, superuser
  149. ):
  150. response = admin_client.post(
  151. users_admin_link,
  152. data={"action": "delete_accounts", "selected_items": [superuser.id]},
  153. )
  154. assert_has_error_message(response)
  155. superuser.refresh_from_db()
  156. def test_delete_users_mass_action_fails_if_user_tries_to_delete_staff_members(
  157. admin_client, users_admin_link
  158. ):
  159. users = create_multiple_users(is_staff=True)
  160. response = admin_client.post(
  161. users_admin_link,
  162. data={"action": "delete_accounts", "selected_items": [u.id for u in users]},
  163. )
  164. assert_has_error_message(response)
  165. for user in users:
  166. user.refresh_from_db()
  167. def test_delete_users_mass_action_fails_if_user_tries_to_delete_superusers(
  168. admin_client, users_admin_link
  169. ):
  170. users = create_multiple_users(is_superuser=True)
  171. response = admin_client.post(
  172. users_admin_link,
  173. data={"action": "delete_accounts", "selected_items": [u.id for u in users]},
  174. )
  175. assert_has_error_message(response)
  176. for user in users:
  177. user.refresh_from_db()
  178. @pytest.fixture
  179. def mock_delete_user_with_content(mocker):
  180. delay = mocker.Mock()
  181. mocker.patch(
  182. "misago.users.admin.views.users.delete_user_with_content",
  183. mocker.Mock(delay=delay),
  184. )
  185. return delay
  186. def test_multiple_users_can_be_deleted_together_with_content_by_mass_action(
  187. admin_client, users_admin_link, users_ids, mock_delete_user_with_content
  188. ):
  189. response = admin_client.post(
  190. users_admin_link, data={"action": "delete_all", "selected_items": users_ids}
  191. )
  192. calls = [call(u) for u in users_ids]
  193. mock_delete_user_with_content.assert_has_calls(calls, any_order=True)
  194. def test_deleting_multiple_users_with_content_disables_their_accounts(
  195. admin_client, users_admin_link, mock_delete_user_with_content
  196. ):
  197. users = create_multiple_users()
  198. response = admin_client.post(
  199. users_admin_link,
  200. data={"action": "delete_all", "selected_items": [u.id for u in users]},
  201. )
  202. for user in users:
  203. user.refresh_from_db()
  204. assert not user.is_active
  205. def test_delete_users_with_content_mass_action_fails_if_user_tries_to_delete_themselves(
  206. admin_client, users_admin_link, superuser, mock_delete_user_with_content
  207. ):
  208. response = admin_client.post(
  209. users_admin_link,
  210. data={"action": "delete_all", "selected_items": [superuser.id]},
  211. )
  212. assert_has_error_message(response)
  213. mock_delete_user_with_content.assert_not_called()
  214. superuser.refresh_from_db()
  215. assert superuser.is_active
  216. def test_delete_users_with_content_mass_action_fails_if_user_tries_to_delete_staff(
  217. admin_client, users_admin_link, mock_delete_user_with_content
  218. ):
  219. users = create_multiple_users(is_staff=True)
  220. response = admin_client.post(
  221. users_admin_link,
  222. data={"action": "delete_all", "selected_items": [u.id for u in users]},
  223. )
  224. assert_has_error_message(response)
  225. mock_delete_user_with_content.assert_not_called()
  226. for user in users:
  227. user.refresh_from_db()
  228. assert user.is_active
  229. def test_delete_users_with_content_mass_action_fails_if_user_tries_to_delete_superusers(
  230. admin_client, users_admin_link, mock_delete_user_with_content
  231. ):
  232. users = create_multiple_users(is_superuser=True)
  233. response = admin_client.post(
  234. users_admin_link,
  235. data={"action": "delete_all", "selected_items": [u.id for u in users]},
  236. )
  237. assert_has_error_message(response)
  238. mock_delete_user_with_content.assert_not_called()
  239. for user in users:
  240. user.refresh_from_db()
  241. assert user.is_active