Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions book/permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from rest_framework.permissions import (
SAFE_METHODS,
BasePermission
)


class IsAdminOrReadOnly(BasePermission):
def has_permission(self, request, view):
if request.method in SAFE_METHODS:
return True
return request.user and request.user.is_staff
100 changes: 74 additions & 26 deletions book/tests/test_book_view_set.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from django.contrib.auth import get_user_model
from rest_framework import status
from rest_framework.test import APITestCase
from book.models import Book

User = get_user_model()

class BookViewSetTest(APITestCase):
def setUp(self):
"""Create a test book entry before tests"""
"""Set up test data before running tests"""
self.book = Book.objects.create(
title="Test Book",
author="Test Author",
Expand All @@ -14,47 +16,93 @@ def setUp(self):
daily_fee=10.00,
)

def test_create_book(self):
"""Test creating a book via the API"""
# Create a superuser using the custom user model
self.superuser = User.objects.create_superuser(
email="admin@example.com",
password="admin123"
)

# Create a regular user using the custom user model
self.user = User.objects.create_user(
email="user@example.com",
password="user123"
)

def test_list_books_unauthenticated(self):
"""Test: Unauthenticated users can view the list of books"""
response = self.client.get("/api/books/")
self.assertEqual(response.status_code, status.HTTP_200_OK)

def test_retrieve_book_unauthenticated(self):
"""Test: Unauthenticated users can view book details"""
response = self.client.get(f"/api/books/{self.book.id}/")
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data["title"], self.book.title)

def test_create_book_as_superuser(self):
"""Test: Superusers can create new books"""
self.client.force_authenticate(user=self.superuser)
data = {
"title": "New Book",
"author": "New Author",
"cover": Book.Cover.HARD,
"inventory": 5,
"daily_fee": 12.00,
}
response = self.client.post(
"/api/book-service/books/", data, format="json"
)
response = self.client.post("/api/books/", data, format="json")
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(response.data["title"], data["title"])

def test_read_book(self):
"""Test retrieving a book via the API"""
response = self.client.get(f"/api/book-service/books/{self.book.id}/")
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data["title"], self.book.title)
def test_create_book_as_regular_user(self):
"""Test: Regular users cannot create new books"""
self.client.force_authenticate(user=self.user)
data = {
"title": "New Book",
"author": "New Author",
"cover": Book.Cover.HARD,
"inventory": 5,
"daily_fee": 12.00,
}
response = self.client.post("/api/books/", data, format="json")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

def test_update_book(self):
"""Test updating a book via the API"""
def test_update_book_as_superuser(self):
"""Test: Superusers can update book details"""
self.client.force_authenticate(user=self.superuser)
data = {
"inventory": 10, # Перевірка нового значення inventory
"title": self.book.title, # Титул залишається незмінним
"author": self.book.author, # Автор залишається незмінним
"cover": self.book.cover, # Обкладинка залишається незмінною
"daily_fee": self.book.daily_fee, # Залишаємо попереднє значення daily_fee
"inventory": 10,
"title": self.book.title,
"author": self.book.author,
"cover": self.book.cover,
"daily_fee": self.book.daily_fee,
}
response = self.client.put(
f"/api/book-service/books/{self.book.id}/", data, format="json"
)
response = self.client.put(f"/api/books/{self.book.id}/", data, format="json")
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.book.refresh_from_db()
self.assertEqual(self.book.inventory, 10)

def test_delete_book(self):
"""Test deleting a book via the API"""
response = self.client.delete(
f"/api/book-service/books/{self.book.id}/"
)
def test_update_book_as_regular_user(self):
"""Test: Regular users cannot update book details"""
self.client.force_authenticate(user=self.user)
data = {
"inventory": 10,
"title": self.book.title,
"author": self.book.author,
"cover": self.book.cover,
"daily_fee": self.book.daily_fee,
}
response = self.client.put(f"/api/books/{self.book.id}/", data, format="json")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

def test_delete_book_as_superuser(self):
"""Test: Superusers can delete books"""
self.client.force_authenticate(user=self.superuser)
response = self.client.delete(f"/api/books/{self.book.id}/")
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
self.assertFalse(Book.objects.filter(id=self.book.id).exists())

def test_delete_book_as_regular_user(self):
"""Test: Regular users cannot delete books"""
self.client.force_authenticate(user=self.user)
response = self.client.delete(f"/api/books/{self.book.id}/")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
5 changes: 2 additions & 3 deletions book/urls.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from django.urls import path, include
from rest_framework import routers
from book.views import BookViewSet

app_name = "book"

router = routers.DefaultRouter()
router.register("books", BookViewSet)
router.register("", BookViewSet, basename="books")

urlpatterns = [path("", include(router.urls))]
urlpatterns = router.urls
2 changes: 2 additions & 0 deletions book/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from rest_framework import viewsets

from book.models import Book
from book.permissions import IsAdminOrReadOnly
from book.serializers import BookSerializer


Expand All @@ -13,3 +14,4 @@ class BookViewSet(viewsets.ModelViewSet):

queryset = Book.objects.prefetch_related("borrowings")
serializer_class = BookSerializer
permission_classes = [IsAdminOrReadOnly,]
2 changes: 1 addition & 1 deletion core/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@
path("api/schema/", SpectacularAPIView.as_view(), name="schema"),
path("api/schema/swagger-ui/", SpectacularSwaggerView.as_view(url_name="schema"), name="swagger-ui"),
path("api/schema/redoc/", SpectacularRedocView.as_view(url_name="schema"), name="redoc"),
path("api/book-service/", include("book.urls", namespace="book")),
path("api/books/", include("book.urls", namespace="book")),
]
Loading