Skip to content

Commit

Permalink
Completed unit test for posts and also completed some endtoend test f…
Browse files Browse the repository at this point in the history
…or post
  • Loading branch information
riadelimemmedov committed Mar 29, 2024
1 parent 2005258 commit 66e6207
Show file tree
Hide file tree
Showing 5 changed files with 226 additions and 4 deletions.
4 changes: 3 additions & 1 deletion backend/apps/posts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ def __str__(self):

# !Post
class Post(TimeStampedModel):
title = models.CharField(_("Post title"), max_length=250, unique=True, null=True)
title = models.CharField(
_("Post title"), max_length=250, unique=True, null=True, blank=False
)
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
verbose_name=_("Author post"),
Expand Down
9 changes: 8 additions & 1 deletion backend/apps/posts/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class PostWriteSerializer(serializers.ModelSerializer):

class Meta:
model = Post
exclude = ["slug"]
exclude = ["likes"]

def validate_categories(self, categories):
if len(categories) <= 0:
Expand All @@ -63,6 +63,13 @@ def validate_categories(self, categories):
)
return categories

def validate_title(self, title):
if title is None:
raise serializers.ValidationError(
"Title cannot be empty,please add title for added post"
)
return title


# !CommentReadSerializer
class CommentReadSerializer(serializers.ModelSerializer):
Expand Down
7 changes: 7 additions & 0 deletions backend/config/tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,10 @@ def categories(self, create, extracted, **kwargs):
return
if extracted:
self.categories.add(extracted)

@factory.post_generation
def likes(self, create, extracted, **kwargs):
if not create:
return
if extracted:
self.likes.add(extracted)
47 changes: 45 additions & 2 deletions backend/config/tests/posts/post/test_post.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

# !TestPosts
class TestPosts:
def test_post_factory_creation(self, post_factory, category_factory):
def test_post_factory_creation(self, post_factory, category_factory, user_factory):
"""
Test the creation of a Post instance using the post_factory.
Expand All @@ -32,13 +32,14 @@ def test_post_factory_creation(self, post_factory, category_factory):
None.
"""
obj = post_factory(categories=category_factory().id)
obj = post_factory(categories=category_factory().id, likes=user_factory().id)
assert isinstance(obj, Post)
assert obj.title is not None
assert obj.author is not None
assert obj.post_photo_url is not None
assert obj.body is not None
assert len(obj.categories.all()) > 0
assert len(obj.likes.all()) > 0

def test_str_method(self, post_factory, category_factory):
"""
Expand Down Expand Up @@ -155,3 +156,45 @@ def test_post_factory_with_categories(self, post_factory, category_factory):
assert isinstance(post, Post)
assert post.categories.count() == 1
assert Post.objects.filter(categories__id=category).exists()

def test_add_category(self, category_factory, post_factory):
"""
Test adding a category to a Post instance.
Args:
category_factory: A factory function to create a Category instance.
post_factory: A factory function to create a Post instance.
Raises:
AssertionError: If any of the assertions fail, indicating a test failure.
Returns:
None.
"""
category = category_factory()
post = post_factory()
post.categories.add(category)
assert post.categories.count() == 1
assert post.categories.first() == category

def test_add_like(self, user_factory, post_factory):
"""
Test adding a like to a Post instance.
Args:
user_factory: A factory function to create a User instance.
post_factory: A factory function to create a Post instance.
Raises:
AssertionError: If any of the assertions fail, indicating a test failure.
Returns:
None.
"""
user = user_factory()
post = post_factory()
post.likes.add(user)
assert post.likes.count() == 1
assert post.likes.first() == user
163 changes: 163 additions & 0 deletions backend/config/tests/posts/post/test_post_endpoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import json

import factory
import pytest
from django.contrib.auth import get_user_model
from django.core.files.uploadedfile import SimpleUploadedFile
from rest_framework import status

# * If you don't declare pytestmark our test class model don't accsess to database table
pytestmark = pytest.mark.django_db

# User
User = get_user_model()


# !TestPostsEndpoints
class TestPostsEndpoints:
endpoint = "/posts/"

def get_register_payload(self):
"""
Returns a dictionary representing the payload for user registration.
Returns:
dict: The payload containing user information.
"""
return {
"username": "User",
"email": "user@mail.ru",
"password": "complexpassword123",
"wallet_address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
}

def get_user_object(self, user_id):
"""
Retrieve a user object by its ID.
Args:
user_id (int): The ID of the user to retrieve.
Returns:
User: The User object matching the provided user ID.
Raises:
User.DoesNotExist: If no user with the provided ID exists.
"""
user = User.objects.get(id=user_id)
return user

@pytest.fixture
def register_response(self, api_client):
"""
Performs a user registration request using the provided API client.
Parameters:
api_client (function): A callable representing the API client.
Yields:
tuple: A tuple containing the payload and the registration response.
"""
payload = self.get_register_payload()
response = api_client().post("/users/register/", payload, format="json")
yield payload, response

@pytest.fixture
def get_user(self, register_response, api_client):
"""
Retrieves user information using the provided registration response and API client.
Parameters:
register_response (tuple): A tuple containing the payload and registration response.
api_client (function): A callable representing the API client.
Yields:
tuple: A tuple containing the user and request headers.
"""
payload, response = register_response
access_token = response.data["tokens"]["access"]
headers = {"Authorization": f"Bearer {access_token}"}
user = api_client().get("/users/", headers=headers)
yield user, headers

@pytest.fixture
def post_response(self, api_client, get_user, post_factory, category_factory):
"""
Perform a POST request to create a new post.
Args:
api_client (APIClient): The API client used to make the request.
get_user (tuple): A tuple containing the user data and headers.
post_factory (factory.Factory): The factory used to create post instances.
category_factory (factory.Factory): The factory used to create category instances.
Yields:
tuple: A tuple containing the payload, response, and user.
"""
user, headers = get_user
user = self.get_user_object(user.data["id"])
if user.is_authenticated:
payload = {
"post_photo_url": SimpleUploadedFile("test.jpg", b"xxxxxxxx"),
"title": "Male",
"body": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua",
"categories": [category_factory().id],
}
response = api_client().post(
self.endpoint, payload, format="multipart", headers=headers
)
yield payload, response, user

def test_return_all_posts(self, post_factory, api_client):
"""
Test the endpoint to return all posts.
Args:
post_factory (factory.Factory): The factory used to create post instances.
api_client (APIClient): The API client used to make the request.
"""
post_factory.create_batch(4)
response = api_client().get(self.endpoint, format="json")
assert response.status_code == status.HTTP_200_OK
assert len(json.loads(response.content)) == 4

def test_return_single_post(self, post_response, api_client):
"""
Test the endpoint to return a single post.
Args:
post_response (tuple): A tuple containing the payload, response, and user.
api_client (APIClient): The API client used to make the request.
"""
payload, response, user = post_response
response = api_client().get(
f"{self.endpoint}{response.data['slug']}/", format="json"
)
assert response.status_code == status.HTTP_200_OK
assert response.data["author"] == user.username

def test_create_post(self, post_response, api_client):
"""
Test the endpoint to create a post.
Args:
post_response (tuple): A tuple containing the payload, response, and user.
api_client (APIClient): The API client used to make the request.
"""
payload, response, user = post_response
assert response.status_code == status.HTTP_201_CREATED
assert (
response.data["id"]
and response.data["post_photo_url"]
and response.data["title"]
and response.data["body"]
and response.data["categories"]
and response.data["slug"]
and response.data["created"]
and response.data["modified"]
) is not None

0 comments on commit 66e6207

Please sign in to comment.