tests.py 8.3 KB

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