import json from django.urls import reverse from konova.settings import DEFAULT_GROUP from konova.tests.test_views import BaseTestCase from konova.utils.user_checks import is_default_group_only class BaseAPIV1TestCase(BaseTestCase): @classmethod def setUpTestData(cls): super().setUpTestData() cls.superuser.get_API_token() cls.superuser.api_token.is_active = True cls.superuser.api_token.save() default_group = cls.groups.get(name=DEFAULT_GROUP) cls.superuser.groups.add(default_group) cls.header_data = { "HTTP_ksptoken": cls.superuser.api_token.token, "HTTP_kspuser": cls.superuser.username, } class APIV1SharingTestCase(BaseAPIV1TestCase): @classmethod def setUpTestData(cls): super().setUpTestData() def _run_share_request(self, url, user_list: list): data = { "users": user_list } data = json.dumps(data) response = self.client.put( url, data, **self.header_data ) return response def _test_api_sharing(self, obj, url): """ Generic test for testing sharing of a ShareableObjectMixin object Args: obj (ShareableObjectMixin): The object url (str): The url to be used for a request Returns: """ self.assertEqual(obj.users.count(), 0) user_list = [ self.superuser.username, self.user.username, ] response = self._run_share_request(url, user_list) # Must fail, since performing user has no access on requested object self.assertEqual(response.status_code, 500) self.assertTrue(len(json.loads(response.content.decode("utf-8")).get("errors", [])) > 0) # Add performing user to shared access users and rerun the request obj.users.add(self.superuser) response = self._run_share_request(url, user_list) shared_users = obj.shared_users self.assertEqual(response.status_code, 200) self.assertEqual(shared_users.count(), 2) self.assertIn(self.superuser, shared_users) self.assertIn(self.user, shared_users) def test_api_token_invalid(self): """ Tests that a request with an invalid token won't be successfull Returns: """ share_url = reverse("api:v1:intervention-share", args=(self.intervention.id,)) # Expect the first request to work properly self.intervention.users.add(self.superuser) response = self._run_share_request(share_url, [self.superuser.username]) self.assertEqual(response.status_code, 200) # Change the token self.header_data["HTTP_ksptoken"] = f"{self.superuser.api_token.token}__X" # Expect the request to fail now response = self._run_share_request(share_url, [self.superuser.username]) self.assertEqual(response.status_code, 403) def test_api_intervention_sharing(self): """ Tests proper sharing of intervention Returns: """ share_url = reverse("api:v1:intervention-share", args=(self.intervention.id,)) self._test_api_sharing(self.intervention, share_url) def test_api_eco_account_sharing(self): """ Tests proper sharing of eco account Returns: """ share_url = reverse("api:v1:ecoaccount-share", args=(self.eco_account.id,)) self._test_api_sharing(self.eco_account, share_url) def test_api_ema_sharing(self): """ Tests proper sharing of ema Returns: """ share_url = reverse("api:v1:ema-share", args=(self.ema.id,)) self._test_api_sharing(self.ema, share_url) def test_api_sharing_as_default_group_only(self): """ Tests that sharing using the API as an only default group user works as expected. Expected: Default only user can only add new users, having shared access. Removing them from the list of users having shared access is only possible if the user has further rights, e.g. being part of a registration or conservation office group. Returns: """ share_url = reverse("api:v1:intervention-share", args=(self.intervention.id,)) # Give the user only default group rights default_group = self.groups.get(name=DEFAULT_GROUP) self.superuser.groups.set([default_group]) self.assertTrue(is_default_group_only(self.superuser)) # Add only him as shared_users an object self.intervention.users.set([self.superuser]) self.assertEqual(self.intervention.users.count(), 1) # Try to add another user via API -> must work! response = self._run_share_request(share_url, [self.superuser.username, self.user.username]) self.assertEqual(response.status_code, 200) self.assertEqual(self.intervention.users.count(), 2) # Now try to remove the user again -> expect no changes at all to the shared user list response = self._run_share_request(share_url, [self.superuser.username]) self.assertEqual(response.status_code, 200) self.assertEqual(self.intervention.users.count(), 2)