PageRenderTime 27ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/integration/test_memberships.py

https://bitbucket.org/mazpaijo/taiga-back
Python | 783 lines | 572 code | 190 blank | 21 comment | 3 complexity | a8246955d50755a713f0e0d170bfac7a MD5 | raw file
Possible License(s): AGPL-3.0
  1. # -*- coding: utf-8 -*-
  2. # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
  3. # Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
  4. # Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
  5. # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
  6. # Copyright (C) 2014-2017 Anler Hernández <hello@anler.me>
  7. # This program is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU Affero General Public License as
  9. # published by the Free Software Foundation, either version 3 of the
  10. # License, or (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU Affero General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU Affero General Public License
  18. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. from unittest import mock
  20. from django.core.urlresolvers import reverse
  21. from taiga.projects import services
  22. from taiga.base.utils import json
  23. from .. import factories as f
  24. import pytest
  25. pytestmark = pytest.mark.django_db
  26. def test_get_members_from_bulk():
  27. data = [{"role_id": "1", "username": "member1@email.com"},
  28. {"role_id": "1", "username": "member2@email.com"}]
  29. members = services.get_members_from_bulk(data, project_id=1)
  30. assert len(members) == 2
  31. assert members[0].email == "member1@email.com"
  32. assert members[1].email == "member2@email.com"
  33. def test_create_member_using_email(client):
  34. project = f.ProjectFactory()
  35. john = f.UserFactory.create()
  36. joseph = f.UserFactory.create()
  37. tester = f.RoleFactory(project=project, name="Tester")
  38. f.MembershipFactory(project=project, user=john, is_admin=True)
  39. url = reverse("memberships-list")
  40. data = {"project": project.id, "role": tester.pk, "username": joseph.email}
  41. client.login(john)
  42. response = client.json.post(url, json.dumps(data))
  43. assert response.status_code == 201
  44. assert response.data["email"] == joseph.email
  45. def test_create_member_using_username_without_being_contacts(client):
  46. project = f.ProjectFactory()
  47. john = f.UserFactory.create()
  48. joseph = f.UserFactory.create()
  49. tester = f.RoleFactory(project=project, name="Tester")
  50. f.MembershipFactory(project=project, user=john, is_admin=True)
  51. url = reverse("memberships-list")
  52. data = {"project": project.id, "role": tester.pk, "username": joseph.username}
  53. client.login(john)
  54. response = client.json.post(url, json.dumps(data))
  55. assert response.status_code == 400
  56. assert "The user must be a valid contact" in response.data["username"][0]
  57. def test_create_member_using_username_being_contacts(client):
  58. project = f.ProjectFactory()
  59. john = f.UserFactory.create()
  60. joseph = f.UserFactory.create()
  61. tester = f.RoleFactory(project=project, name="Tester", permissions=["view_project"])
  62. f.MembershipFactory(project=project, user=john, role=tester, is_admin=True)
  63. # They are members from another project
  64. project2 = f.ProjectFactory()
  65. gamer = f.RoleFactory(project=project2, name="Gamer", permissions=["view_project"])
  66. f.MembershipFactory(project=project2, user=john, role=gamer, is_admin=True)
  67. f.MembershipFactory(project=project2, user=joseph, role=gamer)
  68. url = reverse("memberships-list")
  69. data = {"project": project.id, "role": tester.pk, "username": joseph.username}
  70. client.login(john)
  71. response = client.json.post(url, json.dumps(data))
  72. assert response.status_code == 201
  73. assert response.data["user"] == joseph.id
  74. def test_create_members_in_bulk():
  75. with mock.patch("taiga.projects.services.members.db") as db:
  76. data = [{"role_id": "1", "username": "member1@email.com"},
  77. {"role_id": "1", "username": "member2@email.com"}]
  78. members = services.create_members_in_bulk(data, project_id=1)
  79. db.save_in_bulk.assert_called_once_with(members, None, None)
  80. def test_api_create_bulk_members(client):
  81. project = f.ProjectFactory()
  82. john = f.UserFactory.create()
  83. joseph = f.UserFactory.create()
  84. other = f.UserFactory.create()
  85. tester = f.RoleFactory(project=project, name="Tester", permissions=["view_project"])
  86. gamer = f.RoleFactory(project=project, name="Gamer", permissions=["view_project"])
  87. f.MembershipFactory(project=project, user=john, role=tester, is_admin=True)
  88. # John and Other are members from another project
  89. project2 = f.ProjectFactory()
  90. f.MembershipFactory(project=project2, user=john, role=gamer, is_admin=True)
  91. f.MembershipFactory(project=project2, user=other, role=gamer)
  92. url = reverse("memberships-bulk-create")
  93. data = {
  94. "project_id": project.id,
  95. "bulk_memberships": [
  96. {"role_id": gamer.pk, "username": joseph.email},
  97. {"role_id": gamer.pk, "username": other.username},
  98. ]
  99. }
  100. client.login(john)
  101. response = client.json.post(url, json.dumps(data))
  102. assert response.status_code == 200
  103. response_user_ids = set([u["user"] for u in response.data])
  104. user_ids = {other.id, joseph.id}
  105. assert(user_ids.issubset(response_user_ids))
  106. def test_api_create_bulk_members_invalid_user_id(client):
  107. project = f.ProjectFactory()
  108. john = f.UserFactory.create()
  109. joseph = f.UserFactory.create()
  110. other = f.UserFactory.create()
  111. tester = f.RoleFactory(project=project, name="Tester", permissions=["view_project"])
  112. gamer = f.RoleFactory(project=project, name="Gamer", permissions=["view_project"])
  113. f.MembershipFactory(project=project, user=john, role=tester, is_admin=True)
  114. url = reverse("memberships-bulk-create")
  115. data = {
  116. "project_id": project.id,
  117. "bulk_memberships": [
  118. {"role_id": gamer.pk, "username": joseph.email},
  119. {"role_id": gamer.pk, "username": other.username},
  120. ]
  121. }
  122. client.login(john)
  123. response = client.json.post(url, json.dumps(data))
  124. assert response.status_code == 400
  125. test_api_create_bulk_members_invalid_user_id
  126. def test_api_create_bulk_members_with_invalid_roles(client):
  127. project = f.ProjectFactory()
  128. john = f.UserFactory.create()
  129. joseph = f.UserFactory.create()
  130. tester = f.RoleFactory(name="Tester")
  131. gamer = f.RoleFactory(name="Gamer")
  132. f.MembershipFactory(project=project, user=project.owner, is_admin=True)
  133. url = reverse("memberships-bulk-create")
  134. data = {
  135. "project_id": project.id,
  136. "bulk_memberships": [
  137. {"role_id": tester.pk, "username": john.email},
  138. {"role_id": gamer.pk, "username": joseph.email},
  139. ]
  140. }
  141. client.login(project.owner)
  142. response = client.json.post(url, json.dumps(data))
  143. assert response.status_code == 400
  144. assert "bulk_memberships" in response.data
  145. def test_api_create_bulk_members_with_allowed_domain(client):
  146. project = f.ProjectFactory()
  147. john = f.UserFactory.create()
  148. joseph = f.UserFactory.create()
  149. tester = f.RoleFactory(project=project, name="Tester")
  150. gamer = f.RoleFactory(project=project, name="Gamer")
  151. f.MembershipFactory(project=project, user=project.owner, is_admin=True)
  152. url = reverse("memberships-bulk-create")
  153. data = {
  154. "project_id": project.id,
  155. "bulk_memberships": [
  156. {"role_id": tester.pk, "username": "test1@email.com"},
  157. {"role_id": gamer.pk, "username": "test2@email.com"},
  158. ]
  159. }
  160. client.login(project.owner)
  161. response = client.json.post(url, json.dumps(data))
  162. assert response.status_code == 200
  163. assert response.data[0]["email"] == "test1@email.com"
  164. assert response.data[1]["email"] == "test2@email.com"
  165. def test_api_create_bulk_members_with_allowed_and_unallowed_domain(client, settings):
  166. project = f.ProjectFactory()
  167. settings.USER_EMAIL_ALLOWED_DOMAINS = ['email.com']
  168. tester = f.RoleFactory(project=project, name="Tester")
  169. gamer = f.RoleFactory(project=project, name="Gamer")
  170. f.MembershipFactory(project=project, user=project.owner, is_admin=True)
  171. url = reverse("memberships-bulk-create")
  172. data = {
  173. "project_id": project.id,
  174. "bulk_memberships": [
  175. {"role_id": tester.pk, "username": "test@invalid-domain.com"},
  176. {"role_id": gamer.pk, "username": "test@email.com"},
  177. ]
  178. }
  179. client.login(project.owner)
  180. response = client.json.post(url, json.dumps(data))
  181. assert response.status_code == 400
  182. assert "username" in response.data["bulk_memberships"][0]
  183. assert "username" not in response.data["bulk_memberships"][1]
  184. def test_api_create_bulk_members_with_unallowed_domains(client, settings):
  185. project = f.ProjectFactory()
  186. settings.USER_EMAIL_ALLOWED_DOMAINS = ['email.com']
  187. tester = f.RoleFactory(project=project, name="Tester")
  188. gamer = f.RoleFactory(project=project, name="Gamer")
  189. f.MembershipFactory(project=project, user=project.owner, is_admin=True)
  190. url = reverse("memberships-bulk-create")
  191. data = {
  192. "project_id": project.id,
  193. "bulk_memberships": [
  194. {"role_id": tester.pk, "username": "test1@invalid-domain.com"},
  195. {"role_id": gamer.pk, "username": "test2@invalid-domain.com"},
  196. ]
  197. }
  198. client.login(project.owner)
  199. response = client.json.post(url, json.dumps(data))
  200. assert response.status_code == 400
  201. assert "username" in response.data["bulk_memberships"][0]
  202. assert "username" in response.data["bulk_memberships"][1]
  203. def test_api_create_bulk_members_without_enough_memberships_private_project_slots_one_project(client):
  204. user = f.UserFactory.create(max_memberships_private_projects=3)
  205. project = f.ProjectFactory(owner=user, is_private=True)
  206. role = f.RoleFactory(project=project, name="Test")
  207. f.MembershipFactory(project=project, user=user, is_admin=True)
  208. url = reverse("memberships-bulk-create")
  209. data = {
  210. "project_id": project.id,
  211. "bulk_memberships": [
  212. {"role_id": role.pk, "username": "test1@test.com"},
  213. {"role_id": role.pk, "username": "test2@test.com"},
  214. {"role_id": role.pk, "username": "test3@test.com"},
  215. {"role_id": role.pk, "username": "test4@test.com"},
  216. ]
  217. }
  218. client.login(user)
  219. response = client.json.post(url, json.dumps(data))
  220. assert response.status_code == 400
  221. assert "reached your current limit of memberships for private" in response.data["_error_message"]
  222. def test_api_create_bulk_members_for_admin_without_enough_memberships_private_project_slots_one_project(client):
  223. owner = f.UserFactory.create(max_memberships_private_projects=3)
  224. user = f.UserFactory.create()
  225. project = f.ProjectFactory(owner=owner, is_private=True)
  226. role = f.RoleFactory(project=project, name="Test")
  227. f.MembershipFactory(project=project, user=user, is_admin=True)
  228. url = reverse("memberships-bulk-create")
  229. data = {
  230. "project_id": project.id,
  231. "bulk_memberships": [
  232. {"role_id": role.pk, "username": "test1@test.com"},
  233. {"role_id": role.pk, "username": "test2@test.com"},
  234. {"role_id": role.pk, "username": "test3@test.com"},
  235. {"role_id": role.pk, "username": "test4@test.com"},
  236. ]
  237. }
  238. client.login(user)
  239. response = client.json.post(url, json.dumps(data))
  240. assert response.status_code == 400
  241. assert "reached your current limit of memberships for private" in response.data["_error_message"]
  242. def test_api_create_bulk_members_with_enough_memberships_private_project_slots_multiple_projects(client):
  243. user = f.UserFactory.create(max_memberships_private_projects=6)
  244. project = f.ProjectFactory(owner=user, is_private=True)
  245. role = f.RoleFactory(project=project, name="Test")
  246. f.MembershipFactory(project=project, user=user, is_admin=True)
  247. other_project = f.ProjectFactory(owner=user)
  248. f.MembershipFactory.create(project=other_project)
  249. f.MembershipFactory.create(project=other_project)
  250. f.MembershipFactory.create(project=other_project)
  251. f.MembershipFactory.create(project=other_project)
  252. url = reverse("memberships-bulk-create")
  253. data = {
  254. "project_id": project.id,
  255. "bulk_memberships": [
  256. {"role_id": role.pk, "username": "test1@test.com"},
  257. {"role_id": role.pk, "username": "test2@test.com"},
  258. {"role_id": role.pk, "username": "test3@test.com"},
  259. {"role_id": role.pk, "username": "test4@test.com"},
  260. ]
  261. }
  262. client.login(user)
  263. response = client.json.post(url, json.dumps(data))
  264. assert response.status_code == 200
  265. def test_api_create_bulk_members_without_enough_memberships_public_project_slots_one_project(client):
  266. user = f.UserFactory.create(max_memberships_public_projects=3)
  267. project = f.ProjectFactory(owner=user, is_private=False)
  268. role = f.RoleFactory(project=project, name="Test")
  269. f.MembershipFactory(project=project, user=user, is_admin=True)
  270. url = reverse("memberships-bulk-create")
  271. data = {
  272. "project_id": project.id,
  273. "bulk_memberships": [
  274. {"role_id": role.pk, "username": "test1@test.com"},
  275. {"role_id": role.pk, "username": "test2@test.com"},
  276. {"role_id": role.pk, "username": "test3@test.com"},
  277. {"role_id": role.pk, "username": "test4@test.com"},
  278. ]
  279. }
  280. client.login(user)
  281. response = client.json.post(url, json.dumps(data))
  282. assert response.status_code == 400
  283. assert "reached your current limit of memberships for public" in response.data["_error_message"]
  284. def test_api_create_bulk_members_with_enough_memberships_public_project_slots_multiple_projects(client):
  285. user = f.UserFactory.create(max_memberships_public_projects=6)
  286. project = f.ProjectFactory(owner=user, is_private=False)
  287. role = f.RoleFactory(project=project, name="Test")
  288. f.MembershipFactory(project=project, user=user, is_admin=True)
  289. other_project = f.ProjectFactory(owner=user)
  290. f.MembershipFactory.create(project=other_project)
  291. f.MembershipFactory.create(project=other_project)
  292. f.MembershipFactory.create(project=other_project)
  293. f.MembershipFactory.create(project=other_project)
  294. url = reverse("memberships-bulk-create")
  295. data = {
  296. "project_id": project.id,
  297. "bulk_memberships": [
  298. {"role_id": role.pk, "username": "test1@test.com"},
  299. {"role_id": role.pk, "username": "test2@test.com"},
  300. {"role_id": role.pk, "username": "test3@test.com"},
  301. {"role_id": role.pk, "username": "test4@test.com"},
  302. ]
  303. }
  304. client.login(user)
  305. response = client.json.post(url, json.dumps(data))
  306. assert response.status_code == 200
  307. def test_api_create_bulk_members_with_extra_text(client, outbox):
  308. project = f.ProjectFactory()
  309. tester = f.RoleFactory(project=project, name="Tester")
  310. f.MembershipFactory(project=project, user=project.owner, is_admin=True)
  311. url = reverse("memberships-bulk-create")
  312. invitation_extra_text = "this is a not so random invitation text"
  313. data = {
  314. "project_id": project.id,
  315. "bulk_memberships": [
  316. {"role_id": tester.pk, "username": "john@email.com"},
  317. ],
  318. "invitation_extra_text": invitation_extra_text
  319. }
  320. client.login(project.owner)
  321. response = client.json.post(url, json.dumps(data))
  322. assert response.status_code == 200
  323. assert response.data[0]["email"] == "john@email.com"
  324. message = outbox[0]
  325. assert len(outbox) == 1
  326. assert message.to == ["john@email.com"]
  327. assert "this is a not so random invitation text" in message.body
  328. def test_api_resend_invitation(client, outbox):
  329. invitation = f.create_invitation(user=None)
  330. f.MembershipFactory(project=invitation.project, user=invitation.project.owner, is_admin=True)
  331. url = reverse("memberships-resend-invitation", kwargs={"pk": invitation.pk})
  332. client.login(invitation.project.owner)
  333. response = client.post(url)
  334. assert response.status_code == 204
  335. assert len(outbox) == 1
  336. assert outbox[0].to == [invitation.email]
  337. def test_api_invite_existing_user(client, outbox):
  338. "Should create the invitation linked to that user"
  339. user = f.UserFactory.create()
  340. role = f.RoleFactory.create()
  341. f.MembershipFactory(project=role.project, user=role.project.owner, is_admin=True)
  342. client.login(role.project.owner)
  343. url = reverse("memberships-list")
  344. data = {"role": role.pk, "project": role.project.pk, "username": user.email}
  345. response = client.json.post(url, json.dumps(data))
  346. assert response.status_code == 201, response.data
  347. assert len(outbox) == 1
  348. assert user.memberships.count() == 1
  349. message = outbox[0]
  350. assert message.to == [user.email]
  351. assert "Added to the project" in message.subject
  352. def test_api_create_invalid_membership_no_email_no_user(client):
  353. "Should not create the invitation linked to that user"
  354. user = f.UserFactory.create()
  355. role = f.RoleFactory.create()
  356. client.login(role.project.owner)
  357. url = reverse("memberships-list")
  358. data = {"role": role.pk, "project": role.project.pk}
  359. response = client.json.post(url, json.dumps(data))
  360. assert response.status_code == 400, response.data
  361. assert user.memberships.count() == 0
  362. def test_api_create_invalid_membership_role_doesnt_exist_in_the_project(client):
  363. "Should not create the invitation linked to that user"
  364. user = f.UserFactory.create()
  365. role = f.RoleFactory.create()
  366. project = f.ProjectFactory.create()
  367. client.login(project.owner)
  368. url = reverse("memberships-list")
  369. data = {"role": role.pk, "project": project.pk, "username": user.email}
  370. response = client.json.post(url, json.dumps(data))
  371. assert response.status_code == 400, response.data
  372. assert response.data["role"][0] == "Invalid role for the project"
  373. assert user.memberships.count() == 0
  374. def test_api_create_membership(client):
  375. membership = f.MembershipFactory(is_admin=True)
  376. role = f.RoleFactory.create(project=membership.project)
  377. user = f.UserFactory.create()
  378. client.login(membership.user)
  379. url = reverse("memberships-list")
  380. data = {"role": role.pk, "project": role.project.pk, "username": user.email}
  381. response = client.json.post(url, json.dumps(data))
  382. assert response.status_code == 201
  383. assert response.data["user_email"] == user.email
  384. def test_api_create_membership_with_unallowed_domain(client, settings):
  385. settings.USER_EMAIL_ALLOWED_DOMAINS = ['email.com']
  386. membership = f.MembershipFactory(is_admin=True)
  387. role = f.RoleFactory.create(project=membership.project)
  388. client.login(membership.user)
  389. url = reverse("memberships-list")
  390. data = {"role": role.pk, "project": role.project.pk, "username": "test@invalid-email.com"}
  391. response = client.json.post(url, json.dumps(data))
  392. assert response.status_code == 400
  393. assert "username" in response.data
  394. def test_api_create_membership_with_allowed_domain(client, settings):
  395. settings.USER_EMAIL_ALLOWED_DOMAINS = ['email.com']
  396. membership = f.MembershipFactory(is_admin=True)
  397. role = f.RoleFactory.create(project=membership.project)
  398. client.login(membership.user)
  399. url = reverse("memberships-list")
  400. data = {"role": role.pk, "project": role.project.pk, "username": "test@email.com"}
  401. response = client.json.post(url, json.dumps(data))
  402. assert response.status_code == 201
  403. assert response.data["email"] == "test@email.com"
  404. def test_api_create_membership_without_enough_memberships_private_project_slots_one_projects(client):
  405. user = f.UserFactory.create(max_memberships_private_projects=1)
  406. project = f.ProjectFactory(owner=user, is_private=True)
  407. role = f.RoleFactory(project=project, name="Test")
  408. f.MembershipFactory(project=project, user=user, is_admin=True)
  409. client.login(user)
  410. url = reverse("memberships-list")
  411. data = {"role": role.pk, "project": project.pk, "username": "test@test.com"}
  412. response = client.json.post(url, json.dumps(data))
  413. assert response.status_code == 400
  414. assert "reached your current limit of memberships for private" in response.data["_error_message"]
  415. def test_api_create_membership_with_enough_memberships_private_project_slots_multiple_projects(client):
  416. user = f.UserFactory.create(max_memberships_private_projects=5)
  417. project = f.ProjectFactory(owner=user, is_private=True)
  418. role = f.RoleFactory(project=project, name="Test")
  419. f.MembershipFactory(project=project, user=user, is_admin=True)
  420. other_project = f.ProjectFactory(owner=user)
  421. f.MembershipFactory.create(project=other_project)
  422. f.MembershipFactory.create(project=other_project)
  423. f.MembershipFactory.create(project=other_project)
  424. f.MembershipFactory.create(project=other_project)
  425. client.login(user)
  426. url = reverse("memberships-list")
  427. data = {"role": role.pk, "project": project.pk, "username": "test@test.com"}
  428. response = client.json.post(url, json.dumps(data))
  429. assert response.status_code == 201
  430. def test_api_create_membership_without_enough_memberships_public_project_slots_one_projects(client):
  431. user = f.UserFactory.create(max_memberships_public_projects=1)
  432. project = f.ProjectFactory(owner=user, is_private=False)
  433. role = f.RoleFactory(project=project, name="Test")
  434. f.MembershipFactory(project=project, user=user, is_admin=True)
  435. client.login(user)
  436. url = reverse("memberships-list")
  437. data = {"role": role.pk, "project": project.pk, "username": "test@test.com"}
  438. response = client.json.post(url, json.dumps(data))
  439. assert response.status_code == 400
  440. assert "reached your current limit of memberships for public" in response.data["_error_message"]
  441. def test_api_create_membership_with_enough_memberships_public_project_slots_multiple_projects(client):
  442. user = f.UserFactory.create(max_memberships_public_projects=5)
  443. project = f.ProjectFactory(owner=user, is_private=False)
  444. role = f.RoleFactory(project=project, name="Test")
  445. f.MembershipFactory(project=project, user=user, is_admin=True)
  446. other_project = f.ProjectFactory(owner=user)
  447. f.MembershipFactory.create(project=other_project)
  448. f.MembershipFactory.create(project=other_project)
  449. f.MembershipFactory.create(project=other_project)
  450. f.MembershipFactory.create(project=other_project)
  451. client.login(user)
  452. url = reverse("memberships-list")
  453. data = {"role": role.pk, "project": project.pk, "username": "test@test.com"}
  454. response = client.json.post(url, json.dumps(data))
  455. assert response.status_code == 201
  456. def test_api_edit_membership(client):
  457. membership = f.MembershipFactory(is_admin=True)
  458. client.login(membership.user)
  459. url = reverse("memberships-detail", args=[membership.id])
  460. data = {"username": "new@email.com"}
  461. response = client.json.patch(url, json.dumps(data))
  462. assert response.status_code == 200
  463. def test_api_edit_membership(client):
  464. membership = f.MembershipFactory(is_admin=True)
  465. client.login(membership.user)
  466. url = reverse("memberships-detail", args=[membership.id])
  467. data = {"username": "new@email.com"}
  468. response = client.json.patch(url, json.dumps(data))
  469. assert response.status_code == 200
  470. def test_api_change_owner_membership_to_no_admin_return_error(client):
  471. project = f.ProjectFactory()
  472. membership_owner = f.MembershipFactory(project=project, user=project.owner, is_admin=True)
  473. membership = f.MembershipFactory(project=project, is_admin=True)
  474. url = reverse("memberships-detail", args=[membership_owner.id])
  475. data = {"is_admin": False}
  476. client.login(membership.user)
  477. response = client.json.patch(url, json.dumps(data))
  478. assert response.status_code == 400
  479. assert 'is_admin' in response.data
  480. def test_api_delete_membership(client):
  481. membership = f.MembershipFactory(is_admin=True)
  482. client.login(membership.user)
  483. url = reverse("memberships-detail", args=[membership.id])
  484. response = client.json.delete(url)
  485. assert response.status_code == 400
  486. f.MembershipFactory(is_admin=True, project=membership.project)
  487. url = reverse("memberships-detail", args=[membership.id])
  488. response = client.json.delete(url)
  489. assert response.status_code == 204
  490. def test_api_delete_membership_without_user(client):
  491. membership_owner = f.MembershipFactory(is_admin=True)
  492. membership_without_user_one = f.MembershipFactory(project=membership_owner.project, user=None)
  493. f.MembershipFactory(project=membership_owner.project, user=None)
  494. client.login(membership_owner.user)
  495. url = reverse("memberships-detail", args=[membership_without_user_one.id])
  496. response = client.json.delete(url)
  497. assert response.status_code == 204
  498. def test_api_create_member_max_pending_memberships(client, settings):
  499. settings.MAX_PENDING_MEMBERSHIPS = 2
  500. project = f.ProjectFactory()
  501. john = f.UserFactory.create()
  502. joseph = f.UserFactory.create()
  503. tester = f.RoleFactory(project=project, name="Tester")
  504. f.MembershipFactory(project=project, user=john, is_admin=True)
  505. f.MembershipFactory(project=project, user=None)
  506. f.MembershipFactory(project=project, user=None)
  507. url = reverse("memberships-list")
  508. data = {"project": project.id, "role": tester.id, "username": joseph.email}
  509. client.login(john)
  510. response = client.json.post(url, json.dumps(data))
  511. assert response.status_code == 400
  512. assert "limit of pending memberships" in response.data["_error_message"]
  513. def test_api_create_bulk_members_max_pending_memberships(client, settings):
  514. settings.MAX_PENDING_MEMBERSHIPS = 2
  515. project = f.ProjectFactory()
  516. john = f.UserFactory.create()
  517. joseph = f.UserFactory.create()
  518. tester = f.RoleFactory(project=project, name="Tester")
  519. f.MembershipFactory(project=project, user=john, is_admin=True)
  520. f.MembershipFactory(project=project, user=None)
  521. f.MembershipFactory(project=project, user=None)
  522. url = reverse("memberships-bulk-create")
  523. data = {
  524. "project_id": project.id,
  525. "bulk_memberships": [
  526. {"role_id": tester.id, "username": "testing@taiga.io"},
  527. ]
  528. }
  529. client.login(john)
  530. response = client.json.post(url, json.dumps(data))
  531. assert response.status_code == 400
  532. assert "limit of pending memberships" in response.data["_error_message"]
  533. def test_create_memberhips_throttling(client, settings):
  534. settings.REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"]["create-memberships"] = "1/minute"
  535. membership = f.MembershipFactory(is_admin=True)
  536. role = f.RoleFactory.create(project=membership.project)
  537. user = f.UserFactory.create()
  538. user2 = f.UserFactory.create()
  539. client.login(membership.user)
  540. url = reverse("memberships-list")
  541. data = {"role": role.pk, "project": role.project.pk, "username": user.email}
  542. response = client.json.post(url, json.dumps(data))
  543. assert response.status_code == 201
  544. assert response.data["user_email"] == user.email
  545. data = {"role": role.pk, "project": role.project.pk, "username": user2.email}
  546. response = client.json.post(url, json.dumps(data))
  547. assert response.status_code == 429
  548. settings.REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"]["create-memberships"] = None
  549. def test_api_resend_invitation_throttling(client, outbox, settings):
  550. settings.REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"]["create-memberships"] = "1/minute"
  551. invitation = f.create_invitation(user=None)
  552. f.MembershipFactory(project=invitation.project, user=invitation.project.owner, is_admin=True)
  553. url = reverse("memberships-resend-invitation", kwargs={"pk": invitation.pk})
  554. client.login(invitation.project.owner)
  555. response = client.post(url)
  556. assert response.status_code == 204
  557. assert len(outbox) == 1
  558. assert outbox[0].to == [invitation.email]
  559. response = client.post(url)
  560. assert response.status_code == 429
  561. assert len(outbox) == 1
  562. assert outbox[0].to == [invitation.email]
  563. settings.REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"]["create-memberships"] = None
  564. def test_api_create_bulk_members_throttling(client, settings):
  565. settings.REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"]["create-memberships"] = "2/minute"
  566. project = f.ProjectFactory()
  567. john = f.UserFactory.create()
  568. joseph = f.UserFactory.create()
  569. other = f.UserFactory.create()
  570. tester = f.RoleFactory(project=project, name="Tester", permissions=["view_project"])
  571. gamer = f.RoleFactory(project=project, name="Gamer", permissions=["view_project"])
  572. f.MembershipFactory(project=project, user=john, role=tester, is_admin=True)
  573. # John and Other are members from another project
  574. project2 = f.ProjectFactory()
  575. f.MembershipFactory(project=project2, user=john, role=gamer, is_admin=True)
  576. f.MembershipFactory(project=project2, user=other, role=gamer)
  577. url = reverse("memberships-bulk-create")
  578. data = {
  579. "project_id": project.id,
  580. "bulk_memberships": [
  581. {"role_id": gamer.pk, "username": joseph.email},
  582. {"role_id": gamer.pk, "username": other.username},
  583. ]
  584. }
  585. client.login(john)
  586. response = client.json.post(url, json.dumps(data))
  587. assert response.status_code == 200
  588. response_user_ids = set([u["user"] for u in response.data])
  589. user_ids = {other.id, joseph.id}
  590. assert(user_ids.issubset(response_user_ids))
  591. response = client.json.post(url, json.dumps(data))
  592. assert response.status_code == 429
  593. settings.REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"]["create-memberships"] = None