test_api.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. from django.test import TestCase
  2. from django.urls import reverse
  3. from model_bakery import baker
  4. from apps.organizations_ext.models import OrganizationUserRole
  5. from ..models import Team
  6. class TeamAPITestCase(TestCase):
  7. def setUp(self):
  8. self.user = baker.make("users.user")
  9. self.organization = baker.make("organizations_ext.Organization")
  10. self.org_user = self.organization.add_user(self.user)
  11. self.client.force_login(self.user)
  12. def test_retrieve(self):
  13. team = baker.make("teams.Team", organization=self.organization)
  14. url = reverse("api:get_team", args=[self.organization.slug, team.slug])
  15. res = self.client.get(url)
  16. self.assertContains(res, team.slug)
  17. def test_delete(self):
  18. team = baker.make("teams.Team", organization=self.organization)
  19. url = reverse("api:delete_team", args=[self.organization.slug, team.slug])
  20. res = self.client.delete(url)
  21. self.assertTrue(res.status_code, 204)
  22. self.assertFalse(Team.objects.exists())
  23. team = baker.make("teams.Team", organization=self.organization)
  24. self.org_user.role = OrganizationUserRole.MEMBER
  25. self.org_user.save()
  26. url = reverse("api:delete_team", args=[self.organization.slug, team.slug])
  27. res = self.client.delete(url)
  28. self.assertTrue(res.status_code, 404)
  29. self.assertTrue(Team.objects.exists())
  30. def test_update(self):
  31. team = baker.make("teams.Team", organization=self.organization)
  32. url = reverse("api:update_team", args=[self.organization.slug, team.slug])
  33. slug = "newslug"
  34. res = self.client.put(url, data={"slug": slug}, content_type="application/json")
  35. self.assertContains(res, slug)
  36. team.refresh_from_db()
  37. self.assertEqual(team.slug, slug)
  38. def test_list(self):
  39. url = reverse("api:list_teams", args=[self.organization.slug])
  40. project = baker.make("projects.Project", organization=self.organization)
  41. team = baker.make(
  42. "teams.Team", organization=self.organization, projects=[project]
  43. )
  44. other_organization = baker.make("organizations_ext.Organization")
  45. other_organization.add_user(self.user)
  46. other_team = baker.make("teams.Team", organization=other_organization)
  47. res = self.client.get(url)
  48. self.assertContains(res, team.slug)
  49. self.assertContains(res, project.slug)
  50. self.assertNotContains(res, other_team.slug)
  51. def test_create(self):
  52. url = reverse("api:create_team", args=[self.organization.slug])
  53. data = {"slug": "te$m"}
  54. res = self.client.post(url, data, content_type="application/json")
  55. self.assertEqual(res.status_code, 422)
  56. data["slug"] = "t" * 51
  57. res = self.client.post(url, data, content_type="application/json")
  58. self.assertEqual(res.status_code, 422)
  59. data["slug"] = "team"
  60. res = self.client.post(url, data, content_type="application/json")
  61. self.assertContains(res, data["slug"], status_code=201)
  62. self.assertTrue(Team.objects.filter(slug=data["slug"]).exists())
  63. def test_unauthorized_create(self):
  64. """Only admins can create teams for that org"""
  65. data = {"slug": "team"}
  66. organization = baker.make("organizations_ext.Organization")
  67. url = reverse("api:list_teams", args=[organization.slug])
  68. res = self.client.post(url, data)
  69. # Not even in this org
  70. self.assertEqual(res.status_code, 400)
  71. admin_user = baker.make("users.user")
  72. organization.add_user(admin_user) # First user is always admin
  73. organization.add_user(self.user)
  74. res = self.client.post(url, data)
  75. # Not an admin
  76. self.assertEqual(res.status_code, 400)
  77. def test_invalid_create(self):
  78. url = reverse("api:list_teams", args=["haha"])
  79. data = {"slug": "team"}
  80. res = self.client.post(url, data)
  81. self.assertEqual(res.status_code, 400)
  82. def test_add_member_to_team(self):
  83. team = baker.make("teams.Team", organization=self.organization)
  84. org_user = baker.make(
  85. "organizations_ext.OrganizationUser", organization=self.organization
  86. )
  87. res = self.client.post(
  88. reverse(
  89. "api:add_member_to_team",
  90. args=[self.organization.slug, 9**9, team.slug],
  91. )
  92. )
  93. self.assertEqual(res.status_code, 404)
  94. self.assertEqual(team.members.count(), 0)
  95. res = self.client.post(
  96. reverse(
  97. "api:add_member_to_team",
  98. args=[self.organization.slug, "me", team.slug],
  99. )
  100. )
  101. self.assertEqual(res.status_code, 201)
  102. res = self.client.post(
  103. reverse(
  104. "api:add_member_to_team",
  105. args=[self.organization.slug, org_user.id, team.slug],
  106. )
  107. )
  108. self.assertEqual(res.status_code, 201)
  109. self.assertEqual(team.members.count(), 2)
  110. def test_delete_member_from_team(self):
  111. team = baker.make(
  112. "teams.Team", organization=self.organization, members=[self.org_user]
  113. )
  114. # Make sure correct org user is selected if user has more than one org
  115. other_org = baker.make("organizations_ext.Organization")
  116. baker.make(
  117. "organizations_ext.OrganizationUser", user=self.user, organization=other_org
  118. )
  119. res = self.client.delete(
  120. reverse(
  121. "api:delete_member_from_team",
  122. args=[self.organization.slug, "me", team.slug],
  123. )
  124. )
  125. self.assertEqual(res.status_code, 200)
  126. self.assertEqual(team.members.count(), 0)
  127. def test_organization_users_add_team_member_permission(self):
  128. self.org_user.role = OrganizationUserRole.MEMBER
  129. self.org_user.save()
  130. team = baker.make("teams.Team", organization=self.organization)
  131. url = reverse(
  132. "api:add_member_to_team",
  133. args=[self.organization.slug, self.org_user.id, team.slug],
  134. )
  135. # Add self with open membership
  136. res = self.client.post(url)
  137. self.assertEqual(res.status_code, 201)
  138. res = self.client.delete(url)
  139. # Can't add self without open membership
  140. self.organization.open_membership = False
  141. self.organization.save()
  142. res = self.client.post(url)
  143. self.assertEqual(res.status_code, 403)
  144. self.organization.open_membership = True
  145. self.organization.save()
  146. # Can't add someone else with open membership when not admin
  147. other_user = baker.make("users.User")
  148. other_org_user = self.organization.add_user(other_user)
  149. url = reverse(
  150. "api:add_member_to_team",
  151. args=[self.organization.slug, other_org_user.id, team.slug],
  152. )
  153. res = self.client.post(url)
  154. self.assertEqual(res.status_code, 403)
  155. # Can't add someone when admin and not in team
  156. self.org_user.role = OrganizationUserRole.ADMIN
  157. self.org_user.save()
  158. res = self.client.post(url)
  159. self.assertEqual(res.status_code, 403)
  160. # Can add someone when admin and in team
  161. team.members.add(self.org_user)
  162. res = self.client.post(url)
  163. self.assertEqual(res.status_code, 201)
  164. team.members.remove(self.org_user)
  165. team.members.remove(other_org_user)
  166. # Can add someone else when manager
  167. self.org_user.role = OrganizationUserRole.MANAGER
  168. self.org_user.save()
  169. res = self.client.post(url)
  170. self.assertEqual(res.status_code, 201)
  171. def test_list_project_teams(self):
  172. project = baker.make("projects.Project", organization=self.organization)
  173. url = reverse(
  174. "api:list_project_teams", args=[self.organization.slug, project.slug]
  175. )
  176. team = baker.make(
  177. "teams.Team", organization=self.organization, projects=[project]
  178. )
  179. other_team = baker.make("teams.Team", organization=self.organization)
  180. res = self.client.get(url)
  181. self.assertContains(res, team.slug)
  182. self.assertNotContains(res, other_team.slug)
  183. self.assertNotContains(res, "projects") # Should not have projects relationship
  184. def test_add_team_to_project(self):
  185. new_project = baker.make("projects.Project", organization=self.organization)
  186. team = baker.make("teams.Team", organization=self.organization)
  187. url = reverse(
  188. "api:add_team_to_project",
  189. kwargs={
  190. "organization_slug": self.organization.slug,
  191. "project_slug": new_project.slug,
  192. "team_slug": team.slug,
  193. },
  194. )
  195. self.assertFalse(new_project.teams.exists())
  196. res = self.client.post(url, content_type="application/json")
  197. self.assertContains(res, new_project.slug, status_code=201)
  198. self.assertTrue(new_project.teams.exists())
  199. def test_team_add_project_no_perms(self):
  200. """User must be manager or above to manage project teams"""
  201. team = baker.make("teams.Team", organization=self.organization)
  202. new_project = baker.make("projects.Project", organization=self.organization)
  203. user = baker.make("users.user")
  204. self.client.force_login(user)
  205. self.organization.add_user(user, OrganizationUserRole.MEMBER)
  206. url = reverse(
  207. "api:add_team_to_project",
  208. kwargs={
  209. "organization_slug": self.organization.slug,
  210. "project_slug": new_project.slug,
  211. "team_slug": team.slug,
  212. },
  213. )
  214. self.client.post(url)
  215. self.assertFalse(new_project.teams.exists())
  216. def test_delete_team_from_project(self):
  217. project = baker.make("projects.Project", organization=self.organization)
  218. team = baker.make(
  219. "teams.Team", organization=self.organization, projects=[project]
  220. )
  221. url = reverse(
  222. "api:delete_team_from_project",
  223. kwargs={
  224. "organization_slug": self.organization.slug,
  225. "project_slug": project.slug,
  226. "team_slug": team.slug,
  227. },
  228. )
  229. self.assertTrue(project.teams.exists())
  230. res = self.client.delete(url)
  231. self.assertContains(res, project.slug)
  232. self.assertFalse(project.teams.exists())