Skip to content

Commit 69a1f5f

Browse files
committed
test(mangas): update endpoint tests for mangas app
1 parent 907e2f7 commit 69a1f5f

File tree

7 files changed

+379
-233
lines changed

7 files changed

+379
-233
lines changed

apps/mangas/tests/integration/__init__.py

Whitespace-only changes.
Lines changed: 373 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,373 @@
1+
"""Endpoint Tests for Mangas App."""
2+
3+
import pytest
4+
from django.contrib.contenttypes.models import ContentType
5+
from rest_framework import status
6+
from rest_framework.test import APIClient
7+
8+
from apps.characters.tests.factories import CharacterMangaFactory
9+
from apps.news.tests.factories import NewsFactory
10+
from apps.persons.choices import CategoryChoices
11+
from apps.persons.tests.factories import PersonFactory
12+
from apps.reviews.models import Review
13+
from apps.reviews.tests.factories import ReviewFactory
14+
from apps.users.tests.factories import MemberFactory
15+
from apps.utils.tests.factories import PictureFactory
16+
from ...models import Magazine, Manga
17+
from ..factories import MangaFactory
18+
19+
20+
@pytest.mark.django_db
21+
def test_list_magazines(anonymous_user, magazine):
22+
response = anonymous_user.get("/api/v1/magazines/")
23+
assert response.status_code == status.HTTP_200_OK
24+
assert response.reason_phrase == "OK"
25+
assert len(response.data["results"]) > 0
26+
27+
28+
@pytest.mark.django_db
29+
def test_retrieve_magazine(anonymous_user, magazine):
30+
response = anonymous_user.get(f"/api/v1/magazines/{magazine.id}/")
31+
assert response.status_code == status.HTTP_200_OK
32+
assert str(response.data["id"]) == str(magazine.id)
33+
assert response.data["name"] == magazine.name
34+
35+
36+
@pytest.mark.django_db
37+
def test_retrieve_magazine_errors(anonymous_user):
38+
response = anonymous_user.get(
39+
"/api/v1/magazines/124f0ff1-5236-4cdb-9f0f-c0057e8d805f/"
40+
)
41+
assert response.status_code == status.HTTP_404_NOT_FOUND
42+
43+
44+
@pytest.mark.django_db
45+
def test_create_magazine(contributor_user):
46+
data = {"name": "New Magazine"}
47+
response = contributor_user.post("/api/v1/magazines/", data, format="json")
48+
assert response.status_code == status.HTTP_201_CREATED
49+
assert Magazine.objects.filter(name="New Magazine").exists()
50+
assert response.data["name"] == "New Magazine"
51+
52+
53+
@pytest.mark.django_db
54+
def test_create_magazine_unauthorized(member_user):
55+
data = {"name": "Unauthorized Magazine"}
56+
member_response = member_user.post("/api/v1/magazines/", data, format="json")
57+
assert member_response.status_code == status.HTTP_403_FORBIDDEN
58+
member_user.logout()
59+
anonymus_response = member_user.post("/api/v1/magazines/", data, format="json")
60+
assert anonymus_response.status_code == status.HTTP_401_UNAUTHORIZED
61+
assert not Magazine.objects.filter(name="Unauthorized Magazine").exists()
62+
63+
64+
@pytest.mark.django_db
65+
def test_update_magazine(contributor_user, magazine):
66+
data = {"name": "Updated Magazine"}
67+
response = contributor_user.put(
68+
f"/api/v1/magazines/{magazine.id}/", data, format="json"
69+
)
70+
assert response.status_code == status.HTTP_200_OK
71+
assert response.reason_phrase == "OK"
72+
magazine.refresh_from_db()
73+
assert magazine.name == "Updated Magazine"
74+
75+
76+
@pytest.mark.django_db
77+
def test_partial_update_magazine(contributor_user, magazine):
78+
data = {"name": "Partially Updated Magazine"}
79+
response = contributor_user.patch(
80+
f"/api/v1/magazines/{magazine.id}/",
81+
data,
82+
format="json",
83+
)
84+
assert response.status_code == status.HTTP_200_OK
85+
assert response.reason_phrase == "OK"
86+
magazine.refresh_from_db()
87+
assert magazine.name == "Partially Updated Magazine"
88+
89+
90+
@pytest.mark.django_db
91+
def test_delete_magazine(contributor_user, magazine):
92+
assert magazine.is_available
93+
response = contributor_user.delete(f"/api/v1/magazines/{magazine.id}/")
94+
magazine.refresh_from_db()
95+
assert response.status_code == status.HTTP_204_NO_CONTENT
96+
assert Magazine.objects.filter(id=magazine.id).exists()
97+
assert not magazine.is_available
98+
99+
100+
@pytest.mark.django_db
101+
def test_list_mangas(anonymous_user, manga):
102+
response = anonymous_user.get("/api/v1/mangas/")
103+
assert response.status_code == status.HTTP_200_OK
104+
assert response.reason_phrase == "OK"
105+
assert len(response.data["results"]) > 0
106+
107+
108+
@pytest.mark.django_db
109+
def test_retrieve_manga(anonymous_user, manga):
110+
response = anonymous_user.get(f"/api/v1/mangas/{manga.id}/")
111+
assert response.status_code == status.HTTP_200_OK
112+
assert response.reason_phrase == "OK"
113+
assert str(response.data["id"]) == str(manga.id)
114+
assert response.data["name"] == manga.name
115+
116+
117+
@pytest.mark.django_db
118+
def test_retrieve_manga_not_found(anonymous_user):
119+
response = anonymous_user.get(
120+
"/api/v1/magazines/124f0ff1-5236-4cdb-9f0f-c0057e8d805f/"
121+
)
122+
assert response.status_code == status.HTTP_404_NOT_FOUND
123+
124+
125+
@pytest.mark.django_db
126+
def test_create_manga(contributor_user, manga, demographic):
127+
author = PersonFactory.create(category=CategoryChoices.ARTIST)
128+
data = {
129+
"name": "Oyasumi Punpun",
130+
"name_jpn": "おやすみプンプン",
131+
"image": manga.image,
132+
"synopsis": manga.synopsis,
133+
"background": manga.background,
134+
"media_type": manga.media_type,
135+
"volumes": manga.volumes,
136+
"chapters": manga.chapters,
137+
"status": manga.status,
138+
"published_from": manga.published_from,
139+
"published_to": manga.published_to,
140+
"genres": [str(genre.id) for genre in manga.genres.all()],
141+
"themes": [str(theme.id) for theme in manga.themes.all()],
142+
"demographic_id": str(manga.demographic_id.id),
143+
"serialization_id": str(manga.serialization_id.id),
144+
"author_id": str(author.id),
145+
"website": manga.website,
146+
}
147+
response = contributor_user.post(
148+
"/api/v1/mangas/",
149+
data,
150+
format="multipart",
151+
)
152+
assert response.status_code == status.HTTP_201_CREATED
153+
assert response.reason_phrase == "Created"
154+
assert Manga.objects.filter(name="Oyasumi Punpun").exists()
155+
assert response.data["name"] == "Oyasumi Punpun"
156+
assert response.data["name_jpn"] == "おやすみプンプン"
157+
158+
159+
@pytest.mark.django_db
160+
def test_create_manga_unauthorized(member_user):
161+
data = {}
162+
member_response = member_user.post("/api/v1/mangas/", data, format="json")
163+
assert member_response.status_code == status.HTTP_403_FORBIDDEN
164+
assert member_response.reason_phrase == "Forbidden"
165+
member_user.logout()
166+
anonymus_response = member_user.post("/api/v1/mangas/", data, format="json")
167+
assert anonymus_response.status_code == status.HTTP_401_UNAUTHORIZED
168+
assert anonymus_response.reason_phrase == "Unauthorized"
169+
assert not Manga.objects.filter(name="Unauthorized manga").exists()
170+
171+
172+
@pytest.mark.django_db
173+
def test_update_manga(contributor_user, manga):
174+
author = PersonFactory.create(category=CategoryChoices.ARTIST)
175+
data = {
176+
"name": "Frieren: Beyond Journey's End",
177+
"name_jpn": "葬送のフリーレン",
178+
"image": manga.image,
179+
"synopsis": manga.synopsis,
180+
"background": manga.background,
181+
"media_type": manga.media_type,
182+
"volumes": manga.volumes,
183+
"chapters": manga.chapters,
184+
"status": manga.status,
185+
"published_from": manga.published_from,
186+
"published_to": manga.published_to,
187+
"genres": [str(genre.id) for genre in manga.genres.all()],
188+
"themes": [str(theme.id) for theme in manga.themes.all()],
189+
"demographic_id": str(manga.demographic_id.id),
190+
"serialization_id": str(manga.serialization_id.id),
191+
"author_id": str(author.id),
192+
"website": manga.website,
193+
}
194+
response = contributor_user.put(
195+
f"/api/v1/mangas/{manga.id}/", data, format="multipart"
196+
)
197+
assert response.status_code == status.HTTP_200_OK
198+
assert response.reason_phrase == "OK"
199+
manga.refresh_from_db()
200+
assert manga.name == "Frieren: Beyond Journey's End"
201+
assert manga.name_jpn == "葬送のフリーレン"
202+
203+
204+
@pytest.mark.django_db
205+
def test_partial_update_manga(contributor_user, manga):
206+
data = {"name": "Houseki no Kuni"}
207+
response = contributor_user.patch(
208+
f"/api/v1/mangas/{manga.id}/", data, format="json"
209+
)
210+
assert response.status_code == status.HTTP_200_OK
211+
assert response.reason_phrase == "OK"
212+
manga.refresh_from_db()
213+
assert manga.name == "Houseki no Kuni"
214+
215+
216+
@pytest.mark.django_db
217+
def test_delete_manga(contributor_user, manga):
218+
assert manga.is_available
219+
response = contributor_user.delete(f"/api/v1/mangas/{manga.id}/")
220+
manga.refresh_from_db()
221+
assert response.status_code == status.HTTP_204_NO_CONTENT
222+
assert response.reason_phrase == "No Content"
223+
assert Manga.objects.filter(id=manga.id).exists()
224+
assert not manga.is_available
225+
226+
227+
@pytest.mark.django_db
228+
def test_list_characters_by_manga(anonymous_user, character, manga):
229+
CharacterMangaFactory(character_id=character, manga_id=manga)
230+
response = anonymous_user.get(f"/api/v1/mangas/{manga.id}/characters/")
231+
assert response.status_code == status.HTTP_200_OK
232+
assert response.reason_phrase == "OK"
233+
assert len(response.data) == 1
234+
235+
236+
@pytest.mark.django_db
237+
def test_list_characters_by_manga_errors(anonymous_user, manga):
238+
response = anonymous_user.get(f"/api/v1/mangas/{manga.id}/characters/")
239+
assert response.status_code == status.HTTP_404_NOT_FOUND
240+
assert response.reason_phrase == "Not Found"
241+
assert response.data["detail"] == "No characters found for this manga."
242+
243+
244+
@pytest.mark.django_db
245+
def test_retrieve_stats_by_manga(anonymous_user, manga):
246+
response = anonymous_user.get(f"/api/v1/mangas/{manga.id}/stats/")
247+
assert response.status_code == status.HTTP_200_OK
248+
assert response.reason_phrase == "OK"
249+
assert "id" in response.data
250+
assert "reading" in response.data
251+
assert "completed" in response.data
252+
assert "on_hold" in response.data
253+
assert "dropped" in response.data
254+
assert "plan_to_read" in response.data
255+
assert "total" in response.data
256+
257+
258+
@pytest.mark.django_db
259+
def test_retrieve_stats_by_manga_errors(anonymous_user):
260+
manga_id = "88bf5d4f-115b-4dea-a7c5-4fc45b794c9a"
261+
response = anonymous_user.get(f"/api/v1/mangas/{manga_id}/stats/")
262+
assert response.status_code == status.HTTP_404_NOT_FOUND
263+
assert response.reason_phrase == "Not Found"
264+
assert response.data["detail"] == "Not found."
265+
266+
267+
@pytest.mark.django_db
268+
def test_list_reviews_by_manga(anonymous_user, manga):
269+
review = ReviewFactory(
270+
content_type=ContentType.objects.get_for_model(Manga),
271+
object_id=manga.id,
272+
)
273+
response = anonymous_user.get(f"/api/v1/mangas/{manga.id}/reviews/")
274+
assert response.status_code == status.HTTP_200_OK
275+
assert response.reason_phrase == "OK"
276+
assert len(response.data) > 0
277+
assert str(response.data[0]["id"]) == str(review.id)
278+
279+
280+
@pytest.mark.django_db
281+
def test_create_review_by_manga(member_user, manga, review):
282+
data = {
283+
"comment": "Review created",
284+
"is_spoiler": review.is_spoiler,
285+
"rating": review.rating,
286+
}
287+
response = member_user.post(
288+
f"/api/v1/mangas/{manga.id}/reviews/create/", data, format="json"
289+
)
290+
assert response.status_code == status.HTTP_201_CREATED
291+
assert response.reason_phrase == "Created"
292+
assert Review.objects.filter(comment="Review created").exists()
293+
assert response.data["comment"] == "Review created"
294+
295+
296+
@pytest.mark.django_db
297+
def test_update_review_by_manga(manga):
298+
user = MemberFactory()
299+
api_client = APIClient()
300+
api_client.force_authenticate(user=user)
301+
review = ReviewFactory(
302+
user_id=user,
303+
content_type=ContentType.objects.get_for_model(Manga),
304+
object_id=manga.id,
305+
)
306+
data = {
307+
"comment": "Review updated",
308+
"is_spoiler": review.is_spoiler,
309+
"rating": review.rating,
310+
}
311+
response = api_client.patch(
312+
f"/api/v1/mangas/{manga.id}/reviews/{review.id}/", data, format="json"
313+
)
314+
assert response.status_code == status.HTTP_200_OK
315+
assert response.reason_phrase == "OK"
316+
manga.refresh_from_db()
317+
assert response.data["comment"] == "Review updated"
318+
319+
320+
@pytest.mark.django_db
321+
def test_list_recommendations_by_manga(anonymous_user, theme, genre):
322+
manga = MangaFactory(genres=[genre], themes=[theme])
323+
MangaFactory.create_batch(3, genres=[genre], themes=[theme])
324+
response = anonymous_user.get(f"/api/v1/mangas/{manga.id}/recommendations/")
325+
assert response.status_code == status.HTTP_200_OK
326+
assert response.reason_phrase == "OK"
327+
assert len(response.data) == 3
328+
329+
330+
@pytest.mark.django_db
331+
def test_list_recommendations_by_manga_errors(anonymous_user, manga):
332+
response = anonymous_user.get(f"/api/v1/mangas/{manga.id}/recommendations/")
333+
assert response.status_code == status.HTTP_404_NOT_FOUND
334+
assert response.reason_phrase == "Not Found"
335+
assert response.data["detail"] == "No recommendations found for this manga."
336+
337+
338+
@pytest.mark.django_db
339+
def test_list_news_by_manga(anonymous_user, manga):
340+
NewsFactory.create_batch(3, manga_relations=[manga])
341+
response = anonymous_user.get(f"/api/v1/mangas/{manga.id}/news/")
342+
assert response.status_code == status.HTTP_200_OK
343+
assert response.reason_phrase == "OK"
344+
assert len(response.data) == 3
345+
346+
347+
@pytest.mark.django_db
348+
def test_list_news_by_manga_errors(anonymous_user, manga):
349+
response = anonymous_user.get(f"/api/v1/mangas/{manga.id}/news/")
350+
assert response.status_code == status.HTTP_404_NOT_FOUND
351+
assert response.reason_phrase == "Not Found"
352+
assert response.data["detail"] == "No news found for this manga."
353+
354+
355+
@pytest.mark.django_db
356+
def test_list_pictures_by_manga(anonymous_user, manga):
357+
PictureFactory.create_batch(
358+
3,
359+
content_type=ContentType.objects.get_for_model(Manga),
360+
object_id=manga.id,
361+
)
362+
response = anonymous_user.get(f"/api/v1/mangas/{manga.id}/pictures/")
363+
assert response.status_code == status.HTTP_200_OK
364+
assert response.reason_phrase == "OK"
365+
assert len(response.data) == 3
366+
367+
368+
@pytest.mark.django_db
369+
def test_list_pictures_by_manga_errors(anonymous_user, manga):
370+
response = anonymous_user.get(f"/api/v1/mangas/{manga.id}/pictures/")
371+
assert response.status_code == status.HTTP_404_NOT_FOUND
372+
assert response.reason_phrase == "Not Found"
373+
assert response.data["detail"] == "No pictures found for this manga."

0 commit comments

Comments
 (0)