diff --git a/apps/bookmark/tests.py b/apps/bookmark/tests.py index 7ce503c..289ed9b 100644 --- a/apps/bookmark/tests.py +++ b/apps/bookmark/tests.py @@ -1,3 +1,52 @@ from django.test import TestCase +from django.contrib.auth import get_user_model +from rest_framework.test import APIClient +from rest_framework import status +from django.urls import reverse +from apps.bookmark.models import Bookmark +from dj_language.models import Language -# Create your tests here. +User = get_user_model() + +class BookmarkListViewTestCase(TestCase): + def setUp(self): + self.client = APIClient() + Language.objects.get_or_create(id=69, defaults={'name': 'English', 'code': 'en', 'countries': 'US'}) + self.user = User.objects.create_user(username='testuser', email='testuser@example.com', password='password123') + self.other_user = User.objects.create_user(username='otheruser', email='otheruser@example.com', password='password123') + self.url = reverse('bookmark:bookmark_list') + + def test_unauthenticated_access(self): + response = self.client.get(self.url) + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + + def test_get_bookmarks_authenticated(self): + self.client.force_authenticate(user=self.user) + + # Create active bookmarks for self.user + Bookmark.objects.create(user=self.user, service=Bookmark.ServiceChoices.HADITH, content_id=101, status=True) + Bookmark.objects.create(user=self.user, service=Bookmark.ServiceChoices.LIBRARY, content_id=202, status=True) + # Create inactive bookmark + Bookmark.objects.create(user=self.user, service=Bookmark.ServiceChoices.HADITH, content_id=303, status=False) + # Create bookmark for another user + Bookmark.objects.create(user=self.other_user, service=Bookmark.ServiceChoices.HADITH, content_id=404, status=True) + + response = self.client.get(self.url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data), 2) + content_ids = [item['content_id'] for item in response.data] + self.assertIn(101, content_ids) + self.assertIn(202, content_ids) + self.assertNotIn(303, content_ids) + self.assertNotIn(404, content_ids) + + def test_filter_by_service(self): + self.client.force_authenticate(user=self.user) + Bookmark.objects.create(user=self.user, service=Bookmark.ServiceChoices.HADITH, content_id=101, status=True) + Bookmark.objects.create(user=self.user, service=Bookmark.ServiceChoices.LIBRARY, content_id=202, status=True) + + response = self.client.get(self.url, {'service': 'hadith'}) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data), 1) + self.assertEqual(response.data[0]['content_id'], 101) + self.assertEqual(response.data[0]['service'], 'hadith') diff --git a/apps/bookmark/urls.py b/apps/bookmark/urls.py index c45db51..8c3f16a 100644 --- a/apps/bookmark/urls.py +++ b/apps/bookmark/urls.py @@ -1,10 +1,16 @@ from django.urls import path -from .views import AddBookmarkView, RemoveBookmarkView, BookmarkStatusView, AddBookmarkListView, RemoveBookmarkListView, AddRateView, RemoveRateView, RateStatusView, AverageRateView +from .views import ( + AddBookmarkView, RemoveBookmarkView, BookmarkStatusView, + AddBookmarkListView, RemoveBookmarkListView, BookmarkListView, + AddRateView, RemoveRateView, RateStatusView, AverageRateView +) app_name = 'bookmark' urlpatterns = [ # Bookmark URLs + path('', BookmarkListView.as_view(), name='bookmark_list_root'), + path('list/', BookmarkListView.as_view(), name='bookmark_list'), path('add/', AddBookmarkView.as_view(), name='add_bookmark'), path('add-list/', AddBookmarkListView.as_view(), name='add_bookmark_list'), path('remove/', RemoveBookmarkView.as_view(), name='remove_bookmark'), diff --git a/apps/bookmark/views/bookmark.py b/apps/bookmark/views/bookmark.py index 946ff67..f4212ab 100644 --- a/apps/bookmark/views/bookmark.py +++ b/apps/bookmark/views/bookmark.py @@ -303,3 +303,42 @@ class BookmarkStatusView(APIView): result = list(service_counts.values()) return Response(result, status=status.HTTP_200_OK) + + +class BookmarkListView(APIView): + """ + Return all active bookmarks for the current user. + Optionally filter by service (e.g. ?service=hadith). + """ + permission_classes = [IsAuthenticated] + authentication_classes = [TokenAuthentication] + + @swagger_auto_schema( + operation_description="Return all active bookmarks for the current user. Optionally filter by service query parameter (e.g., 'hadith', 'library').", + tags=["Dobodbi - Bookmarks"], + manual_parameters=[ + openapi.Parameter( + 'service', + openapi.IN_QUERY, + description="Filter bookmarks by service (e.g., 'hadith', 'library', 'video', 'podcast', 'article')", + type=openapi.TYPE_STRING, + required=False + ) + ], + responses={ + 200: BookmarkSerializer(many=True) + } + ) + def get(self, request, *args, **kwargs): + service = request.query_params.get('service') + bookmarks = Bookmark.objects.filter( + user=request.user, + status=True + ) + if service: + bookmarks = bookmarks.filter(service=service) + + bookmarks = bookmarks.order_by('-created_at') + serializer = BookmarkSerializer(bookmarks, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) +