<filename>app/api/tests/test_friend_request_api.py
from django.test import TestCase
from django.urls import reverse

from rest_framework.test import APIClient
from rest_framework import status

from .utils import create_user, create_friend_request

from core.models import FriendRequest

CREATE_FRIEND_REQUEST_URL = reverse('api:friend_request_create')
LIST_FRIEND_REQUEST_URL = reverse('api:friend_request_list')
MANAGE_FRIEND_REQUEST_URL = 'api:friend_request_manage'


class TestPublicFriendRequestAPI(TestCase):
    """Tests for the public API for the FriendRequest model"""

    def setUp(self) -> None:
        """Sets up the APIClient for the tests and creates users"""

        self.user_one = create_user(
            email='<EMAIL>',
            password='<PASSWORD>',
            username='test_username_one',
        )
        self.user_two = create_user(
            email='<EMAIL>',
            password='<PASSWORD>',
            username='test_username_two',
        )
        self.client = APIClient()

    def test_create_friend_request_unauthorized(self) -> None:
        """
        Tests what happens if a FriendRequest is created by an anonymous User
        """

        payload = {'to_user': self.user_one, 'from_user': self.user_two}
        response = self.client.post(CREATE_FRIEND_REQUEST_URL, payload)

        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

    def test_list_friend_request_unauthorized(self) -> None:
        """
        Tests what happens if a FriendRequest is listed by an anonymous User
        """

        response = self.client.get(LIST_FRIEND_REQUEST_URL)

        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

    def test_manage_friend_request_unauthorized(self) -> None:
        """
        Tests what happens if a FriendRequest is managed by an anonymous User
        """

        data = {'to_user': self.user_one, 'from_user': self.user_two}
        friend_request = create_friend_request(**data)
        response = self.client.get(
            reverse(
                MANAGE_FRIEND_REQUEST_URL, kwargs={'pk': friend_request.pk}
            )
        )

        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)


class TestFriendRequestPrivateAPI(TestCase):
    """Tests for the private API for the FriendRequest model"""

    def setUp(self) -> None:
        """Creates client and users for the tests"""

        self.user_one = create_user(
            email='<EMAIL>',
            password='<PASSWORD>',
            username='test_username_one',
        )
        self.user_two = create_user(
            email='<EMAIL>',
            password='<PASSWORD>',
            username='test_username_two',
        )
        self.client = APIClient()
        self.client.force_authenticate(self.user_one)

    def test_create_friend_request_successfully(self) -> None:
        """Tests if a FriendRequest is created successfully"""

        payload = {
            'crypto_key': self.user_two.crypto_key,
            'from_user': self.user_one.pk,
        }
        response = self.client.post(CREATE_FRIEND_REQUEST_URL, payload)

        self.assertEqual(response.status_code, status.HTTP_201_CREATED)

    def test_create_friend_request_already_exists_sent_by_user(self) -> None:
        """
        Tests if a FriendRequest isn't created when the
        same one has already been sent by User
        """

        create_friend_request(to_user=self.user_two, from_user=self.user_one)
        payload = {
            'crypto_key': self.user_two.crypto_key,
            'from_user': self.user_one.pk,
        }
        response = self.client.post(CREATE_FRIEND_REQUEST_URL, payload)

        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

    def test_create_friend_request_already_exists_sent_to_user(self) -> None:
        """
        Tests if a FriendRequest isn't created when the
        same one has already been sent to User
        """

        create_friend_request(to_user=self.user_two, from_user=self.user_one)
        payload = {
            'crypto_key': self.user_one.crypto_key,
            'from_user': self.user_two.pk,
        }
        response = self.client.post(CREATE_FRIEND_REQUEST_URL, payload)

        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

    def test_create_friend_request_no_crypto_key_provided(self) -> None:
        """
        Tests if a FriendRequest isn't created when 'crypto_key' isn't provided
        """

        payload = {'from_user': self.user_one.pk}
        response = self.client.post(CREATE_FRIEND_REQUEST_URL, payload)

        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
        self.assertIn(b'No \'crypto_key\' provided', response.content)

    def test_list_friend_request_successfully(self) -> None:
        """Tests if a FriendRequest is listed successfully"""

        data = {'to_user': self.user_one, 'from_user': self.user_two}
        create_friend_request(**data)
        response = self.client.get(LIST_FRIEND_REQUEST_URL)

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(len(response.data), 1)

    def test_manage_friend_request_does_not_exist(self) -> None:
        """
        Tests what happens when User tries to
        access FriendRequest, which doesn't exist
        """

        response = self.client.get(
            reverse(MANAGE_FRIEND_REQUEST_URL, kwargs={'pk': 1})
        )

        self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)

    def test_manage_friend_request_forbidden(self) -> None:
        """
        Tests what happens when User tries to
        access FriendRequest, which wasn't meant for them
        """

        data = {'to_user': self.user_two, 'from_user': self.user_one}
        friend_request = create_friend_request(**data)
        response = self.client.get(
            reverse(
                MANAGE_FRIEND_REQUEST_URL, kwargs={'pk': friend_request.pk}
            )
        )
        message = b'You don\'t have permission to manage this FriendRequest'

        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
        self.assertIn(message, response.content)

    def test_retrieve_friend_request_successfully(self) -> None:
        """Tests if a FriendRequest is retrieved successfully"""

        data = {'to_user': self.user_one, 'from_user': self.user_two}
        friend_request = create_friend_request(**data)
        response = self.client.get(
            reverse(
                MANAGE_FRIEND_REQUEST_URL, kwargs={'pk': friend_request.pk}
            )
        )
        expected_data = {
            'from_user': self.user_two.pk,
            'to_user': self.user_one.pk,
            'is_new': True,
            'is_accepted': False,
        }

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data, expected_data)

    def test_update_friend_request_successfully(self) -> None:
        """Tests if a FriendRequest is updated successfully"""

        data = {'to_user': self.user_one, 'from_user': self.user_two}
        friend_request = create_friend_request(**data)
        response = self.client.patch(
            reverse(
                MANAGE_FRIEND_REQUEST_URL, kwargs={'pk': friend_request.pk}
            ),
            {'is_new': False, 'is_accepted': True},
        )
        friend_request.refresh_from_db()

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertFalse(friend_request.is_new)
        self.assertTrue(friend_request.is_accepted)

    def test_delete_friend_request_successfully(self) -> None:
        """Tests if a FriendRequest is deleted successfully"""

        data = {'to_user': self.user_one, 'from_user': self.user_two}
        friend_request = create_friend_request(**data)
        response = self.client.delete(
            reverse(
                MANAGE_FRIEND_REQUEST_URL, kwargs={'pk': friend_request.pk}
            )
        )
        friend_request_exists = FriendRequest.objects.filter(
            pk=friend_request.pk
        ).exists()

        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
        self.assertFalse(friend_request_exists)

