123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- from django.test import TestCase
- from django.urls import reverse
- from django.utils import timezone
- from model_bakery import baker
- from apps.organizations_ext.constants import OrganizationUserRole
- from ..models import Project, ProjectKey
- class ProjectsAPITestCase(TestCase):
- @classmethod
- def setUpTestData(cls):
- cls.user = baker.make("users.user")
- cls.organization = baker.make("organizations_ext.Organization")
- cls.org_user = cls.organization.add_user(
- cls.user, role=OrganizationUserRole.OWNER
- )
- cls.project = baker.make(
- "projects.Project",
- organization=cls.organization,
- name="Alpha",
- first_event=timezone.now(),
- )
- cls.team = baker.make(
- "teams.Team",
- organization=cls.organization,
- members=[cls.org_user],
- projects=[cls.project],
- )
- cls.url = reverse("api:list_projects")
- cls.detail_url = reverse(
- "api:get_project", args=[cls.organization.slug, cls.project.slug]
- )
- cls.update_url = reverse(
- "api:update_project", args=[cls.organization.slug, cls.project.slug]
- )
- def setUp(self):
- self.client.force_login(self.user)
- def test_projects_api_list(self):
- # Ensure project annotate_is_member works with two teams on one project
- baker.make(
- "teams.Team",
- organization=self.organization,
- members=[self.org_user],
- projects=[self.project],
- )
- res = self.client.get(self.url)
- self.assertContains(res, self.organization.name)
- data = res.json()[0]
- self.assertIsInstance(data["id"], str)
- self.assertEqual(data["name"], self.project.name)
- self.assertTrue(data["isMember"])
- data_keys = res.json()[0].keys()
- self.assertNotIn("keys", data_keys, "Project keys shouldn't be in list")
- self.assertNotIn("teams", data_keys, "Teams shouldn't be in list")
- def test_default_ordering(self):
- projectA = self.project
- projectZ = baker.make(
- "projects.Project", organization=self.organization, name="Z Proj"
- )
- baker.make("projects.Project", organization=self.organization, name="B Proj")
- res = self.client.get(self.url)
- data = res.json()
- self.assertEqual(data[0]["name"], projectA.name)
- self.assertEqual(data[2]["name"], projectZ.name)
- def test_projects_api_retrieve(self):
- res = self.client.get(self.detail_url)
- self.assertTrue(res.json()["firstEvent"])
- def test_projects_api_update(self):
- self.assertEqual(self.project.event_throttle_rate, 0)
- self.assertEqual(self.project.platform, None)
- res = self.client.put(
- self.update_url,
- {
- "name": "New Name",
- "eventThrottleRate": 50,
- "platform": "python",
- },
- content_type="application/json",
- )
- self.assertEqual(res.status_code, 200)
- self.project.refresh_from_db()
- self.assertEqual(self.project.name, "New Name")
- self.assertEqual(self.project.event_throttle_rate, 50)
- self.assertEqual(self.project.platform, "python")
- def test_projects_pagination(self):
- """
- Test link header pagination
- """
- page_size = 50
- firstProject = self.project
- baker.make(
- "projects.Project",
- organization=self.organization,
- name="B",
- _quantity=page_size,
- )
- lastProject = baker.make(
- "projects.Project",
- organization=self.organization,
- name="Last Alphabetically",
- )
- res = self.client.get(self.url)
- self.assertNotContains(res, lastProject.name)
- self.assertContains(res, firstProject.name)
- link_header = res.get("Link")
- self.assertIn('results="true"', link_header)
- def test_project_isolation(self):
- """Users should only access projects in their organization"""
- user2 = baker.make("users.user")
- org2 = baker.make("organizations_ext.Organization")
- org2.add_user(user2)
- project1 = self.project
- project2 = baker.make("projects.Project", organization=org2)
- res = self.client.get(self.url)
- self.assertContains(res, project1.name)
- self.assertNotContains(res, project2.name)
- def test_project_delete(self):
- team = baker.make("teams.Team", organization=self.organization)
- self.project.teams.add(team)
- res = self.client.delete(self.detail_url)
- self.assertEqual(res.status_code, 204)
- self.assertEqual(Project.objects.all().count(), 0)
- def test_project_invalid_delete(self):
- """Cannot delete projects that are not in the organization the user is an admin of"""
- organization = baker.make("organizations_ext.Organization")
- organization.add_user(self.user, OrganizationUserRole.ADMIN)
- project = baker.make("projects.Project")
- url = reverse("api:delete_project", args=[organization.slug, project.slug])
- res = self.client.delete(url)
- self.assertEqual(res.status_code, 404)
- class TeamProjectsAPITestCase(TestCase):
- def setUp(self):
- self.user = baker.make("users.user")
- self.organization = baker.make("organizations_ext.Organization")
- self.organization.add_user(self.user, OrganizationUserRole.ADMIN)
- self.team = baker.make("teams.Team", organization=self.organization)
- self.client.force_login(self.user)
- self.url = reverse(
- "api:list_team_projects", args=[self.organization.slug, self.team.slug]
- )
- def test_list(self):
- project = baker.make("projects.Project", organization=self.organization)
- project.teams.add(self.team)
- not_my_project = baker.make("projects.Project")
- res = self.client.get(self.url)
- self.assertContains(res, project.name)
- self.assertNotContains(res, not_my_project.name)
- # If a user is in multiple orgs, that user will have multiple org users.
- # Make sure endpoint doesn't show projects from other orgs
- second_org = baker.make("organizations_ext.Organization")
- second_org.add_user(self.user, OrganizationUserRole.ADMIN)
- project_in_second_org = baker.make("projects.Project", organization=second_org)
- res = self.client.get(self.url)
- self.assertNotContains(res, project_in_second_org.name)
- # Only show projects that are associated with the team in the URL.
- # If a project is on another team in the same org, it should not show
- project_teamless = baker.make(
- "projects.Project", organization=self.organization
- )
- res = self.client.get(self.url)
- self.assertNotContains(res, project_teamless)
- def test_create(self):
- data = {"name": "test-team"}
- res = self.client.post(self.url, data, content_type="application/json")
- res = self.assertContains(res, data["name"], status_code=201)
- res = self.client.get(self.url)
- self.assertContains(res, data["name"])
- self.assertEqual(ProjectKey.objects.all().count(), 1)
- def test_projects_api_create_unique_slug(self):
- name = "test project"
- data = {"name": name}
- res = self.client.post(self.url, data, content_type="application/json")
- first_project = Project.objects.get()
- res = self.client.post(self.url, data, content_type="application/json")
- self.assertContains(res, name, status_code=201)
- projects = Project.objects.all()
- self.assertNotEqual(projects[0].slug, projects[1].slug)
- self.assertEqual(ProjectKey.objects.all().count(), 2)
- org2 = baker.make("organizations_ext.Organization")
- org2_project = Project.objects.create(name=name, organization=org2)
- # The same slug can exist between multiple organizations
- self.assertEqual(first_project.slug, org2_project.slug)
- def test_projects_api_project_has_team(self):
- """
- The frontend UI requires you to assign a new project to a team, so make sure
- that the new project has a team associated with it
- """
- name = "test project"
- data = {"name": name}
- self.client.post(self.url, data, content_type="application/json")
- project = Project.objects.first()
- self.assertEqual(project.teams.all().count(), 1)
- def test_project_reserved_words(self):
- data = {"name": "new"}
- res = self.client.post(self.url, data, content_type="application/json")
- self.assertContains(res, "new-1", status_code=201)
- self.client.post(self.url, data)
- self.assertFalse(Project.objects.filter(slug="new").exists())
|