from django.test import TestCase from django.urls import reverse from model_bakery import baker from apps.organizations_ext.models import OrganizationUserRole from ..models import Team class TeamAPITestCase(TestCase): def setUp(self): self.user = baker.make("users.user") self.organization = baker.make("organizations_ext.Organization") self.org_user = self.organization.add_user(self.user) self.client.force_login(self.user) def test_retrieve(self): team = baker.make("teams.Team", organization=self.organization) url = reverse("api:get_team", args=[self.organization.slug, team.slug]) res = self.client.get(url) self.assertContains(res, team.slug) def test_delete(self): team = baker.make("teams.Team", organization=self.organization) url = reverse("api:delete_team", args=[self.organization.slug, team.slug]) res = self.client.delete(url) self.assertTrue(res.status_code, 204) self.assertFalse(Team.objects.exists()) team = baker.make("teams.Team", organization=self.organization) self.org_user.role = OrganizationUserRole.MEMBER self.org_user.save() url = reverse("api:delete_team", args=[self.organization.slug, team.slug]) res = self.client.delete(url) self.assertTrue(res.status_code, 404) self.assertTrue(Team.objects.exists()) def test_update(self): team = baker.make("teams.Team", organization=self.organization) url = reverse("api:update_team", args=[self.organization.slug, team.slug]) slug = "newslug" res = self.client.put(url, data={"slug": slug}, content_type="application/json") self.assertContains(res, slug) team.refresh_from_db() self.assertEqual(team.slug, slug) def test_list(self): url = reverse("api:list_teams", args=[self.organization.slug]) project = baker.make("projects.Project", organization=self.organization) team = baker.make( "teams.Team", organization=self.organization, projects=[project] ) other_organization = baker.make("organizations_ext.Organization") other_organization.add_user(self.user) other_team = baker.make("teams.Team", organization=other_organization) res = self.client.get(url) self.assertContains(res, team.slug) self.assertContains(res, project.slug) self.assertNotContains(res, other_team.slug) def test_create(self): url = reverse("api:create_team", args=[self.organization.slug]) data = {"slug": "te$m"} res = self.client.post(url, data, content_type="application/json") self.assertEqual(res.status_code, 422) data["slug"] = "t" * 51 res = self.client.post(url, data, content_type="application/json") self.assertEqual(res.status_code, 422) data["slug"] = "team" res = self.client.post(url, data, content_type="application/json") self.assertContains(res, data["slug"], status_code=201) self.assertTrue(Team.objects.filter(slug=data["slug"]).exists()) def test_unauthorized_create(self): """Only admins can create teams for that org""" data = {"slug": "team"} organization = baker.make("organizations_ext.Organization") url = reverse("api:list_teams", args=[organization.slug]) res = self.client.post(url, data) # Not even in this org self.assertEqual(res.status_code, 400) admin_user = baker.make("users.user") organization.add_user(admin_user) # First user is always admin organization.add_user(self.user) res = self.client.post(url, data) # Not an admin self.assertEqual(res.status_code, 400) def test_invalid_create(self): url = reverse("api:list_teams", args=["haha"]) data = {"slug": "team"} res = self.client.post(url, data) self.assertEqual(res.status_code, 400) def test_add_member_to_team(self): team = baker.make("teams.Team", organization=self.organization) org_user = baker.make( "organizations_ext.OrganizationUser", organization=self.organization ) res = self.client.post( reverse( "api:add_member_to_team", args=[self.organization.slug, 9**9, team.slug], ) ) self.assertEqual(res.status_code, 404) self.assertEqual(team.members.count(), 0) res = self.client.post( reverse( "api:add_member_to_team", args=[self.organization.slug, "me", team.slug], ) ) self.assertEqual(res.status_code, 201) res = self.client.post( reverse( "api:add_member_to_team", args=[self.organization.slug, org_user.id, team.slug], ) ) self.assertEqual(res.status_code, 201) self.assertEqual(team.members.count(), 2) def test_delete_member_from_team(self): team = baker.make( "teams.Team", organization=self.organization, members=[self.org_user] ) # Make sure correct org user is selected if user has more than one org other_org = baker.make("organizations_ext.Organization") baker.make( "organizations_ext.OrganizationUser", user=self.user, organization=other_org ) res = self.client.delete( reverse( "api:delete_member_from_team", args=[self.organization.slug, "me", team.slug], ) ) self.assertEqual(res.status_code, 200) self.assertEqual(team.members.count(), 0) def test_organization_users_add_team_member_permission(self): self.org_user.role = OrganizationUserRole.MEMBER self.org_user.save() team = baker.make("teams.Team", organization=self.organization) url = reverse( "api:add_member_to_team", args=[self.organization.slug, self.org_user.id, team.slug], ) # Add self with open membership res = self.client.post(url) self.assertEqual(res.status_code, 201) res = self.client.delete(url) # Can't add self without open membership self.organization.open_membership = False self.organization.save() res = self.client.post(url) self.assertEqual(res.status_code, 403) self.organization.open_membership = True self.organization.save() # Can't add someone else with open membership when not admin other_user = baker.make("users.User") other_org_user = self.organization.add_user(other_user) url = reverse( "api:add_member_to_team", args=[self.organization.slug, other_org_user.id, team.slug], ) res = self.client.post(url) self.assertEqual(res.status_code, 403) # Can't add someone when admin and not in team self.org_user.role = OrganizationUserRole.ADMIN self.org_user.save() res = self.client.post(url) self.assertEqual(res.status_code, 403) # Can add someone when admin and in team team.members.add(self.org_user) res = self.client.post(url) self.assertEqual(res.status_code, 201) team.members.remove(self.org_user) team.members.remove(other_org_user) # Can add someone else when manager self.org_user.role = OrganizationUserRole.MANAGER self.org_user.save() res = self.client.post(url) self.assertEqual(res.status_code, 201) def test_list_project_teams(self): project = baker.make("projects.Project", organization=self.organization) url = reverse( "api:list_project_teams", args=[self.organization.slug, project.slug] ) team = baker.make( "teams.Team", organization=self.organization, projects=[project] ) other_team = baker.make("teams.Team", organization=self.organization) res = self.client.get(url) self.assertContains(res, team.slug) self.assertNotContains(res, other_team.slug) self.assertNotContains(res, "projects") # Should not have projects relationship def test_add_team_to_project(self): new_project = baker.make("projects.Project", organization=self.organization) team = baker.make("teams.Team", organization=self.organization) url = reverse( "api:add_team_to_project", kwargs={ "organization_slug": self.organization.slug, "project_slug": new_project.slug, "team_slug": team.slug, }, ) self.assertFalse(new_project.teams.exists()) res = self.client.post(url, content_type="application/json") self.assertContains(res, new_project.slug, status_code=201) self.assertTrue(new_project.teams.exists()) def test_team_add_project_no_perms(self): """User must be manager or above to manage project teams""" team = baker.make("teams.Team", organization=self.organization) new_project = baker.make("projects.Project", organization=self.organization) user = baker.make("users.user") self.client.force_login(user) self.organization.add_user(user, OrganizationUserRole.MEMBER) url = reverse( "api:add_team_to_project", kwargs={ "organization_slug": self.organization.slug, "project_slug": new_project.slug, "team_slug": team.slug, }, ) self.client.post(url) self.assertFalse(new_project.teams.exists()) def test_delete_team_from_project(self): project = baker.make("projects.Project", organization=self.organization) team = baker.make( "teams.Team", organization=self.organization, projects=[project] ) url = reverse( "api:delete_team_from_project", kwargs={ "organization_slug": self.organization.slug, "project_slug": project.slug, "team_slug": team.slug, }, ) self.assertTrue(project.teams.exists()) res = self.client.delete(url) self.assertContains(res, project.slug) self.assertFalse(project.teams.exists())