<filename>app/api/tests/test_friend_request_api.py
from django.test import TestCase
from django.urls import reverse

from rest_framework.test import APIClient
from rest_framework import status

from .utils import create_user, create_friend_request

from core.models import FriendRequest

CREATE_FRIEND_REQUEST_URL = reverse('api:friend_request_create')
LIST_FRIEND_REQUEST_URL = reverse('api:friend_request_list')
MANAGE_FRIEND_REQUEST_URL = 'api:friend_request_manage'


class TestPublicFriendRequestAPI(TestCase):
    """Tests for the public API for the FriendRequest model"""

    def setUp(self) -> None:
        """Sets up the APIClient for the tests and creates users"""

        self.user_one = create_user(
            email='<EMAIL>',
            password='<PASSWORD>',
            username='test_username_one',
        )
        self.user_two = create_user(
            email='<EMAIL>',
            password='<PASSWORD>',
            username='test_username_two',
        )
        self.client = APIClient()

    def test_create_friend_request_unauthorized(self) -> None:
        """
        Tests what happens if a FriendRequest is created by an anonymous User
        """

        payload = {'to_user': self.user_one, 'from_user': self.user_two}
        response = self.client.post(CREATE_FRIEND_REQUEST_URL, payload)

        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

    def test_list_friend_request_unauthorized(self) -> None:
        """
        Tests what happens if a FriendRequest is listed by an anonymous User
        """

        response = self.client.get(LIST_FRIEND_REQUEST_URL)

        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

    def test_manage_friend_request_unauthorized(self) -> None:
        """
        Tests what happens if a FriendRequest is managed by an anonymous User
        """

        data = {'to_user': self.user_one, 'from_user': self.user_two}
        friend_request = create_friend_request(**data)
        response = self.client.get(
            reverse(
                MANAGE_FRIEND_REQUEST_URL, kwargs={'pk': friend_request.pk}
            )
        )

        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)


