tests.py 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. from django.conf import settings
  2. from django.shortcuts import reverse
  3. from django.utils import timezone
  4. from rest_framework.test import APITestCase
  5. from model_bakery import baker
  6. from glitchtip import test_utils # pylint: disable=unused-import
  7. from organizations_ext.models import OrganizationUserRole
  8. from ..models import ProjectKey, Project
  9. class ProjectsAPITestCase(APITestCase):
  10. def setUp(self):
  11. self.user = baker.make("users.user")
  12. self.client.force_login(self.user)
  13. self.url = reverse("project-list")
  14. def test_projects_api_create(self):
  15. """ This endpoint can't be used to create """
  16. data = {"name": "test"}
  17. res = self.client.post(self.url, data)
  18. # Must specify organization and team
  19. self.assertEqual(res.status_code, 405)
  20. def test_projects_api_list(self):
  21. organization = baker.make("organizations_ext.Organization")
  22. organization.add_user(self.user, role=OrganizationUserRole.OWNER)
  23. project = baker.make("projects.Project", organization=organization)
  24. res = self.client.get(self.url)
  25. self.assertContains(res, project.name)
  26. def test_projects_api_retrieve(self):
  27. organization = baker.make("organizations_ext.Organization")
  28. organization.add_user(self.user, role=OrganizationUserRole.OWNER)
  29. project = baker.make(
  30. "projects.Project", organization=organization, first_event=timezone.now()
  31. )
  32. res = self.client.get(
  33. reverse(
  34. "project-detail", kwargs={"pk": organization.slug + "/" + project.slug}
  35. )
  36. )
  37. self.assertTrue(res.data["firstEvent"])
  38. def test_projects_pagination(self):
  39. """
  40. Test link header pagination
  41. """
  42. page_size = settings.REST_FRAMEWORK.get("PAGE_SIZE")
  43. organization = baker.make("organizations_ext.Organization")
  44. organization.add_user(self.user, role=OrganizationUserRole.OWNER)
  45. projects = baker.make(
  46. "projects.Project", organization=organization, _quantity=page_size + 1
  47. )
  48. res = self.client.get(self.url)
  49. self.assertNotContains(res, projects[0].name)
  50. self.assertContains(res, projects[-1].name)
  51. link_header = res.get("Link")
  52. self.assertIn('results="true"', link_header)
  53. def test_project_isolation(self):
  54. """ Users should only access projects in their organization """
  55. user1 = self.user
  56. user2 = baker.make("users.user")
  57. org1 = baker.make("organizations_ext.Organization")
  58. org2 = baker.make("organizations_ext.Organization")
  59. org1.add_user(user1)
  60. org2.add_user(user2)
  61. project1 = baker.make("projects.Project", organization=org1)
  62. project2 = baker.make("projects.Project", organization=org2)
  63. res = self.client.get(self.url)
  64. self.assertContains(res, project1.name)
  65. self.assertNotContains(res, project2.name)
  66. def test_project_delete(self):
  67. organization = baker.make("organizations_ext.Organization")
  68. organization.add_user(self.user, OrganizationUserRole.ADMIN)
  69. team = baker.make("teams.Team", organization=organization)
  70. project = baker.make("projects.Project", organization=organization, team=team)
  71. url = reverse(
  72. "project-detail", kwargs={"pk": f"{organization.slug}/{project.slug}"}
  73. )
  74. res = self.client.delete(url)
  75. self.assertEqual(res.status_code, 204)
  76. self.assertEqual(Project.objects.all().count(), 0)
  77. def test_project_invalid_delete(self):
  78. """ Cannot delete projects that are not in the organization the user is an admin of """
  79. organization = baker.make("organizations_ext.Organization")
  80. organization.add_user(self.user, OrganizationUserRole.ADMIN)
  81. project = baker.make("projects.Project")
  82. url = reverse(
  83. "project-detail", kwargs={"pk": f"{organization.slug}/{project.slug}"}
  84. )
  85. res = self.client.delete(url)
  86. self.assertEqual(res.status_code, 404)
  87. class TeamProjectsAPITestCase(APITestCase):
  88. def setUp(self):
  89. self.user = baker.make("users.user")
  90. self.organization = baker.make("organizations_ext.Organization")
  91. self.organization.add_user(self.user, OrganizationUserRole.ADMIN)
  92. self.team = baker.make("teams.Team", organization=self.organization)
  93. self.client.force_login(self.user)
  94. self.url = reverse(
  95. "team-projects-list",
  96. kwargs={"team_pk": f"{self.organization.slug}/{self.team.slug}"},
  97. )
  98. def test_list(self):
  99. project = baker.make("projects.Project", organization=self.organization)
  100. project.team_set.add(self.team)
  101. not_my_project = baker.make("projects.Project")
  102. res = self.client.get(self.url)
  103. self.assertContains(res, project.name)
  104. self.assertNotContains(res, not_my_project.name)
  105. """
  106. If a user is in multiple orgs, that user will have multiple org users.
  107. Make sure endpoint doesn't show projects from other orgs
  108. """
  109. second_org = baker.make("organizations_ext.Organization")
  110. second_org.add_user(self.user, OrganizationUserRole.ADMIN)
  111. project_in_second_org = baker.make("projects.Project", organization=second_org)
  112. res = self.client.get(self.url)
  113. self.assertNotContains(res, project_in_second_org.name)
  114. """
  115. Only show projects that are associated with the team in the URL.
  116. If a project is on another team in the same org, it should not show
  117. """
  118. project_teamless = baker.make(
  119. "projects.Project", organization=self.organization
  120. )
  121. res = self.client.get(self.url)
  122. self.assertNotContains(res, project_teamless)
  123. def test_create(self):
  124. data = {"name": "test-team"}
  125. res = self.client.post(self.url, data)
  126. self.assertContains(res, data["name"], status_code=201)
  127. res = self.client.get(self.url)
  128. self.assertContains(res, data["name"])
  129. self.assertEqual(ProjectKey.objects.all().count(), 1)
  130. def test_projects_api_create_unique_slug(self):
  131. name = "test project"
  132. data = {"name": name}
  133. res = self.client.post(self.url, data)
  134. res = self.client.post(self.url, data)
  135. self.assertContains(res, name, status_code=201)
  136. projects = Project.objects.all()
  137. self.assertNotEqual(projects[0].slug, projects[1].slug)
  138. self.assertEqual(ProjectKey.objects.all().count(), 2)
  139. org2 = baker.make("organizations_ext.Organization")
  140. org2_project = Project.objects.create(name=name, organization=org2)
  141. # The same slug can exist between multiple organizations
  142. self.assertEqual(projects[0].slug, org2_project.slug)
  143. """
  144. The frontend UI requires you to assign a new project to a team, so make sure
  145. that the new project has a team associated with it
  146. """
  147. def test_projects_api_project_has_team(self):
  148. name = "test project"
  149. data = {"name": name}
  150. res = self.client.post(self.url, data)
  151. project = Project.objects.first()
  152. self.assertEqual(project.team_set.all().count(), 1)