Skip to content

Commit 9ff02be

Browse files
committed
test(animes): add endpoint tests for animes app
1 parent 6f1fe42 commit 9ff02be

File tree

1 file changed

+241
-0
lines changed

1 file changed

+241
-0
lines changed
Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
"""Endpoint Tests for Animes App."""
2+
3+
import pytest
4+
from datetime import timedelta
5+
from django.contrib.contenttypes.models import ContentType
6+
from rest_framework import status
7+
from rest_framework.test import APIClient
8+
9+
from apps.utils.functions import generate_test_image
10+
from apps.characters.tests.factories import CharacterAnimeFactory
11+
from apps.characters.serializers import CharacterMinimalSerializer
12+
from apps.persons.tests.factories import PersonFactory, StaffAnimeFactory
13+
from apps.persons.models import Person, StaffAnime
14+
from apps.persons.serializers import StaffMinimalSerializer
15+
from apps.producers.tests.factories import ProducerFactory
16+
from apps.producers.choices import TypeChoices
17+
from apps.reviews.tests.factories import ReviewFactory
18+
from apps.reviews.models import Review
19+
from apps.reviews.serializers import ReviewReadSerializer
20+
from apps.users.tests.factories import MemberFactory
21+
from ...models import Anime
22+
from ...choices import SeasonChoices
23+
24+
25+
@pytest.mark.django_db
26+
def test_list_animes(anonymous_user, anime):
27+
response = anonymous_user.get("/api/v1/animes/")
28+
assert response.status_code == status.HTTP_200_OK
29+
assert len(response.json()) > 0
30+
31+
32+
@pytest.mark.django_db
33+
def test_retrieve_anime(anonymous_user, anime):
34+
response = anonymous_user.get(f"/api/v1/animes/{anime.id}/")
35+
assert response.status_code == status.HTTP_200_OK
36+
assert str(response.data["id"]) == str(anime.id)
37+
assert response.data["name"] == anime.name
38+
39+
40+
@pytest.mark.django_db
41+
def test_retrieve_anime_not_found(anonymous_user):
42+
response = anonymous_user.get(
43+
"/api/v1/genres/989423d1-d6c0-431a-8f62-d805b8a5f321/"
44+
)
45+
assert response.status_code == status.HTTP_404_NOT_FOUND
46+
47+
48+
@pytest.mark.django_db
49+
def test_create_anime(contributor_user, genre, theme):
50+
producer = ProducerFactory(type=TypeChoices.STUDIO)
51+
image = generate_test_image(size=(600, 600))
52+
data = {
53+
"name": "New Anime",
54+
"name_jpn": "New Anime",
55+
"image": image,
56+
"season": SeasonChoices.SPRING,
57+
"year": 2024,
58+
"aired_from": "2023-07-01",
59+
"studio_id": str(producer.id),
60+
"genres": [str(genre.id)],
61+
"themes": [str(theme.id)],
62+
"duration": timedelta(hours=1, minutes=45, seconds=30),
63+
}
64+
response = contributor_user.post(
65+
"/api/v1/animes/",
66+
data,
67+
format="multipart",
68+
)
69+
assert response.status_code == status.HTTP_201_CREATED
70+
assert Anime.objects.filter(name="New Anime").exists()
71+
assert response.data["name"] == "New Anime"
72+
73+
74+
@pytest.mark.django_db
75+
def test_create_anime_unauthorized(member_user):
76+
data = {}
77+
member_response = member_user.post("/api/v1/animes/", data, format="json")
78+
assert member_response.status_code == status.HTTP_403_FORBIDDEN
79+
member_user.logout()
80+
anonymus_response = member_user.post("/api/v1/animes/", data, format="json")
81+
assert anonymus_response.status_code == status.HTTP_401_UNAUTHORIZED
82+
83+
84+
@pytest.mark.django_db
85+
def test_update_anime(contributor_user, anime, genre, theme):
86+
producer = ProducerFactory(type=TypeChoices.STUDIO)
87+
image = generate_test_image(size=(600, 600))
88+
data = {
89+
"name": "Updated Anime",
90+
"name_jpn": "Updated Anime",
91+
"image": image,
92+
"season": SeasonChoices.SPRING,
93+
"year": 2024,
94+
"aired_from": "2023-07-01",
95+
"studio_id": str(producer.id),
96+
"genres": [str(genre.id)],
97+
"themes": [str(theme.id)],
98+
"duration": timedelta(hours=1, minutes=45, seconds=30),
99+
}
100+
response = contributor_user.put(
101+
f"/api/v1/animes/{anime.id}/", data, format="multipart"
102+
)
103+
assert response.status_code == status.HTTP_200_OK
104+
anime.refresh_from_db()
105+
assert anime.name == "Updated Anime"
106+
107+
108+
@pytest.mark.django_db
109+
def test_partial_update_anime(contributor_user, anime):
110+
data = {"name": "Partially Updated Anime"}
111+
response = contributor_user.patch(
112+
f"/api/v1/animes/{anime.id}/",
113+
data,
114+
format="json",
115+
)
116+
assert response.status_code == status.HTTP_200_OK
117+
anime.refresh_from_db()
118+
assert anime.name == "Partially Updated Anime"
119+
120+
121+
@pytest.mark.django_db
122+
def test_delete_anime(contributor_user, anime):
123+
assert anime.is_available
124+
response = contributor_user.delete(f"/api/v1/animes/{anime.id}/")
125+
anime.refresh_from_db()
126+
assert response.status_code == status.HTTP_204_NO_CONTENT
127+
assert Anime.objects.filter(id=anime.id).exists()
128+
assert not anime.is_available
129+
130+
131+
@pytest.mark.django_db
132+
def test_list_characters_by_anime(anonymous_user, anime, character):
133+
CharacterAnimeFactory(character_id=character, anime_id=anime)
134+
response = anonymous_user.get(f"/api/v1/animes/{anime.id}/characters/")
135+
assert response.status_code == status.HTTP_200_OK
136+
expected_data = CharacterMinimalSerializer([character], many=True).data
137+
assert response.json() == expected_data
138+
139+
140+
@pytest.mark.django_db
141+
def test_list_characters_by_anime_errors(anonymous_user, anime):
142+
response = anonymous_user.get(f"/api/v1/animes/{anime.id}/characters/")
143+
assert response.status_code == status.HTTP_404_NOT_FOUND
144+
assert response.data["detail"] == "No characters found for this anime."
145+
146+
147+
@pytest.mark.django_db
148+
def test_list_staff_by_anime(anonymous_user, anime):
149+
staff_one = PersonFactory()
150+
staff_two = PersonFactory()
151+
StaffAnimeFactory(person_id=staff_one, anime_id=anime)
152+
StaffAnimeFactory(person_id=staff_two, anime_id=anime)
153+
response = anonymous_user.get(f"/api/v1/animes/{anime.id}/staff/")
154+
assert response.status_code == status.HTTP_200_OK
155+
staff_ids = StaffAnime.objects.filter(anime_id=anime.id).values_list(
156+
"person_id", flat=True
157+
)
158+
staff = Person.objects.filter(id__in=staff_ids)
159+
serializer = StaffMinimalSerializer(staff, many=True)
160+
assert response.data == serializer.data
161+
162+
163+
@pytest.mark.django_db
164+
def test_list_staff_by_anime_errors(anonymous_user, anime):
165+
response = anonymous_user.get(f"/api/v1/animes/{anime.id}/staff/")
166+
assert response.status_code == status.HTTP_404_NOT_FOUND
167+
assert response.data["detail"] == "No staff found for this anime."
168+
169+
170+
@pytest.mark.django_db
171+
def test_retrieve_stats_by_anime(anonymous_user, anime):
172+
response = anonymous_user.get(f"/api/v1/animes/{anime.id}/stats/")
173+
assert response.status_code == status.HTTP_200_OK
174+
assert "id" in response.data
175+
assert "watching" in response.data
176+
assert "completed" in response.data
177+
assert "on_hold" in response.data
178+
assert "dropped" in response.data
179+
assert "plan_to_watch" in response.data
180+
assert "total" in response.data
181+
182+
183+
@pytest.mark.django_db
184+
def test_retrieve_stats_by_anime_errors(anonymous_user, anime):
185+
response = anonymous_user.get(
186+
"/api/v1/animes/1ec14918-dbf8-41cd-b1fd-1ad4b4493835/stats/"
187+
)
188+
assert response.status_code == status.HTTP_404_NOT_FOUND
189+
assert response.data["detail"] == "Not found."
190+
191+
192+
@pytest.mark.django_db
193+
def test_list_reviews_by_anime(anonymous_user, anime):
194+
review = ReviewFactory(
195+
content_type=ContentType.objects.get_for_model(Anime),
196+
object_id=anime.id,
197+
)
198+
response = anonymous_user.get(f"/api/v1/animes/{anime.id}/reviews/")
199+
expected_data = ReviewReadSerializer([review], many=True).data
200+
assert response.status_code == status.HTTP_200_OK
201+
assert response.data == expected_data
202+
203+
204+
@pytest.mark.django_db
205+
def test_create_review_by_anime(member_user, anime, review):
206+
data = {
207+
"comment": "Review created",
208+
"is_spoiler": review.is_spoiler,
209+
"rating": review.rating,
210+
}
211+
response = member_user.post(
212+
f"/api/v1/animes/{anime.id}/reviews/create/",
213+
data,
214+
format="json",
215+
)
216+
assert response.status_code == status.HTTP_201_CREATED
217+
assert Review.objects.filter(comment="Review created").exists()
218+
assert response.data["comment"] == "Review created"
219+
220+
221+
@pytest.mark.django_db
222+
def test_update_review_by_anime(anime):
223+
user = MemberFactory()
224+
api_client = APIClient()
225+
api_client.force_authenticate(user=user)
226+
review = ReviewFactory(
227+
user_id=user,
228+
content_type=ContentType.objects.get_for_model(Anime),
229+
object_id=anime.id,
230+
)
231+
data = {
232+
"comment": "Review updated",
233+
"is_spoiler": review.is_spoiler,
234+
"rating": review.rating,
235+
}
236+
response = api_client.patch(
237+
f"/api/v1/animes/{anime.id}/reviews/{review.id}/", data, format="json"
238+
)
239+
assert response.status_code == status.HTTP_200_OK
240+
anime.refresh_from_db()
241+
assert response.data["comment"] == "Review updated"

0 commit comments

Comments
 (0)