class TestFriendRequestPrivateAPI(TestCase):
    """Tests for the private API for the FriendRequest model"""

    def setUp(self) -> None:
        """Creates client and users for the tests"""

        self.user_one = create_user(
            email='<EMAIL>',
            password='<PASSWORD>',
            username='test_username_one',
        )
        self.user_two = create_user(
            email='<EMAIL>',
            password='<PASSWORD>',
            username='test_username_two',
        )
        self.client = APIClient()
        self.client.force_authenticate(self.user_one)

    def test_create_friend_request_successfully(self) -> None:
        """Tests if a FriendRequest is created successfully"""

        payload = {
            'crypto_key': self.user_two.crypto_key,
            'from_user': self.user_one.pk,
        }
        response = self.client.post(CREATE_FRIEND_REQUEST_URL, payload)

        self.assertEqual(response.status_code, status.HTTP_201_CREATED)

    def test_create_friend_request_already_exists_sent_by_user(self) -> None:
        """
        Tests if a FriendRequest isn't created when the
        same one has already been sent by User
        """

        create_friend_request(to_user=self.user_two, from_user=self.user_one)
        payload = {
            'crypto_key': self.user_two.crypto_key,
            'from_user': self.user_one.pk,
        }
        response = self.client.post(CREATE_FRIEND_REQUEST_URL, payload)

        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

    def test_create_friend_request_already_exists_sent_to_user(self) -> None:
        """
        Tests if a FriendRequest isn't created when the
        same one has already been sent to User
        """

        create_friend_request(to_user=self.user_two, from_user=self.user_one)
        payload = {
            'crypto_key': self.user_one.crypto_key,
            'from_user': self.user_two.pk,
        }
        response = self.client.post(CREATE_FRIEND_REQUEST_URL, payload)

        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

    def test_create_friend_request_no_crypto_key_provided(self) -> None:
        """
        Tests if a FriendRequest isn't created when 'crypto_key' isn't provided
        """

        payload = {'from_user': self.user_one.pk}
        response = self.client.post(CREATE_FRIEND_REQUEST_URL, payload)

        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
        self.assertIn(b'No \'crypto_key\' provided', response.content)

    def test_list_friend_request_successfully(self) -> None:
        """Tests if a FriendRequest is listed successfully"""

        data = {'to_user': self.user_one, 'from_user': self.user_two}
        create_friend_request(**data)
        response = self.client.get(LIST_FRIEND_REQUEST_URL)

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(len(response.data), 1)

    def test_manage_friend_request_does_not_exist(self) -> None:
        """
        Tests what happens when User tries to
        access FriendRequest, which doesn't exist
        """

        response = self.client.get(
            reverse(MANAGE_FRIEND_REQUEST_URL, kwargs={'pk': 1})
        )

        self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)

    def test_manage_friend_request_forbidden(self) -> None:
        """
        Tests what happens when User tries to
        access FriendRequest, which wasn't meant for them
        """

        data = {'to_user': self.user_two, 'from_user': self.user_one}
        friend_request = create_friend_request(**data)
        response = self.client.get(
            reverse(
                MANAGE_FRIEND_REQUEST_URL, kwargs={'pk': friend_request.pk}
            )
        )
        message = b'You don\'t have permission to manage this FriendRequest'

        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
        self.assertIn(message, response.content)

    def test_retrieve_friend_request_successfully(self) -> None:
        """Tests if a FriendRequest is retrieved successfully"""

        data = {'to_user': self.user_one, 'from_user': self.user_two}
        friend_request = create_friend_request(**data)
        response = self.client.get(
            reverse(
                MANAGE_FRIEND_REQUEST_URL, kwargs={'pk': friend_request.pk}
            )
        )
        expected_data = {
            'from_user': self.user_two.pk,
            'to_user': self.user_one.pk,
            'is_new': True,
            'is_accepted': False,
        }

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data, expected_data)

    def test_update_friend_request_successfully(self) -> None:
        """Tests if a FriendRequest is updated successfully"""

        data = {'to_user': self.user_one, 'from_user': self.user_two}
        friend_request = create_friend_request(**data)
        response = self.client.patch(
            reverse(
                MANAGE_FRIEND_REQUEST_URL, kwargs={'pk': friend_request.pk}
            ),
            {'is_new': False, 'is_accepted': True},
        )
        friend_request.refresh_from_db()

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertFalse(friend_request.is_new)
        self.assertTrue(friend_request.is_accepted)

    def test_delete_friend_request_successfully(self) -> None:
        """Tests if a FriendRequest is deleted successfully"""

        data = {'to_user': self.user_one, 'from_user': self.user_two}
        friend_request = create_friend_request(**data)
        response = self.client.delete(
            reverse(
                MANAGE_FRIEND_REQUEST_URL, kwargs={'pk': friend_request.pk}
            )
        )
        friend_request_exists = FriendRequest.objects.filter(
            pk=friend_request.pk
        ).exists()

        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
        self.assertFalse(friend_request_exists)

Tests for the public API for the FriendRequest model Sets up the APIClient for the tests and creates users Tests what happens if a FriendRequest is created by an anonymous User Tests what happens if a FriendRequest is listed by an anonymous User Tests what happens if a FriendRequest is managed by an anonymous User Tests for the private API for the FriendRequest model Creates client and users for the tests Tests if a FriendRequest is created successfully Tests if a FriendRequest isn't created when the         same one has already been sent by User Tests if a FriendRequest isn't created when the         same one has already been sent to User Tests if a FriendRequest isn't created when 'crypto_key' isn't provided Tests if a FriendRequest is listed successfully Tests what happens when User tries to         access FriendRequest, which doesn't exist Tests what happens when User tries to         access FriendRequest, which wasn't meant for them Tests if a FriendRequest is retrieved successfully Tests if a FriendRequest is updated successfully Tests if a FriendRequest is deleted successfully